Zgodność ze stabilnym HLO

StableHLO to zgodna wstecznie operacja obliczeniowa ML inspirowana HLO/MHLO. W tym dokumencie opisujemy rodzaje i zakres gwarancji zgodności zapewnianych przez StableHLO na podstawie procesu podanego w specyfikacji zgodności.

Wersje

Aktualną wersję StableHLO znajdziesz w Version.h.

W serii 0.x.x wersja podrzędna jest potraktowana za każdym razem, gdy wprowadzana jest zmiana w ustawieniu StableHLO lub formacie serializacji StableHLO, a wersja poprawki jest ponawiana za każdym razem, gdy wdrażamy StableHLO w strumieniu, czyli w repozytorium openxla/xla.

Gwarancje

6 miesięcy zgodności wstecznej: przenośne artefakty zserializowane przez starszą wersję libStablehlo mają tę samą semantykę* po deserializacji za pomocą nowej wersji libStablehlo, pod warunkiem że te wersje zostały utworzone na podstawie zobowiązań openxla/stablehlo, które różnią się od siebie mniej niż 6 miesięcy.

Zgodność z 1 miesiącem do przodu: artefakty przenośne zserializowane przez nową wersję libStablehlo mają tę samą semantykę* po deserializacji za pomocą starej wersji libStablehlo, pod warunkiem, że te wersje zostały utworzone na podstawie zgłoszeń openxla/stablehlo, w odstępie co najmniej jednego miesiąca, chyba że program korzysta z nowych funkcji wprowadzonych od starej wersji.

* Programy StableHLO są konwertowane na przenośne artefakty za pomocą interfejsów API zgodności. Semantyka tych programów jest określana przez specyfikację StableHLO. Więcej informacji znajdziesz w sekcji „Poza zakresem”.

Interfejsy API

Przenośne artefakty można tworzyć za pomocą narzędzia stablehlo-translate albo bezpośrednio w interfejsach API w C++ lub Pythonie. Serializacja wymaga docelowej wersji stabilnej HLO, aby zapisać artefakt napisany w formacie #.#.# (bieżącą wersję znajdziesz w sekcji Version.h). Deserializacja używa bieżącej wersji StableHLO do odczytu artefaktu.

stablehlo-translate

To najprostszy sposób na utworzenie i odczytanie artefaktu mobilnego.

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

W przypadku zautomatyzowanych przepływów pracy StableHLO udostępnia te interfejsy API zgodności:

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

Pełne informacje o interfejsach API znajdziesz w sekcjach stablehlo/api/PortableApi.h i stablehlo/dialect/Serialization.h.

Przykład użycia tych interfejsów API znajdziesz w sekcji StablehloTranslateMain.cpp.

Python

StableHLO udostępnia też powiązania Pythona z interfejsami API zgodności 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: ...

Pełne informacje o interfejsach API Pythona znajdziesz w sekcji StablehloModule.cpp.

Na stronie stablehlo.py > test_serialization_apis znajdziesz przykłady użycia interfejsów API serializacji w Pythonie.

Testy

W sekcji stablehlo/tests udostępniamy pakiet zgodności, który obejmuje kompleksowe kompendium operacji StableHLO zserializowanych na potrzeby wszystkich obsługiwanych wersji StableHLO. W przypadku każdego żądania pull testujemy zgodność wsteczną i do przodu – tzn. czy można poddać zestawowi kierowania na element HEAD (zgodność wsteczną), że kompendium może być zserializowane na wszystkich obsługiwanych wersjach StableHLO (zgodność do przodu), a wyniki są składniowo identyczne z pierwotnymi programami StableHLO.

Praca w przyszłości

Utwórz pakiet zgodności na potrzeby żądań MLIR: korzystając z wniosków z ustalania i utrzymywania gwarancji StableHLO, planujemy udostępnić pakiet zgodności dla żądań MLIR, aby zapewnić wczesne wykrywanie przypadkowych przerw w zgodności w infrastrukturze kodów bajtów MLIR (#1632).

Użyj implementacji referencyjnej: obecnie testowanie zgodności obejmuje deserializację pakietu zgodności zserializowanego za pomocą starszych wersji biblioteki libStablehlo i upewnienie się, że deserializacja generuje programy o identycznej składni. W tych testach zamierzamy też użyć implementacji referencyjnej, łagodząc nadmiernie uciążliwe wymaganie związane z tożsamością składniową i gruntownie przetestować implementację referencyjną (#1245).

Wykracza poza zakres

Nieprzenośne artefakty: gwarancje zgodności są udzielane tylko w przypadku artefaktów tworzonych w określony sposób. Inne rodzaje artefaktów, takie jak predykcja dialektu StableHLO, czy nawet reprezentacja dialektu StableHLO przy użyciu kodu bajtowego, nie są w stanie zagwarantować zgodności.

Nieokreślone funkcje: możemy wprowadzać niezgodne zmiany w funkcjach, które były wcześniej obsługiwane w programach StableHLO, ale nie są jeszcze objęte specyfikacją StableHLO. Na przykład nie gwarantujemy zgodności niezarejestrowanych atrybutów.

Zgodność błędów: możemy wprowadzić niezgodne zmiany, jeśli implementacja w libStablehlo jest sprzeczna ze specyfikacją StableHLO. Na przykład jeśli definicja w dialekcie VHLO jest błędna lub weryfikator w dialekcie StableHLO nie odpowiada specyfikacji.

Dokładność liczbowa: StableHLO ma wiele operacji z określoną dokładnością w ramach implementacji w odniesieniu do różnych klientów, a nawet w ramach tego samego klienta w różnych wersjach. W związku z tym system StableHLO nie gwarantuje dokładności liczbowej, chociaż w przyszłości może się to zmienić (#1156).

Zależy nam na zgodności źródeł interfejsów API w językach C, C++ i Pythona w libStablehlo. Obecnie nie gwarantujemy zgodności źródła, ale daj nam znać, jeśli ten przypadek użycia jest dla Ciebie ważny – możemy omówić z Tobą kwestię jego obsługi (#1247).