两周时间,把推理吞吐拉高三倍,还要扛住十万卡级别的集群规模——这个数字组合放在任何一家做大模型推理的团队面前,都足够让人停下来多看两眼。智谱这次公开的《GLM如何自建推理基础设施》里,最抓人的其实不是"三倍"这个结果,而是他们选择了一条和主流"拿来即用"完全不同的路:自建推理引擎、自研调度、自己啃底层。我前后把这份材料翻了几遍,结合自己在推理服务上踩过的坑,聊聊这套东西到底解决了什么问题、哪些思路可以直接抄、哪些地方是别人学不来的。
如果你正在做推理服务的性能优化,或者纠结要不要从现成方案切换到自建栈,又或者只是好奇"十万卡"这种规模下推理到底难在哪,这篇解读应该能给你一些能落地的参考。我会尽量把里面涉及的核心技术点——推理引擎、调度、并行策略、Infra Agent 这些——拆开讲清楚,同时补上原文没细说但实操中一定会遇到的东西。
1. 为什么"两周三倍"这个说法值得认真对待
先把结论摆前面:推理吞吐提升三倍,在已经调优过的生产系统上,是一件非常难的事。很多人对推理优化的想象是"换个更快的引擎就行",但真实情况是,当一个推理服务已经跑在成熟框架上、显存打满、batch 也调过之后,你能榨出来的空间通常只有百分之十几到几十。三倍这个量级,意味着不是某个单点优化,而是整条链路上多个环节同时被重新设计过。
1.1 吞吐这个指标本身就有很多坑
聊优化之前得先对齐"吞吐"到底指什么。业内常见的口径有这么几种,混着用很容易得出错误结论:
| 指标口径 | 含义 | 容易被误用的地方 |
|---|---|---|
| tokens/s(总) | 整个集群每秒产出的 token 数 | 忽略延迟,堆 batch 就能刷高 |
| tokens/s/user | 单用户视角的生成速度 | 和总吞吐经常互相矛盾 |
| requests/s | 每秒完成的请求数 | 长短请求混合时失真严重 |
| goodput | 满足 SLO 前提下的有效吞吐 | 最接近真实业务价值,但最难测 |
智谱提到的"三倍吞吐",从上下文看更接近在满足延迟约束下的有效吞吐(goodput),而不是单纯把 batch 拉大刷出来的数字。这个区别很关键:如果你只追总 tokens/s,把 batch size 从 64 拉到 512,数字确实会涨,但首 token 延迟(TTFT)和单用户生成速度会崩掉,线上体验直接完蛋。所以看到"三倍"的时候,第一反应应该是问一句:在什么延迟约束下测的?
1.2 两周的时间尺度说明了什么
两周不是一个从零开始搭系统的周期,而是一个在已有基础上做集中攻坚的周期。这暗示了几件事:基础设施(集群、网络、存储、监控)是现成的,团队对业务负载特征有清晰认知,优化目标是明确的而不是探索性的。换句话说,这两周花在"把已知的瓶颈逐个打掉",而不是"摸索该做什么"。
我自己做性能攻坚的经验是,真正耗时间的从来不是改代码,而是定位瓶颈。一个推理服务慢,可能是计算瓶颈、可能是显存带宽瓶颈、可能是调度排队、可能是网络通信、也可能是 Python 层的 GIL 或者序列化开销。在没有完善 profiling 的情况下,你可能花一周都在猜。所以"两周出结果"背后,大概率有一套成熟的性能观测体系在支撑——这点原文没展开,但它是前提。
1.3 十万卡规模把问题性质改变了
单机 8 卡和十万卡集群,完全是两个物种的问题。规模上去之后,会出现一些在小规模下根本不存在或者可以忽略的现象:
- 通信占比飙升:张量并行、流水线并行、专家并行带来的 all-reduce、all-to-all 通信,在万卡级别会吃掉大量时间,通信和计算的重叠(overlap)做不好,GPU 利用率直接腰斩。
- 故障成为常态:十万卡意味着每天都有卡在坏。推理服务不能像训练那样 checkpoint 重启,必须做到故障时快速摘除、请求重路由,用户几乎无感。
- 调度复杂度爆炸:请求怎么分配到不同节点、如何做负载均衡、如何处理热点专家(MoE 场景),这些在单机上是 trivial 的问题,在集群级别是核心难题。
- 显存碎片与 KV Cache 管理:长上下文场景下 KV Cache 会吃掉大量显存,十万卡级别的显存管理策略直接决定能跑多长的上下文、能并发多少请求。
理解了这三点,再看"自建推理基础设施"这个选择,就顺理成章了——通用框架很难同时满足这种规模和这种定制化需求。
2. 自建推理栈 vs 现成方案:这笔账怎么算
这是很多人最关心的问题:市面上已经有 SGLang、vLLM 这些成熟的开源推理引擎,为什么还要自建?我先把这个问题拆成"什么时候该用现成的"和"什么时候该自建"两个子问题。
2.1 现成引擎已经解决了 80% 的问题
必须承认,SGLang 和 vLLM 这类项目已经把推理引擎的通用问题解决得相当好了。它们提供的核心能力包括:
- PagedAttention / RadixAttention这类显存管理机制,把 KV Cache 的碎片问题基本解决;
- 连续批处理(continuous batching),让不同长度的请求可以动态拼批,大幅提升 GPU 利用率;
- 前缀缓存(prefix caching),对多轮对话、few-shot 场景效果显著;
- 张量并行,单机多卡开箱即用;
- OpenAI 兼容 API,接入成本极低。
对绝大多数团队来说,直接用 SGLang 或 vLLM 是性价比最高的选择。你不需要懂 CUDA kernel,不需要懂通信原语,配好参数就能跑出一个相当不错的服务。我见过不少团队一上来就想着自研,结果半年过去性能还不如调好的 vLLM,这是典型的重复造轮子。
2.2 什么情况下自建才划算
自建的门槛很高,但确实有几类场景是现成方案覆盖不好的:
第一类是规模极端。十万卡这种量级,通用框架的调度器、通信策略、故障处理往往不是为这个规模设计的。比如默认的负载均衡策略在几千卡上够用,到万卡级别可能因为元数据同步延迟导致热点。
第二类是负载特征特殊。如果你的业务是超长上下文(比如几十万 token)、或者 MoE 模型专家分布极不均匀、或者有非常严格的延迟 SLO,通用框架的默认策略可能不是最优的,而框架本身又不允许你改到那么深。
第三类是成本敏感。当推理量足够大时,哪怕 10% 的效率提升,换算成 GPU 成本都是天文数字。这时候自建带来的定制化收益,能覆盖掉研发和维护成本。
第四类是技术自主。这个不用多说,核心链路上依赖外部框架,在极端情况下会有风险。
智谱的情况基本是这几类的叠加。所以他们的选择不是"为了自建而自建",而是规模、负载、成本三者共同把自建推到了划算的那一侧。
2.3 一个务实的判断框架
我给一个自己常用的判断表,你可以对照自己的情况打分:
| 维度 | 倾向用现成方案 | 倾向自建 |
|---|---|---|
| 集群规模 | 千卡以内 | 万卡以上 |
| 负载特征 | 通用对话、常规 RAG | 超长上下文、MoE、特殊 SLO |
| 团队能力 | 无底层优化经验 | 有 CUDA/通信/调度积累 |
| 成本压力 | 推理量中等 | 推理量巨大,效率即成本 |
| 迭代节奏 | 快速上线优先 | 长期优化优先 |
如果五个维度里你有三个以上落在右边,自建才值得认真考虑。否则,把 SGLang 调优到极致,收益往往比自研更大。
3. 推理引擎里真正决定性能的几个环节
不管自建还是用现成的,性能瓶颈总是出在那么几个地方。这部分我把推理引擎的核心环节拆开讲,顺便说说智谱这类自建方案通常会在哪里做文章。
3.1 显存管理:KV Cache 是主战场
推理服务的显存基本被三样东西占着:模型权重、KV Cache、激活值。其中KV Cache 是变量最大、最值得优化的部分。它的计算公式大致是:
KV Cache 大小 = 2 × 层数 × 注意力头数 × head_dim × 序列长度 × batch_size × 精度字节数以常见的 70B 模型、FP16 为例,单 token 的 KV Cache 大概在几百 KB 量级。如果并发 100 个请求、每个请求上下文 8K,光 KV Cache 就要吃掉几十 GB。这就是为什么长上下文和高并发很难同时满足。
优化 KV Cache 的常见手段有这么几层:
- 分页管理:把 KV Cache 切成固定大小的 block,按需分配,避免预分配造成的浪费。PagedAttention 就是这个思路。
- 前缀共享:多个请求如果有相同前缀(比如同一个 system prompt),可以共享这部分 KV,RadixAttention 做的是这件事。
- 量化:把 KV Cache 从 FP16 压到 INT8 甚至更低,显存直接减半,代价是精度损失,需要评估。
- 驱逐与换出:把不活跃的 KV 换到 CPU 内存甚至 SSD,需要时再换回来,适合超长上下文。
自建方案在这里的优势是可以针对自己的负载特征定制策略。比如你的业务里前缀重复率特别高,就可以把前缀缓存的粒度做得更细、命中率做得更高;如果你的请求长度分布很集中,block size 就可以调得更贴合。
3.2 批处理策略:连续批处理是基础,调度才是上限
连续批处理现在已经是标配了,它的核心思想是:不等一个 batch 里所有请求都结束,只要有请求完成就立刻把新请求塞进去,让 GPU 始终有活干。这个机制把 GPU 利用率从"等最慢的请求"提升到了"动态填满"。
但连续批处理只是基础,真正拉开差距的是调度策略。几个关键决策点:
- 请求优先级:交互式请求和批处理请求混在一起时,怎么保证交互式的延迟?
- 抢占与恢复:显存不够时,抢占哪个请求?被抢占的请求怎么恢复?
- 长度感知调度:长请求和短请求怎么搭配,才能既填满 batch 又不让短请求被长请求拖死?
- chunked prefill:把长请求的 prefill 阶段切成小块,和 decode 阶段交错执行,避免长 prefill 阻塞其他请求的 decode。
智谱在调度上大概率做了不少定制,因为调度是自建栈里收益最直接、也最依赖业务理解的部分。通用框架的调度器要照顾所有场景,往往偏保守;自建可以针对自己的流量模型做激进优化。
3.3 并行策略:TP、PP、EP 怎么选
大模型推理绕不开并行。三种主要并行方式各有适用场景:
| 并行方式 | 切分维度 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 张量并行 TP | 切权重矩阵 | 延迟低 | 通信频繁,跨机损耗大 | 单机内多卡 |
| 流水线并行 PP | 切层 | 通信少 | 有气泡,延迟高 | 跨机、大模型 |
| 专家并行 EP | 切 MoE 专家 | 适合 MoE | all-to-all 通信重 | MoE 模型 |
实际部署里通常是组合使用,比如单机内 TP=8,跨机用 PP 或 EP。关键难点在于通信和计算的重叠——如果通信不能藏在计算后面,GPU 就会空等。这需要精细的流水线设计和通信原语优化,也是自建栈能做出差异的地方。
MoE 模型还有个特殊问题:专家负载不均。热门专家会被打爆,冷门专家闲着。解决思路包括专家复制、请求路由时的负载感知、以及动态调整专家分布。这些在通用框架里支持有限,自建可以做得更细。
3.4 一个容易被忽略的点:Python 开销
很多人优化推理只盯着 GPU,忽略了 CPU 侧。实际上在高速推理场景下,Python 的调度开销、序列化开销、GIL 争用都可能成为瓶颈。尤其是当单步计算时间被压到很短之后,CPU 侧的调度如果跟不上,GPU 就会周期性空转。
常见的应对手段:把关键路径用 C++/Rust 重写、用异步 IO 减少阻塞、把 tokenizer 和采样逻辑移出主循环、用零拷贝减少数据搬运。这些工作在通用框架里往往不是重点,但自建栈可以针对性地做。
4. Infra Agent:把运维经验变成自动化能力
"Infra Agent"这个词在材料里出现,值得单独拎出来讲。我的理解是,它指的是用智能化的方式管理推理基础设施,把过去靠人盯、靠脚本处理的运维工作,变成自动化的决策和执行。
4.1 十万卡规模下,人工运维是不可能的
先算一笔账:十万卡集群,假设每天有 0.5% 的卡出现各种异常(这个比例在超大规模下不算夸张),那就是每天 500 张卡需要处理。如果每张卡都要人工介入,运维团队直接崩溃。所以故障的检测、隔离、恢复必须自动化。
推理场景比训练更苛刻的地方在于:训练可以 checkpoint 重启,推理不行。用户请求正在处理中,节点挂了,请求怎么办?必须做到:
- 快速检测:秒级发现节点异常,而不是等心跳超时;
- 请求重路由:把受影响请求转到健康节点,尽量不丢;
- 状态恢复:如果用了 KV Cache 换出等机制,要能恢复上下文;
- 优雅降级:实在恢复不了,也要给用户明确反馈,而不是卡死。
4.2 Agent 化运维的几个层次
我把这类 Infra Agent 的能力分成几个层次,从低到高:
第一层是监控告警。这是基础,把指标采集、异常检测、告警通知做扎实。看起来简单,但在十万卡规模下,指标的量级和采集频率本身就是工程挑战。
第二层是自动修复。检测到问题后自动执行预案,比如重启服务、摘除节点、切换流量。这一层需要预案足够完备,且执行要幂等、可回滚。
第三层是根因分析。不只是"发现问题",还要"定位问题"。比如吞吐下降,是哪个环节的问题?是某批节点通信异常,还是某个专家过载,还是上游流量突增?这需要把全链路的可观测性打通。
第四层是预测与优化。基于历史数据预测容量需求、提前扩容、动态调整资源分配。这一层最接近"智能",也最难做。
智谱提到的 Infra Agent,我猜至少覆盖了前两层,可能在某些场景做到了第三层。对大多数团队来说,先把前两层做扎实,收益就已经很大了,不必一上来就追求"智能"。
4.3 一个实操建议:从可观测性开始
如果你也想往这个方向走,我的建议是先把可观测性做透。具体来说:
- 指标要全:GPU 利用率、显存占用、通信耗时、队列长度、TTFT、TPOT(每 token 输出时间)、请求成功率,一个都不能少;
- 粒度要细:能下钻到单卡、单请求级别,否则定位问题时会抓瞎;
- 采样要合理:全量采集成本太高,关键指标高频、次要指标低频,做好聚合;
- 链路要通:从请求入口到 GPU 执行,整条链路能串起来看,否则你只能看到"慢",看不到"哪里慢"。
这套东西搭起来之后,很多优化机会会自己浮现出来——你会发现瓶颈根本不用猜,数据直接告诉你。
5. 从这份材料里能抄走的具体做法
前面讲了不少原理,这部分我挑几个可以直接借鉴的点,说说怎么落地。
5.1 先建立性能基线,再谈优化
任何优化都要有基线。我见过太多团队优化了半天,最后说不清到底提升了多少,因为一开始就没测准。建立基线的要点:
- 固定测试集:用真实流量的采样,或者构造有代表性的合成数据,覆盖长短请求、不同并发;
- 固定环境:同样的硬件、同样的模型、同样的参数,否则对比没意义;
- 多轮测量:性能测试波动很大,单次结果不可信,至少跑三轮取稳定值;
- 记录完整指标:不只是吞吐,还有延迟分布(P50/P90/P99)、GPU 利用率、显存峰值。
基线建好之后,每次优化都对照基线看,才能知道方向对不对。
5.2 用 profiling 找瓶颈,而不是靠猜
性能优化的第一原则是测量优先于猜测。常用的 profiling 手段:
- PyTorch Profiler:看算子级别的耗时,找出热点;
- Nsight Systems / Nsight Compute:看 GPU 侧的 kernel 执行、通信、空转;
- 自定义埋点:在关键路径上打时间戳,看各阶段耗时占比。
一个典型的发现是:你以为瓶颈在计算,结果 profiling 显示 GPU 有 30% 时间在等通信,或者 20% 时间在等 CPU 调度。不测就改,大概率改错地方。
5.3 优化要有优先级,先啃大头
优化机会通常符合二八定律:少数几个环节贡献了大部分损耗。我的排序经验是:
- 先看 GPU 利用率:如果利用率低于 70%,说明有大量空转,先找空转原因;
- 再看通信占比:并行场景下通信往往是隐形杀手,尤其是跨机通信;
- 然后看调度效率:队列是否经常空、batch 是否经常填不满;
- 最后看单算子优化:kernel 融合、量化这些,收益相对小但确定性高。
按这个顺序,通常能快速拿到第一波收益,再逐步深入。
5.4 故障处理要当成一等公民
在规模上去之后,故障处理不是"锦上添花",而是"决定能不能用"。几个实操要点:
- 健康检查要快:心跳间隔、超时阈值要调优,太慢发现不了问题,太快误报多;
- 摘除要果断:宁可误摘,不可漏摘,因为一个坏节点可能拖垮整个 batch;
- 恢复要幂等:重试逻辑要保证重复执行不出错;
- 演练要定期:主动注入故障,验证预案是否有效,别等真出事才发现预案是纸上谈兵。
6. 这套打法不适合谁,以及常见的误判
最后聊聊边界。自建推理基础设施不是万能药,有几类情况我建议谨慎。
6.1 规模不够时,自建是负收益
如果你的推理量还没到"效率提升能覆盖研发成本"的程度,自建就是纯亏。研发一个能打的推理引擎,投入是几十人月起步,还要持续维护。在规模不够的时候,把这些人力投到业务上,回报高得多。
6.2 团队没有底层能力时,别硬上
推理引擎涉及 CUDA、通信、分布式系统、编译优化等多个硬核领域。如果团队里没有相关积累,自建的结果往往是"能跑但很慢",还不如调好的开源方案。先招人或者先积累,再谈自建。
6.3 别把"自建"当成目标
我见过一些团队,把"自研推理引擎"当成技术实力的象征,为了自建而自建。这是本末倒置。自建是手段,不是目的。目的是更低的成本、更好的体验、更强的可控性。如果现成方案能达到目的,就没必要自建。
6.4 一个常见的误判:以为优化是一次性的
性能优化不是"做完就完了",而是持续的过程。业务在变、模型在变、硬件在变,今天的优化明天可能就失效了。所以自建栈必须配套持续的观测和迭代机制,否则很快会退化。这也是为什么 Infra Agent 这类自动化能力很重要——它让持续优化变得可持续。
回头看智谱这份材料,"两周三倍"和"十万卡"这两个数字背后,是一整套从引擎到调度到运维的体系化能力。单看任何一个点都不新鲜,难的是把它们组合起来、在极端规模下跑通。对大多数团队来说,不必照搬全套,但里面关于性能观测、调度定制、故障自动化的思路,是可以直接借鉴的。我自己在做推理优化时最大的体会就是:先把数据测准,再谈优化;先把故障处理好,再谈性能。顺序反了,做多少都是白费。