תאימות ל-StableHLO

StableHLO היא פעולת מחשוב של למידת מכונה תואמת לאחור בהשראת HLO/MHLO. במסמך הזה מוסבר על הסוג וההיקף של התחייבויות התאימות ש-StableHLO מספקת, על סמך התהליך שנקבע ב-RFC של התאימות.

גרסאות

הגרסה הנוכחית של StableHLO מופיעה בדף Version.h.

הגרסה המשנית נחשפה בכל פעם שמתבצעים שינויים ב-opset של StableHLO או בפורמט של סריאליזציה של StableHLO, וגרסת התיקון מתועדת בכל פעם שאנחנו משלבים את StableHLO ב-downstream, כלומר במאגר של openxla/xla.

ערבויות

בהתאם ל-StableHLO v1.0 RFC RFC, חלון התאימות כולל את הפרטים הבאים:

5 שנים של תאימות לאחור: ארטיפקטים ניידים שיש להם סריאליזציה לגרסה ישנה של libStablehlo יש את אותה סמנטיקה* כשהיא מיובשת על ידי גרסה חדשה של libStablehlo, אם הגרסאות האלה בנויות מהתחייבויות של openxla/stablehlo שמופרדות ביניהן של פחות מ-5 שנים.

תאימות לשנתיים: ארטיפקטים ניידים שיש להם סריאליזציה לגרסה חדשה של libStablehlo יש את אותה סמנטיקה* כשהיא מיושבת על ידי גרסה ישנה של libStablehlo, אם הגרסאות האלה נוצרות מהתחייבויות של openxla/stablehlo בהפרש של פחות משנתיים, אלא אם התוכנית משתמשת בתכונות חדשות שנוספו מאז הגרסה הקודמת.

* תוכניות של StableHLO מומרות אל ארטיפקטים ניידים או שמקורם בממשקי API של תאימות, והסמנטיקה של התוכנות האלה מוגדרת במפרט StableHLO. עיינו בקטע 'לא נכלל' כדי לראות דוגמאות למה שלא נכלל בהגדרת התאימות הזו.

ממשקי API

אפשר ליצור ארטיפקטים ניידים באמצעות הכלי stablehlo-translate, או ישירות בממשקי API של C++ או Python. כדי ליצור סריאליזציה, נדרשת גרסת יעד של StableHLO כדי לכתוב ארטיפקט שנכתב בפורמט #.#.# (יש לעיין בגרסה Version.h של הגרסה הנוכחית). מאחר שגרסאות תיקון לא משפיעות על התאימות, כל יעד עם גרסת תיקון שאינה אפס מוגדר כברירת מחדל ל-0 במהלך סריאליזציה. פעולת deserialization משתמשת בגרסה הנוכחית של StableHLO כדי לקרוא פריט מידע שנוצר בתהליך פיתוח (Artifact).

stablehlo-translate

זו הדרך הקלה ביותר ליצור ולקרוא ארטיפקט נייד.

# Write a StableHLO program to a portable artifact
$ stablehlo-translate --serialize file.mlir --target=0.9.0 > portable_artifact.mlir.bc

# Read StableHLO portable artifact
$ stablehlo-translate --deserialize portable_artifact.mlir.bc

C++

לתהליכי עבודה פרוגרמטיים, StableHLO מספקת את ממשקי ה-API הבאים לתאימות:

// From: #include "stablehlo/api/PortableApi.h"

// Get the current StableHLO version.
//
// This value can be used as the `targetVersion` argument to
// `serializePortableArtifact`.
std::string getCurrentVersion();

// Get the minimum supported StableHLO version.
//
// This value can be used as the `targetVersion` argument to
// `serializePortableArtifact`.
std::string getMinimumVersion();

// From: #include "stablehlo/dialect/Serialization.h"

// Write a StableHLO program to a portable artifact
// Writes a stable payload for `module` to `os`. If compatibility with a
// previous version of StableHLO is required, provide the required version
// string `#.#.#` for `targetVersion`.
//
// Can fail if `module` cannot be expressed in the `targetVersion` version of
// StableHLO, e.g. if it's using new or removed features, or if it involves
// unsupported dialects.
LogicalResult serializePortableArtifact(ModuleOp module,
                                        StringRef targetVersion,
                                        raw_ostream& os);

// Read StableHLO portable artifact
//
// Can fail if `sourceStr` cannot be expressed in the current version of
// StableHLO, e.g. if it's using incompatible features. Returns nullptr if
// `sourceStr` is invalid or fails to deserialize.
OwningOpRef<ModuleOp> deserializePortableArtifact(StringRef sourceStr,
                                                  MLIRContext* context);

למידע על ממשקי API מלאים, ראו stablehlo/api/PortableApi.h ו-stablehlo/dialect/Serialization.h.

ראו StablehloTranslateMain.cpp לדוגמה שימוש בממשקי ה-API האלה.

Python

פלטפורמת StableHLO מספקת גם קישורי Python לממשקי ה-API של תאימות C++:

def get_current_version() -> str: ...
def get_minimum_version() -> str: ...
def serialize_portable_artifact(module: ir.Module, target_version: str) -> bytes: ...
def serialize_portable_artifact(module: str, target_version: str) -> bytes: ...
def deserialize_portable_artifact(context: ir.Context, artifact: bytes) -> ir.Module: ...
def deserialize_portable_artifact(artifact: bytes) -> str: ...

קראו את המאמר StablehloModule.cpp לממשקי API מלאים של Python.

ראו stablehlo.py > test_serialization_apis דוגמאות לשימוש דו-כיווני לשימוש בממשקי ה-API של סידור בהמשכים ב-Python.

בדיקות

יש לנו חבילת תאימות ב-stablehlo/tests/vhlo שכוללת אוסף מקיף של פעולות StableHLO, שעבר סריאליזציה לכל הגרסאות הנתמכות של StableHLO. בכל בקשת משיכה אנחנו בודקים גם תאימות לאחור וגם תאימות קדימה, כלומר אפשר לבצע ב-SDK התמקדות ב-HEAD (תאימות לאחור) בחבילה, שאפשר לערוך בה סריאליזציה כדי לטרגט את כל הגרסאות הנתמכות של StableHLO (תאימות קדימה) ושהתוצאות זהות מבחינה תחבירית לתוכניות ה-StableHLO המקוריות.

עבודה עתידית

יצירה של חבילת תאימות ב-MLIR ב-upstream: על סמך התובנות מהתהליך של ביסוס התחייבויות StableHLO ותחזוקה שלהן, אנחנו מתכננים להוסיף חבילת תאימות ל-MLIR ב-upstream כדי לספק זיהוי מוקדם של פריצות תאימות מקריות בתשתית קוד הבייטים של MLIR (#1632).

שימוש בהטמעת קובצי העזר: בשלב הזה, בדיקות התאימות כוללות ביצוע deseriality של חבילת התאימות עם סריאליזציה לגרסאות ישנות יותר של libStablehlo, ובדיקה שההתמדה יוצרת תוכנות זהות מבחינה תחבירית. אנחנו מתכננים להשתמש גם בהטמעת קובצי עזר בבדיקות האלה, כדי להקל על הדרישה הממושכת מדי לזהות תחבירית ולבצע בדיקה מקיפה של הטמעת קובצי העזר (#1245).

לא כלול

ארטיפקטים לא ניידים: הבטחת תאימות ניתנת רק לארטיפקטים ניידים שנוצרים בצורה ספציפית מאוד. לסוגים אחרים של ארטיפקטים, כמו ייצוג מודפס של הניב ה-StableHLO או אפילו ייצוג ה-bytecode של הדיאלקט של StableHLO, לא ניתן להבטיח תאימות.

תכונות ללא ציון: יכול להיות שנבצע שינויים לא תואמים בתכונות שנתמכות בעבר בתוכניות StableHLO, אבל עדיין לא נכללות במפרט של StableHLO. למשל, אנחנו לא מבטיחים תאימות למאפיינים לא רשומים.

תאימות באג: יכול להיות שנבצע שינויים לא תואמים אם ההטמעה ב-libStablehlo סותרת את המפרט של StableHLO, למשל אם הגדרה בדיאלקט של VHLO שגויה או אם המאמת בדיאלקט היציבHLO לא תואם למפרט.

דיוק מספרי: ל-StableHLO יש מספר פעולות עם רמת דיוק שהוגדרה עבור ההטמעה בקרב הצרכנים ואפילו עבור אותו צרכן בכל הגרסאות. כתוצאה מכך, ב-StableHLO לא רוצים להיות התחייבויות לגבי דיוק מספרי, אבל זה עשוי להשתנות בעתיד (#1156).

תאימות מקור לממשקי API של C, C++ ו-Python בתוך libStablehlo היא היעד הרצוי. בשלב זה אנחנו לא מבטיחים תאימות למקור, אבל ספרו לנו אם זה תרחיש חשוב עבורכם, ונוכל לדון בתמיכה (#1247).