研究 · NVIDIA Technical Blog

24个GPU算子迁往Rust:共同编译语言让代理结果可验证

NVIDIA介绍了由AI代理把24个TileGym算子从Python迁往Rust的工作,GPU内核执行速度接近原实现。关键在于能够比较编译器中间代码,并自动验证每个阶段。对于维护自定义计算算子的团队,这改变了本地编程助手所需的配套条件。

这对买家意味着什么

代码聊天与可验证的GPU内核迁移需要不同环境。这里支撑结果的是参考实现、编译器、测试和测量。买方应先评估为自己的算子建立这套流程的准备成本,再考虑增加助手的计算资源。

接近相同的速度属于特定测量

NVIDIA团队把全部24个公开TileGym算子迁到cuTile Rust,合计约40个GPU内核,涉及归一化、注意力和MoE计算。相对cuTile Python的总体速度比几何平均值为0.995。测量在NVIDIA DGX B200上完成,每个后端独占一块GPU,包含347组配对配置,并取四次CI运行中的最佳测量。这是在明确迁移任务中的有力结果。NVIDIA分析。

报告使用CUPTI device time,表示内核本身在GPU上的执行时间。用户经历的总耗时还包括启动和调度,这对非常短的操作尤其重要。因此,0.995不能解释为代理编写程序的速度,也不能直接表示整台本地服务器的提速。作者测量了总耗时,但最终算子比较采用的是设备执行时间。

为什么这种翻译可以逐项核对

cuTile Python、Triton-TileIR和cuTile Rust都生成CUDA Tile IR,也就是程序的中间表示,再交给同一个tileiras编译器优化并生成GPU二进制代码。迁移是在另一种语言接口中重现计算。团队因此拥有比源代码外观更精确的依据,可以比较数据块形状、内存操作和归约运算,而不必依赖代理对自己工作的描述。

主要困难是参数特化。Python会根据调用条件隐式生成对应内核;Rust要求在内核签名中明确声明这些条件。例如,Python未执行的分支可能在编译前消失,Rust的两个分支却都必须通过类型检查。因此,一个原始内核有时要拆成多个结构版本。代理需要恢复隐藏的程序约定,单纯替换语法并不足够。

完整集成之前先定位错误

流程从分析参考实现开始,生成analysis.json,记录结构版本、数据类型、误差容限、启动参数等条件。内核编写代理只负责kernel.rs。结果先通过不含Python和语言桥接层的独立Rust测试,再比较Tile IR。这种顺序使团队能在完整扩展尚未形成之前,区分计算错误和组件连接错误,减少后来排查时的混淆。

下一阶段加入C ABI调用约定和Python封装,使其他语言能够调用Rust,并通过TileGym测试检查实际形状和数据类型。只有机器可检查的成功判定才允许进入性能测量。作者特别指出,看似合理的内核可能通过常规测试,却丢失重要属性或改变内存操作。IR比较因此把验证范围扩展到测试样例之外。

Rust仍然存在需要检查的接口边界

cuTile Rust把Rust的所有权模型延伸到GPU内核,将可修改输出划分为互不重叠的部分。不过,一些已提供的迁移实现仍采用不受检查的接口,因为只有这种路径能重现参考IR;向安全接口迁移的工作仍在继续。跨过C ABI之后,错误的数组步长也可能悄悄破坏数据,所以封装层和调用接口各有检查责任。

在文中描述的PyTorch连接方式里,启动层不复制或分配内存,不接管其他组件的缓冲区所有权,并使用调用方的CUDA流。这些细节关系到能否接入现有代码,也说明数学公式正确只是一个条件。数据形状、内存访问以及语言之间的约定必须一并保留,否则算子仍可能在集成过程中出错。

主要投入是准备可复现的环境

这套流程需要CUDA 13.1及以上、Rust 1.89及以上、tileiras编译器,并要求用Blackwell GPU进行性能检查。作者称,一次完整转换的令牌消耗达到百万量级。流程限制重试次数,无法收敛时留下诊断记录。因此,团队需要准备参考实现、合适的工具,以及能够区分翻译缺陷和编译器问题的人员。

这项成果最适合确实维护自定义GPU算子的团队。共同IR让特定工具家族中的自动迁移具有验证基础,任意Python项目并不会自动拥有同样条件。具体选择应是先为一个必要算子安排可复现环境的预算。这样的准备决定本地代理能否创造价值,也应先于扩大助手服务器的决定。

选购系统前要验证什么

  • 团队经常修改哪些自定义GPU算子,哪些确实需要迁移?
  • 谁能分析IR差异以及上游编译器可能存在的缺陷?
  • 预算如何计入首次启动编译和后续缓存复用?
  • 完成一次转换的令牌支出上限是多少?

买家建议属于我们的编辑解读。原文并不证明目录中某款系统的速度或兼容性。