StableHLO との互換性

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

バージョン

StableHLO の最新バージョンは Version.h にあります。

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

保証

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

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

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

API

移植可能なアーティファクトは、stablehlo-translate ツールを使用して作成することも、C++ API や 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 には互換性スイートがあります。これには、サポートされているすべての 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)。