1. 为什么“AI基建转向Rust”这个说法值得认真对待
第一次看到“AI基建正在转向Rust”这个判断时,我的反应是:又一个语言之争的标题党。毕竟过去十年,AI基础设施的默认技术栈几乎被Python和C++牢牢锁死——Python负责胶水层和实验迭代,C++负责算子内核和推理引擎。Rust想挤进来,凭什么?
但把最近两年几个关键项目的技术选型摊开来看,这个判断不是空穴来风。所谓“3个信号”,我理解它指向的是三个层面的变化:新立项的AI运行时开始默认选Rust、存量Python/C++项目在关键路径上引入Rust重写、以及大厂在推理服务与训练调度这类核心组件上公开押注Rust。这三个信号叠加起来,才构成“转向”这个量级的描述,而不是某个小项目的一时兴起。
这篇文章我想做的事很具体:把这三个信号拆开,讲清楚每个信号背后对应的真实工程问题是什么、Rust到底解决了什么Python和C++解决不好或解决起来代价太高的问题、以及如果你是一个正在做AI系统的人,现在要不要跟进、怎么跟进。适合的读者是:写过Python训练脚本、碰过C++算子、正在被性能或内存问题折磨的工程师,以及需要做技术选型决策的架构负责人。不要求你会写Rust,但要求你对AI系统的运行链路有基本概念。
先把结论放在前面,方便你带着判断往下读:Rust在AI基建里的位置,不是取代Python做实验,也不是全面取代C++写算子,而是填补“高性能+高并发+内存安全+可维护”这四者交集处的空白。这个空白过去一直存在,只是以前大家用C++硬扛,或者用Python加各种补丁绕过去。现在Rust的生态成熟到能扛这个位置了,所以转向发生了。
2. 信号一:新立项的AI运行时与推理框架默认选Rust
2.1 这个信号具体指什么
第一个信号最直观:近两年新出现的AI运行时、推理服务框架、向量检索组件,在技术选型阶段就把Rust列为首选,而不是像过去那样先Python原型、再C++重写。这不是个别现象,而是一批项目呈现出的共同倾向。
我梳理了一下这类项目的共同特征:它们大多处于“AI系统的中间层”——上面是Python写的业务逻辑和模型定义,下面是CUDA或各类加速硬件,中间需要一个东西来管理内存、调度请求、做批处理、处理并发。这一层过去要么用C++写,要么用Python硬撑,现在越来越多项目直接用Rust写。
为什么这一层特别适合Rust?因为它同时具备几个特征:对延迟敏感、对内存布局敏感、需要处理大量并发连接、但又不需要像算子内核那样极致压榨每一条指令。C++能胜任前三点,但第四点带来的开发效率和安全性代价太高;Python能胜任开发效率,但前三点全都吃力。Rust恰好卡在中间。
2.2 为什么是现在,而不是五年前
五年前Rust的异步生态还不成熟,写一个高并发服务要自己处理大量底层细节,学习曲线陡到劝退。现在不一样了,异步运行时、HTTP框架、序列化库、GPU绑定这些基础设施都到了可用甚至好用的程度。一个团队用Rust写推理服务的开发体验,和用Go写微服务已经差不太多,但性能上限更高、内存控制更精细。
另一个关键变化是AI系统的部署形态变了。过去模型推理多是离线批处理,对并发和延迟不敏感,Python脚本跑一晚上也没人管。现在大量场景是在线推理,要求毫秒级响应、要处理突发流量、要在同一台机器上跑多个模型。这种形态下,中间层的质量直接决定整个系统的可用性,Rust的价值就被放大了。
2.3 实操层面的观察:新项目选型时的真实考量
我跟几个做推理服务的朋友聊过选型逻辑,他们的考量顺序大致是这样的:
- 延迟底线能不能守住:Python的GIL和GC在高压下会出现不可预测的停顿,C++能守住但开发慢,Rust能守住且开发效率可接受。
- 内存占用能不能压住:在线服务往往要在有限内存里塞多个模型,Rust没有GC、内存布局可控,比Python省,比C++省心。
- 出故障时好不好查:C++的段错误和内存泄漏排查成本极高,Rust在编译期就挡掉大部分这类问题,线上事故率明显低。
- 团队能不能招到人、能不能留住:这点很现实,Rust人才虽然少,但愿意学的人多,而且一旦团队上手,代码可维护性比C++好很多。
注意:这里说的“默认选Rust”是指新立项的中间层组件,不是说整个AI系统都用Rust写。模型定义、数据处理、实验管理这些还是Python的天下,短期内不会变。
3. 信号二:存量Python/C++项目在关键路径引入Rust重写
3.1 重写不是推倒重来,而是“关键路径替换”
第二个信号比第一个更有意思:不是新项目选Rust,而是已经在跑的Python或C++项目,把其中某一段关键路径抽出来用Rust重写,然后通过FFI或子进程的方式嵌回原系统。这种做法在过去一年明显增多。
为什么是“关键路径替换”而不是整体重写?因为整体重写的风险和成本没人扛得住。一个跑了三年的训练平台,几十万行Python,你说全部用Rust重写,老板第一个不同意。但你说“把数据加载和预处理这一段用Rust重写,训练速度能提升30%”,这个账就算得过来。
我见过几个典型的替换场景:
- 数据加载与预处理:Python的DataLoader在多进程下经常成为瓶颈,尤其是做复杂增强时。用Rust写一个数据加载器,通过PyO3暴露给Python调用,吞吐量能翻几倍。
- Tokenization与文本处理:大模型推理前的tokenize、推理后的detokenize,以及各种文本清洗逻辑,Python实现慢且占内存。Rust重写后单机吞吐显著提升。
- 请求路由与批处理调度:推理服务前面的路由层、动态批处理逻辑,Python写起来简单但并发一高就崩,Rust重写后稳定性和吞吐都上来了。
- 自定义算子:以前用C++写CUDA算子,现在有些团队用Rust写CPU侧的逻辑,再通过绑定调用GPU,开发体验和安全性都更好。
3.2 PyO3和FFI:让Rust和Python和平共处的关键工具
这里必须提一下PyO3,它是Rust和Python互操作的核心工具。没有它,“用Rust重写Python关键路径”这件事的成本会高到没人愿意做。PyO3让你可以用Rust写一个Python扩展模块,Python侧import进来就像用普通模块一样,调用开销很低。
一个典型的替换流程是这样的:
# 用maturin创建一个Rust+Python的混合项目 maturin init --bindings pyo3然后在Rust侧写核心逻辑,用#[pyfunction]标注要暴露的函数,编译成wheel后Python直接pip install。整个过程比写C扩展舒服太多,构建工具链也成熟。
实操心得:不要一上来就重写最复杂的部分。先找一个“逻辑独立、性能瓶颈明确、输入输出接口清晰”的模块下手,跑通整个Rust+Python的构建和部署流程,让团队先熟悉这套工具链,再逐步扩大替换范围。
3.3 重写带来的真实收益与隐藏成本
收益方面,我看到的案例里比较典型的数据是:数据加载环节吞吐提升2到5倍,文本处理环节内存占用降低一半以上,推理路由层在同等硬件下QPS提升30%到80%。这些数字因场景而异,但方向是一致的。
隐藏成本也要说清楚:
- 构建复杂度上升:原来纯Python项目,现在多了一套Rust工具链,CI/CD要改,部署包要处理多平台wheel。
- 调试链路变长:Python和Rust之间的边界出问题时,排查比纯Python麻烦,需要同时懂两边。
- 团队技能要求提高:至少要有一个人能维护Rust侧代码,不能全靠外包或临时学。
所以我的建议是:只有当某个环节的性能问题已经明确成为业务瓶颈,且用Python层面的优化手段(换库、调参、加机器)都解决不了时,才考虑引入Rust重写。不要为了用Rust而用Rust。
4. 信号三:大厂在推理服务与训练调度上公开押注Rust
4.1 这个信号的份量为什么最重
前两个信号还可以说是社区行为或个别团队的选择,第三个信号的性质不同:当有资源、有规模、有长期技术判断能力的团队,在推理服务和训练调度这类核心组件上公开选择Rust,说明这不是试验,而是经过验证的工程决策。
推理服务和训练调度是AI基建里最“硬”的部分。它们要处理的是:成千上万的并发请求、复杂的资源分配、跨节点的通信协调、故障时的快速恢复。这些场景对语言的要求极其苛刻——既要性能,又要安全,还要可维护。过去这块基本是C++和Go的领地,现在Rust挤进来了。
4.2 推理服务为什么特别适合Rust
推理服务的核心挑战可以归纳为四个字:高并发、低延迟。展开来说:
- 每个请求都要做tokenize、组batch、调模型、detokenize、返回结果,链路长且每步都不能慢。
- 请求量波动大,需要动态批处理和弹性扩缩容。
- 多个模型可能共享同一张GPU,需要精细的显存管理和调度。
- 服务不能崩,崩一次影响面很大。
Rust在这几个点上的优势是叠加的:没有GC所以延迟稳定,所有权模型所以并发安全,零成本抽象所以性能接近C++,错误处理强制显式所以线上故障少。这些优势单独看都不稀奇,但叠在一起,在推理服务这个场景里就形成了明显的综合优势。
4.3 训练调度为什么也开始用Rust
训练调度比推理服务更复杂,它要管理的是长时间运行的任务、跨节点的资源协调、检查点保存与恢复、故障重试等。这块过去主流是Go和Python,Go胜在并发模型简单,Python胜在生态丰富。
Rust切入这块的逻辑不太一样:它不是为了替代Go的并发优势,而是为了解决Go在资源精细控制和长时间运行稳定性上的不足。训练任务动辄跑几天几周,任何内存泄漏或资源未释放都会累积成大问题。Rust的所有权模型在编译期就强制你处理好资源生命周期,这对长时间运行的系统是巨大的可靠性保障。
另外,训练调度往往要和底层硬件、网络、存储打交道,Rust的零成本抽象让你能写出既安全又高效的底层代码,不用在安全和性能之间做取舍。
4.4 一个值得关注的趋势:Rust正在成为AI基建的“系统语言”
把三个信号放在一起看,一个清晰的图景浮现出来:Rust正在成为AI基建的“系统语言”。这里的“系统语言”不是指写操作系统,而是指写那些支撑AI系统运行的基础组件——运行时、调度器、推理引擎、数据管道。
Python仍然是AI的“用户语言”,用来定义模型、做实验、写业务逻辑。C++仍然是“内核语言”,用来写极致优化的算子和驱动。而Rust占据的是中间那层“系统语言”的位置,负责把用户语言和内核语言粘起来,同时保证整个系统的性能、安全和可维护性。
这个分层不是谁取代谁,而是各归其位。过去中间这层没有专门的语言,大家用Python硬撑或用C++硬写,现在Rust来了,把这块补上了。
5. 如果你要跟进,从哪里开始
5.1 先判断你的场景是否真的需要Rust
不是所有AI项目都需要引入Rust。我的判断标准很简单:如果你现在没有遇到Python解决不了的性能问题、没有遇到C++解决不了的安全问题、没有遇到Go解决不了的资源控制问题,那就不需要Rust。技术选型的第一原则是解决问题,不是追新。
具体来说,以下场景值得认真考虑Rust:
- 推理服务的延迟或吞吐已经影响到业务指标,且Python层面优化空间见底。
- 数据管道的吞吐成为训练瓶颈,加机器成本太高。
- 系统需要长时间运行且对稳定性要求极高,C++的内存问题反复出现。
- 团队有长期维护AI基建的规划,愿意投入学习成本换取长期可维护性。
5.2 最小可行的上手路径
如果你决定跟进,我建议的路径是这样的:
- 先学Rust基础,但不要学太深:把所有权、借用、生命周期、错误处理这几个核心概念搞明白,能写简单的命令行工具就行。不用一上来就啃异步和宏。
- 用PyO3写一个小的Python扩展:找一个你熟悉的Python函数,用Rust重写,通过PyO3暴露回去,跑通构建和调用流程。这一步的目的是熟悉工具链,不是追求性能。
- 在真实项目里找一个独立模块替换:选一个逻辑独立、接口清晰的模块,用Rust重写并接入。跑一段时间,观察性能、稳定性、维护成本的变化。
- 根据结果决定是否扩大:如果替换效果明显且团队能hold住,再考虑扩大范围;如果效果一般或维护成本太高,及时收手也不丢人。
5.3 工具链与生态的现状
Rust在AI基建相关的生态已经比较完整了:
| 用途 | 推荐工具/库 | 说明 |
|---|---|---|
| Python互操作 | PyO3 + maturin | 写Python扩展的标准方案 |
| 异步运行时 | tokio | 高并发服务的基石 |
| HTTP服务 | axum / actix-web | 写推理服务API层 |
| 序列化 | serde | 处理JSON、protobuf等 |
| GPU绑定 | cust / wgpu | 调用CUDA或跨平台GPU |
| 张量计算 | candle / burn | 纯Rust的推理框架 |
| 向量检索 | 各类Rust实现的向量库 | 用于RAG等场景 |
注意:生态虽然完整,但和Python的成熟度还有差距。有些库文档少、示例少,遇到问题需要自己啃源码。这是引入Rust的现实成本之一。
6. 常见问题与排查技巧实录
6.1 Rust和Python互操作时最容易踩的坑
问题一:GIL释放时机不对导致性能没提升。PyO3默认在调用Rust函数时持有GIL,如果你的Rust代码是计算密集型的,必须显式释放GIL,否则Python侧的其他线程还是被阻塞。用py.allow_threads(|| { ... })把耗时逻辑包起来。
问题二:数据在Python和Rust之间来回拷贝。如果每次调用都要把大数组从Python拷到Rust再拷回来,拷贝开销可能吃掉所有性能收益。解决办法是尽量让数据在Rust侧处理完再返回,或者用零拷贝的方式共享内存。
问题三:异常处理边界不清。Rust的panic如果跨FFI边界传播,行为是未定义的。所有可能panic的地方都要用catch_unwind包住,转换成Python异常返回。
6.2 异步代码的常见陷阱
Rust的异步和Python的异步在思路上有相似之处,但细节差异很大。最常见的坑是在异步上下文里做阻塞操作,比如同步文件IO、同步锁、CPU密集计算。这些操作会阻塞整个运行时线程,导致其他任务饿死。解决办法是用tokio::task::spawn_blocking把阻塞操作挪到专用线程池。
另一个坑是Future没有被poll就不会执行。Rust的Future是惰性的,你创建一个Future但不await它,它什么都不会发生。这和Python的协程类似,但Rust编译器不会提醒你,需要自己注意。
6.3 排查工具与技巧速查表
| 问题现象 | 可能原因 | 排查手段 |
|---|---|---|
| 性能没提升 | GIL未释放 / 数据拷贝过多 | 用py-spy看GIL占用,检查FFI边界 |
| 内存持续增长 | 循环引用 / 资源未释放 | 用valgrind或Rust的泄漏检测 |
| 服务偶发卡顿 | 异步上下文阻塞 | 检查是否有同步IO或CPU密集操作 |
| 编译报错看不懂 | 生命周期或借用问题 | 先看编译器建议,再查文档 |
| 跨平台构建失败 | 工具链或依赖问题 | 用Docker统一构建环境 |
实操心得:Rust编译器报错虽然长,但信息量很大,认真读通常能直接定位问题。新手最容易犯的错是看到一屏报错就慌,其实关键信息往往在最后几行。
7. 我对这个趋势的个人判断
说“AI基建正在转向Rust”,我认为准确但不完整。更准确的描述是:AI基建正在分层,Rust正在成为中间层的默认选择。这个分层是AI系统规模变大、部署形态变复杂之后的必然结果,不是语言偏好驱动的。
我在实际项目里看到的规律是:当一个AI系统还小的时候,Python一把梭完全够用,引入Rust是过度设计。但当系统大到一定程度——推理QPS上万、训练数据每天TB级、服务要7x24跑——中间层的质量就成为瓶颈,这时候Rust的价值就体现出来了。
所以我的建议不是“赶紧学Rust”,而是“先搞清楚你的系统有没有到那个临界点”。到了,Rust是值得认真评估的选项;没到,继续用Python把业务跑起来更重要。技术选型永远是为业务服务的,语言之争本身没有意义。
最后分享一个我自己的观察:那些成功引入Rust的团队,往往不是先招一个Rust专家,而是先让一两个愿意折腾的工程师用Rust写一个小模块,跑通了再逐步扩大。这个过程慢,但稳。急着全面切换的,大多会摔跟头。