VHLO 方言

如需了解更改 VHLO 时应遵循的步骤,请参阅 vhlo_checklist.md

什么是 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 方言仅包含最新版本的操作。在运行的示例中,v0.11.0 的 StableHLO 方言只有包含 operandattrStableHLO_MyOp,而 VHLO 会捕获运算演变的每个阶段。

VHLO 有何作用?

通过使用版本化方言,我们可以定位到 StableHLO 操作集的旧版本。这封装了 VHLO 方言中操作之间的转换中的向前和向后兼容性。

向前兼容性:通过转换为 VHLO 并将操作降级到目标版本来实现向前兼容性。如果 VHLO 程序中的每个操作/类型/属性都可以降级到目标版本,则保证在运行高于或等于目标版本的使用方上,它可进行反序列化并转换为 StableHLO,因为 VHLO 当时具有操作集的快照。

向前兼容性图片

如果使用上一操作集中不存在的操作或功能,此降级转换将失败。这意味着,向前兼容性是在生产方发现的,而不是在运行时发现的。

向后兼容性:通过将 VHLO 操作升级到其最新版本(如果需要),然后将操作转换回 StableHLO 来提供向后兼容性。兼容期内的所有 VHLO 程序均可升级为 StableHLO,这意味着不同版本的使用方可以反序列化来自之前版本的相同 VHLO 载荷。

向后兼容性图片

更重要的是,VHLO 在序列化后会被抽象化。这意味着,机器学习框架(生产方)只需以 StableHLO 运算为目标,而编译器后端(使用方)只需支持最新版本(即 StableHLO 运算集)。从 VHLO 和向 VHLO 的转换由 StableHLO 代码库中维护的机制处理。

MLIR 字节码格式版本

为了保持向前兼容性,StableHLO 版本具有关联的 MLIR 字节码格式版本。此外,最新版本的 StableHLO 将使用最新版本的 MLIR 字节码格式。当 MLIR 字节码格式版本递增时,StableHLO 的下一个版本将递增次要版本并更新 Version.cpp 以使用最新的 MLIR 字节码格式版本。

如需详细了解 MLIR 字节码格式以及在 StableHLO 中使用该格式的原因,请参阅 bytecode.md