2026年9月,英伟达(NVIDIA)宣布推进 Rust 原生 GPU 编程,CUDA Rust 将成熟至2027年及以后。AI 系统层含推理引擎、驱动与智能体运行时,渐用 Rust 编写以编译期捕错且不损性能。英伟达的诺瓦Linux驱动(Nova Linux driver)、迪纳摩(NVIDIA Dynamo)与 NVTX 均用 Rust,但 GPU 内核常需另写语言,CUDA Rust 补此缺口,让内核用 Rust 原生编译为 PTX。
正文
2026年9月,NVIDIA 宣布投入 Rust 原生 GPU 编程。AI 系统层涵盖推理引擎、服务基础设施、驱动和智能体运行时,随模型与技术不断变动,其中越来越多用 Rust 编写,因为它在编译期捕获大量错误且不牺牲性能。NVIDIA 也在转向:Nova Linux 驱动用 Rust 写,NVIDIA Dynamo 基于 Rust 核心,NVTX 有 Rust 绑定。但 GPU 核函数例外,以往只能从 Rust 启动核函数,核函数本身常需用其他语言写。CUDA Rust 填补了这一空白,核函数可用 Rust 原生编译为 PTX,而非包裹别处代码。
CUDA 本身有两条轨道,Rust 也有对应两种用法。SIMT 是你在 CUDA C++ 或 numba-cuda 中已用的模型,你写明单个线程做什么,然后启动数千个线程。Tile 是较新模型,C++ 和 Python 也有,你只需表明一个数据 tile 做什么,剩下的交给 Tile IR 编译器。选择时先选 Tile,因为编译器决定 tile 如何映射到各架构,源码无需编码架构特定选择;需要那种控制或想自管内存线程时,再降到 SIMT。用哪种语言与用哪种模型是两回事,选最适合现有栈的 CUDA 暴露方式,下面两个项目针对栈是 Rust 的情况。NVIDIA 计划支持跨语言互操作,选择不会将你锁死。
下面是两种轨道上相同的核函数,对 1024 个浮点数逐元素相加。两者都是完整程序、都会运行并打印同一行,可对照阅读。
SIMT 轨道:cuda-oxide
cuda-oxide 是定制的 rustc 代码生成后端。它拦截编译,将 #[kernel] 函数经 Rust MIR、社区 Pliron IR 框架和 LLVM IR 生成 PTX,其余交给标准后端;基于 Pliron 的 GPU 方言及所有变换都保持 Rust 直到标准 LLVM 后端接手。
你需要 Linux、计算能力 8.0 以上的 GPU、CUDA 工具包 12.x 以上、带 libclang 头的 clang,以及固定的 nightly 工具链。cargo oxide doctor 会检查这一切。安装 cargo-oxide 子命令后,脚手架并运行项目,模板即是完整的向量加法程序,主机与设备代码同文件、单命令构建、无需独立核 crate:
- cargo oxide new vecadd_demo
- cd vecadd_demo
- cargo oxide doctor
- cargo oxide run
首次 cargo oxide run 会构建代码生成后端,耗时较长,后续运行复用缓存。程序打印 PASSED: all 1024 elements correct。
先看核函数签名,它承载了整个安全论证。a 和 b 是普通共享切片,每个线程可读;c 是 DisjointSlice
启动是被检查而非被信任的。#[launchcontract] 声明该核函数以一维、256 线程块索引。preparevecadd 针对该声明和实时设备限制验证你的 LaunchConfig1D,并交回安全 vecadd 方法所需的证明。无 contract 的核只暴露原始不安全启动方法,因为裸 LaunchConfig 未说明它启动的是什么核。
Tile 轨道:cutile-rs
cutile-rs 高一个层级,你对 tile 而非标量做计算。每个 tile 块作为单一逻辑线程在数据的子张量上运行一次核体,编译器决定背后有多少真实 GPU 线程。#[cutile::module] 宏将核的 AST 嵌入主机二进制,并在核首次被需要时经 CUDA Tile IR JIT 编译。
需求比 SIMT 轨道轻:计算能力 8.0 以上 GPU、CUDA 13.3、稳定版 Rust 1.89 以上和 Linux,不需 nightly 工具链和自有 LLVM。cutile 已发布,无需克隆:
- cargo new vecadd_demo
- cd vecadd_demo
- cargo add cutile
同样的逐元素加法用 tile 写,核函数 add 带静态 tile 宽 B 作为静态维度,输出 z 是独占子张量,输入 x、y 用 -1 表示动态维度,在启动时解析,故形状变化无需重编译。主机端对 1024 元素零张量做 .partition([128]),它同时做三件事:给每个 tile 块独占其 128 元素块(即 &mut 保证的独占性)、固定网格为 1024/128=8 个 tile、并提供 B(启动器从分区读取 tile 宽,调用处无需写)。因此可变的 &mut 输出在传入前必须分区。
Tile 轨道在稳定版 Rust 得到相同答案,签名做相同安全论证。其主机启动返回宏生成的启动器而非设备函数,它获取三个张量所有权并在 GPU 完成后归还,.first() 取回输出。在 .sync_on(&stream) 之前一切皆是惰性描述(包括 ones、zeros、核调用乃至拷回主机),仅在此处同步运行。打印结果同为 PASSED: all 1024 elements correct。
编译器捕获了什么
两个核函数对内存做了相同声明:输入共享,输出仅属一个写者。区别仅在声明层级及是否需要专用类型。这很重要,因为数千线程以无保证顺序访问同一缓冲,若两个线程命中同地址且其一在写,次序决定结果;这类错误难复现,过测试却在生产失败。
将 SIMT 核的输出缓冲作为自身输入传入不会编译:cannot borrow c_dev as mutable because it is also borrowed as immutable。Tile 侧相同别名也不编译:use of moved value: z。两者都在编译期抓住经典别名错误,但位置不同:cuda-oxide 检查每次启动调用;cutile-rs 的所有权跨启动边界跟踪张量,声明更强。
Tile 没有共享内存或线程索引可让你出错,因为编译器拥有二者。tile 块是单逻辑线程,故无线程可竞态,这使其构造安全,也是你放弃的东西。SIMT 保留控制,目前其共享内存需 unsafe;共享内存是快速 SIMT 核的基础,让该路径安全是正在进行的工作。
项目现状
两个项目均早期,非生产就绪。cuda-oxide 是早 alpha。cutile-rs 更靠前,已发布于 crates.io 并被 NVIDIA 之外的 HuggingFace Grout 推理引擎和 mistral.rs 使用。覆盖不全,API 会变动,遇到毛刺欢迎反馈。
Cargo 和 crate 让人期待易上手,而 GPU 编程历史相反,缩短距离是工作一部分。SIMT 轨道仍需固定 nightly 工具链,这正是我们想不再要求的。GPU 上的 Rust 不新,此前有先驱工作并行。cuda-oxide 书中的生态附录标明了我们相对 Rust-GPU、rust-cuda、CubeCL 等的位置,我们正与 rust-cuda 维护者合作。
新的是我们投入的工程和清晰方向。
你如今能做什么
- 运行 SIMT 例:在 cuda-oxide 中 cargo oxide new 然后 cargo oxide run。
- 运行 Tile 例:克隆 cutile-rs,然后 cargo run -p cutile-examples --example hello_world。
- 读文档:cuda-oxide book 与 cuTile Rust 文档。
- 读论文:Fearless Concurrency on the GPU。
- 提 issue:在 cuda-oxide 或 cutile-rs 仓库告知破损与缺失。
- 加入讨论:两仓库的 GitHub Discussions 或 cuda-oxide Discord。
- 来听演讲:Melih Elibol 将在 RustConf 2026(9月8至11日蒙特利尔)讲“Fearless Concurrency on the GPU”,NVIDIA 其他员工也参会。
把玩现有东西并与我们共建。它早且开放,你现在的构建将塑造未来。NVIDIA 兴奋地与 Rust 社区一同提升原生 Rust GPU 编程;rust-cuda、rust-gpu、cudarc 等项目开创了 GPU 与 Rust 结合,其背后的人(包括 VectorWare 团队)持续塑造我们的思考。
评论
讨论整体偏怀疑:多数人对官方公告的 AI 代笔痕迹和 pre-1.0 的成熟度都不买账,少数人则因为「终于能用 Rust 写原生 kernel」重新燃起兴趣。分歧核心在于这层新抽象究竟降低了门槛,还是只是又多了一层绑定和排错负担。
认为公告像是模型代笔,因此对项目本身也信任不足
- 多人指出文章的行文与配图透着明显的生成痕迹,进而推断 NVIDIA 内部并没有人真正投入这个项目(较多人) > 如果真有人在意,至少会找个活人来写公告。(@nicebyte)
- 有人直接称其为「AI 垃圾文章」,质疑凭什么让人信任(较多人)
- 也有人以调侃收尾,把话题拐到 NVIDIA 在 Linux 下始终查不到 TJunc 热点温度这件事上(少数人)
认为再叠一层抽象会把排错变成猜谜
- 关键担忧是调试路径被拉长:kernel 出问题时,要先在 cuda-oxide、Rust 前端、CUDA 运行时和 Tile 之间逐层排除(较多人)
- 作为 pre-1.0 且要求 nightly 编译器的项目,本身就被贴上了「不稳定软件」的标签(较多人)
- 整条链路里只有 CUDA 是闭源的,一旦问题落在这一层,用户只能等 NVIDIA 自己修(较多人)
看好 Rust 原生 kernel 的方向,但打算等它稳定
- 有人把它放进 Rust 推理生态的叙事里,认为配合 Candle 这类库,是走向原生 Rust kernel 的合理一步(较多人)
- 更有意思的反直觉理由是:如今什么代码都像 LLM 写的,学 Rust 的动力被消磨,而这类模型尚未被训练过的项目反而让人重拾兴趣(少数人)
- 已经在用 WGPU 加 cudarc 的人则表示愿意尝试,但卡在 Linux-only 与必须使用异步这两点上(少数人)
认为问题不在语言,而在 CUDA 的专有绑定
- 强烈反对在 C++ 代码库里引入 CUDA,认为一旦引入就很难剥离,最终要么被单一厂商绑定,要么掉进 #ifdef 地狱(少数人)
- 主张承认 GPU 不是 CPU:kernel 应写在独立文件里手动启动,像 Metal、OpenCL、D3D12 那样;Triton 这类 DSL 比在 Rust 里硬凑更顺手(少数人)
- 对「只支持 NVIDIA」表示不意外,转而推荐 rust-gpu 这类跨厂商路线(少数人)
有价值的补充
- cuda-oxide 的主机端定位与 cudarc 相近,真正的新意是 kernel 用 Rust 风格方言编写:好处是主机与设备端能共享结构体,代价是放弃标准 CUDA kernel,换成一个仍在演进的方言。
- 两条可选路径(SIMT 与 Tile)意味着「出问题时该怪谁」本身就是个问题,这是该项目可维护性上被反复点名的成本。
- 有评论把 Hugging Face 的 Candle 当作生态拼图,但其中「NVIDIA 已收购 Hugging Face」的前提并不成立,这一点需要打上问号。
- 被拿来对比的还有 rust-gpu 与 vectorware,说明社区真正关心的是跨厂商的 Rust GPU 编程方案,而不是某一个厂商新造的一层绑定。