VHLO 方言

什麼是 VHLO 方言?

VHLO (版本化 StableHLO) 方言用於序列化和穩定性。透過版本管理個別程式元素,提供特定時間點的 StableHLO 方言快照。

VHLO 是新增的方言,具有版本化運算、類型和屬性,也就是說,一旦將功能新增至方言,就無法以任何會影響語意的方式修改。

任何對運算、類型或屬性所做的變更,都必須在方言中加入新版本。舉例來說,如果假設的 my_op 已在 0.9.0 中新增至 StableHLO,但在 0.11.0 中變更,我們會在 VHLO 中加入下列內容:

// This represents the StableHLO version of the op from 0.9.0 -> 0.10.0
// Both the lower and the upper bound of versions are inclusive
def VHLO_MyOpV1 : VHLO_Op<"my_op_v1", "0.9.0", "0.10.0"> {
  let arguments = (ins
    VHLO_AnyType:$operand
  );
  let results = (outs VHLO_AnyType:$result);
}

// This represents the StableHLO version of the op from 0.11.0 -> current
def VHLO_MyOpV2 : VHLO_Op<"my_op_v2", "0.11.0", "current"> {
  let arguments = (ins
    VHLO_AnyType:$operand,
    VHLO_AnyAttr:$attr  // New attribute added to StableHLO in 0.11.0
  );
  let results = (outs VHLO_AnyType:$result);
}

StableHLO 方言只有最新版本的 Ops。在執行範例中,v0.11.0 的 StableHLO 方言只會有含有 operandattrStableHLO_MyOp,而 VHLO 會擷取該運算的演進每個階段。

VHLO 有何用處?

使用版本化方言時,我們可以指定舊版 StableHLO 運算集。這會封裝 VHLO 方言間作業之間的轉換前瞻與回溯相容性。

轉送相容性:轉換至 VHLO 並將作業降級至目標版本的方式提供前進相容性。如果 VHLO 程式中的每個運算/類型/注意力都可以降級至目標版本,由於 VHLO 當時擁有設定該運算組的快照,因此當 VHLO 程式中的每個運算/類型/最佳化器都可降級為目標版本時,應可將其取消序列化,並轉換為 StableHLO。

「前瞻相容性」圖片

如果使用舊版運算集中沒有的運算或功能,這項降級轉換就會失敗。這表示前瞻相容性會在生產端 (而不是執行階段) 找到。

回溯相容性:系統會透過將 VHLO 運算升級至最新版本 (如有需要),然後將運算轉換回 StableHLO,藉此提供回溯相容性。相容性視窗中的所有 VHLO 程式皆可升級為 StableHLO,這表示不同版本的取用者可以反序列化先前版本的相同 VHLO 酬載。

回溯相容性圖片

更重要的是,VHLO 會以序列化的方式抽象化。也就是說,機器學習架構 (生產者) 只需要指定 StableHLO 運算,而編譯器後端 (消費者) 只需要支援最新版本,也就是 StableHLO 運算集。VHLO 的往返轉換是由 StableHLO 存放區中維護的機器處理。

MLIR 位元組格式版本

為維持前瞻相容性,StableHLO 版本具有相關的 MLIR 位元組格式版本。此外,最新版本的 StableHLO 將使用最新版本的 MLIR 位元組格式。當 MLIR 位元組格式版本遞增時,下一個 StableHLO 版本將會遞增子版本,並且更新 Version.cpp 以使用最新的 MLIR 位元組格式版本。

如要進一步瞭解 MLIR 位元組格式,以及在 StableHLO 中使用該格式的原因,請參閱 bytecode.md

提供不相容的變更

涉及相容性的所有變更都必須經過 RFC 程序。這包括新增、淘汰或重新命名地圖項目。RFC 核准後,以下是一些貢獻規範:

將 Version.h 中的版本號碼遞增

在更新 VHLO 運算、屬性、類型或轉換之前,請先增加 Version.h 中的次要版本號碼。所有新增的 VHLO 功能都會使用這個升起版本,例如在將 0.10.0 --> 0.11.0 排除後,即使用 VhloOps.td 中的新運算:

VHLO_Op<"abs_v2", "0.11.0", "current">

新增必要的 VHLO 導入作業與轉換

整合新功能所需的確切程式碼會有所不同,但大部分程式碼必須變更:

最近的相容性相關提交範例為新增兩種 FP8 類型,以及在 #1379 中導入 VHLO 的方式。

新增 / 更新單元測試

不相容變更的貢獻者同時負責功能的正負單位測試,以及相容性單元測試。

相容性單元測試會更新 stablehlo_legalize_to_vhlo.mlir,確保 StableHLO 來回行程使用最新版本的 VHLO,以及所需的其他前瞻或回溯相容性測試。

以下提供幾個範例:

新增版本化序列化測試

將測試點新增至 stablehlo_legalize_to_vhlo.mlir 後,請建立名為 stablehlo_legalize_to_vhlo.0_X_0.mlir 的檔案的版本副本,以及副檔名為 .0_X_0.mlir.bc 的該檔案的位元碼版本。新增適當的 FileCheck 行,進行前瞻相容性測試。

$ export TARGET_VERSION=0.X.0
$ export TARGET_FILENAME=${TARGET_VERSION//./_}
$ cp stablehlo/tests/stablehlo_legalize_to_vhlo.mlir stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir
$ build/bin/stablehlo-translate --serialize --target=$TARGET_VERSION --strip-debuginfo stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir > stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir.bc

# Replace RUN commands in stablehlo/tests/stablehlo_legalize_to_vhlo.0_X_0.mlir with the following for 0.X.0:
// RUN: stablehlo-opt --mlir-print-op-generic %s.bc | FileCheck %s
// RUN: stablehlo-translate --deserialize %s.bc | stablehlo-translate --serialize --target=0.X.0 | stablehlo-opt --mlir-print-op-generic | FileCheck %s
// RUN: diff <(stablehlo-translate --deserialize %s.bc | stablehlo-opt) <(stablehlo-opt --strip-debuginfo %s)
// RUN: diff %s.bc <(stablehlo-translate --serialize --target=0.X.0 --strip-debuginfo %s)

#1430 中的版本化測試範例。