LLM 推理是怎么变快的:从 KV Cache 到投机解码的系统性拆解
面向工程师的推理优化全景图。读完你应该能回答三个问题:LLM 推理慢在哪?每种优化手段到底在优化什么?代价是什么?<br><br>文中的硬件数字以 NVIDIA A100/H100 公开规格为准,模型结构数字以 Llama 系列公开配置为准;标注「量级估算」的地方表示不必纠结个位数精度,抓住数量级即可。
0. 一个反直觉的事实:推理大部分时间 GPU 在「等数据」
很多人对 GPU 的直觉是「算力怪兽,瓶颈在计算」。但对 LLM 的生成阶段来说,这个直觉是错的:大部分时间里,计算单元在空转,等着显存把数据搬过来。
理解这一点,需要一个贯穿全文的分析工具:算术强度(Arithmetic Intensity)。
算术强度 = 计算量 (FLOPs) / 访存量 (Bytes)
任何一块 GPU 都有两个关键指标:
- 算力:每秒能做多少次浮点运算。A100 的 FP16 Tensor Core 算力约 312 TFLOPS。
- 显存带宽:每秒能从 HBM 搬多少数据。A100 80GB (SXM) 约 2039 GB/s,即约 2 TB/s。
两者相除得到一个「分界点」(Roofline 模型里的 ridge point):
A100: 312 TFLOPS / 2039 GB/s ≈ 153 FLOPs/Byte
含义:你的程序每从显存读 1 字节,至少要做约 153 次浮点运算,才能把算力吃满。算术强度低于这个值,就是内存带宽瓶颈(memory-bound)——GPU 再强也快不起来,因为它在等数据;高于这个值才是算力瓶颈(compute-bound)。
H100 的这个比值更极端(FP16 约 989 TFLOPS / 3.35 TB/s ≈ 295 FLOPs/Byte)。硬件迭代中算力增长快于带宽增长,所以「喂饱 GPU」只会越来越难。
记住这个数字,下面所有优化手段的动机都从它出发。
1. Prefill 与 Decode:一次推理的两副面孔
一次 LLM 推理请求分两个阶段:
1.1 Prefill(预填充):处理你的输入
用户发来一段 prompt(比如 2000 个 token),模型需要对这 2000 个 token 做一次完整的前向传播,产出第一个输出 token。
关键特点:2000 个 token 可以并行处理。它们组成一个 [2000, hidden_dim] 的大矩阵,与权重做矩阵乘。权重从显存读一次,被 2000 行输入复用——算术强度很高,是典型的 compute-bound。GPU 火力全开,这一阶段的耗时决定了首 token 延迟(TTFT, Time To First Token)。
1.2 Decode(解码):逐个吐字
从第二个输出 token 开始,模型进入自回归循环:拿上一个 token,前向一次,得到下一个 token;再前向一次……每次只处理 1 个 token。
这就是灾难所在。做个粗略估算(量级估算):
对参数量为 P 的稠密模型,生成 1 个 token 的计算量约为 2P FLOPs(每个参数参与一次乘加)。而访存量呢?每生成一个 token,都必须把全部权重从显存完整读一遍(权重太大,放不进片上缓存)。FP16 下权重占 2P 字节。于是:
decode (batch=1) 的算术强度 ≈ 2P FLOPs / 2P Bytes = 1 FLOP/Byte
1,对比分界点 153。低了两个数量级。此时 A100 的实际算力利用率只有 1% 左右,99% 的时间在等显存。
由此可以直接推出 batch=1 时生成速度的理论上限:
每 token 耗时 ≥ 权重字节数 / 显存带宽
例:7B 模型,FP16 权重 14 GB,A100 带宽 ~2 TB/s
每 token ≥ 14 / 2039 ≈ 6.9 ms → 上限约 145 token/s
实测 vLLM 等框架跑 7B 模型单请求能到 100+ token/s,正好是这个上限的七八成——验证了 decode 就是在「用带宽换 token」。
类比:prefill 像一辆坐满 50 人的大巴跑一趟高速(油钱摊薄,效率高);decode 像同一辆大巴每趟只载 1 个乘客,来回跑几百趟。车(算力)没变,浪费在「跑趟」(搬运权重)上了。
1.3 两阶段的优化目标不同
| Prefill | Decode | |
|---|---|---|
| 瓶颈 | 算力 (compute-bound) | 显存带宽 (memory-bound) |
| 用户感知指标 | 首 token 延迟 TTFT | 吐字速度 TPOT (Time Per Output Token) |
| 优化思路 | 减计算:FlashAttention、chunked prefill、prefix caching | 减访存:量化、batch、投机解码 |
后文的每个技术,都可以问一句:它在优化哪个阶段的哪个瓶颈?
2. KV Cache:一切的起点
2.1 为什么需要它
Transformer 的自注意力里,第 t 个 token 要和前面所有 token 的 Key/Value 做交互:
Attention(q_t, K_{1..t}, V_{1..t}) = softmax(q_t · K^T / √d) · V
关键观察:由于因果掩码(causal mask),历史 token 的 K、V 一旦算出来就永远不变。如果每生成一个新 token 都从头对整个序列重算一遍,生成第 t 个 token 的成本是 O(t),生成长度为 n 的序列总成本 O(n²) 次完整前向——完全不可接受。
KV Cache 就是把每层算出的 K、V 存下来,decode 时每步只为新 token 算一份新的 K/V 追加进去,再和缓存做 attention。这样每步的前向就只处理 1 个 token,整体从 O(n²) 降到 O(n)。
它不是「锦上添花的优化」,而是自回归推理能够实用的前提。所有现代推理框架默认开启,后续一切优化(分页、量化、GQA、投机解码)都建立在它之上——所以说它是起点。
2.2 显存占用怎么算(这个公式值得背下来)
KV Cache 字节数 =
2 (K 和 V)
× num_layers(层数)
× num_kv_heads(KV 头数)
× head_dim(每头维度)
× seq_len(序列长度)
× dtype 字节数
× batch_size
代入几个真实模型(FP16,即 2 字节):
Llama-2-7B(32 层,32 个 KV 头,head_dim=128,标准多头注意力 MHA):
每 token: 2 × 32 × 32 × 128 × 2 B = 512 KiB
4096 token 的一条序列: 512 KiB × 4096 = 2 GiB
一条 4K 上下文的对话就吃掉 2 GB 显存——而整个模型权重才 14 GB。如果想同时服务 32 个这样的请求,光 KV Cache 就要 64 GB,一张 A100 直接爆掉。
Llama-3-8B(32 层,但 KV 头从 32 降到 8,用了 GQA):
每 token: 2 × 32 × 8 × 128 × 2 B = 128 KiB (只有 Llama-2 的 1/4)
8K 上下文一条序列: 1 GiB
Llama-3-70B(80 层,8 个 KV 头):
每 token: 2 × 80 × 8 × 128 × 2 B = 320 KiB
128K 上下文一条序列: 320 KiB × 131072 ≈ 40 GiB
看到问题了吗?长上下文时代,KV Cache 不是权重的零头,而是和权重同量级甚至更大的显存消耗者,而且它随并发数和上下文长度线性增长,权重却是固定的。
2.3 顺着这个公式做减法:MQA / GQA / MLA
公式里每一项都是优化的靶子:
- MQA(Multi-Query Attention):所有 query 头共享 1 组 KV,
num_kv_heads = 1,缓存缩小 32 倍。激进,但质量有损,需要训练时就这么设计。 - GQA(Grouped-Query Attention):折中方案,若干 query 头共享一组 KV(如 32 个 Q 头配 8 个 KV 头,4:1)。质量几乎无损,已成开源模型标配(Llama 3、Qwen、Mistral 都用)。
- MLA(Multi-head Latent Attention,DeepSeek-V2/V3):更进一步,把 K/V 投影到一个低秩潜向量再缓存,推理时只存潜向量。DeepSeek-V2 每层每 token 只缓存 576 个数(512 维压缩潜向量 + 64 维 RoPE 分量),相比同规模 MHA 缓存缩小一个数量级(量级估算),代价是解压时多一点计算——但 decode 本来就闲着算力,用富余的计算换紧缺的带宽和显存,稳赚。
- 还可以动
dtype:KV Cache 量化到 FP8/INT8/INT4(见第 4 节),以及动seq_len:滑动窗口注意力只保留最近 N 个 token 的缓存(Mistral 的做法)。
一句话心智模型:KV Cache 是「用显存换计算」的经典交易。后续所有 KV 相关优化,都是在讨价还价——能不能少付点显存,同时别把计算的账单加回去太多。
3. 显存与批处理:PagedAttention 和 Continuous Batching
第 1 节说 decode 是带宽瓶颈:读一遍 14 GB 权重只服务 1 个 token 太亏。最直接的解法是批处理(batching):一次读权重,同时为 32 个请求各算 1 个 token——权重访存摊薄 32 倍,吞吐量接近提升 32 倍,而每个请求的延迟几乎不变(因为原本瓶颈就不在计算)。
Batch size 是推理吞吐最重要的旋钮。 而能开多大 batch,取决于显存里还能塞下多少 KV Cache。于是问题转化为:怎么高效管理 KV Cache 显存?2023 年之前的系统在这里浪费严重,两项技术改变了局面。
3.1 PagedAttention:给 KV Cache 上一套「虚拟内存」
老方案的问题:KV Cache 随生成逐 token 增长,但需要在显存里连续存放。系统不知道每个请求最终会生成多长,只好按「最大可能长度」(比如 2048 或 4096)预分配一整块连续显存。结果:
- 内部碎片:请求实际只生成了 200 个 token,剩下 3800 多个 token 的预留空间全程空置。
- 外部碎片:不同请求预留块大小不一,释放后在显存里留下无法利用的空洞。
vLLM 论文(Kwon et al., SOSP 2023)实测:在当时的主流系统里,KV Cache 显存的实际利用率只有 20%~40%,也就是 60%~80% 被浪费。
PagedAttention 的解法照抄了操作系统教科书:分页。
- 把 KV Cache 切成固定大小的块(block),比如每块存 16 个 token 的 KV。
- 逻辑上连续的序列,物理上由分散在显存各处的块拼成,用一张块表(block table)维护「逻辑块 → 物理块」的映射——完全对应虚拟内存的页表。
- 请求生长时按需分配新块,结束时立刻归还;浪费被压缩到「最后一个块内不足 16 个 token」的零头,利用率提到 90% 以上。
- 额外红利:块可以共享。多个请求共享同一段系统 prompt 时,那部分物理块只存一份,配合 copy-on-write——这就是各框架 prefix caching / prompt caching 的基础机制之一。
代价很小:attention kernel 需要按块表做间接寻址,实现更复杂,有个位数百分比的 kernel 开销(量级估算),但换来的 batch size 提升让吞吐提高 2~4 倍(vLLM 论文对比 Orca 的数据)。
3.2 Continuous Batching:别让快的等慢的
有了显存,还要解决调度问题。静态批处理的做法是:攒 32 个请求组成一批,一起跑到全部结束。问题显而易见——有的请求生成 20 个 token 就完了,有的要生成 2000 个,先完成的请求得陪跑到最后,期间它占着的算力和显存全在空转。
Continuous batching(连续批处理,源自 Orca 论文的 iteration-level scheduling,OSDI 2022)把调度粒度从「整个请求」降到「单次迭代」:
- 每生成一步(一次前向)之后重新审视批次:完成的请求立即退出、返回结果、释放 KV 块;
- 等待队列里的新请求立即插进空位,先做它的 prefill,然后加入 decode 大军。
GPU 的 batch 因此始终保持饱满。它和 PagedAttention 是天作之合:一个保证「随时能插入新请求」在调度上可行,一个保证在显存上可行。这两项合起来,是 vLLM 相比朴素 HuggingFace 推理拿到 10 倍以上吞吐提升的主要来源。
再往下还有一个精细化问题:新请求的 prefill 是一大坨 compute-bound 计算,直接插进 decode 批次会让所有人卡一下(decode 延迟抖动)。Chunked prefill 把长 prefill 切成小段,和 decode 步混合执行,抹平抖动;更彻底的方案是 P/D 分离(disaggregated prefill/decode)——用不同的 GPU 池分别跑 prefill 和 decode,各自按自己的瓶颈配置硬件,KV Cache 通过高速互联传输(DeepSeek、Mooncake 等生产系统的做法)。
一句话心智模型:这一节全部内容 = 操作系统课的复仇。PagedAttention 是虚拟内存分页,continuous batching 是抢占式调度,prefix caching 是共享内存页。
4. 量化:既省显存,又「直接」提速
4.1 为什么量化对 decode 特别有效
一般理解量化是「省显存的有损压缩」。这没错,但漏掉了对推理更关键的一点:decode 的速度上限 = 权重字节数 / 带宽(第 1 节的公式)。权重从 FP16 压到 INT4,字节数变成 1/4,每 token 的访存量直接变成 1/4,理论生成速度提高近 4 倍——不是靠算得快,是靠读得少。
这也解释了一个实践中的现象:weight-only 量化(只压权重,计算时反量化回 FP16 再算)在小 batch 下就有实打实的加速,尽管它增加了反量化的计算——因为 decode 本来就算力大量闲置,多算一点无所谓,省下的带宽才是真金白银。
4.2 主流方案与取舍
按「量化什么」分两大类:
A. Weight-only(只量化权重)——针对小 batch / decode 场景:
- GPTQ(INT4/INT3):逐层用二阶信息(Hessian 近似)最小化量化误差,需要少量校准数据,量化过程逐列补偿。优点是精度好、生态成熟;4bit 下 perplexity 损失通常很小。
- AWQ(INT4):观察到约 1% 的「显著权重通道」对精度影响极大,通过对激活值大的通道做等价缩放(scale 塞进前一层)来保护它们,不需要反向传播。精度与 GPTQ 相当,量化更快,对指令模型鲁棒性口碑较好。
- 两者都是 W4A16(权重 4bit、激活 FP16):显存 ~1/4,小 batch 生成速度提升 2~3 倍(量级估算,取决于 kernel 质量)。
B. Weight + Activation(权重和激活都量化)——针对大 batch / prefill / 高吞吐场景:
- INT8(W8A8):代表是 SmoothQuant。难点在激活值有少数极端离群通道(outlier),直接量化会炸精度;SmoothQuant 把激活的离群幅度「匀」一部分到权重上再量化。W8A8 能用上 INT8 Tensor Core,计算本身也翻倍,对 compute-bound 的 prefill 和大 batch decode 有效。
- FP8(E4M3/E5M2):Hopper(H100)及之后的 GPU 原生支持。相比 INT8,浮点格式动态范围大,对离群值天然更宽容,通常不需要复杂的校准手术,精度损失普遍小于 1%(量级估算)。目前生产部署的事实趋势:有 H100 就优先 FP8。
C. KV Cache 量化:把缓存的 K/V 存成 FP8/INT8/INT4。同样显存直接省一半到 3/4,能开更大 batch 或更长上下文;FP8 KV 基本无损,INT4 KV 在长文本任务上需要实测把关。
4.3 决策表
| 方案 | 位宽 | 显存 | 加速场景 | 精度风险 | 适用 |
|---|---|---|---|---|---|
| FP16/BF16 | 16 | 1× | 基线 | 无 | 显存充裕、追求无损 |
| FP8 (W8A8) | 8 | ~0.5× | prefill + decode 都加速 | 很低 | 有 H100/H200,首选 |
| INT8 SmoothQuant | 8 | ~0.5× | 大 batch 吞吐 | 低,需校准 | A100 等无 FP8 硬件 |
| GPTQ / AWQ (W4A16) | 4 | ~0.3× | 小 batch decode | 中,4bit 需评测 | 单卡跑大模型、本地部署 |
| KV Cache FP8/INT8 | — | KV 减半+ | 更大 batch/更长上下文 | 低 | 与上述任意方案叠加 |
经验法则:7B 以下的小模型对 4bit 更敏感,70B 级别的大模型 4bit 后往往仍强于同显存下能放的 FP16 小模型——「大模型 + 低精度」通常优于「小模型 + 高精度」,但这是一条经验规律而非定理,上线前必须用自己的评测集验证,尤其是数学、代码这类对精度敏感的任务。
5. 投机解码:让「串行」也能并行
前面的手段都在「摊薄」访存(batch)或「减少」访存(量化),但没有动一个根本约束:decode 是串行的,第 t+1 个 token 必须等第 t 个出来才能算。投机解码(speculative decoding,Leviathan et al. 与 Chen et al. 于 2023 年分别提出)直接攻击这个约束。
5.1 核心思路:便宜地猜,昂贵地验
关键洞察有两个:
- 验证比生成便宜。让大模型「检查 5 个给定的 token 对不对」,只需一次前向(5 个 token 并行进网络,像一次 mini-prefill);而「生成 5 个 token」需要 5 次串行前向。每次前向的主要成本是读一遍权重,所以验证 5 个 ≈ 1/5 的生成成本。
- 很多 token 很好猜。语言有大量低熵片段——代码的缩进和括号、
"United"后面的"States"、格式化的模板文字。这些用小模型猜也八九不离十,何必让 70B 大模型逐个亲自写?
于是流程变成:
循环:
1. 草稿模型(如 1B)快速串行生成 k 个候选 token(如 k=5)
2. 目标模型(如 70B)一次前向,并行验证这 k 个 token
3. 从左到右接受,遇到第一个「不合格」的 token 停下,
由目标模型在该位置给出修正 token
4. 回到 1
最好情况:一次大模型前向产出 k+1 个 token;最差情况:草稿全被拒,也能产出 1 个 token(大模型的修正)——永远不会比不用投机更慢地产出 token(不计草稿开销时;实际上草稿开销存在,见 5.3)。
5.2 为什么「完全不损失质量」——不是玄学,是数学
这是投机解码最漂亮的地方。它不是「小模型答案差不多就凑合用」,而是通过投机采样(speculative sampling,一种修正的拒绝采样)保证:输出序列的概率分布与只用目标模型逐 token 采样完全一致。
规则(对每个草稿 token x,草稿模型概率 q(x),目标模型概率 p(x)):
以 min(1, p(x)/q(x)) 的概率接受 x
若拒绝:从修正分布 norm(max(0, p - q)) 中重新采样一个 token
直觉:草稿模型比目标模型「更爱」这个 token(q > p)时,按比例打折接受,多出来的概率质量被拒绝路径上的修正分布精确补回。两条路径合起来,每个 token 的边际分布严格等于 p。这是可以三行代数验证的恒等式,不是近似。
所以投机解码是本文唯一一个数学上零质量损失的加速手段(贪心解码下则退化为简单规则:草稿 token 等于目标模型的 argmax 就接受)。
5.3 加速比与代价
设草稿 token 的平均接受率为 α,每轮草稿长度 k,则每次目标模型前向平均产出的 token 数约为:
E[tokens/轮] = (1 - α^(k+1)) / (1 - α)
α = 0.8、k = 5 时约 3.7 个 token/轮,扣掉草稿模型自身的开销(通常是目标模型的 5%~10%),端到端加速 2~3 倍是文献和生产中的典型区间(量级估算)。
代价与适用条件:
- 需要一个好草稿。经典方案是同家族小模型(词表必须一致);后来的变体消除了独立草稿模型:Medusa 给目标模型加多个预测头一次猜多步;EAGLE 用目标模型的隐层特征训练轻量草稿头(当前开源方案里加速比领先,EAGLE 系列论文报告 3~4 倍);prompt lookup / n-gram 直接从上文里检索匹配片段当草稿,零训练成本,对「大量复述输入」的任务(改写、抽取、代码编辑)出奇地好。
- 吃闲置算力。投机解码本质是「用富余算力换串行步数」,所以小 batch 时收益最大;batch 很大时 GPU 算力已经被填满,验证的并行前向不再是免费的,收益缩水甚至为负。低并发的本地部署和延迟敏感场景是它的主场。
- 接受率看任务。代码、模板化文本 α 高;开放式创作、高温度采样 α 低,可能白忙。
类比:资深工程师(大模型)审代码远快于自己写代码。让实习生(草稿模型)先写,工程师批量 review,通过的直接合入,不通过的从出错处自己改——只要实习生靠谱率够高,团队产出翻倍,且代码质量标准丝毫未降(每一行都经过了工程师之手)。
6. 三个专题:FlashAttention、MoE、长上下文
6.1 FlashAttention:不减少计算,只减少搬运
朴素 attention 实现的问题不在计算量,在中间结果:S = QK^T 是一个 [n, n] 矩阵,n=8192 时单头就是 8192² × 2 B = 128 MiB,必须写回 HBM,softmax 后再读回来乘 V。整个过程对 HBM 读写 O(n²) 的数据——又撞上带宽墙,且 n 越长越严重。
FlashAttention(Dao et al., 2022)的做法:
- 分块(tiling):把 Q、K、V 切成小块,装进 SRAM(A100 每 SM 192 KB,比 HBM 快一个数量级以上),在片上算完一块的 QK^T、softmax、乘 V,只把最终小结果写回。
- Online softmax:softmax 需要全行的 max 和 sum 才能归一化,看似必须先算完整行。技巧是分块流式处理时维护运行中的 max 和 sum,每来一块就用重缩放修正之前的部分结果——数学上严格等价,结果精确,不是近似 attention。
- 代价是反向传播时不存 n² 的中间矩阵而是重算(recompute),推理时无此负担。
效果:HBM 访存从 O(n²) 降到 O(n²/M)(M 为 SRAM 块大小相关因子),attention kernel 提速 2~4 倍,且 n² 的中间显存彻底消失——长上下文的 prefill 因此才可行。它是「IO-aware 算法设计」的教科书案例:算得一样多,搬得少得多。FlashAttention-2/3 进一步优化了并行划分和对 Hopper 硬件特性(TMA、FP8)的利用。
顺带一提,第 3 节的 PagedAttention 和这里是正交的:FlashAttention 管「片上怎么算」,PagedAttention 管「HBM 里怎么存」,现代框架两者同时用(如 FlashInfer、vLLM 的融合 kernel)。
6.2 MoE 推理:参数很多,干活的很少
MoE(Mixture of Experts)把 FFN 层换成 N 个「专家」,每个 token 由路由器选 top-k(通常 k=1~2,加共享专家)个专家处理。比如 Mixtral 8x7B:总参数 47B,每 token 激活约 13B。
推理特性因此很拧巴:
- 显存按总参数付费:47B 参数一个不少都得在显存里(你不知道下个 token 路由到谁),FP16 要 ~94 GB——显存需求是 47B 稠密模型级别。
- 计算/带宽按激活参数付费:每 token 只读约 13B 参数对应的权重(量级估算,batch=1 时),decode 速度接近 13B 稠密模型。
所以 MoE 的交易是:用显存容量换「同等速度下更高的模型质量」。这带来两个工程后果:
- 小 batch 是甜点,大 batch 有摩擦:batch 大了之后,不同 token 路由到不同专家,一个 batch 几乎会激活所有专家——权重访存的摊薄效果比稠密模型差;且专家负载不均衡时,最忙的专家决定整批的延迟。
- 天然适合大规模专家并行:把专家分散到多卡/多机(expert parallelism),token 通过 all-to-all 通信找自己的专家。DeepSeek-V3 这类细粒度 MoE(每层 256 个小专家激活 8 个)在大集群上反而能做出极低的单 token 成本——但这是「数据中心级」玩法,通信工程复杂度极高。
对单机部署者的实用结论:MoE 模型选型时,显存按总参数算,速度按激活参数估,两头都要过一遍。
6.3 长上下文的代价:一笔三重账
上下文从 4K 拉到 128K,付出的不是一种代价,是三种:
- Prefill 计算,O(n²):attention 计算量随长度平方增长。128K 是 4K 的 32 倍长,attention 计算量是 ~1000 倍。即使有 FlashAttention(它降访存不降计算量),128K 输入在单卡上的 TTFT 也是几十秒级(量级估算)——这就是长文档场景「转圈久」的根源,也是 prefix caching(缓存复用历史对话/文档的 KV,命中时跳过重算)成为多轮对话和 Agent 场景刚需的原因。
- KV Cache 显存,O(n):第 2 节算过,Llama-3-70B 一条 128K 序列的 KV Cache 约 40 GiB。长上下文直接吃掉并发度:显存装得下 100 个 4K 请求的 KV,只装得下 3 个 128K 请求。
- Decode 每步访存,O(n):decode 时每步除了读权重,还要读整个 KV Cache。当 KV Cache(40 GiB)超过权重分片大小时,decode 瓶颈从「读权重」变成「读 KV」,吐字速度随上下文变长显著下降。
所以长上下文优化是一个专门的军备竞赛方向:GQA/MLA 压 KV 体积、KV 量化、滑动窗口/稀疏 attention(如 NSA、MInference 类方法)砍 attention 范围、KV 卸载到 CPU/SSD 分层存储、prefix caching 避免重算。使用侧的朴素建议:不要把 128K 窗口当免费午餐,RAG 检索出 4K 相关内容,往往比塞 100K 原文又快又好又便宜。
7. 总结对照表
| 优化手段 | 攻击的瓶颈 | 核心思路 | 典型收益(量级) | 代价 / 局限 |
|---|---|---|---|---|
| KV Cache | decode 重复计算 | 缓存不变的历史 K/V,用显存换计算 | 使自回归生成从 O(n²) 前向降为 O(n),是可用性前提 | 显存随上下文和并发线性增长,成为新瓶颈 |
| GQA / MQA / MLA | KV Cache 显存 + decode 读 KV 带宽 | 减少/压缩需要缓存的 KV | KV 缩小 4~30 倍 | 需训练时采用,无法给现成 MHA 模型后装;MLA 增加少量计算 |
| PagedAttention | KV 显存碎片浪费 | 分页 + 块表,按需分配、支持共享 | 显存利用率 20~40% → 90%+,batch 更大 | kernel 需间接寻址,实现复杂度高 |
| Continuous batching | GPU 空转(快请求陪跑慢请求) | 按「迭代」而非「请求」调度,随时进出 | 吞吐 2~10 倍(对比静态 batch) | 调度器复杂;prefill 插入引起 decode 抖动(需 chunked prefill 缓解) |
| 量化 (weight-only, INT4) | decode 读权重带宽 + 显存 | 权重压到 1/4,读得少所以快 | 显存 ~1/4,小 batch 提速 2~3 倍 | 有损,需评测把关;大 batch 下反量化开销显现 |
| 量化 (FP8/INT8 W8A8) | 算力 + 带宽 + 显存 | 用低精度 Tensor Core,算存双降 | 吞吐接近 2 倍 | FP8 需 Hopper+ 硬件;INT8 需离群值处理(校准) |
| KV Cache 量化 | KV 显存 + decode 读 KV 带宽 | 缓存用 FP8/INT4 存 | KV 显存降 2~4 倍 → batch/上下文更大 | 低位宽下长文本精度需实测 |
| 投机解码 | decode 的串行性 | 小模型猜、大模型并行验,拒绝采样保分布 | 延迟降 2~3 倍,数学上零质量损失 | 需草稿模型/额外头;吃闲置算力,大 batch 下收益消失;接受率看任务 |
| FlashAttention | attention 的 HBM 访存(尤其长序列 prefill) | tiling + online softmax,中间结果不落 HBM | attention kernel 快 2~4 倍,省 O(n²) 中间显存 | 精确无损;仅优化 attention 部分,kernel 与硬件强绑定 |
| MoE 架构 | 「质量 vs 每 token 计算量」的根本权衡 | 参数多、激活少 | 同等速度下模型质量更高 | 显存按总参数付费;专家负载不均;大规模需专家并行+复杂通信 |
| Prefix caching | 重复 prefill 计算(多轮对话/共享 prompt) | 缓存并复用历史 KV | 命中时 TTFT 大幅下降 | 占显存/需分层存储;依赖前缀完全匹配 |
| P/D 分离 | prefill 与 decode 瓶颈异质、互相干扰 | 两阶段分池部署,KV 跨机传输 | 消除干扰,两侧独立扩缩容 | 需高速互联传 KV,系统复杂度显著提高 |
8. 收尾:一个可复用的心智模型
把全文压缩成四条,以后遇到任何新的推理优化论文,都可以往这个框架里放:
- 先问阶段:它优化 prefill(compute-bound,TTFT)还是 decode(memory-bound,吐字速度)?两者的药方几乎不通用。
- decode 的一切围绕「每 token 搬多少字节」:
每 token 耗时 ≈ (权重字节 + KV 字节) / 带宽 / batch摊薄。量化减小分子,batching 摊薄分子,GQA/MLA/KV量化减小 KV 项,投机解码则减少「搬运的次数」。 - 显存是吞吐的隐形上限:batch 开多大取决于 KV Cache 塞得下多少,所以 PagedAttention 这种「不碰计算、只管内存」的工作能带来数倍吞吐提升。
- 免费午餐分两种:严格无损的(KV Cache、FlashAttention、PagedAttention、投机解码——数学等价,只是算得/搬得更聪明)和统计近似的(量化、稀疏 attention——通常没事,但上线前必须评测)。分清这两类,是判断一项优化能不能闭眼上的关键。
参考文献(关键结论的出处)
- Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention (vLLM), SOSP 2023 —— KV 显存浪费 60~80% 的实测与分页方案。
- Yu et al., Orca: A Distributed Serving System for Transformer-Based Generative Models, OSDI 2022 —— iteration-level scheduling(continuous batching 的源头)。
- Leviathan et al., Fast Inference from Transformers via Speculative Decoding, ICML 2023;Chen et al., Accelerating Large Language Model Decoding with Speculative Sampling, 2023 —— 投机采样及其分布一致性证明。
- Dao et al., FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness, NeurIPS 2022;及 FlashAttention-2 (2023)。
- Frantar et al., GPTQ, ICLR 2023;Lin et al., AWQ, MLSys 2024;Xiao et al., SmoothQuant, ICML 2023。
- Ainslie et al., GQA: Training Generalized Multi-Query Transformer Models, EMNLP 2023;DeepSeek-AI, DeepSeek-V2 技术报告(MLA)。
- Cai et al., Medusa, 2024;Li et al., EAGLE 系列, 2024。
- 硬件规格:NVIDIA A100 / H100 官方数据手册。
本文由 AI 撰写。文中标注「量级估算」的数字用于建立直觉,工程决策请以目标硬件上的实测为准。