🏠 总目录📚 本教程 推理≠训练
📑 本页目录(点开跳转)

15 · 推理和训练是两回事

28 分钟 | ⭐⭐ 把训练经验套到推理上是最贵的错误


🎯 一句话

训练是算力瓶颈,推理(解码阶段)是带宽瓶颈 —— 两者的瓶颈完全相反。 这意味着几乎所有训练侧的优化直觉,到推理侧都要反过来想。


🔀 一、一次推理请求分成两个完全不同的阶段

用户输入 "请解释一下量子纠缠"(假设 10 个 token),模型输出 500 个 token —— 这一次请求会被拆成两个性质完全不同的阶段:

Prefill(预填充)一次性处理全部 10 个输入 token
并行度高 ✅
【算力瓶颈】
占时间 ~10%
Decode(解码)一个一个地生成 500 个 token,每次只处理 1 个
并行度 = 1 ⚠️
【带宽瓶颈】⭐
占时间 ~90% ⭐
Prefill Decode
每步处理的 token 全部输入(几百~几万) 1 个
矩阵乘的形状 矩阵 × 矩阵 向量 × 矩阵
算术强度 高(几百) ~2 💀
瓶颈 算力 显存带宽
决定的指标 TTFT(首字延迟) TPOT(每字延迟)
优化方向 更强的算力、并行 减少数据搬运

🔑 这张表是这一章的全部Prefill 和 Decode 是两个性质完全不同的工作负载,跑在同一个模型上。 很多推理系统的设计(甚至硬件选型)都源于这个分裂。


💀 二、Decode 为什么这么惨

   生成 1 个 token 要做什么:
   ① 把【全部模型权重】从 HBM 读进来
   ② 和一个【长度为 1】的向量相乘
   ③ 丢掉

   ⭐ 读了 14GB 的权重(7B BF16),只做了很少的计算
   → 算术强度 ≈ 2
   → 离 A100 的平衡点 156 差了【78 倍】💀

理论上限第 4 章那个心算公式):

$$\text{最快解码速度} = \frac{\text{显存带宽}}{\text{模型大小}}$$

   7B BF16(14GB)在 A100(2TB/s):
   2000 / 14 ≈ 143 tokens/秒     ← 单请求的物理上限 ⭐

   ⚠️ 注意:这个上限和 GPU 的算力【完全无关】
      换 H100(989 TFLOPS,是 A100 的 3 倍算力)
      → 但带宽只有 3.35TB/s(1.7 倍)
      → 解码速度也只提升 1.7 倍,不是 3 倍

🔑 这解释了一个常见的困惑"为什么我换了更强的卡,生成速度没快多少?" 因为你买的是算力,而你的瓶颈是带宽。


⭐ 三、批处理:Decode 唯一的救命稻草

   ⭐ 关键洞察:读一遍权重,可以【同时服务多个请求】

   batch=1:  读 14GB → 生成 1 个 token   → 效率 1/14GB
   batch=32: 读 14GB → 生成 32 个 token  → 效率 32/14GB  ⭐ 32 倍!

   → 权重的读取成本被【摊薄】了
   吞吐 vs batch size(7B 模型,A100)示意:

   batch=1    →  ~140 tok/s   (单请求也是 140)
   batch=8    →  ~1000 tok/s  (单请求 ~125,略降)
   batch=32   →  ~3500 tok/s  (单请求 ~110)
   batch=128  →  ~8000 tok/s  (单请求 ~62,明显降)⚠️
   batch→∞    →  受算力限制,不再增长

🔑 两个关键结论: ① 批处理几乎是免费的吞吐 —— 这是推理优化的第一原则 ② 但单请求延迟会随 batch 增大而变差 —— 吞吐和延迟的经典权衡

🔗 第 17 章讲怎么在动态到达的请求上做批处理, 那才是真正的难点。

⚠️ 但批处理有个天花板:KV Cache

   batch 越大,KV Cache 占的显存越多

   7B 模型,seq=2048,batch=32:
   KV Cache ≈ 2 × 32层 × 2048 × 4096 × 2字节 × 32 = 34 GB ⭐

   → 显存装不下 → batch 上不去 → 吞吐上不去

   ⭐ 所以【KV Cache 管理才是推理吞吐的真正瓶颈】(第 16、17 章)

📊 四、推理的四个核心指标

指标 含义 由什么决定
TTFT Time To First Token(首字延迟) Prefill 速度 + 排队时间
TPOT Time Per Output Token(每字延迟) Decode 速度(带宽)⭐
吞吐 总 tokens/秒 batch size(受 KV Cache 限制)
成本 每百万 token 的钱 吞吐 ÷ GPU 单价
   端到端延迟 = TTFT + TPOT × 输出长度

   例:TTFT=200ms, TPOT=25ms, 输出 500 token
   → 200 + 25×500 = 12.7 秒
   ⭐ 注意:TPOT 占了 98% —— 优化 TTFT 意义不大

不同产品对这两个指标的要求完全不同: - 聊天/流式输出 → TTFT 要低(用户要立刻看到字),TPOT 要跟得上阅读速度(~50ms 够) - 批量处理/离线 → 只关心吞吐,两个延迟都无所谓 - 代码补全TTFT 极度敏感(超过 200ms 用户就放弃了) - Agent / 长思考 → 输出很长,TPOT 是决定性的


🔄 五、训练直觉到推理的翻译表

训练侧的直觉 推理侧的实际情况
"换算力更强的卡" ⚠️ 看带宽,不是算力
"MFU 45% 算不错" ⚠️ Decode 阶段 MFU 通常只有 1-5%,这是正常的
"梯度检查点省显存" ❌ 推理没有反向,不适用
"ZeRO 切优化器状态" ❌ 推理没有优化器状态,只有权重和 KV Cache
"大 batch 影响收敛" ✅ 推理没有收敛问题,batch 越大越好(受显存限)
"量化会掉精度" ✅ 但推理侧收益大得多(直接提速),值得权衡 ⭐
"FlashAttention 省显存" ✅ 仍然有用,但推理的大头是 KV Cache

💥 "Decode 的 MFU 只有 1-5%"这一条经常引起恐慌: 有人看到推理时 GPU 算力利用率极低,就以为配置错了,拼命调优。 实际上这是物理决定的 —— 带宽瓶颈下算力本来就用不满。 推理该看的指标是"带宽利用率"和"吞吐",不是 MFU。


🧭 六、推理优化的正确顺序

   ① 用专门的推理引擎(vLLM / SGLang / TensorRT-LLM)
      → 别用 HuggingFace 的 generate() 上生产 ⭐
      → 光这一步常常就是 5-10 倍

   ② 开【连续批处理】(第 17 章)
      → 吞吐再翻几倍

   ③ 量化权重(第 18 章)
      → 模型小一半 → 解码速度快一倍 + 能开更大 batch

   ④ 量化 KV Cache
      → 能开更大 batch

   ⑤ 张量并行(如果单卡装不下,或要降 TPOT)

   ⑥ 投机解码(第 19 章)—— 低延迟场景

   ⑦ 前缀缓存(相同的系统提示词只算一次)⭐

第 ⑦ 条常常被忽略但收益巨大: 如果你的所有请求都带着同一个 2000 token 的系统提示词, 前缀缓存能把 Prefill 的成本降到接近零。 vLLM 的 enable_prefix_caching=True

🚧 第 ① 条留了个尾巴:这里说了「换个专门的引擎常常 5–10 倍」,却没说该换成哪个。 三个名字并排放着,你并不知道自己的场景该选谁。 👉 第 20 章 · 推理服务化开头有一张七个引擎的横评和一棵四问决策树 (单机还是集群?要不要动态加载多个 LoRA?跑在自己机器上还是 GPU 集群?延迟敏感还是吞吐优先?)。 在你按上面这个顺序动手之前,先去那里把 ① 定下来——顺序里后面六步都建立在引擎选型之上。


🔗 和站内其他章的关系

相关的地方 这里的位置
第 3 章 batch=1 矩阵乘算术强度 ~2 Decode 的全部困境
第 4 章 带宽 ÷ 模型大小 解码速度的物理上限
第 16 章 KV Cache 批处理的天花板
第 17 章 连续批处理 动态请求下的批处理
第 18 章 量化 推理侧收益远大于训练侧
《大模型全景导论》06 推理优化 先理解瓶颈在哪:两个阶段 同一件事的一页纸版;本章补上"Decode 算力闲置 95%"背后的那个数字
《模型上线之后》18 成本与容量 LLM 服务的成本结构 Prefill/Decode 的拆分,就是那边"输入便宜、输出贵"的物理原因
《智能体工程教程》16 企业落地与生产化 算账的三条口诀 Agent 输出长、还要循环多轮 —— 它的账几乎全压在 Decode 这一侧

✅ 检查点

  1. 一次推理请求分成哪两个阶段?各自的瓶颈是什么?
  2. Decode 阶段的算术强度是多少?为什么这么低?
  3. 单请求解码速度的物理上限公式是什么?7B 在 A100 上是多少?
  4. 为什么"换更强的卡"对解码速度提升有限?
  5. 批处理为什么能提高吞吐?它的天花板是什么?
  6. TTFT 和 TPOT 分别由什么决定?端到端延迟里哪个占主导?
  7. 四种产品形态对延迟指标的要求有什么不同?
  8. 为什么 Decode 阶段 MFU 只有 1-5% 是正常的?该看什么指标?
  9. 推理优化的第一步是什么?为什么第 ⑦ 条常被忽略?
👀 答案
  1. Prefill(一次性处理全部输入,算力瓶颈,占时间 ~10%)和 Decode(一个一个生成,带宽瓶颈,占时间 ~90%)。
  2. 约 2。因为生成 1 个 token 要把全部模型权重从 HBM 读进来,却只和一个长度为 1 的向量相乘——读了 14GB 只做了很少计算,离平衡点 156 差 78 倍。
  3. 显存带宽 ÷ 模型大小。7B BF16(14GB)在 A100(2TB/s)≈ 143 tokens/秒
  4. 因为上限只和带宽有关,和算力无关。H100 算力是 A100 的 3 倍但带宽只有 1.7 倍,解码速度也只快 1.7 倍
  5. 因为读一遍权重可以同时服务多个请求,权重读取成本被摊薄。天花板是 KV Cache 显存——batch 越大 KV Cache 越多(7B/seq2048/batch32 就要 34GB),装不下就上不去。
  6. TTFT 由 Prefill 速度 + 排队时间决定,TPOT 由 Decode 速度(带宽)决定。端到端 = TTFT + TPOT×输出长度,TPOT 占主导(例子里占 98%)。
  7. 聊天/流式:TTFT 要低、TPOT 跟上阅读速度即可;批量离线:只关心吞吐;代码补全:TTFT 极度敏感(>200ms 就放弃);Agent/长思考:TPOT 是决定性的
  8. 因为带宽瓶颈下算力本来就用不满,这是物理决定的不是配置错误。该看带宽利用率和吞吐,不是 MFU。
  9. 第一步:用专门的推理引擎(vLLM/SGLang/TensorRT-LLM),别用 HF 的 generate() 上生产——光这一步常常 5-10 倍。第 ⑦ 条前缀缓存常被忽略是因为它看起来简单,但如果所有请求都带同一个长系统提示词,它能把 Prefill 成本降到接近零

🛑 可以停在这里

走神救援

⭐⭐训练是算力瓶颈,Decode 是带宽瓶颈——完全相反。一次请求分两阶段:Prefill(一次处理全部输入、矩阵×矩阵、算力瓶颈、占时间 10%、决定 TTFT)和 Decode(一次 1 个 token、向量×矩阵算术强度只有 2、带宽瓶颈、占时间 90%、决定 TPOT)。💀Decode 惨在:生成 1 个 token 要把全部权重从 HBM 读一遍却只和长度为 1 的向量相乘,离平衡点差 78 倍。⭐⭐物理上限 = 显存带宽 ÷ 模型大小(7B 在 A100 ≈ 143 tok/s),⭐和算力完全无关——换 H100 算力 3 倍但带宽只 1.7 倍,解码也只快 1.7 倍(这解释了"换了更强的卡为什么没快多少")。⭐批处理是唯一救命稻草读一遍权重同时服务多个请求,权重成本被摊薄(batch=32 效率 32 倍);但单请求延迟随 batch 变差,且天花板是 KV Cache 显存(7B/seq2048/batch32 就要 34GB)→ ⭐KV Cache 管理才是推理吞吐的真正瓶颈四指标:TTFT / TPOT / 吞吐 / 成本;端到端 = TTFT + TPOT×输出长度,⭐TPOT 通常占 98%,优化 TTFT 意义不大(除非是代码补全那种 TTFT 极度敏感的场景)。⭐训练直觉的翻译:看带宽不是算力、Decode 的 MFU 只有 1-5% 是正常的(物理决定,别恐慌,该看带宽利用率和吞吐)、梯度检查点/ZeRO 都不适用、推理没有收敛问题所以 batch 越大越好量化在推理侧收益大得多优化顺序:①⭐先换专门的推理引擎(vLLM/SGLang/TRT-LLM),别用 HF generate() 上生产——光这步常 5-10 倍 ②连续批处理 ③量化权重 ④量化 KV Cache ⑤张量并行 ⑥投机解码 ⑦⭐前缀缓存(同一个长系统提示词只算一次,能把 Prefill 成本降到接近零)。

下一节 👉 16-KV-Cache.md ⭐⭐

打卡记录保存在你的浏览器里,首页能看到总进度