推理加速-Speculative-PrefixCache与Chunked-Prefill

推理加速 · 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. 加速技术全景图

flowchart TB ROOT[推理加速] --> A[降低延迟] ROOT --> B[提高吞吐] A --> A1[Prefill 加速] A --> A2[Decode 加速] A1 --> A1a[Chunked Prefill] A1 --> A1b[Prefix Cache] A2 --> A2a[Speculative Decoding<br/>Eagle/Medusa] A2 --> A2b[量化<br/>INT4/INT8/FP8] B --> B1[Continuous Batching] B --> B2[PagedAttention] B --> B3[增大 batch]

本章只讲降低单次延迟 的算法(左侧)。吞吐优化 (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)

sequenceDiagram participant D as Draft Model(小/快) participant T as Target Model(大/准) D->>D: 自回归生成 k 个候选 token(快,小模型) D->>T: 提交 [t1,t2,...,tk] 给大模型 T->>T: 一次并行验证 k 个位置(并行,大模型) Note over T: 对比小模型 logits vs 大模型 logits T-->>T: 接受前 m 个匹配的 token,拒绝第 m+1 Note over T: 拒绝后用大模型 logits 采样一个修正 token T-->>D: 返回最终 n 个 token(n ≤ k+1)

关键点

  1. Draft 模型生成 k 个候选------小模型自回归快,但可能错。
  2. 大模型一次并行验证 ------因为大模型前向时可以同时算每个位置的 logits ,验证 k 个候选只需1 次大模型前向(而非 k 次)。
  3. 接受/拒绝规则(重要)
    • 若小模型概率 q(x) ≤ 大模型概率 p(x)接受(小模型没低估它)。
    • q(x) > p(x):以 1 - p/q 概率拒绝 ,并从修正分布 max(0, p-q) 重采样。
  4. 数学保证输出分布与大模型单独采样完全一致------加速但不改结果质量(无损)。

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)

  1. 度量 :用 08-可观测 分解延迟,发现 Prefill 占 TTFT 的 70%------因为每次都重算 2400 token。
  2. Prefix Cache:system prompt + 高频 KB chunk 前缀稳定,开启 Prefix Cache,命中后跳过 ~1800 token 的 Prefill。TTFT 降到 900ms。
  3. Chunked Prefill:开启后,长 prompt 不再饿死短请求,TTFT P99 从 900ms 稳到 750ms。
  4. Speculative(Eagle):客服回复有模板化特征,接 Eagle head,TPOT 从 60ms 降到 28ms。
  5. 量化已有(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 · 官方文档

L2 · 官方源码

L3 · 论文

相关推荐
想要成为糕糕手4 小时前
NO.48 旋转图像 —— LeetCode 热题 100 面试导向深度解析
javascript·算法·面试
JieE2124 小时前
LeetCode 138 随机链表的复制|两种解法详解(哈希表 + 原地 O (1) 空间)
javascript·算法·面试
zzz_23686 小时前
【Java实习面试算法冲刺】动态规划
java·算法·面试
胡萝卜术6 小时前
V040:RAG 检索增强生成的工程链路解构与生产级系统设计
面试·架构·github
kyriewen17 小时前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
黄敬峰20 小时前
从零搭建 RAG 应用 —— 一个故事带你彻底搞懂检索增强生成
面试
众人皆醒我独醉20 小时前
etcd,其实不是你以为的"数据库"——Kubernetes 大脑的六个反直觉真相
面试·kubernetes
Hyyy21 小时前
Electron-Vite是什么,和Vite有什么区别
前端·面试
兰令水1 天前
hot100【acm版】【2026.7.14打卡-java版本】
java·数据结构·算法·leetcode·面试