Compatibilité StableHLO

StableHLO est un ensemble d'opérations de calcul de ML rétrocompatible, inspiré de HLO/MHLO. Ce document décrit le type et l'étendue des garanties de compatibilité fournies par StableHLO, en fonction du processus établi dans le document RFC de compatibilité.

Versions

La version actuelle de StableHLO est disponible dans Version.h.

Dans la série 0.xxx, la version mineure est repoussée chaque fois que des modifications sont apportées à l'opération StableHLO ou au format de sérialisation StableHLO. La version de correctif est repoussée à chaque intégration de StableHLO en aval, c'est-à-dire dans le dépôt openxla/xla.

Garanties

6 mois de rétrocompatibilité:les artefacts portables sérialisés par une ancienne version de libStablehlo ont la même sémantique* lorsqu'ils sont désérialisés par une nouvelle version de libStablehlo si ces versions sont créées à partir de commits openxla/stablehlo à moins de six mois d'intervalle.

Un mois de compatibilité ascendante:les artefacts portables sérialisés par une nouvelle version de libStablehlo ont la même sémantique* lorsqu'ils sont désérialisés par une ancienne version de libStablehlo si ces versions sont compilées à partir de commits openxla/stablehlo à moins d'un mois d'intervalle, sauf si le programme utilise de nouvelles fonctionnalités introduites depuis l'ancienne version.

* Les programmes StableHLO sont convertis en artefacts portables ou à partir d'artefacts portables via des API de compatibilité. La sémantique de ces programmes est définie par la spécification StableHLO. Consultez la section "Hors champ d'application" pour obtenir des exemples de ce qui n'est pas couvert par cette définition de compatibilité.

API

Vous pouvez créer des artefacts portables à l'aide de l'outil stablehlo-translate ou directement dans les API C++ ou Python. La sérialisation nécessite une version cible de StableHLO pour écrire un artefact écrit au format #.#.# (consultez Version.h pour connaître la version actuelle). La désérialisation utilise la version actuelle de StableHLO pour lire un artefact.

stablehlo-translate

Il s'agit du moyen le plus simple de créer et de lire un artefact portable.

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

Pour les workflows programmatiques, StableHLO fournit les API de compatibilité suivantes:

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

Consultez stablehlo/api/PortableApi.h et stablehlo/dialect/Serialization.h pour obtenir des API complètes.

Pour voir un exemple d'utilisation de ces API, consultez StablehloTranslateMain.cpp.

Python

StableHLO fournit également des liaisons Python vers les API de compatibilité 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: ...

Consultez la page StablehloModule.cpp pour obtenir la version complète des API Python.

Consultez la section stablehlo.py > test_serialization_apis pour obtenir des exemples aller-retour d'utilisation des API de sérialisation Python.

Tests

Nous disposons d'une suite de compatibilité dans stablehlo/tests qui implique un compendium complet d'opérations StableHLO sérialisées pour toutes les versions de StableHLO compatibles. Pour chaque demande d'extraction, nous testons la rétrocompatibilité, c'est-à-dire que la suite peut être désérialisée avec le ciblage HEAD (rétrocompatibilité), que le Compendium peut être sérialisé ciblant toutes les versions StableHLO compatibles (compatibilité ascendante) et que les résultats sont identiques au niveau de la syntaxe des programmes StableHLO d'origine.

Travaux futurs

Création d'une suite de compatibilité dans MLIR en amont:en nous appuyant sur les enseignements tirés de l'établissement et de la maintenance des garanties StableHLO, nous prévoyons de proposer une suite de compatibilité à MLIR en amont afin de permettre une détection précoce des ruptures de compatibilité accidentelles dans l'infrastructure de bytecode MLIR (#1632).

Utiliser une implémentation de référence:à l'heure actuelle, les tests de compatibilité consistent à désérialiser la suite de compatibilité sérialisée par d'anciennes versions de libStablehlo et à s'assurer que la désérialisation génère des programmes syntaxiquement identiques. Nous prévoyons également d'utiliser une implémentation de référence dans ces tests, en assouplissant l'exigence excessive d'une identité syntaxique et en testant de manière exhaustive l'implémentation de référence (#1245).

Hors du champ d'application

Artefacts non portables:les garanties de compatibilité ne sont fournies que pour les artefacts portables créés de manière très spécifique. D'autres types d'artefacts, tels que la représentation formatée du dialecte StableHLO ou même la représentation en bytecode du dialecte StableHLO, n'ont pas de garantie de compatibilité.

Fonctionnalités non spécifiées:nous pouvons apporter des modifications incompatibles aux fonctionnalités qui sont historiquement compatibles avec les programmes StableHLO, mais qui ne font pas encore partie de la spécification StableHLO. Par exemple, nous ne fournissons pas de garanties de compatibilité pour les attributs non enregistrés.

Compatibilité avec les bugs:nous pouvons apporter des modifications incompatibles si l'implémentation dans libStablehlo contredit la spécification StableHLO (par exemple, si une définition dans le dialecte VHLO est incorrecte ou si un vérificateur du dialecte StableHLO ne correspond pas aux spécifications).

Précision numérique:StableHLO comporte plusieurs opérations dont la précision est définie par l'implémentation pour tous les consommateurs et même au sein d'un même consommateur d'une version à l'autre. Par conséquent, StableHLO ne vise pas à garantir la précision numérique, bien que cela puisse changer à l'avenir (#1156).

La compatibilité des sources pour les API C, C++ et Python dans libStablehlo est un objectif ambitieux. Nous ne proposons pas de garantie de compatibilité des sources pour le moment, mais n'hésitez pas à nous indiquer s'il s'agit d'un cas d'utilisation important pour vous afin que nous puissions discuter de sa prise en charge (#1247).