推理加速 · Speculative Decoding / Prefix Cache / Chunked Prefill / Eagle / Medusa
定位 :03-部署-模型Serving 的算法纵深专章。03 讲了 Serving 栈四层 + KV Cache + 量化 + FinOps(工程口径),本篇只挖**「让单次推理更快」的算法层**------为什么 Prefill 慢、为什么 Decode 难并行、四大加速流派怎么取舍。不含部署运维。
风格说明:机制型为主------从自回归解码的「内存墙」物理根因出发,拆解 Prefill/Decode 两阶段瓶颈,再逐个讲 Speculative Decoding(含 Eagle/Medusa)、Prefix Cache、Chunked Prefill 的原理、收益、陷阱。
前置阅读 :01-Transformer(Attention 与 KV Cache 是前提);03-部署(KV Cache/PagedAttention/量化的工程口径)。
1. 本质:推理慢在哪里
1.1 两阶段:Prefill vs Decode
LLM 推理分两个阶段,瓶颈完全不同:
| 阶段 | 做什么 | 计算量 | 显存 | 瓶颈 | 延迟特征 |
|---|---|---|---|---|---|
| Prefill(预填) | 处理 prompt,算所有 prompt token 的 KV | 大(O(L²) attention,高度并行) | KV 写入 | 算力受限(compute-bound) | TTFT(首字延迟) |
| Decode(解码) | 逐个生成 token,复用历史 KV | 小(每步只算 1 个 token 的 attention) | KV 读取 | 显存带宽受限(memory-bound) | TPOT(每字延迟) |
1.2 核心洞察:Decode 是「内存墙」问题
金句 :Decode 阶段每生成 1 个 token,要把整个模型的权重 + 历史 KV 从显存读到计算单元,但只做极少量计算 。GPU 算力大量闲置------不是算不过来,是数据搬不过来。
量化感知:
text
以 70B 模型、batch=1、单步 decode 为例:
- 模型权重读取: ~140GB(FP16)或 ~35GB(INT4)
- 实际计算: ~2 × 70G FLOPs(矩阵向量乘,很小)
- GPU 算力利用率: < 5%(A100/H100 大量空转)
- 瓶颈: 显存带宽(~2TB/s on H100),不是算力(~1000 TFLOPS)
工程含义:所有 Decode 加速算法的本质,都是**「一次搬运,多算几个 token」**------把闲置算力用起来。这是 Speculative Decoding 的物理动机。
1.3 延迟分解(面试必背)
text
端到端延迟 = TTFT + TPOT × output_tokens
TTFT(Time To First Token)= Prefill 时间 + 队列 + 网络
TPOT(Time Per Output Token)= 每步 Decode 时间
客服 Agent 典型 SLA:
TTFT P99 < 800ms(用户等首字)
TPOT P99 < 45ms/token(读起来不卡顿)
2. 加速技术全景图
本章只讲降低单次延迟 的算法(左侧)。吞吐优化 (Continuous Batching / PagedAttention)已在 03-部署 详述,不重复。
3. Prefix Cache · 「相同前缀,只算一次」
对齐 03-部署 § Prefix cache。本节讲透原理与陷阱。
3.1 原理
问题 :多轮对话 / RAG 场景,每次请求的 prompt 有大量相同前缀(system prompt + 长文档 + 历史轮),但每次都重新 Prefill,浪费算力。
解决 :把已算过的前缀 KV 缓存起来 ,下次命中前缀时跳过 Prefill 直接复用。
text
请求 1: [system][doc_A][user_q1] → Prefill 全算,缓存 KV
请求 2: [system][doc_A][user_q2] → [system][doc_A] 命中缓存,只 Prefill [user_q2]
3.2 命中条件与实现要点
- Token 级精确匹配 :必须逐 token 完全相同才命中。差一个字、差一个 system prompt 顺序就 miss。
- 位置编码依赖 :RoPE 等位置编码让 KV 与位置绑定,所以前缀必须是从位置 0 开始的连续 token。
- LRU 淘汰:显存有限,按 LRU 淘汰冷前缀。
- 实现:vLLM、SGLang、TGI 均内置;基于 PagedAttention 的 block 级哈希匹配。
3.3 收益与陷阱
| 维度 | 收益 |
|---|---|
| TTFT | 长前缀场景可降 50-80% |
| 通用性 | 适合 system prompt 固定 / RAG / 多轮 |
| 陷阱 | 应对 |
|---|---|
| 动态 system prompt(含时间戳/用户名)导致永远 miss | 把静态部分放前面,动态部分放后 |
| 前缀太短收益不明显 | 只缓存长度 > 阈值的前缀 |
| 并发请求抢 KV 显存 | 设缓存上限 + LRU |
RAG 场景金句 :「RAG 的 system prompt + 长 chunk 是天然的前缀复用场景。检索结果相同的多轮对话,Prefix Cache 几乎是白赚的 TTFT 优化。」
4. Speculative Decoding · 「猜对了白赚,猜错了不算」
本章重点。这是 2023-2026 Decode 加速最热的方向。
4.1 动机:让闲置算力干活
Decode 每步只算 1 个 token,GPU 算力闲置 > 95%。能不能一次并行验证多个候选 token,把闲置算力用起来?
4.2 核心机制(Draft + Verify)
关键点:
- Draft 模型生成 k 个候选------小模型自回归快,但可能错。
- 大模型一次并行验证 ------因为大模型前向时可以同时算每个位置的 logits ,验证 k 个候选只需1 次大模型前向(而非 k 次)。
- 接受/拒绝规则(重要) :
- 若小模型概率
q(x)≤ 大模型概率p(x):接受(小模型没低估它)。 - 若
q(x) > p(x):以1 - p/q概率拒绝 ,并从修正分布max(0, p-q)重采样。
- 若小模型概率
- 数学保证 :输出分布与大模型单独采样完全一致------加速但不改结果质量(无损)。
4.3 为什么能加速
- 小模型生成 k 个 token 很快(小模型 decode 便宜)。
- 大模型验证 k 个候选 = 1 次前向(并行),而非 k 次串行 decode。
- 若 k 个候选都对 → 一次拿到 k+1 个 token,等效 TPOT 降近 k 倍。
- 即使部分错,接受的前 m 个也是白赚的。
加速上限:取决于「小模型猜对率」和 k 大小。实测在代码/结构化生成场景,猜对率高,加速 2-3x;开放创意写作猜对率低,加速有限。
4.4 Draft 模型的四种来源
| 方案 | Draft 是谁 | 优点 | 缺点 |
|---|---|---|---|
| 小模型(经典) | 同家族小模型(如 Llama-70B + Llama-7B) | 通用 | 需部署两个模型,占显存 |
| Eagle | 自回归头(与主模型共享 embedding/特征) | 猜对率高,额外开销小 | 需训练 head |
| Medusa | 多个并行头(每个头预测 +2/+3/...位置) | 无需额外模型 | 猜对率低于 Eagle |
| Lookup / N-gram | 用语料/上下文做 n-gram 查表 | 零模型开销 | 仅对重复/结构化文本有效 |
Eagle 详解(2024 主流)
- 原理 :训练一个轻量「自回归头」,它复用主模型的隐藏状态(hidden states),只需一个小 MLP 预测下一个 token 的特征,再过 LM head。
- 为什么强 :因为直接拿主模型已经算好的特征,不用重跑 embedding 层,Draft 成本极低且猜对率高(论文报告接受率 60-80%)。
- 适用:已进入 vLLM 等推理引擎。
Medusa 详解
- 原理 :在主模型最后一层接多个并行头,第一个头预测下一个 token(=主任务),第二个头预测下下个,第三个预测下下下个......一次前向同时得到多步候选。
- 代价 :头之间不交流,猜对率不如 Eagle,但完全不增加 decode 步骤。
4.5 适用场景与陷阱
| 适合 | 不适合 |
|---|---|
| 代码生成(强规则,猜对率高) | 开放创意写作(猜对率低) |
| 结构化输出(JSON/schema 约束) | 极短输出(k 设小,收益不显) |
| RAG/客服(大量模板化回复) | batch 已很大时(算力已不闲置) |
| 陷阱 | 应对 |
|---|---|
| Draft 模型与主模型分布差异大 → 接受率低 | 用同家族小模型 / 训练 Eagle head |
| 小模型本身要占显存 | 用 Eagle/Medusa 自带头,不额外部署 |
| k 太大反而慢(验证成本) | 动态调 k(根据近期接受率) |
| 改变了采样逻辑,与某些约束解码冲突 | 选用支持 grammar 的 spec decoding 实现 |
5. Chunked Prefill · 「长 prompt 不再阻塞」
5.1 问题
Prefill 是 compute-bound,一个超长 prompt(如 32K token 的 RAG)会让该请求长时间占满 GPU ,拖慢同 batch 内其他请求的 Decode(首字延迟被饿死)。
5.2 机制
把一次大 Prefill 切成多个 chunk ,与 Decode 请求混批调度:
text
传统:[大 Prefill 32K 占满 GPU 500ms] → 其他请求 Decode 全等
Chunked:[Prefill chunk 512][Decode batch][Prefill chunk 512][Decode batch]...
长请求的 Prefill 分摊,短请求的 Decode 不被饿死
5.3 收益
- TTFT 公平性:短请求不会被一个长 prompt 拖死。
- GPU 利用率 :Prefill(compute-bound)与 Decode(memory-bound)混批,互补占用算力和带宽。
- vLLM 默认开启(
--enable-chunked-prefill),chunk size 默认 512。
5.4 陷阱
- chunk 太小 → Prefill 整体变慢(多轮调度开销);太大 → 退化成传统模式。
- 与 prefix cache / continuous batching 的协同需调参。
6. 四大技术对比与选型
| 技术 | 优化目标 | 加速比 | 无损? | 额外开销 | 适用 |
|---|---|---|---|---|---|
| Prefix Cache | TTFT(长前缀) | 50-80% | ✅ 完全无损 | 显存(存 KV) | system prompt 固定 / RAG / 多轮 |
| Speculative(Eagle) | TPOT | 2-3x | ✅ 数学无损 | 训练 head + 少量算力 | 代码/结构化/模板化 |
| Speculative(小模型) | TPOT | 1.5-2x | ✅ 无损 | 多部署一个模型 | 有同家族小模型 |
| Chunked Prefill | TTFT 公平性 + 利用率 | 间接 | ✅ 无损 | 调度开销 | 长短混合负载 |
| 量化(INT4/FP8) | TTFT + TPOT + 显存 | 2-4x | ⚠️ 微损 | 校准 | 通用,见 03 |
组合使用 :生产实践常同时开 Prefix Cache + Chunked Prefill + 量化,Speculative 按场景开。四者正交,收益可叠加。
7. STAR 实战:RAG 客服 Agent 的延迟优化
情境(S):电商客服 Agent,prompt 含 system + 商品 KB + 历史,平均 2400 token。TTFT P99 = 1.8s(超 SLA 800ms),TPOT = 60ms(超 45ms)。自托管 Llama-3.1-70B AWQ on 2×A100。
任务(T):不改模型、不加卡,把延迟压回 SLA 内。
行动(A):
- 度量 :用 08-可观测 分解延迟,发现 Prefill 占 TTFT 的 70%------因为每次都重算 2400 token。
- Prefix Cache:system prompt + 高频 KB chunk 前缀稳定,开启 Prefix Cache,命中后跳过 ~1800 token 的 Prefill。TTFT 降到 900ms。
- Chunked Prefill:开启后,长 prompt 不再饿死短请求,TTFT P99 从 900ms 稳到 750ms。
- Speculative(Eagle):客服回复有模板化特征,接 Eagle head,TPOT 从 60ms 降到 28ms。
- 量化已有(AWQ INT4),未动。
结果(R) :TTFT P99 1.8s → 750ms,TPOT 60ms → 28ms,未加卡未改模型,全部通过推理引擎配置 + Eagle head 实现。吞吐(QPS)同步提升 ~40%(Chunked Prefill 提高利用率)。
8. 与相关章节的边界
| 主题 | 本章 | 去这里看 |
|---|---|---|
| KV Cache / PagedAttention / Continuous Batching | 仅引用 | 03-部署 |
| 量化(AWQ/GPTQ/FP8)选型 | 不展开 | 03-部署 |
| 多模型路由 / FinOps / $/task | 不展开 | 07-Gateway |
| 延迟/成本可观测(TTFT/TPOT trace) | 仅引用 | 08-可观测 |
| 私有化 vLLM 部署 | 不展开 | work/supplements/P2-03 |
99. 面试速查 · 高频满分答
Q1:LLM 推理慢在哪里?为什么 Decode 阶段 GPU 利用率这么低?
推理分 Prefill(算 prompt)和 Decode(逐字生成)。Prefill 是 compute-bound (算力受限),Decode 是 memory-bound (显存带宽受限)。Decode 每生成 1 个 token 要把整个模型权重 + 历史 KV 搬到计算单元,但只做极少计算,GPU 算力利用率 < 5%------不是算不过来,是数据搬不过来。这是 Speculative Decoding 的物理动机:用闲置算力一次验证多个 token。
Q2:什么是 Speculative Decoding?为什么能无损加速?
用一个小/快的 Draft 模型 先猜 k 个候选 token,再用大模型一次前向并行验证 (而不是 k 次串行)。接受规则:若小模型概率 ≤ 大模型概率则接受,否则按
1-p/q概率拒绝并从修正分布重采样。数学上保证输出分布与大模型单独采样完全一致------无损。加速来自:小模型猜对的部分是白赚的。代码/结构化场景猜对率高,加速 2-3x;创意写作收益低。
Q3:Eagle 和 Medusa 有什么区别?
Medusa :在主模型最后一层接多个并行头,每个头预测不同步数的 token,一次前向拿多步候选。简单、不额外部署模型,但头之间不交流,猜对率较低。Eagle :训练一个自回归头,复用主模型隐藏状态,只加一个轻量 MLP 预测下一 token 的特征。因为直接拿主模型算好的特征,Draft 成本极低且猜对率高(60-80%),是 2024 主流方案,已进 vLLM 等引擎。
Q4:Prefix Cache 的原理和陷阱?
把已算过的前缀 KV 缓存,下次命中就跳过 Prefill。适合 system prompt 固定 / RAG / 多轮场景,TTFT 可降 50-80%。命中条件是 token 级精确匹配 + 从位置 0 开始 。最大陷阱:动态 system prompt(含时间戳、用户名)会导致永远 miss------要把静态部分放前面,动态部分放后面。还要注意显存上限和 LRU 淘汰。
Q5:Chunked Prefill 解决什么问题?
解决「长 prompt 饿死短请求」。一个 32K 的 Prefill 是 compute-bound,会占满 GPU 数百毫秒,同 batch 的 Decode 请求全等。Chunked Prefill 把大 Prefill 切成多个小 chunk,与 Decode 混批调度------长请求分摊、短请求不被饿死,且 Prefill(compute-bound)与 Decode(memory-bound)互补占用算力和带宽,提高整体利用率。vLLM 默认开启。
Q6:你要优化一个 RAG 客服 Agent 的延迟,怎么下手?
先用 trace 分解 TTFT 和 TPOT。① TTFT 高 :多半是 Prefill 重算,开 Prefix Cache (system + KB 前缀稳定);长 prompt 混合负载开 Chunked Prefill 防公平性问题。② TPOT 高 :Decode memory-bound,若回复模板化开 Speculative(Eagle)。③ 通用:确认量化(INT4/FP8)已开。四者正交可叠加。我实测在 70B 模型上,Prefix Cache + Chunked + Eagle 把 TTFT 1.8s→750ms、TPOT 60ms→28ms,没加卡没改模型。
一页 Checklist
- 是否区分了 Prefill(compute-bound)与 Decode(memory-bound)瓶颈?
- Prefix Cache 是否开启?前缀是否做到 token 级稳定?
- Chunked Prefill 是否开启(长短混合负载)?
- 量化(INT4/FP8)是否已选型上线?
- Speculative Decoding 是否对模板化/代码场景启用(Eagle 优先)?
- Draft 模型是否与主模型同家族(保证接受率)?
- 是否有 TTFT/TPOT 的 P99 trace 度量(08-可观测)?
- Continuous Batching + PagedAttention 是否开启(03-部署)?
官方文档与源码(一级依据)
推理加速 · 本章算法机制依据 官方源码(L2) 与 论文(L3) ;加速比为论文/社区实测口径,实际因模型和负载而异。 写作规范:docs/official-sources-registry.md §0
L1 · 官方文档
- vLLM Docs - Features (Prefix Caching / Chunked Prefill / Speculative)
- SGLang Docs
- NVIDIA TensorRT-LLM Developer Guide
L2 · 官方源码
- vllm-project/vllm(Prefix Cache / Chunked Prefill / Eagle 集成)
- SGlang/SGLang(RadixAttention 前缀缓存)
- FUJI-AI/Eagle(Eagle 自回归头)
- TogetherAI/Medusa
L3 · 论文