Compatibilità StableHLO

StableHLO è un set di operazioni di computing ML compatibile con le versioni precedenti ispirato a HLO/MHLO. Questo documento illustra il tipo e la portata delle garanzie di compatibilità forniti da StableHLO, in base alla procedura stabilita nella RFC per la compatibilità.

Versioni

La versione corrente di StableHLO è disponibile in Version.h.

La versione secondaria viene sottoposta a picco ogni volta che vengono apportate modifiche all'opset StableHLO o al formato di serializzazione StableHLO e la versione della patch viene eseguita ogni volta che integriamo StableHLO downstream, ovvero nel repository openxla/xla.

Garanzie

In base alla specifica RFC per la compatibilità di StableHLO v1.0, la finestra di compatibilità include quanto segue:

5 anni di compatibilità con le versioni precedenti: gli elementi portatili serializzati da una versione precedente di libStablehlo hanno la stessa semantica* quando sono deserializzati da una nuova versione di libStablehlo se queste versioni sono create da commit openxla/stablehlo a meno di 5 anni di distanza.

2 anni di compatibilità in avanti: gli artefatti portatili serializzati da una nuova versione di libStablehlo hanno la stessa semantica* quando sono deserializzati da una vecchia versione di libStablehlo se queste versioni sono create da commit openxla/stablehlo a meno di 2 anni di distanza, a meno che il programma non utilizzi nuove funzionalità introdotte dalla versione precedente.

* I programmi StableHLO vengono convertiti in/da artefatti portatili tramite API di compatibilità e la semantica di questi programmi è definita dalla specifica di StableHLO. Consulta la sezione "Fuori ambito" per visualizzare esempi di contenuti non coperti da questa definizione di compatibilità.

API

Gli artefatti portatili possono essere creati utilizzando lo strumento stablehlo-translate o direttamente nelle API C++ o Python. La serializzazione richiede una versione di destinazione di StableHLO per scrivere un artefatto scritto in formato #.#.# (vedi Version.h per la versione attuale). Poiché le versioni di patch non influiscono sulla compatibilità, qualsiasi target con versione patch diversa da zero viene impostato in modo predefinito su zero durante la serializzazione. La deserializzazione utilizza la versione corrente di StableHLO per leggere un artefatto.

stablehlo-translate

Si tratta del modo più semplice per creare e leggere un artefatto portatile.

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

Per i flussi di lavoro programmatici, StableHLO fornisce le seguenti API di compatibilità:

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

Consulta stablehlo/api/PortableApi.h e stablehlo/dialect/Serialization.h per le API complete.

Consulta la sezione StablehloTranslateMain.cpp per un esempio sull'utilizzo di queste API.

Python

StableHLO fornisce anche associazioni Python alle API di 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: ...

Consulta StablehloModule.cpp per le API Python complete.

Consulta stablehlo.py > test_serialization_apis per esempi di round trip sull'utilizzo delle API di serializzazione Python.

Test

In stablehlo/tests/vhlo è disponibile una suite di compatibilità che prevede un compendio completo di operazioni StableHLO con serie per tutte le versioni di StableHLO supportate. Per ogni richiesta di pull, stiamo testando la compatibilità con le versioni precedenti e successive, ovvero che la suite può scegliere come target HEAD (compatibilità con le versioni precedenti), che il compendio può essere serializzato scegliendo come target tutte le versioni di StableHLO supportate (compatibilità in avanti) e che i risultati sono sintatticamente identici ai programmi StableHLO originali.

Lavori futuri

Crea una suite di compatibilità nell'upstream MLIR: utilizzando quanto appreso dalla definizione e dalla gestione delle garanzie di StableHLO, stiamo pianificando di contribuire a una suite di compatibilità a MLIR upstream per fornire il rilevamento precoce di interruzioni di compatibilità accidentali nell'infrastruttura bytecode MLIR (#1632).

Utilizza l'implementazione dei riferimenti: al momento, i test di compatibilità consistono nella deserializzazione della suite di compatibilità seriale da versioni precedenti di libStablehlo e nell'assicurarsi che la deserializzazione produca programmi sintatticamente identici. Prevediamo di utilizzare anche un'implementazione di riferimento in questi test, allentando il requisito eccessivamente oneroso dell'identità sintattica e testando in modo esaustivo l'implementazione del riferimento (#1245).

Fuori ambito

Elementi non portatili: le garanzie di compatibilità sono fornite solo per gli artefatti portatili che vengono creati in un modo molto specifico. Altri tipi di artefatti, ad esempio la rappresentazione piuttosto stampata del dialetto StableHLO o anche una rappresentazione in bytecode del dialetto StableHLO, non hanno garanzie di compatibilità.

Funzionalità non specificate: potremmo apportare modifiche incompatibili alle funzionalità che sono storicamente supportate nei programmi StableHLO, ma che non fanno ancora parte della specifica StatableHLO. Ad esempio, non forniamo garanzie di compatibilità per gli attributi non registrati.

Compatibilità di bug: potremmo apportare modifiche incompatibili se l'implementazione in libStablehlo contraddice la specifica StableHLO, ad esempio se una definizione nel dialetto VHLO è errata o se un verificatore nel dialetto StableHLO non corrisponde alla specifica.

Accuratezza numerica: in StableHLO sono presenti più operazioni con un'accuratezza definita dall'implementazione per tutti i consumatori e anche per tutte le versioni dello stesso consumatore. Di conseguenza, StableHLO non mira a fornire garanzie sull'accuratezza numerica, anche se questo potrebbe cambiare in futuro (#1156).

La compatibilità del codice sorgente per le API C, C++ e Python in libStablehlo è un obiettivo aspirazionale. Al momento non offriamo garanzie di compatibilità delle fonti, ma facci sapere se si tratta di un caso d'uso importante per te e potremo discuterne con il supporto (#1247).