chapter 09 / llm-inference · 预计学习时间 120-150 分钟

LLM 推理与部署
每个 token 都是

AUDIO // 本章语音导读
本章目录
  1. 两种截然不同的阶段:Prefill 与 Decode
  2. KV Cache:用显存买时间
  3. 交互实验室 ①:KV Cache 显存计算器
  4. 省 KV 的三代方案:MQA → GQA → MLA
  5. vLLM:把操作系统的智慧搬进显存
  6. 量化:精度换吞吐的谱系
  7. 推测解码:免费的加速
  8. 采样全家桶:温度的第四次登场
  9. 成本工程:把推理账算到产品里
  10. 交互实验室 ②:产品推理成本估算器
  11. 章节测验

两种截然不同的阶段:Prefill 与 Decode

第 6 章埋的雷正式爆炸:训练可以全句并行,生成必须逐 token 串行。一次推理实际包含两个性格完全相反的阶段:

Prefill(读 prompt)Decode(逐 token 生成)
计算形态整个 prompt 一次矩阵乘并行处理每步只算 1 个 token
瓶颈计算密集(吃满 GPU 算力)内存带宽密集:每生成 1 个 token,要把全部权重从显存搬进计算单元一遍
用户感知首 token 延迟(TTFT)生成速度(tokens/s)

Decode 的带宽天花板可以直接心算:tokens/s ≈ 显存带宽 ÷ 模型字节数。H100(3.35TB/s)跑 bf16 的 70B(140GB):单流上限 ≈ 24 tokens/s——再贵的卡也突破不了物理。这个 roofline 直觉解释了本章一半的技术:量化(把模型字节变小)、批处理(一次搬权重服务多个请求)、推测解码(一次搬权重验证多个 token),全是在跟「搬运权重」这件事搏斗。

KV Cache:用显存买时间

朴素生成每出一个新 token 都要把全部历史重算一遍注意力——$O(n^2)$ 复杂度变成生成全程 $O(n^3)$,不可接受。观察:因果掩码下,历史 token 的 K 和 V 永远不变(它们只依赖自己之前的内容)。那就存下来:每生成一个 token,只算它自己的 q/k/v,新 k/v 追加进缓存,注意力直接查缓存。每 token 的 KV 占用有个必背公式:

$$\text{KV bytes/token} = \underbrace{2}_{K和V} \times L \times n_{kv} \times d_{head} \times \underbrace{2}_{bf16}$$

LLaMA-3 8B($L{=}32, n_{kv}{=}8, d_{head}{=}128$):128KB/token —— 8K 上下文一条序列就是 1GB,128K 上下文是 16GB(比模型权重还大)。长上下文的真实成本不在算力在显存,且它随 batch 线性增长——这就是「并发数」成为推理服务核心参数的原因。

交互实验室 ①:KV Cache 显存计算器

必做实验:① 8B + 128K 上下文——KV 比权重还大;② 切到 GPT-3 风格 MHA——96 个 KV 头不共享的恐怖账单,秒懂为什么 GQA 成为标配;③ 切到 DeepSeek MLA——同等上下文 KV 缩一个数量级,这就是它能便宜服务长上下文的硬件原因。

kv-cache.calculator

公式:2 × L × n_kv × d_head × 2字节 × 上下文 × 并发 · 判定含权重粗估

省 KV 的三代方案:MQA → GQA → MLA

VIDEO 01
How DeepSeek Rewrote the Transformer [MLA](DeepSeek 如何重写 Transformer)
Welch Labs 18:09
观看指南 · 本章 §1-§4 的最佳影像版
  • 02:30 KV cache 为什么存在、占多大——§2 公式的动画推演。
  • 07:00 MQA/GQA 的取舍。
  • 10:30 MLA 低秩压缩的几何直觉 + 与 RoPE 兼容的工程细节——生成速度 6 倍于朴素 Transformer 的来源。

vLLM:把操作系统的智慧搬进显存

2023 年前的推理服务有个隐蔽浪费:KV cache 按「最大可能长度」预分配连续显存,实际只用一小段——显存利用率常常不到 40%。vLLM 的 PagedAttention 把操作系统虚拟内存那套搬了过来:KV 切成固定大小的块(如 16 token/块),逻辑连续、物理分散,按需分配。配上 continuous batching(不等整批完成,谁的序列结束立刻换新请求进来,GPU 永不空转),吞吐量提升 2-4 倍。今天 vLLM/SGLang 是开源推理服务的事实标准——「跑个模型」和「高效服务模型」之间隔着一整门系统工程。

量化:精度换吞吐的谱系

Roofline 说了:decode 速度 ≈ 带宽÷模型字节。把字节砍半,速度近似翻倍,显存减半——量化是推理最划算的杠杆:

方案位宽要点
bf1616基线
FP88H100 原生支持,训练推理通吃,几乎无损——前沿实验室新默认
INT8 (LLM.int8)8逐通道缩放+离群值分离(LLM 激活有少数巨大离群维度,整列保留 fp16)
GPTQ / AWQ4训练后权重量化:GPTQ 逐层最小化二阶误差;AWQ 按激活幅度保护重要权重。~1% 损失换 4 倍压缩
KV cache 量化8/4权重之外的第二战场——长上下文场景收益巨大(直接砍 §2 的账单)

经验法则:权重 4 bit 是质量悬崖前的最后一站(3 bit 以下显著掉点);参数多+量化狠 通常优于 参数少+全精度(70B-int4 ≳ 13B-bf16)。

推测解码:免费的加速

Decode 是带宽瓶颈 → GPU 计算单元大量空闲 → 能不能「一次搬权重,验证多个 token」?推测解码:小草稿模型快速猜 k 个 token,大模型一次前向并行验证。关键是它数学上无损:对每个猜测 token,以 $\min(1, p_{target}/p_{draft})$ 接受,拒绝处从修正分布重采样——可以证明最终输出分布与大模型独自采样完全相同。草稿对了赚 k 倍速度,错了只浪费一点空闲算力。典型加速 2-3 倍,尤其在代码这类「下一个 token 常常很确定」的领域。变体:自起草(Medusa/EAGLE 给大模型加轻量预测头)、n-gram 匹配(prompt 里抄答案)。

采样全家桶:温度的第四次登场

模型给出下一 token 分布后,怎么选?Greedy(永远取最大)会陷入重复循环(「我觉得我觉得我觉得」——高概率短语互相强化)。实用组合拳:

成本工程:把推理账算到产品里

规模化产品里,模型选型本质是单位经济学。三个杠杆按优先级:

  1. Prompt caching(最容易被低估):API 对命中缓存的输入 token 收 10-25% 价格。机制:请求间共享的前缀(system prompt、模板、few-shot 例子)的 KV cache 直接复用(§2 的 KV 不用重算=不用重新收费)。关键工程认知:真实应用的命中率远高于 benchmark 测算——尤其是 remix/模板类场景,海量请求的输入几乎相同(同一模板+同一素材库),命中率 80-90% 不稀奇。设计提示词时把固定部分置前、可变部分置后,是免费拿折扣的结构纪律。
  2. 用量漏斗设计:内容型产品的生成成本由漏斗决定——消费:remix:PGC ≈ 1 : 1/100 : 1/1000 量级时,绝大多数 DAU 只读现成内容(零生成成本),只有创作行为才烧 token。「先消费后创作」的产品结构本身就是成本控制。在下面的估算器里拖一拖 remix 率,感受漏斗每收紧一档对账单的影响。
  3. 模型分层:高频、窄域、格式化的功能(你的像素画 JSON!)下沉到 flash 级 API 或自训小模型(第 8 章 SFT 闭环);低频、开放域、高价值的留给旗舰模型。「每个请求都打旗舰模型」是创业公司最常见的烧钱姿势。

交互实验室 ②:产品推理成本估算器

必做实验:① 默认参数(10 万 DAU、remix 1/100、PGC 1/1000、缓存命中 70%)下对比三档模型的月账单;② 把缓存命中拉到 0 再拉到 95%——理解为什么「输入结构设计」值钱;③ remix 率从 1/100 拉到 1/10(产品爆了,人人都在创作)——看旗舰模型账单的失控曲线,以及自托管小模型为什么在高频场景是数量级的差异。

inference-cost.estimator

月成本 = 30 × 日生成数 × (未命中输入×原价 + 命中输入×缓存价 + 输出×输出价) · 滑块均可拖

为什么 API 定价输出 token 通常是输入的 4-5 倍?用本章的 prefill/decode 框架解释。
输入在 prefill 阶段处理:全部 token 一次并行矩阵乘,计算密集、GPU 利用率高、单 token 摊薄成本低。输出在 decode 阶段产生:每 token 都要完整搬一遍权重(带宽瓶颈、利用率低),还要为它维护 KV cache 与批调度。成本结构差异直接写进了价签。同理可解释:为什么 prompt caching 折扣能给到 75-90%(缓存命中连 prefill 都省了,只剩存储成本);为什么「长输入短输出」的任务(如分类、抽取)单位成本远低于「短输入长输出」(如写作)。

章节测验