StableHLO の互換性

StableHLO は、HLO/MHLO に着想を得た下位互換性のある ML コンピューティング オプセットです。このドキュメントでは、互換性 RFC で確立されたプロセスに基づいて、StableHLO によって提供される互換性保証の種類と範囲について説明します。

バージョン

StableHLO の最新バージョンは Version.h で確認できます。

マイナー バージョンは、StableHLO オペレーションセットまたは StableHLO シリアル化形式が変更されるたびにバンプされ、パッチ バージョンは、StableHLO のダウンストリーム(openxla/xla リポジトリ)を統合するたびにバンプされます。

保証

StableHLO v1.0 互換性 RFC に従い、互換性ウィンドウには以下の項目が含まれます。

5 年間の下位互換性: 古いバージョンの libStablehlo でシリアル化されたポータブル アーティファクトは、5 年未満の間隔にある openxla/stablehlo commit からビルドされている場合、新しいバージョンの libStablehlo でシリアル化解除しても、同じセマンティクス* になります。

2 年間の上位互換性: libStablehlo の新しいバージョンでシリアル化されたポータブル アーティファクトは、古いバージョンの libStablehlo でシリアル化解除された場合、これらのバージョンが 2 年未満の openxla/stablehlo commit からビルドされている場合、セマンティクス* が同じになります。ただし、プログラムが古いバージョン以降に導入された新機能を使用している場合を除きます。

* StableHLO プログラムは、互換性 API を介してポータブル アーティファクトとの間で変換されます。これらのプログラムのセマンティクスは、StableHLO 仕様で定義されています。この互換性定義の対象外となる例については、「対象範囲外」セクションをご覧ください。

API

移植可能なアーティファクトは、stablehlo-translate ツールを使用して、または C++ または Python API で直接作成できます。シリアル化には、#.#.# 形式で記述されたアーティファクトを書き込むために、StableHLO のターゲット バージョンが必要です(現在のバージョンについては Version.h をご覧ください)。パッチ バージョンは互換性に影響しないため、パッチ バージョンがゼロ以外のターゲットは、シリアル化時にデフォルトでゼロに設定されます。逆シリアル化では、StableHLO の最新バージョンを使用してアーティファクトを読み取ります。

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.hstablehlo/dialect/Serialization.h をご覧ください。

これらの API の使用例については、StablehloTranslateMain.cpp をご覧ください。

Python

StableHLO には、C++ 互換 API への Python バインディングも用意されています。

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

完全な Python API については、StablehloModule.cpp をご覧ください。

Python Serialization API の往復の例については、stablehlo.py > test_serialization_apis をご覧ください。

試験

stablehlo/tests/vhlo には互換性スイートがあり、サポートされているすべての StableHLO バージョンに対してシリアル化された StableHLO オペレーションの包括的な概要が含まれています。pull リクエストごとに後方互換性と上位互換性の両方をテストします。つまり、スイートを HEAD(後方互換性)をターゲットとしてシリアル化解除できること、サポートされているすべての StableHLO バージョンをターゲットとしてシリアル化できること(上位互換性)、結果が元の StableHLO プログラムと構文的に同一であること、などです。

今後の作業

MLIR アップストリームに互換性スイートを作成する: StableHLO 保証の確立と維持から得られた知見を利用して、MLIR アップストリームに互換性スイートを提供し、MLIR バイトコード インフラストラクチャ(#1632)の偶発的な互換性の破損を早期に検出できるようにする予定です。

リファレンス実装を使用する: 現時点では、互換性テストでは、古いバージョンの libStablehlo によってシリアル化された互換性スイートをシリアル化解除し、シリアル化解除によって構文的に同じプログラムが生成されることを確認します。これらのテストではリファレンス実装を使用して、構文的同一性に関する過度に面倒な要件を緩和し、リファレンス実装を包括的にテストする予定です(#1245)。

対象外

ポータブルでないアーティファクト: 互換性が保証されるのは、非常に特殊な方法で作成されたポータブル アーティファクトのみです。その他の種類のアーティファクト(StableHLO 言語の プリティプリントされた表現や、StableHLO 言語のバイトコード表現など)では、互換性が保証されません。

未指定の機能: これまで StableHLO プログラムでサポートされていたが、まだ StableHLO 仕様に含まれていない機能に対して互換性のない変更を加える場合があります。たとえば、未登録の属性に対する互換性は保証されません。

バグの互換性: libStablehlo の実装が StableHLO の仕様と矛盾している場合、互換性のない変更が行われることがあります。たとえば、VHLO 言語の定義が間違っている場合や、StableHLO 言語の検証ツールが仕様と一致していない場合などです。

数値の正確性: StableHLO には、コンシューマ間、さらにはバージョン間で同じコンシューマ内でも実装定義の精度を持つ複数のオペレーションがあります。そのため、将来変更される可能性がありますが、StableHLO は数値の正確性を保証するものではありません(#1156)。

libStablehlo 内での C、C++、Python の API のソースの互換性は、野心的な目標です。現時点ではソース互換性の保証は提供していませんが、これがお客様にとって重要なユースケースである場合はお知らせください。サポートについてご相談させていただきます(#1247)。