chapter 09 / llm-inference · 预计学习时间 120-150 分钟
第 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),全是在跟「搬运权重」这件事搏斗。
朴素生成每出一个新 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 线性增长——这就是「并发数」成为推理服务核心参数的原因。
必做实验:① 8B + 128K 上下文——KV 比权重还大;② 切到 GPT-3 风格 MHA——96 个 KV 头不共享的恐怖账单,秒懂为什么 GQA 成为标配;③ 切到 DeepSeek MLA——同等上下文 KV 缩一个数量级,这就是它能便宜服务长上下文的硬件原因。
公式:2 × L × n_kv × d_head × 2字节 × 上下文 × 并发 · 判定含权重粗估
2023 年前的推理服务有个隐蔽浪费:KV cache 按「最大可能长度」预分配连续显存,实际只用一小段——显存利用率常常不到 40%。vLLM 的 PagedAttention 把操作系统虚拟内存那套搬了过来:KV 切成固定大小的块(如 16 token/块),逻辑连续、物理分散,按需分配。配上 continuous batching(不等整批完成,谁的序列结束立刻换新请求进来,GPU 永不空转),吞吐量提升 2-4 倍。今天 vLLM/SGLang 是开源推理服务的事实标准——「跑个模型」和「高效服务模型」之间隔着一整门系统工程。
Roofline 说了:decode 速度 ≈ 带宽÷模型字节。把字节砍半,速度近似翻倍,显存减半——量化是推理最划算的杠杆:
| 方案 | 位宽 | 要点 |
|---|---|---|
| bf16 | 16 | 基线 |
| FP8 | 8 | H100 原生支持,训练推理通吃,几乎无损——前沿实验室新默认 |
| INT8 (LLM.int8) | 8 | 逐通道缩放+离群值分离(LLM 激活有少数巨大离群维度,整列保留 fp16) |
| GPTQ / AWQ | 4 | 训练后权重量化: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(永远取最大)会陷入重复循环(「我觉得我觉得我觉得」——高概率短语互相强化)。实用组合拳:
规模化产品里,模型选型本质是单位经济学。三个杠杆按优先级:
必做实验:① 默认参数(10 万 DAU、remix 1/100、PGC 1/1000、缓存命中 70%)下对比三档模型的月账单;② 把缓存命中拉到 0 再拉到 95%——理解为什么「输入结构设计」值钱;③ remix 率从 1/100 拉到 1/10(产品爆了,人人都在创作)——看旗舰模型账单的失控曲线,以及自托管小模型为什么在高频场景是数量级的差异。
月成本 = 30 × 日生成数 × (未命中输入×原价 + 命中输入×缓存价 + 输出×输出价) · 滑块均可拖