
最近在扒AI基建开源项目的代码时我越来越强烈地感觉到一个变化过去几年里很多关键基础设施组件是用C、Go甚至Java写的但现在新起的最有生命力的项目底层语言越来越集中于Rust。一开始我以为这只是个别团队的偏好但看多了以后发现这不是孤立的选型决定而是AI基建这条技术路径上正在发生的系统性转向。这个转向有三个非常明显的信号第一向量检索、数据管道这类基础设施开始用Rust重写第二推理服务运行时和调度层开始把Rust当作主力语言第三Python生态里越来越多的热点模块被Rust扩展替代连跨语言调用的工具链都成熟到可以大规模落地。这三个信号放到一起基本可以判断AI基建从Python/C主导逐步走到“Python留应用层、Rust打地基”的格局不是猜测而是正在发生的事。这篇文章我会把这3个信号逐个拆开讲清楚每个信号背后的技术逻辑、落地场景和实操经验最后再聊聊如果你所在团队也想跟进转向该怎么选模块、怎么过渡、怎么避坑。无论你是在做AI平台、推荐系统、向量数据库还是大模型推理服务这篇文章都值得你花几分钟看完。1. 信号一基础设施层的关键组件进入Rust重写周期1.1 AI基建的老痛点性能、内存安全与并发三者难兼顾先想一个问题AI基建里的基础设施层到底在解决什么问题简单说大量数据的引入、预处理、索引、检索、调度这些工作对吞吐和延迟的要求极高。拿向量数据库举例海量向量要实时写入索引线上要同时支撑几千上万个检索请求每个请求要在一两毫秒内做完相似度计算。这种场景下语言选型直接决定服务的上限。过去大家通常有两个选择。一是C性能确实拉满但开发节奏慢内存安全问题让每个团队都得背着ASAN、Valgrind过日子而且模块依赖管理基本靠手工。二是Go并发模型好用部署也简单但GC是绕不过的坎堆上对象一多GC停顿就会在高峰期冒出来导致p99延迟出现肉眼可见的尖刺。这个尖刺在普通业务里还能接受在AI检索这种延迟敏感场景里用户体感非常差。Rust正好卡在这个矛盾点上。它没有GC靠所有权和借用检查在编译期管理内存所以运行时不存在GC停顿的问题同时它提供的是零成本抽象手写出来的代码性能跟C平级甚至因为编译器约束更容易做激进优化。加上Cargo这套统一的包管理和构建体系工程效率比C高一大截。我见过不少从C迁过来的团队普遍反馈是“性能没降开发效率反而上来了而且内存问题少了很多”。1.2 率先浮现的Rust重写方向向量索引与流式数据处理在这波重写周期里最先动起来的不是业务代码而是离业务最远的底层。我观察到的核心重写方向主要落在两类组件上。第一类就是向量索引。无论是暴力扫描还是图式索引核心操作都离不开大批量浮点计算、内存紧凑布局和并发读写控制。Rust的强项在于能用很自然的代码表达这些需求而且标准库加第三方库的组合让开发者不需要像C那样自己造轮子。举一个很实际的例子一套百万级向量的检索服务原本用带GC的语言写的时候单实例QPS卡在两千左右换Rust重写核心检索路径之后同样的机器直接推到上万QPS且p99波动远小于之前。这背后没有魔法纯粹是GC和锁竞争消除带来的收益。第二类是流式数据处理与管道。数据管道里需要处理背压、乱序、批量聚合这类问题Rust的所有权模型让数据竞争的隐患在编译期就被堵死运行时不需要锁或者只需要极少量的细粒度同步。流式框架里最怕的就是数据竞争和状态共享失控Rust的铁律虽然让写代码的人一开始觉得约束太多但写完之后回头看几乎不需要花时间调试并发问题这种“编译过了就能跑”的体验在AI基建这种高并发领域价值极其明显。1.3 为什么取代的不是C也不是Go而是Rust一定有人问C性能跟Rust差不多为什么要换我的看法是不必把Rust定义成C的完美替代它更像是“带着现代工程化能力的C”。如果你是底层系统开发者你能感受到Rust保留了对内存布局、指令级细节的掌控力这些在AI基础设施里很重要。但是Cargo让你享受依赖管理测试工具链让单元测试、模糊测试在工程里跑起来更顺手。综合下来在同样的项目周期里Rust交付的质量和速度都比C更有竞争力。至于Go它的生态在云原生领域很强但AI基建里越来越多的负载是高密集型计算和低延迟路径Go的GC和内存模型在这种负载下会被放大劣势。更关键的是Rust可以向下接管C的存量库而Go很难做到同等性能。所以这轮转向的逻辑很清楚底层要性能选了Rust上层要生态选了Python中间那层交给谁就很自然了。2. 信号二推理服务运行时和调度层把Rust当作主力语言2.1 大模型推理的关键路径低延迟与高并发的双重挑战AI基建的另一块重头是推理服务。这里说的推理服务不只是“把模型加载起来跑一次前向”而是包括请求接入、排队、动态批处理、采样、流式输出、审计等一系列环节。整个链路里模型前向计算这一块通常还是C或CUDA的天下模型本身不会用Rust重写但围绕模型的“服务骨架”正在快速Rust化。为什么因为在线推理服务对两个指标非常敏感延迟和并发。原始请求进来之后服务端要把同一批请求动态组合成batch塞给GPU跑这中间涉及大量并发编排和排队策略。用动态语言写调度逻辑说实话也能跑但一旦请求量冲到几千QPS解释器的开销和锁竞争就会变得不可控。更麻烦的是流式输出模型一个token一个token往回流服务端要同时维护成千上万个流式连接这时候并发模型稍有波动用户那边立刻能感知到“卡顿”和“中断”。2.2 Rust在推理栈中拿下的核心位置接入层与调度层具体来说我看到的Rust化主要发生在两个位置。第一个是接入层任务很简单接收请求、校验参数、做鉴权、转发到推理进程或GPU节点。以往这块用Python或Go写也没问题但接入层是流量最密集的地方任何一个阻塞点都会被放大。Rust在这里的收益是线程模型和异步机制配合得非常好可以用极少的线程支撑数万并发连接。实际调优中一个Rust写的接入层实例同时挂几万个WebSocket或gRPC流CPU和内存占用都非常平稳很难出现动态语言那种“线程一多就调度不过来了”的问题。第二个是调度和动态批处理层。动态批处理的核心逻辑是在一个时间窗口内收集请求按模型和资源约束决定哪些请求可以拼在一起执行再决定当前这批请求在GPU上跑完之后的令牌分发策略。这本质是一个带优先级的并发队列系统。Rust的异步运行时在这里提供了非常顺手的channel和超时控制原语可以很干净地实现批处理窗口的轮询、控制批大小、处理超时任务。相比之下Python的GIL让真正的并行受限制Go的话则要小心GC对批处理时间线的影响。2.3 从调度到模型加载Rust正在接管模型服务的外围路径还有一个容易被忽略但很关键的环节模型加载与权重解析。一个大语言模型的权重文件动辄几十GB加载过程中要解析大量metadata、处理张量存储格式、做合法性检查和数据重排。传统上用Python解析这类文件会比较慢而且解析长度、偏移量这类字段时稍不小心就有越界读取的风险。Rust在这个场景下的优势是双重的一是解析性能高同样一个权重格式Rust的解析速度能比Python快几倍二是Rust可以安全地处理不受信任的外部输入避免在加载恶意构造的权重文件时出现内存破坏。随着新型安全权重格式逐步普及加载路径上出现纯Rust实现的趋势已经越来越明显。我个人做过的实验里把模型元数据解析和加载逻辑重写成Rust模块之后整个加载流程从原来的十几秒降到了几秒而且边界检查让解析代码明显更容易验证正确性。对于追求服务快速扩容和弹性伸缩的团队来说这个收益在流量突增时非常值得在意。3. 信号三Python外围出现“Rust后门”工具链已成熟到可规模化落地3.1 大多数团队的起点不重写架构只替换热点模块对大部份团队来说短期内不太可能把整个AI平台都换成Rust最现实的路径是Python还是那套Python但把热点模块一个一个用Rust重写通过扩展机制嵌回去。这就是第三个信号的核心。以前做这件事的门槛很高因为用C或者C写Python扩展很麻烦需要考虑Python C API的引用计数、GIL、错误处理等一堆细节。一个扩展写下来光把接口调对就要花不少时间。但如今专门面向Rust的Python扩展工具链已经非常成熟你可以用很接近Rust习惯的方式编写扩展函数把数据结构从Python传到Rust做完计算再传回来。配合现代的构建打包工具一条命令就能把Rust源码编译成Python的wheel包CI/CD里可以直接用。也就是说现在一个团队在Rust里写一个高性能函数包装成Python模块整个过程的工程复杂度已经降到跟写纯Python差不多。3.2 热点替换的真实案例文本预处理函数快30倍我在一次数据处理管线的优化里做过一个很典型的尝试。当时线上有一个文本清洗函数负责把原始语料里的噪声字符规则化、做子串匹配和统计。这个串在Python里被调用得非常频繁因为要处理海量短文本Python版本的实现跑一次大概要几百微秒积少成多CPU开销非常可观。Profile数据里这个函数独占到了三分之一的CPU时间。我当时做的事很简单把这个函数的逻辑用Rust重写一遍输入输出保持跟原函数一致然后通过扩展机制暴露给Python调用。整个重写只花了一个下午。上线之后的结果非常直观同一个函数在相同输入下耗时从几百微秒降到了几十微秒速度提升接近30倍。那一刻你会真切感受到Python在AI链路里的瓶颈很多时候不是算法本身的复杂度而是解释器层面的固定开销。这个固定开销是可以被Rust模块精准拆解的。3.3 渐进式迁移策略按热点路径逐层替换这带来一个很实用的渐进式迁移策略。不要试图一次性把Python平台换成Rust而是把整个请求链路做一次针对性的性能剖析找到消耗最高的那部分热点。热点通常集中在数据预处理、编解码、校验、排序去重、特征计算这类重复度高的逻辑上。先挑一个边界清晰、数据接口稳定、逻辑不怎么变动的函数用Rust重写并接入。跑一段时间验证延迟、稳定性、部署流程都没问题之后再去替换下一个热点。这个策略的意义在于它把Rust引入团队的风险降到了很低。你不需要立刻组建一个Rust团队也不需要重写架构只需要一两个熟悉Rust的工程师就能把收益先拿回来。等到热点模块覆盖得越来越多团队对Rust的信心越来越足再考虑把一个完整的新服务直接写成Rust就顺理成章了。4. 落地指南AI基建转向Rust前先想清楚这几件事4.1 什么样的模块值得迁到Rust什么样的不建议动看多了成功案例也见过不少迁移失败的。我的判断框架很简单从四个维度评估延迟敏感度、并发密度、变更频率和生命周期。高延迟敏感度、高并发密度、低变更频率、长生命周期的模块是最理想的Rust重写目标比如索引构建、向量检索、接入网关、数据管道核心算子。这类模块一旦写好长期稳定运行投入产出比最高。反之如果某个模块业务逻辑变化极快几乎每周都在改需求那就不适合用Rust因为Rust的静态类型约束和编译时间会让频繁迭代的成本变高。这个边界一定要想清楚千万不要因为“Rust性能好”就把所有模块都硬塞进来最后会被变更成本和编译时间拖垮。我整理了一张简单的判断清单供选型时参考评估维度适合Rust的场景不建议Rust的场景延迟敏感度在线检索、推理调度、流式转发离线报表、后台管理接口并发密度高并发连接、大量状态共享低频调用、简单CRUD变更频率基础组件、长期稳定接口快速迭代业务逻辑运行时长常驻服务、生命周期长短小一次性脚本内存安全需求处理外部不可信数据纯内部可信计算压力不大4.2 团队过渡怎么把学习成本控制在可接受范围Rust的学习曲线是真实存在的但也没有外界传得那么可怕。如果团队里已经有后端工程师比如写Go或者写过C的过渡到Rust的时间会比完全零基础快很多。借用检查器是初期最大的拦路虎但它的报错信息非常好用基本是在“指导”你写出安全代码。我见过的绝大多数新人在前两周会疯狂跟编译器搏斗到了第三四周就能比较顺畅地写出能跑的代码。建议团队搞一个“缓冲项目”来做过渡不要一上来就挑战核心组件选一个内部工具、一个小型独立服务或一个测试用的子系统用Rust完整写一遍把整个CI/CD链路跑通。等这个项目做完了团队对Rust的“手感”基本就建立起来了。另外团队一定要建立Rust代码评审习惯。Rust虽然比C安全但unsafe块依然存在如果代码里随处可见unsafe那安全性就打折扣了。评审的重点就是“unsafe用得是否合理、是否可以避免”以及错误处理是否用了错误类型把边界情况都覆盖了。只要把控住这两点Rust项目的长期质量通常都不错。4.3 架构分层建议如果还没有思路可以按这个顺序推进如果团队认可Rust方向但不知道从哪里入手我给一个循序渐进的落地顺序。第一步选一个处理大量数据且逻辑稳定的热点函数做成Python扩展把最直接的性能收益拿到手。第二步把某个独立服务的接入层或调度层用Rust重写积累服务端Rust的运维经验。第三步在验证充分后再考虑把核心检索或索引层整体迁到Rust到这一步才是真正的“AI基建Rust化”。这样做的好处是每一层都有上一层的经验做支撑风险被摊薄团队能力也能跟着项目逐步提升。反过来如果一开始就直扑最核心的索引层一旦出了问题你连排查的基础经验都不够很容易造成项目反复和团队信心受挫。5. 常见问题与避坑实录5.1 编译时间过长怎么优化Rust项目做大了之后编译时间确实是个痛点。我第一次写一个中等规模的服务时一次全量编译要三分钟迭代起来很难受。后来做了三件事合理拆分成多个crate让增量编译只影响改动的那一部分调整链接器比如用更快的替代链接器把开发环境的优化级别调低发布时才开全量优化。这三点做完日常迭代编译能压到几十秒级别基本不影响开发心情。5.2 借检查器劝退新人怎么办借用检查器确实会劝退一部分新人这是正常的。我通常的建议是不要一开始就追求写出非常优雅零拷贝的代码。先用最简单的方式写该clone就clone该用引用计数就用引用计数代码能跑起来自己先舒服。等对所有权模型理解深入了再回头把明显多余的clone优化掉。如果你刚写Rust就满脑子“性能最优、零拷贝”很容易被编译器绕昏头。5.3 异步线程模型里线程和异步运行时怎么选AI基建里经常需要判断到底是每个请求开一个线程还是统一走异步我的经验是如果请求之间没有太多CPU密集型计算以IO为主且数量很庞大那用Rust生态里的异步运行时模型收益明显线程开销和上下文切换都能降下来。如果任务本来就是CPU密集型或者每个任务的生命周期很长那普通的多线程模型反而更简洁也不容易踩异步生命周期和任务调度的坑。实际项目里两种模型混用也很常见重点是每个服务根据自己的负载特征做选择不要一概而论。5.4 与Python交互时的性能陷阱用Rust写Python扩展的时候最大的性能陷阱不是计算本身而是数据来回拷贝和对象转换。如果你在Rust里处理一个很长的列表频繁把数据转换成Python对象那开销会非常大甚至抵消Rust带来的性能优势。正确的做法是在Rust侧尽可能以小批量的方式读取原始内存数据整个计算过程都在Rust内存空间里完成最后只返回一个最终结果。还有一个细节是如果扩展的某些分支不涉及Python对象记得在有长耗时计算时主动释放GIL否则核心线程还是会被卡住。5.5 依赖管理要克制别把Rust项目变成全家桶Rust的Cargo让引入依赖变得非常容易但依赖并不是越多越好。AI基建场景里你引用的每一个依赖都意味着更多的编译时间、更大的体积和潜在的安全风险。我见过一些项目为了省事把一个大型工具库拖进来结果整个编译链变重出了问题还不好定位。合理的做法是能用标准库解决的不引依赖必须引用的选维护活跃、API稳定的库像序列化、异步运行时、命令行解析这类基础库选型之后就不要轻易换因为改动成本会波及到整个项目。5.6 线上出问题Rust服务反而更难排查吗很多团队担心Rust代码panic之后服务不好排查。实际上Rust的panic信息比大多数动态语言更容易定位。如果你的编译关闭了debug信息优化panic栈会直接指到源码行号。更大的坑往往是panic之后连接残留、状态未清理这类问题。我的建议是边界处要收敛好错误不该让下层panic一路冒到对端所有外部请求入口都要做错误转换统一返回业务码而不是直接暴露panic。这套规则在Rust项目里一旦建立起来线上排查的效率跟其他语言没有太大区别甚至因为类型安全很多问题根本不会在运行时出现。这波AI基建转向Rust的趋势我自己最大的体会是技术选型永远要跟着负载特征走。Rust并不是要替代Python而是补上Python和C之间那块空白——既要高性能、又要内存安全、还要现代工程化能力。如果你所在团队也正在做AI平台或推理服务我的建议很简单不要急着搞全局重写找一个稳定的热点模块用Rust做一次扩展亲自测一下延迟和吞吐的变化你会对这个趋势有更真实的体感。数据会告诉你下一步该往哪个方向走。