Stabile HLO-Kompatibilität

StableHLO ist ein abwärtskompatibles ML-Computing-Opset, das von HLO/MHLO inspiriert ist. In diesem Dokument werden die Art und den Umfang der Kompatibilitätsgarantien von StableHLO basierend auf dem im Kompatibilitäts-RFC festgelegten Prozess erläutert.

Versionen

Die aktuelle Version von StableHLO finden Sie in Version.h.

In der 0.x.x-Serie wird die Nebenversion bei jeder Änderung am StableHLO-Opset oder am SableHLO-Serialisierungsformat aktualisiert. Die Patchversion wird jedes Mal erweitert, wenn wir StableHLO im Downstream integrieren, d. h. in das Openxla-/xla-Repository.

Garantien

6 Monate Abwärtskompatibilität:Portable Artefakte, die durch eine alte Version von libStablehlo serialisiert wurden, haben die gleiche Semantik*, wenn sie durch eine neue Version von libStablehlo deserialisiert werden, wenn diese Versionen aus openxla/stablehlo-Commits erstellt werden, die weniger als sechs Monate auseinanderliegen.

1 Monat Aufwärtskompatibilität:Portable Artefakte, die von einer neuen Version von libStablehlo serialisiert wurden, haben die gleiche Semantik*, wenn sie durch eine alte Version von libStablehlo deserialisiert werden, wenn diese Versionen aus openxla/stablehlo-Commits erstellt werden, die weniger als einen Monat auseinanderliegen, es sei denn, das Programm verwendet neue Funktionen, die seit der alten Version eingeführt wurden.

* StabileHLO-Programme werden über Kompatibilitäts-APIs in tragbare Artefakte konvertiert und umgekehrt. Die Semantik dieser Programme ist durch die SableHLO-Spezifikation definiert. Im Abschnitt „Nicht zulässig“ finden Sie Beispiele dafür, was von dieser Definition der Kompatibilität nicht abgedeckt wird.

APIs

Portable Artefakte können entweder mit dem stablehlo-translate-Tool oder direkt in C++ oder Python APIs erstellt werden. Die Serialisierung benötigt eine Zielversion von StableHLO, um ein Artefakt zu schreiben, das im Format #.#.# geschrieben wurde (siehe Version.h für die aktuelle Version). Die Deserialisierung verwendet die aktuelle Version von StableHLO, um ein Artefakt zu lesen.

stablehlo-translate

Dies ist die einfachste Möglichkeit, ein portables Artefakt zu erstellen und zu lesen.

# 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++

Für programmatische Workflows bietet StableHLO die folgenden Kompatibilitäts-APIs:

// 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);

Vollständige APIs finden Sie unter stablehlo/api/PortableApi.h und stablehlo/dialect/Serialization.h.

Unter StablehloTranslateMain.cpp finden Sie ein Beispiel zur Verwendung dieser APIs.

Python

StableHLO stellt auch Python-Bindungen an die C++-Kompatibilitäts-APIs bereit:

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: ...

Die vollständigen Python APIs finden Sie unter StablehloModule.cpp.

Unter stablehlo.py > test_serialization_apis finden Sie Beispiele für die Verwendung der Python-Serialisierungs-APIs.

Tests

Wir haben eine Kompatibilitätssuite in stablehlo/Tests, die ein umfassendes Kompendium von StableHLO-Vorgängen enthält, das für alle unterstützten StableHLO-Versionen serialisiert ist. Für jede Pull-Anfrage testen wir die Abwärts- und Vorwärtskompatibilität, d.h., dass die Suite deserialisiert werden kann und auf HEAD (Abwärtskompatibilität) ausgerichtet sein kann, dass das Compendium auf alle unterstützten StableHLO-Versionen ausgerichtet werden kann (Aufwärtskompatibilität) und dass die Ergebnisse syntaktisch mit den ursprünglichen StableHLO-Programmen identisch sind.

Zukünftige Arbeiten

Eine Kompatibilitätssuite in MLIR-Upstream erstellen: Anhand der Erkenntnisse aus dem Einrichten und Pflegen von StableHLO-Garantien planen wir, eine Kompatibilitätssuite zu MLIR Upstream hinzuzufügen, um eine Früherkennung von Fehlern bei der versehentlichen Kompatibilität in der MLIR-Bytecode-Infrastruktur zu ermöglichen (#1632).

Referenzimplementierung verwenden:Aktuell besteht bei Kompatibilitätstests die Deserialisierung der von älteren Versionen von libStablehlo serialisierten Kompatibilitätssuite und es wird dafür gesorgt, dass durch die Deserialisierung syntaktisch identische Programme erzeugt werden. Wir haben vor, in diesen Tests auch eine Referenzimplementierung zu verwenden, die übermäßig aufwendige Anforderung einer syntaktischen Identität zu lockern und die Referenzimplementierung umfassend zu testen (#1245).

Ausgeschlossen

Nicht portierbare Artefakte:Kompatibilitätsgarantien werden nur für portierbare Artefakte gegeben, die auf eine ganz bestimmte Weise erstellt werden. Andere Arten von Artefakten, z.B. eine optimierte Darstellung des StableHLO-Dialekts oder sogar die Bytecode-Darstellung des StableHLO-Dialekts, haben keine Kompatibilitätsgarantien.

Nicht spezifizierte Features:Wir können inkompatible Änderungen an Funktionen vornehmen, die bisher in StableHLO-Programmen unterstützt wurden, aber noch nicht Teil der StableHLO-Spezifikation sind. Beispielsweise geben wir keine Kompatibilitätsgarantien für nicht registrierte Attribute.

Fehlerkompatibilität:Wir können inkompatible Änderungen vornehmen, wenn die Implementierung in libStablehlo der StableHLO-Spezifikation widerspricht, z.B. wenn eine Definition im VHLO-Dialekt falsch ist oder ein Verifier im StableHLO-Dialekt nicht der Spezifikation entspricht.

Numerische Genauigkeit: StableHLO hat mehrere Vorgänge mit implementierungsdefinierter Genauigkeit für alle Nutzer und sogar innerhalb desselben Nutzers über verschiedene Versionen hinweg. Infolgedessen bietet StableHLO keine Garantien für die numerische Genauigkeit, obwohl sich dies in Zukunft ändern kann (#1156).

Die Quellkompatibilität für C-, C++- und Python-APIs in libStablehlo ist ein ambitioniertes Ziel. Derzeit können wir keine Garantien für die Quellenkompatibilität geben. Wenn dies jedoch für Sie ein wichtiger Anwendungsfall ist, teilen Sie uns dies bitte mit, damit wir über eine mögliche Unterstützung sprechen können (#1247).