[控场AI]
· 6 分钟阅读· 3,285 字

IBM Spyre加速器为何放弃自研编译栈,转向PyTorch Inductor?

IBM Spyre加速器为何放弃自研编译栈,转向PyTorch Inductor?

IBM Spyre 弃自研 sendnn 改用开源 Inductor,以适配层换生态红利。

IBM 将 Spyre AI 加速器的 torch.compile 后端从自研 sendnn 编译栈切换为开源 Inductor,这一决定反映了 AI 芯片编译器领域"自建还是复用"的经典取舍。自研栈虽早期可控,但随 PyTorch 算子集扩展,维护成本指数上升;接入 Inductor 后,IBM 只需聚焦 Spyre 专属的调度与内存适配,充分利用社区验证过的图优化与代码生成能力。这一策略与 Intel、AMD 一致,标志着碎片化编译栈正被收敛,芯片-框架适配复杂度从 O(M×N) 降至接近 O(M+N)。文章同时指出风险:通用后端在极端优化场景仍有局限,厂商需保留关键算子的手写通道,并持续跟进上游接口变动。

IBM 的 Spyre AI 加速器最近做了一个关键决定:将 torch.compile 的后端从自研的 sendnn 编译栈切换为开源社区维护的 Inductor。这不只是换一个工具那么简单,背后涉及编译器工程中一个经典的两难——自建还是复用。

IBM Spyre加速器编译器架构调整

从sendnn到Inductor:一次编译栈的"拆旧换新"

据 PyTorch 官方博客介绍,IBM Spyre 加速器的软件栈此前依赖 sendnn——一套完全从零搭建的独立编译堆栈。这个方案在早期能快速跑通链路,但随着模型复杂度增长和硬件迭代加速,维护成本开始失控。

换成 Inductor 后,Spyre 直接进入 PyTorch 的主干生态。Inductor 本身是 torch.compile 的默认后端,能够将 PyTorch 计算图降级为 Triton 内核或 C++/OpenMP 代码,再针对目标硬件做代码生成。这意味着 IBM 不需要重复造轮子,而是把精力集中在 Spyre 特有的硬件适配层上。

这条路和 Intel、AMD 等厂商的策略一致:接入 Inductor 的扩展机制,通过自定义后端接口做硬件专属优化,而非维护一套平行的编译管线。

自研编译栈的隐性成本

编译器的核心复杂度不在于"让代码跑起来",而在于"让代码在每一代硬件上都跑得好"。自建栈意味着算子融合策略、内存规划、循环变换、后端代码生成全部要自己实现和调试。当 PyTorch 上游算子集每季度都在扩展时,追赶成本会指数级上升。

Inductor 提供的是一套经过大量模型验证的降级和优化 pass,硬件厂商只需要实现少量接口就能获得社区级别的优化能力。对 IBM 来说,这笔账算得很清楚。

torch.compile 是 PyTorch 2.0 引入的即时编译(JIT)机制,开发者只需在模型外层加一行 @torch.compile 装饰器,即可在运行时把 Python 执行的计算图捕获下来,经过多层图优化后交给后端生成高效内核。它的工作分三步:先用 TorchDynamo 在字节码层面抓取计算图,再用 AOTAutograd 处理前向与反向的图结构,最后交由后端编译器落地成可执行代码。torch.compile 本身只是"调度层",真正的代码生成本事取决于所挂载的后端。默认后端就是 Inductor,因此"换后端"本质上是在替换 torch.compile 的最终出口,而不改变前端捕获逻辑。理解这一分层是理解本文的前提:IBM 换的是出口,不是整个编译框架。

Inductor的扩展点:硬件厂商如何接入

Inductor 的设计允许第三方硬件通过多种方式介入编译流程。

自定义后端与Triton代码生成

最直接的方式是实现 Inductor 的后端接口。编译器在生成内核时,可以选择走 Triton 路径或 C++ 路径。对于有自定义编程模型的加速器,厂商可以接管特定算子的代码生成,把 Inductor 产出的中间表示映射到自家指令集。

Spyre 走的就是这条路线。IBM 在 Inductor 之上做了 Spyre 专属的调度和内存层级适配,而不是另起炉灶。

Triton 是 OpenAI 开源的一门面向 GPU 内核的编程语言与编译器,它让开发者用接近 Python 的语法写并行内核,而由 Triton 编译器自动完成线程划分、共享内存分配、向量化等底层优化。Inductor 在生成内核时,默认会把优化后的计算图翻译成 Triton 代码,再交给 Triton 编译器生成机器码;当目标硬件不支持 Triton 或不适合时,则回退到 C++/OpenMP 路径。对硬件厂商而言,这意味着只要实现好图到 Triton(或 C++)的降级规则,就能借用社区积累的大量内核模板,而不必从 PTX 或汇编层重写。Spyre 的适配正是建立在这一层抽象之上:IBM 只需要把 Inductor 输出的中间表示映射到 Spyre 指令集,前端捕获、图优化等繁重工作全部由 PyTorch 主干承担。

上游贡献的反哺机制

接入开源栈还有一个常被低估的好处:改动可以回流上游。当 IBM 在适配过程中发现 Inductor 的某个 pass 对稀疏计算支持不够好,可以提 PR 改进通用逻辑,而不是在私有 fork 里打补丁。这种反哺会让后续适配越来越轻。

"上游"(upstream)在开源协作中指项目的主干代码库,与厂商自己维护的 fork(分叉版本)相对。向主干提交 PR 并合入,意味着你的改动会成为所有用户共享的通用能力。私有 fork 的问题在于:每次主干更新,你都要把上游改动合并回来,冲突越积越多,最终可能彻底无法跟进。反哺机制的好处是双向的——厂商贡献的通用改进(例如对稀疏算子、特定数据类型或新硬件特性的支持)一旦进入主干,后续所有适配工作都站在更高的基线上。这解释了为什么 Intel、AMD、IBM 等厂商愿意投入工程师专职做上游贡献:短期的 PR 成本,换来的是长期维护负担的系统性下降,也避免了各家用私有补丁把通用生态割裂成互不兼容的孤岛。

对AI芯片生态意味着什么

这次切换释放的信号比技术细节更有价值。

碎片化的编译栈正在被收敛。 过去几年,几乎每家 AI 芯片公司都在自建编译器,结果是模型移植成本极高,用户被迫为每款芯片单独调优。Inductor 正在成为事实上的中间层,把"芯片-框架"的适配从 O(M×N) 降到接近 O(M+N)。

开源后端的性能天花板在抬高。 早期 Inductor 在非 NVIDIA 硬件上的表现常被诟病,但随着 Microsoft、Intel、AMD 以及现在 IBM 的持续投入,通用代码生成质量已经能覆盖相当一部分训练和推理负载。自研栈在特定场景下的性能优势,未必能抵消维护上的劣势。

硬件厂商的竞争焦点在转移。 当编译层趋于统一,差异化就落到芯片本身的架构、互联带宽、内存带宽,以及软件栈中真正独有的部分——比如 Spyre 的特定数据流调度。这对用户是好消息:换芯片不再意味着重写整套工具链。

O(M×N) 到 O(M+N) 是软件工程中描述"适配组合爆炸"的经典框架。假设有 M 款 AI 芯片、N 个主流框架,如果每对"芯片-框架"组合都需要单独开发与维护一套编译适配,总工作量就是 M×N,随双方数量增长呈乘积式膨胀。当出现一个被广泛接受的中间层(如 Inductor)后,芯片厂商只需适配这一层,框架方也只需对接这一层,工作量降为 M+N 的加法关系。这正是操作系统、浏览器、数据库驱动等领域反复验证过的规律:中间抽象层是控制生态复杂度的关键手段。对 AI 芯片而言,谁被纳入主流中间层,谁就更可能被开发者默认支持;而中间层本身则由上游社区主导其演进方向,这也是厂商竞相投入上游的深层动机。

值得关注的风险

Inductor 作为通用后端,在极端优化场景下仍有局限。对延迟极度敏感或算子高度定制的工作负载,通用 pass 可能不如专用编译器。IBM 需要在接入 Inductor 的同时,保留针对 Spyre 关键算子的手写优化通道,否则可能在某些 benchmark 上失去竞争力。

另一个问题是上游兼容性。Inductor 迭代速度快,接口和内部 IR 时有变动。硬件厂商的适配层需要持续跟进,这本身也是一种维护成本,只是从"维护整个编译器"变成"维护适配层+跟进上游"。

总体来看,IBM 这一步是务实的工程取舍。在 AI 芯片编译器还远未标准化的阶段,选择站在 PyTorch 生态这一边,至少保证了开发者不用为 Spyre 学一套新工具。

#IBM Spyre#PyTorch Inductor#torch.compile#AI加速器编译器#sendnn#Triton#AI芯片软件栈
分享:

相关推荐