为什么ML生态需要StableHLO:一文读懂HLO到MHLO再到StableHLO的完整演进史

📅 2026/8/24 9:46:15
为什么ML生态需要StableHLO:一文读懂HLO到MHLO再到StableHLO的完整演进史
为什么ML生态需要StableHLO一文读懂HLO到MHLO再到StableHLO的完整演进史【免费下载链接】stablehloBackward compatible ML compute opset inspired by HLO/MHLO项目地址: https://gitcode.com/gh_mirrors/st/stablehlo如果你在做机器学习大概率听说过 HLO、MHLO 和 StableHLO 这三个名字却分不清它们的关系。StableHLO 正是为解决ML 框架与编译器互不兼容而生的操作集opset它充当 TensorFlow、JAX、PyTorch 等框架与 XLA、IREE 等编译器之间的可移植性中间层。本文用一篇演进史讲清楚HLO 从哪里来、MHLO 做了什么、StableHLO 又补齐了什么以及它靠什么兑现5 年后还能读旧模型的兼容性承诺。一个真实的痛点框架与编译器各说各话在 StableHLO 出现之前ML 生态面临一个经典的N×M 问题前端 N 个框架TensorFlow、JAX、PyTorch、Julia 的 Reactant 等各自有自己的一套 IR后端 M 个编译器XLA、IREE、Google AI Edge、CoreML 转换器……每个都要为每个框架单独写一套导入逻辑。框架每升级一次、后端每迭代一次所有交叉组合都可能断裂。生态需要的是一个大家都认、且保证长期稳定的中间表示——这就是 StableHLO 存在的意义。一句话定位StableHLO 是高层操作HLO的操作集框架生产 StableHLO 程序编译器消费 StableHLO 程序彼此彻底解耦完整定义见 docs/spec.md。演进史HLO → MHLO → StableHLO 三步走第一步HLO —— 从 XLA 内部长出来的土话HLOHigh Level Operations最早是 XLA 编译器内部的中间表示表达 add、conv、dot、gather 这类贴近硬件语义的高层算子。它非常强大但有个致命问题没有对外承诺过任何稳定性——它是编译器内部实现升级随时可能改。框架厂商们一直在偷偷依赖它却没有任何保障。第二步MHLO —— 用 MLIR 重写从方言开始规范MHLO 是 XLA 团队把 HLO 移植到 MLIR 框架后的产物成为 MLIR 的一个标准方言dialect。这一步带来了结构化、可组合的编译基础设施但 MHLO 本质上是跟随 XLA 主线走的XLA 改它就改。对于我要把模型存下来、过两年再编译这种跨时间场景依然不够。第三步StableHLO —— 为跨时间、跨组织而生StableHLO 基于 MHLO 方言但目标完全不同它不再只是XLA 的 IR而是整个生态的公共接口。根据 README.md它相比 MHLO 增强了两大能力序列化采用 MLIR Bytecode 作为标准存储格式详见 docs/bytecode.md版本化与兼容保证明确的向后/向前兼容窗口且写入 rfcs/20230623-compatibility.md 这份兼容性 RFC。可以说HLO 是 XLA 的母语MHLO 是它在 MLIR 世界的口音版而 StableHLO 才是被整个行业签了稳定性合同的官方普通话。三大核心设计StableHLO 如何做到稳定设计一VHLO 版本化方言只增不改StableHLO 引入了一套影子方言VHLOVersioned StableHLO规则是add-only只添加、不修改 逐个元素版本化每个算子、类型、属性一旦加入 VHLO 就不能改变语义想改那就加一个新版本v1、v2……。▲ StableHLO 后向兼容机制同一份 v0.9.0 的可移植产物可被 v0.9.0 和 v0.11.0 两个不同版本的消费者反序列化——新版消费者会把旧算子升级到最新 VHLO 版本my_op_v1→my_op_v2再转回 StableHLO对普通用户来说VHLO 被完全封装在序列化层之后框架只需面向最新的 StableHLO 算子编译器只需支持最新版——中间所有升降级工作由仓库里维护的转换机制自动完成机制说明见 docs/vhlo.md方言定义见 stablehlo/dialect/VhloDialect.td。设计二MLIR Bytecode 序列化 显式版本目标StableHLO 不依赖文本形式传递程序而是使用 MLIR Bytecode 二进制格式并提供明确的目标版本参数向前兼容生产者可以指定我这个程序只用了 v0.9.0 的特性请降级到这个版本由ToVersion(0.9)转换完成如果程序用了旧版本不存在的新算子降级立即失败——不兼容问题在生产端就暴露而不是等消费者运行时才炸。▲ StableHLO 前向兼容流程程序先合法化legalize为 VHLO再用 ToVersion 转换降级到目标旧版本生成可被旧消费者读取的可移植产物这套机制的完整定义可以在早期兼容性 RFC rfcs/20220912-compatibility.md 中找到其中还给出了序列化目标版本 vs 当前版本的对照示例▲ StableHLO 序列化/反序列化的版本处理示例当 stablehlo.add 在 v0.4.0 发生变更后VHLO 中新增 vhlo.add_v2序列化端按目标版本降级算子版本反序列化端则升级后转回 StableHLO设计三写进 RFC 的兼容性承诺StableHLO v1.0 之后兼容窗口白纸黑字见 docs/compatibility.md承诺内容5 年后向兼容旧版本序列化的产物5 年内的新版本仍能正确读出、语义不变⏩2 年向前兼容新版本序列化的产物2 年内的旧版本仍能读出前提是不使用新特性版本号遵循语义化版本小版本对应 opset 或序列化格式变化补丁版本对应向 XLA 下游集成版本定义见 stablehlo/dialect/Version.h。每个 PR 都会跑一套兼容测试把覆盖全算子的测试语料序列化到所有受支持版本验证双向兼容测试套件见 stablehlo/tests/。工具链上stablehlo-translate工具一条命令即可完成序列化/反序列化C 与 Python 也提供了对等的 APIstablehlo/api/PortableApi.h、stablehlo/dialect/Serialization.hPython 侧绑定见 stablehlo/integrations/python/。StableHLO 生态谁在生产谁在消费这套稳定中间层不是纸上谈兵已有大量真实落地生产者框架侧JAX、TensorFlow、PyTorch/XLA、Julia 的 Reactant.jl、Go 语言的 GoMLX……消费者编译器侧XLA、IREE覆盖多种设备与加速器、Google AI Edge经 StableHLO 部署到移动设备、StableHLO→CoreML 转换器等。生态全景见 docs/awesome.md。快速上手3 步体验 StableHLO准备构建环境安装 CMake、NinjaLinux 建议再加 lld 与 ccache克隆仓库并构建克隆本仓库及 LLVM 子仓库后按 README.md 中的步骤构建 MLIR 与 StableHLO跑测试验证执行ninja check-stablehlo-tests全部通过即环境就绪。想深入了解算子语义直接读规格文档 docs/spec.md想跟随 JAX/PyTorch 导出的实战路径可参考 docs/tutorials/ 下的教程笔记。总结一次关于信任的演进回顾这条演进线本质是信任半径不断扩大的过程HLOXLA 内部自用只信自己MHLO搬进 MLIR信框架内的社区协作StableHLO加上 VHLO 版本化方言、Bytecode 序列化、RFC 级兼容承诺信整个行业、信五年后的自己。对新手来说记住三件事就够了StableHLO 是 ML 生态的USB-C 接口它的稳定来自 VHLO 这套只增不改的版本化设计它的承诺是 5 年后向 2 年向前的兼容窗口。理解了这三点你就真正读懂了 StableHLO 的演进史。【免费下载链接】stablehloBackward compatible ML compute opset inspired by HLO/MHLO项目地址: https://gitcode.com/gh_mirrors/st/stablehlo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考