LLM 面试备考
首页/Agent 基础设施

推测解码(Speculative Decoding)

所属:01-fundamentals / 06-agent-infra
面试权重:★★★
来源:《深入理解 AI Infra:量化分析与系统设计》第 8.5 节(李博杰,github.com/bojieli/ai-infra-book);算例与实测均有实验条件,非本仓库测量
相关知识点:vllm-pagedattention.md(分页器如何回滚被丢弃的草稿 KV)、batching-parallelism.md(并发下权重读取的摊薄)、latency-cost.md(TPOT 的优化手段)、../01-llm-core/arch-variants.md(MTP 头)、quantization.md(同样是在带宽受限的 decode 上做文章)

一句话#

推测解码用一段便宜的草稿去换目标模型一次前向确定多个 token —— 关键在于它不改变输出分布(拒绝时按正差额重采样,严格还原 p(x)p(x)),所以是「无损加速」;而它真正的取舍不是「草稿准不准」,而是**「每轮多输出了几个 token」与「每轮多花了多少时间」之比**。

为什么重要(面试角度)#

  • 它是最经典的推理优化题之一,而且有一层几乎所有人都答不对的反直觉:草稿接受率低也能加速。因为验证的开销极小,而每轮至少确定一个 token —— 说得出这一点,就说明你理解了机制而不只是背了名词。
  • 它的第二个反直觉更值钱:更快的草稿生成方式可能让整条请求更慢(并行生成草稿更快,但接受率下降反而增加每 token 均摊时间)。能讲清这个条件依赖,是「会算账」而不是「知道有这个东西」。
  • 它是「低并发优化」的典型:低负载时多行验证吃闲置算力,高负载时普通批处理已经充分共享权重,草稿与验证反而争用资源。被问到「什么时候不该用」时,这是标准答案。
  • 它和 KV / 内存管理强耦合:验证失败要回滚 KV 有效长度、分页器块引用、采样器与语法检查器状态 —— 这是面试官顺着往 vllm-pagedattention.md 挖的接口。

⚠️ 边界声明:本篇是《AI Infra》第 8.5 节的知识梳理与算式复现,不是一手实测。文中 RTX PRO 6000、DFlash 等数据都来自书中的实验条件(batch 1、2K 上下文等)。面试时按知识 + 会算账讲,不要说成自己调过的。

核心内容#

1. 机制:草稿 → 验证 → 回退#

普通 decode 中,目标模型每次前向只确定一个 token。推测解码的思路:先为同一请求生成一段草稿序列,再由目标模型一次前向同时验证其中多个位置。 若多个草稿被接受,一次计算就确定多个输出。

贪心生成下的规则最直观。 草稿是 a b c d,目标模型在各位置分别给出自己的选择:

  • 前两个与草稿相同 → 保留;
  • 第三个目标模型选了 x(≠ c)→ 保留前两个、在第三处输出 x;
  • 第四个草稿 token 是在错误的第三个之后生成的,随之丢弃(即使目标模型已经算过它的验证结果也不能用)。

所以这一次验证最终留下 2 个匹配 + 1 个修正 = 3 个输出。若四个全部匹配,目标模型通常还能在它们之后再给一个 token。

采样生成下必须保证分布不变。 设目标分布 p(x)p(x)、草稿分布 q(x)q(x)。先从 qq 采样得到草稿 token xx,再以下列概率接受:

α(x)=min⁡(1, p(x)q(x))\alpha(x)=\min\left(1,\ \frac{p(x)}{q(x)}\right)

直接接受的概率是 q(x)α(x)=min⁡(p(x),q(x))q(x)\alpha(x)=\min(p(x),q(x)),距离目标 p(x)p(x) 还差 [p(x)−q(x)]+[p(x)-q(x)]_+(只取正差额)。因此拒绝后,把这个正差额归一化,从中重新采样 —— 两种情况合起来,最终输出的概率恰好是 p(x)p(x)。

两符号算例(可背):p(A)=1/4, p(B)=3/4p(A)=1/4,\ p(B)=3/4。

  • 草稿恒为 A → 接受 A 的概率 1/4,其余 3/4 拒绝并改出 B;
  • 草稿恒为 B → 接受 B 的概率 3/4,其余情况改出 A。

两种草稿都给出完全相同的目标分布,但接受率差三倍 —— 这就是「草稿质量」为什么重要,以及为什么它只影响效率、不影响正确性。

验证之后要清理状态(容易被漏掉的一步):KV 的有效长度调整到已经确定的输出位置,被丢弃的草稿 token 对应的 KV 不再参与后续计算;分页器按确定的输出长度更新块引用;采样器与语法检查器(按输出格式限制可选 token 的组件)恢复到对应状态。下一轮从修正后的序列继续。

2. 该用的指标:平均每输出 token 的耗时#

推测解码同时改变每轮的耗时和输出数,所以正确的度量是

tˉspec=∑rTr∑rNr\bar t_{\mathrm{spec}}=\frac{\sum_r T_r}{\sum_r N_r}

必须用总时间除以总 token 数,而不是「先算每轮的平均值再对轮次取平均」。

为什么:两轮各 1.5 ms,分别输出 1 个和 5 个 token。正确的算法是 3/6=0.53/6=0.5 ms/token。若先算每轮的值(1.5 和 0.3 ms/token)再等权平均,会得到 0.9 ms —— 这等于让「只输出 1 个 token 的轮次」和「输出 5 个的轮次」占相同权重。这是一个很容易被追问的计算细节。

每轮平均输出多少? 设前面草稿都被接受时当前位置的接受概率为 aa,草稿长度 mm,则

E[Nm]=1+a+a2+⋯+am\mathbb{E}[N_m]=1+a+a^2+\cdots+a^m

(每一项对应「至少输出这么多个 token」的概率。)m=4m=4 时:

草稿 aa 平均每轮输出
AAAA 1/4 约 1.33
BBBB 3/4 约 3.05

3. 反直觉一:接受率低也照样加速#

这是全篇最值钱的一段。在 RTX PRO 6000、batch 1、2K 上下文下,普通 decode 一轮 26.26 ms(实验 8-1)。验证 5 个位置时,读取的权重和 KV 与普通 decode 相同,多出的 4 行矩阵运算约 65 GFLOP,按 BF16 峰值 62% 算只要约 0.2 ms —— 所以一轮验证仍按 26.26 ms 计。实验 8-5 也观察到同样现象:DFlash 每轮生成 7 个草稿、验证 8 个位置,中位耗时 15.2 ms,与同配置普通 decode 一步的 16.9 ms 相当。

于是加上草稿查询的 0.1 ms,一轮约 26.36 ms:

草稿 平均每轮输出 平均每 token
普通 decode 1 26.26 ms
AAAA(接受率 1/4) 1.33 约 19.8 ms
BBBB(接受率 3/4) 3.05 约 8.64 ms

接受率只有 25% 的草稿,也把每 token 耗时从 26.26 降到 19.8 ms。 原因有两条:① 验证几乎不增加一轮的时间(权重和 KV 的读取量没变,多的只是几行矩阵运算);② 每轮至少确定一个 token,所以推测解码永远不会比普通 decode 更差 —— 最坏情况退化成普通 decode。

上限条件由此而来:一轮总耗时必须小于「平均输出数 × 26.26 ms」。扣除验证的 26.26 ms,留给草稿查询的预算是:

  • AAAA:约 8.7 ms
  • BBBB:约 53.9 ms

超过这个预算,草稿本身的成本就吃掉全部收益。

准备成本要摊。 若建立上下文索引需要 2 秒,而 BBBB 每个输出 token 省约 26.26−8.64≈17.626.26-8.64\approx17.6 ms,则生成约 114 个 token 就能抵消。一个输出 256 token 的请求:普通 decode 约 6.72 s;先花 2 秒建索引再用 BBBB 草稿,期望约 4.22 s。如果索引能提前建立并被多个请求共用,这笔开销还能摊得更薄。

4. 反直觉二:更快的草稿可能让整条请求更慢#

草稿从哪来,决定了「每轮多花多少时间」,而这笔账不能只看草稿生成快不快。

草稿来源 做法 主要代价
上下文查找 从输入或已有回答里找重复片段 匹配与建索引的开销(可能要秒级)
独立小模型逐步生成 单独的前向,逐步出草稿 额外一份权重与 KV;每 token 要前向一次
EAGLE 类 把目标模型的中间表示送入较小的预测网络 额外网络 + 中间表示
DFlash 类 并行一次生成整段草稿 额外网络;草稿分布与目标差异可能更大
模型自带 MTP 头 训练时联合学出的多 token 预测能力 需要模型本身支持(见 arch-variants.md)

把每轮拆成生成草稿、准备验证、目标验证、确定输出四段,就能逐项比较。以 DFlash(权重约 1.95 GiB)为例,按 batch 1 的有效带宽(26.26 ms 读 15.44 GB,约 588 GB/s)算,该网络前向一次约 3.57 ms:

  • 逐个生成 4 个草稿 = 4 次前向 = 14.28 ms,加验证 26.26 ms,平均输出 3 个 → 约 13.5 ms/token;
  • 并行生成 整段草稿 = 1 次前向 = 3.57 ms,同样加验证,平均输出 3 个 → 约 9.9 ms/token。

并行赢了 —— 但只在这个接受率下成立。若并行草稿的接受率较低,平均输出降到 2 个:

(3.57+26.26)/2≈14.9 ms(3.57+26.26)/2\approx14.9\ \mathrm{ms}

14.9 > 13.5 —— 并行方式反而比串行慢。 草稿生成省下的 10.7 ms 被「每轮输出变少」抵消了。这就是「草稿快 ≠ 端到端快」的完整机制:分子变小,分母也变小,谁赢取决于两者谁降得多。

5. 草稿长度:边际收益递减,还有执行形状的阶跃#

边际判据。 长度为 mm 的草稿平均输出 E[Nm]=1+∑j=1m∏i=1jai\mathbb{E}[N_m]=1+\sum_{j=1}^{m}\prod_{i=1}^{j}a_i。从 m−1m-1 增到 mm,平均只多输出 ΔN=∏i=1mai\Delta N=\prod_{i=1}^{m}a_i 个 token —— 接受概率连乘,越靠后的草稿 token 保留下来的概率越低。设为此多花 ΔT\Delta T,要让每 token 耗时下降,需要

ΔTΔN<TN\frac{\Delta T}{\Delta N}<\frac{T}{N}

即:为新增输出付出的平均时间,必须低于原来的平均每 token 耗时。

执行形状会造成阶跃。 若验证 4 或 5 个 token 都补齐为 8 行矩阵、复用预准备的 8 行计算图,多一个 token 的额外计算很少;待验证从 8 个增到 9 个就要补齐为 16 行、换计算图,计算量突然增加。 所以草稿长度不是连续可调的量 —— 选在分组边界内(如 4、8)比选在边界外(5、9)更划算。

实测印证。 Qwen3-8B / DFlash 的短提取任务、并发 1,完整耗时中位数:

配置 耗时中位数
普通 decode 90.0 ms
K7(每轮 7 个草稿) 30.6 ms
K15(每轮 15 个草稿) 29.4 ms

普通 → K7 省了约 59 ms,K7 → K15 只再省约 1.2 ms。 逐轮记录里还出现两种块长都只接受一个草稿 token 的轮次(K7 丢弃 6 个、K15 丢弃 14 个),输出长度相同,更大的验证块只增加了计算量。

动态调整的方向:对接受概率高、增加验证位置便宜的请求用更长的草稿;对前几个位置就经常不过、或会触发更大执行形状的请求缩短块长。定块长时还要给目标模型和草稿模型的 KV 留空间,再按常规方法决定接收多少请求。

6. 什么时候不该用:并发是决定性的#

低负载时,多行验证是在吃闲置算力,收益明显。高负载时,普通批处理已经把权重读取充分摊薄了,草稿生成和验证还要与其他请求争用加速器和内存 —— 收益下降甚至转负。

一句话记住:推测解码是延迟优化,不是吞吐优化。它的位置和 quantization.md 里「weight-only 量化利好带宽受限的 decode」是同一类判断 —— 都在 decode 的带宽瓶颈上做文章,而 decode 恰好是 batch 小、算力空闲的那个阶段。

常见面试问法#

Q:推测解码是怎么保证输出不变的? A:靠接受—重采样这套组合。先按草稿分布 qq 采样出 token xx,以 α(x)=min⁡(1,p(x)/q(x))\alpha(x)=\min(1,p(x)/q(x)) 的概率接受。直接接受的概率是 q(x)α(x)=min⁡(p(x),q(x))q(x)\alpha(x)=\min(p(x),q(x)),与目标 p(x)p(x) 还差 [p(x)−q(x)]+[p(x)-q(x)]_+;拒绝后把这个正差额归一化再采一次,两条路径合起来正好还原 p(x)p(x)。所以草稿质量只影响速度,不影响正确性 —— 两符号算例最能说明:草稿恒为 A(接受率 1/4)和恒为 B(接受率 3/4),最终分布完全一样,但接受率差三倍。验证之后还要回滚状态:KV 有效长度截到已确定位置、分页器更新块引用、采样器与语法检查器恢复对应状态。

Q:草稿接受率只有 25%,还有加速吗? A:有,而且幅度不小。 RTX PRO 6000 / batch 1 / 2K 上下文下普通 decode 一轮 26.26 ms;验证 5 个位置的权重与 KV 读取量完全相同,只多约 65 GFLOP 的几行矩阵运算(约 0.2 ms),所以一轮验证仍约 26.26 ms。草稿恒为 A 时 a=1/4a=1/4,平均每轮输出 1+a+a2+a3+a4≈1.331+a+a^2+a^3+a^4\approx1.33 个 → 加上草稿查询 0.1 ms 后约 19.8 ms/token,仍低于 26.26。两个原因:① 验证几乎不增加一轮时间;② 每轮至少确定一个 token,所以最坏情况退化成普通 decode,不会更差。上限条件是一轮总耗时 < 平均输出数 × 26.26 ms —— 留给草稿查询的预算 AAAA 约 8.7 ms、BBBB 约 53.9 ms。

Q:都用并行生成草稿不是更快吗? A:不一定,要看接受率。 并行一次前向生成整段草稿确实省时间:DFlash 网络前向一次约 3.57 ms,串行生成 4 个要 4 次前向约 14.28 ms。平均输出 3 个时,串行约 (14.28+26.26)/3≈13.5(14.28+26.26)/3\approx13.5 ms/token,并行约 (3.57+26.26)/3≈9.9(3.57+26.26)/3\approx9.9 ms/token,并行赢。但若并行的草稿接受率较低、平均输出降到 2 个,就变成 (3.57+26.26)/2≈14.9(3.57+26.26)/2\approx14.9 ms/token,反而慢于串行。机制是:并行让分子(每轮时间)变小,接受率下降让分母(每轮输出数)也变小 —— 谁赢取决于两者谁降得多。所以不能脱离接受率断言某种草稿方式更好。

Q:草稿是不是越长越好? A:不是,边际收益递减,而且有执行形状的阶跃。 从长度 m−1m-1 增到 mm,平均只多输出 ∏i=1mai\prod_{i=1}^{m}a_i 个 token(接受概率连乘,越靠后越难留下);要让每 token 耗时下降需要 ΔT/ΔN<T/N\Delta T/\Delta N<T/N。执行形状还会造成不连续:验证 4 或 5 个 token 都补齐成 8 行矩阵、复用同一张计算图,但从 8 个增到 9 个就要补齐到 16 行、换计算图。实测上:Qwen3-8B/DFlash 短提取任务在并发 1 时,普通 decode / K7 / K15 的耗时中位数约 90.0 / 30.6 / 29.4 ms —— 普通到 K7 省了约 59 ms,K7 到 K15 只再省约 1.2 ms,而且出现过两种块长都只接受一个草稿的轮次(K7 丢 6 个、K15 丢 14 个),输出长度一样。动态策略是按接受率调:接受率高、加验证位置便宜的用长草稿;前几个位置就常挂、或会触发更大执行形状的缩短。

Q:什么场景不该上推测解码? A:高并发场景要谨慎。 低负载时多行验证利用的是闲置算力;高负载时普通批处理已经把权重读取充分摊薄,草稿生成和验证还要和别的请求争加速器与内存,收益下降甚至为负。另外:上下文查找型草稿要先摊准备成本 —— 建索引 2 秒、每 token 省 17.6 ms,要生成约 114 个 token 才回本,所以短输出请求不划算(256 token 的请求则是 6.72 s → 4.22 s,明显划算)。一句话:它是延迟优化,不是吞吐优化。

易错点#

易错说法 问题 应该说
「草稿不准就没意义」 漏了验证几乎免费的机制 接受率 25% 仍然加速(19.8 vs 26.26 ms/token)—— 验证的权重与 KV 读取量与普通 decode 相同,而每轮至少确定一个 token,最坏退化等于普通 decode
「推测解码会损失精度」 机制理解错 采样路径的接受—重采样严格还原目标分布 p(x)p(x),是无损的;草稿只影响速度
「并行生成草稿一定更好」 忽略了接受率 并行更快,但若接受率下降、每轮输出变少,可能反而更慢(14.9 vs 13.5 ms/token)
「草稿越长越好」 忽略了连乘衰减与执行形状阶跃 边际收益 ΔN=∏ai\Delta N=\prod a_i 递减;8→9 个 token 会补齐到 16 行换计算图。实测 K7→K15 只再省约 1.2 ms
「先算每轮平均耗时再平均」 权重错了 用 ∑Tr/∑Nr\sum T_r/\sum N_r(总时间 ÷ 总 token)。等权平均会让输出 1 个的轮次和输出 5 个的轮次同权,1.5/0.3 会错算成 0.9 而不是 0.5 ms
「验证失败就整轮作废」 漏了保留规则 保留匹配的前缀并在分歧处输出目标模型的 token;只有分歧点之后的草稿才作废
「验证完直接继续生成」 漏了状态回滚 必须回滚 KV 有效长度、分页器块引用、采样器与语法检查器状态,否则被丢弃的草稿 KV 会污染后续计算
「高并发下也能拿到同样的加速」 场景判断错 高负载下批处理已摊薄权重读取,草稿与验证转而争用资源;它是延迟优化而非吞吐优化
把书里的 RTX PRO 6000 / DFlash 数字说成自己的实测 触碰仓库硬规矩 这些数字带实验条件(batch 1、2K 上下文、特定模型),引用即可,别讲成「我测过」

自测#

1. 解释推测解码为什么是无损的,并说明「草稿恒为 A」和「草稿恒为 B」在效率上差在哪、在正确性上为什么没有差别。

答案

无损的机制是「接受 + 重采样」的组合。 设目标分布 p(x)p(x)、草稿分布 q(x)q(x):先从 qq 采样出草稿 token xx,以 α(x)=min⁡(1,p(x)/q(x))\alpha(x)=\min(1,p(x)/q(x)) 的概率接受它。直接接受这条路径给出 q(x)α(x)=min⁡(p(x),q(x))q(x)\alpha(x)=\min(p(x),q(x)) 的概率,距离目标 p(x)p(x) 还差 [p(x)−q(x)]+[p(x)-q(x)]_+(只取正差额,即 qq 给多了的那部分)。拒绝后把这个正差额归一化、从中重新采样 —— 两条路径合起来,最终输出 xx 的概率恰好是 p(x)p(x)。

两符号算例:p(A)=1/4, p(B)=3/4p(A)=1/4,\ p(B)=3/4。草稿恒为 A 时接受 A 的概率是 1/4,其余 3/4 拒绝并改出 B;草稿恒为 B 时接受概率是 3/4,其余改出 A。两者的最终分布完全一致(都是 1/4,3/41/4,3/4),所以正确性上没有差别 —— 草稿质量不影响输出,只影响速度。

效率上的差别来自接受率。 平均每轮输出 E[N]=1+a+a2+a3+a4\mathbb{E}[N]=1+a+a^2+a^3+a^4(m=4m=4):a=1/4a=1/4 时约 1.33 个 token,a=3/4a=3/4 时约 3.05 个。同样一轮约 26.36 ms,平均每 token 耗时约 19.8 ms vs 8.64 ms。但要注意:即使是接受率低的那个也比普通 decode(26.26 ms)快,因为验证几乎不增加一轮时间,且每轮至少确定一个 token。

还差一步:验证之后必须回滚状态 —— KV 有效长度截到已确定位置、分页器更新块引用、采样器与语法检查器恢复对应状态,否则被丢弃的草稿 KV 会污染后续计算。

2. 一个同事说「我们在低并发下测推测解码有 2 倍加速,所以打算全量开」。你要提醒他什么?

答案

核心提醒:推测解码是延迟优化,不是吞吐优化,高并发下收益会消失甚至转负。

原因:低负载时,多行验证消耗的是闲置算力,几乎白拿。高负载时,普通批处理已经通过增大 batch 把权重读取充分摊薄了 —— 这正是推测解码原本要补的那个缺口;而草稿生成和验证还要和其他请求争用加速器与内存,净收益下降甚至为负。

第二点:要按请求形态分。 ① 短输出请求不划算(上下文查找型草稿要先摊建索引成本:2 秒建索引、每 token 省 17.6 ms,要约 114 个 token 才回本);② 长输出请求划算(256 token 的请求:普通 6.72 s → 加 2 秒索引后用 BBBB 草稿约 4.22 s);③ 如果索引能提前建立并被多个请求共享,这笔开销能摊得更薄,那么门槛也降低。

第三点:块长要按接受率动态调,不能全量统一。 实测 Qwen3-8B/DFlash 短提取任务并发 1 时,普通 / K7 / K15 的耗时中位数约 90.0 / 30.6 / 29.4 ms —— 普通到 K7 省约 59 ms,K7 到 K15 只再省约 1.2 ms。无脑开大块长只增加计算量,还会因为执行形状补齐(8→9 个 token 要换 16 行计算图)产生阶跃成本。

最后:给一条可以量化的上线判据。 一轮总耗时必须小于「平均输出数 × 普通 decode 一轮时间」,扣除验证后留给草稿查询的预算 AAAA 约 8.7 ms、BBBB 约 53.9 ms。上线前应当按并发档位分别测 tˉ=∑Tr/∑Nr\bar t=\sum T_r/\sum N_r(不能对每轮取等权平均),只在高并发档仍成立的请求类型上开。

3. 为什么「先算每轮的平均每 token 耗时、再对轮次求平均」是错的?举一个数字例子。

答案

因为不同轮输出的 token 数不同,对轮次等权平均等于给「只输出 1 个 token 的轮次」和「输出 5 个 token 的轮次」相同的权重,而后者实际承担了 5 倍的产出。正确做法是总时间除以总 token 数:

tˉspec=∑rTr∑rNr\bar t_{\mathrm{spec}}=\frac{\sum_r T_r}{\sum_r N_r}

数字例子:两轮各耗时 1.5 ms,分别输出 1 个和 5 个 token。总计 3 ms、6 个 token → 正确结果是 0.5 ms/token。若先算每轮的值(1.5 和 1.5/5=0.31.5/5=0.3 ms/token)再等权平均,得到 (1.5+0.3)/2=(1.5+0.3)/2= 0.9 ms —— 几乎是正确答案的两倍。

这个错误在推测解码上特别容易犯,因为它的整个设计就是让每轮的输出数不相等(接受几个草稿决定本轮输出几个 token)。同样的口径问题在任何「每次产出数量不等」的系统里都存在(如批处理、投机执行、缓存命中与否的混合负载)。

4. 给你 26.26 ms 的普通 decode 一轮耗时、0.1 ms 的草稿查询开销、以及 a=3/4a=3/4 的接受概率(草稿长 4)。请算出平均每 token 耗时,并求出「草稿查询最多能花多久还不亏」。

答案

① 平均每轮输出:E[N]=1+a+a2+a3+a4=1+0.75+0.5625+0.4219+0.3164≈3.05\mathbb{E}[N]=1+a+a^2+a^3+a^4=1+0.75+0.5625+0.4219+0.3164\approx3.05 个 token。

② 一轮总耗时:验证仍约 26.26 ms(权重与 KV 读取量与普通 decode 相同,多出的几行矩阵运算按 62% 峰值算只需约 0.2 ms),加草稿查询 0.1 ms → 约 26.36 ms。

③ 平均每 token 耗时:26.36/3.05≈8.64 ms26.36/3.05\approx\mathbf{8.64\ ms},远低于普通 decode 的 26.26 ms/token。

④ 不亏的上限:条件是「一轮总耗时 < 平均输出数 × 普通 decode 一轮时间」,即

26.26+Tquery<3.05×26.26≈80.1 ms ⇒ Tquery<53.9 ms26.26+T_{query}<3.05\times26.26\approx80.1\ \mathrm{ms}\ \Rightarrow\ T_{query}<53.9\ \mathrm{ms}

所以草稿查询只要不超过约 53.9 ms 就仍然划算。对照接受率低的情形(a=1/4a=1/4,E[N]≈1.33\mathbb{E}[N]\approx1.33):预算只有 1.33×26.26−26.26≈8.7 ms1.33\times26.26-26.26\approx\mathbf{8.7\ ms}。接受率低会把草稿预算压缩近 6 倍 —— 这就是为什么草稿来源的查询成本必须和接受率一起看。

⑤ 别忘了准备成本:若建索引要 2 秒,每 token 省 26.26−8.64≈17.626.26-8.64\approx17.6 ms,需生成约 114 个 token 才回本。输出 256 token 的请求:普通约 6.72 s,先用 2 秒建索引再用该草稿约 4.22 s。

5. 推测解码和量化都在优化 decode,它们是什么关系?各自的适用条件有什么不同?

答案

相同点:都在「decode 阶段的显存带宽瓶颈」上做文章,因为 decode 每步只处理少量 token、却要把权重全部读一遍,是典型的带宽受限阶段(相比之下 prefill 是计算受限)。所以在 decode 上省字节、或者让一次读取服务更多 token,都能直接换成速度。

不同点在于它们缩短的是什么:

推测解码 量化(weight-only,如 W4A16)
改变的量 每轮输出的 token 数(分子分母同时变) 每步要读的字节数
收益条件 一轮耗时 < 平均输出数 × 原一轮耗时;低并发更划算 瓶颈确实是带宽;精度损失可接受
主要代价 草稿模型/索引的额外开销与内存;高并发下争用资源 掉点(必须重跑评测);低精度 kernel 的硬件支持
场景冲突 高负载下收益下降(批处理已摊薄权重读取) 与负载无关,是稳定收益

两者的收益会相互影响:量化减小了权重读取量,普通 decode 每步变快,推测解码要比较的基线也跟着变了;而量化让实例能装更多 KV、接收更多请求,batch 变大又进一步摊薄权重读取 —— 这同样削弱推测解码的相对收益。所以「组合优化」不能把各自单独测得的加速比相乘,必须在目标并发档位下一起测。

一句话:量化是降低每步成本,推测解码是让每步产出更多 —— 前者对负载不敏感,后者依赖低并发。