תאימות ל-SableHLO

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

גרסאות

אפשר למצוא את הגרסה הנוכחית של StableHLO ב-Version.h.

בסדרה 0.x.x, הגרסה המשנית מושפעת בכל פעם שעושים שינויים בתפעול StableHLO או לפורמט העריכה בסדרה של StableHLO. גרסת התיקון מופיעה בכל פעם שמשלבים את StableHLO במורד הזרם, כלומר למאגר Openxla/xla.

ערבויות

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

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

* תוכנות StableHLO מומרות אל פריטי מידע שנוצרים בתהליך פיתוח (Artifact) באמצעות ממשקי API לתאימות, והסמנטיקה של התוכנות האלה מוגדרת במפרט StableHLO. כדאי לעיין בקטע "Out of scope" כדי לראות דוגמאות למה שלא נכלל בהגדרת התאימות הזו.

ממשקי API

אפשר ליצור פריטי מידע נישאים באמצעות הכלי stablehlo-translate, או ישירות בממשקי C++ או Python API. כדי לערוך סריאליזציה, נדרשת גרסת יעד של SttableHLO כדי לכתוב פריט מידע שנוצר בתהליך פיתוח (Artifact) בפורמט #.#.# (לגרסה הנוכחית, ראו Version.h). פעולת 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: ...

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

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

בדיקות

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

עבודה עתידית

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

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

לא בטווח האחריות

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

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

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

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

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