资深设计师工作室接了个加急海报,客户要求傍晚交稿。张老师是业内公认的画师,但他有个“毛病”:每落一笔,都要停下来端详半天,反复推敲线条、色彩、构图,确认这一笔完美无瑕,才肯画下一笔。笔尖落纸只需一秒,思考却要三分钟。墙上时钟走过一圈,画布上只有寥寥几笔。实习助理小李看在眼里,急在心里,终于忍不住开口:“老师,您别每笔都亲自磨了。我按您的画风先把接下来几笔草拟出来,您一口气看完,觉得对的直接勾掉,不对的您亲手改一笔。”张老师一试,原来画十笔要想十次,现在确认一次就能定下好几笔——速度立竿见影地快了起来。 这个“小助理先猜、大专家后验”的套路,就是大模型推理领域大名鼎鼎的推测解码(Speculative Decoding)。它让一个又快又小的草稿模型大胆猜测接下来的几个词,再让权威的大模型一次性批量验证。猜对的直接收下,猜错的纠正重来。本文将用这个故事贯穿始终,把推测解码的原理、选型、流程、调优、性能对比和工程落地讲得明明白白。

岗位关联

掌握推测解码,是你从“会部署模型”进阶到“能优化推理”的关键一跃——同样的 GPU,Token 产出量可以提升 2~3 倍,在线服务的延迟肉眼可见地下降。

目录
  1. 可视化演示
  2. 背景与痛点:大模型为何“一步一停”
  3. 核心原理:实习生先写,专家后审
  4. 草稿模型选择:好助理的三个标准
  5. 猜测验证流程:从草稿到定稿的完整链路
  6. 接受率优化:让助理更懂专家的心思
  7. 性能对比分析:快多少,用公式算
  8. 工程实现方案:把协作流程搬进生产线
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示小模型草稿猜测与大模型并行验证的推测解码流程,并对比推测解码与标准自回归解码在不同接受率下的加速比

本节配有交互动效(进入视口后自动加载,约 3KB)。

Speculative Decoding: 草稿猜测与并行验证 小模型快速生成K个候选token(草稿) 大模型并行验证所有草稿token E[accept] = \u03B1\u1d4f \u03A3(1-\u03B1)\u1d62 接受的token无需额外前向推理,实现加速

背景与痛点:大模型为何“一步一停”

先回到工作室。张老师画技精湛,但他有个“职业病”:每画一笔,都要停下来把整幅画的布局重新端详一遍,确认这一笔放进去依然和谐,才肯落下。笔落时行云流水,思考时却度秒如年。客户催得急,他额头上冒出了细密的汗珠——他不是手慢,是每画一笔都要重新权衡全局这件事太慢了。

大模型生成文本时的处境如出一辙。它每一步只能吐出一个 token(可以理解为“一个词”),而每生成一个 token,都要把前面已经写下的所有 token 重新“读”一遍,做一次包含几十层网络、动辄上千亿参数的前向传播。一次前向的耗时是固定的,却只换来一个词。GPU 明明具备大规模并行计算的能力,却在这种“一步一等”的串行流程中大量空转。

这就是自回归(Auto-Regressive)生成的根本约束。它可以用一个简洁的公式刻画:

张老师擦着汗想明白了:要提速,不是让自己画得更快,而是减少自己“反复权衡全局”的次数。有没有办法让那些不需要深思熟虑的笔触,由一个快手代劳,自己只在关键处把一道关?这个念头,正是推测解码的萌芽。

P(x1,x2,…,xn)=∏t=1nP(xt∣x1,x2,…,xt−1)\displaystyle P(x_1, x_2, \ldots, x_n) = \prod_{t=1}^{n} P(x_t \mid x_1, x_2, \ldots, x_{t-1})
这个公式说明:整段文字出现的概率,等于每个词在前面所有词都确定后出现的条件概率相乘。每一步依赖上一步,想快也快不起来。
  1. 整句概率公式左边 \(P(x_1, x_2, \ldots, x_n)\) 表示整段文字出现的概率,我们的目标就是让每段输出都有合理的概率。
    P(x1,x2,…,xn)\displaystyle P(x_1, x_2, \ldots, x_n)
  2. 连乘符号\(\prod_{t=1}^{n}\) 表示从第 1 个词一直乘到第 n 个词,任何一步的概率为零,整句概率就为零。
    ∏t=1n\displaystyle \prod_{t=1}^{n}
  3. 条件概率\(P(x_t \mid x_1, \ldots, x_{t-1})\) 的意思是“在已经知道前面所有词的前提下,下一个词是 \(x_t\) 的概率”。
    P(xt∣x1,…,xt−1)\displaystyle P(x_t \mid x_1, \ldots, x_{t-1})
  4. 串行依赖注意第 t 步依赖前 t-1 步的全部结果,这意味着第 10 个词必须等第 9 个词算完才能开始。
    xt←f(x1,x2,…,xt−1)\displaystyle x_t \gets f(x_1, x_2, \ldots, x_{t-1})

核心原理:实习生先写,专家后审

小李的提议听起来简单,细想却很大胆:“您看这样行不行——我先按您的风格,把接下来可能画的五笔都画出来。您拿到草稿后,一次性审查这五笔:对的地方直接留下,不对的地方您改掉,改完我们就继续。”张老师半信半疑地试了一次。草稿摆在面前,他一眼扫过去,四笔可以留,一笔需要改。他只在那一笔上落了手——省下了四次“端详全局”的时间。

推测解码(Speculative Decoding)正是这个流程的算法化。系统里同时部署两个模型:草稿模型(Draft Model)和目标模型(Target Model)。草稿模型通常小几个量级,推理速度飞快,它负责连续自回归生成 K 个候选 token;目标模型则是那个权威的大模型,它把这 K 个候选 token 连同已经确认的前缀拼接起来,做一次性前向传播,同时得到 K+1 个位置的预测分布。有了分布,就能逐位检查:草稿猜的每一个词,目标模型是否“认可”。

这里的关键在于“认可”的标准。如果草稿模型的猜测和目标模型的分布重合度高,直接接受;如果低了,则按概率拒绝。这个机制叫拒绝采样(Rejection Sampling),它的精妙之处在于:虽然我们让草稿模型代替大模型走了几步,但最终输出的分布,和直接让大模型一步一步自己生成完全一致。接受概率由这个公式决定:

小李的“草稿”为什么能提速?因为大模型一次前向计算可以同时验证很多个位置,把原本要串行做 K 次的前向传播压缩成了 1 次。张老师的“端详”次数从每笔一次,变成了每批一次——这就是加速的本质。

r(x~)=min⁡(1,p(x~)q(x~))\displaystyle r(\tilde{x}) = \min\left(1, \frac{p(\tilde{x})}{q(\tilde{x})}\right)
其中 \(q(\tilde{x})\) 是草稿模型认为候选词 \(\tilde{x}\) 该出现的概率,\(p(\tilde{x})\) 是目标模型的判断。草稿猜得越好,比值越接近甚至超过 1,越容易全盘接受。
  1. 草稿概率\(q(\tilde{x})\) 是草稿模型对小李画的那一笔 \(\tilde{x}\) 的置信度,它代表“助理觉得这笔画得对”。
    q(x~)\displaystyle q(\tilde{x})
  2. 目标概率\(p(\tilde{x})\) 是目标模型对同一笔的判断,代表“专家眼中这一笔该不该这么画”。
    p(x~)\displaystyle p(\tilde{x})
  3. 概率比值\(\frac{p(\tilde{x})}{q(\tilde{x})}\) 衡量两者的共识程度,比值越高,说明助理恰好画到了专家的心坎里。
    p(x~)q(x~)\displaystyle \frac{p(\tilde{x})}{q(\tilde{x})}
  4. 截断到 1\(\min(1, \cdot)\) 意味着当草稿的概率比专家还高时,也最多按 1 处理——专家不仅认可,甚至觉得“就该这么画”,自然直接通过。
    min⁡(1,p(x~)q(x~))\displaystyle \min\left(1, \frac{p(\tilde{x})}{q(\tilde{x})}\right)

草稿模型选择:好助理的三个标准

小李能在张老师手下干活,不是因为他画得多快,而是因为他“懂张老师”。面试助理时,有三个标准缺一不可:手要快——他画一笔的时间要远小于张老师;心要齐——他的画风和张老师要有默契,猜十笔至少中六笔;人要便宜——请一个和张老师一样贵的助理,成本上就划不来了。

草稿模型的选择标准惊人地相似。手快意味着推理延迟低,通常参数量要比目标模型小一个数量级以上;心齐意味着它的输出分布和目标模型足够接近,否则草稿猜十笔错九笔,验证变成“全盘纠正”,反而比直接生成更慢;便宜则对应部署成本低,推理开销可以忽略不计。

实践中草稿模型主要有两类来源。一类是同源小模型:从目标模型同一家族中蒸馏或剪枝出来的小版本,比如用 LLaMA 系列蒸馏出一个 LLaMA-0.5B 来给 LLaMA-13B 当草稿。这类模型因为“基因相同”,分布天然对齐,接受率通常很漂亮。另一类是独立小模型:比如 n-gram 统计模型、独立的轻量 Transformer,它们不依赖目标模型的权重,部署更灵活,但需要额外做分布对齐训练。

“心齐”这件事,数学上可以用 KL 散度来度量——它衡量两个概率分布的差距有多大:

选草稿模型时,用 KL 散度先“面试”一轮:把候选模型在验证集上的分布和目标模型比一比,散度最小的那个,往往就是最懂专家的“小李”。

DKL(p∥q)=∑x∈Vp(x)log⁡p(x)q(x)\displaystyle D_{KL}(p \parallel q) = \sum_{x \in \mathcal{V}} p(x) \log \frac{p(x)}{q(x)}
这个公式告诉我们:草稿模型分布 \(q\) 和目标模型分布 \(p\) 的差距越小,KL 散度越接近 0,代表两者“越默契”。
  1. 遍历词表\(\sum_{x \in \mathcal{V}}\) 表示对词表里每一个可能的词都计算一遍,看两个模型在每个词上的分歧。
    ∑x∈V\displaystyle \sum_{x \in \mathcal{V}}
  2. 对数差距\(\log \frac{p(x)}{q(x)}\) 是目标模型概率和草稿模型概率的对数比,比值越偏离 1,这一项的绝对值越大。
    log⁡p(x)q(x)\displaystyle \log \frac{p(x)}{q(x)}
  3. 按权求和乘上 \(p(x)\) 表示以目标模型的判断为主视角,目标模型认为重要的词,分歧的权重要更大。
    p(x)log⁡p(x)q(x)\displaystyle p(x) \log \frac{p(x)}{q(x)}
  4. 散度归零当且仅当 \(p(x) = q(x)\) 对所有词成立时,KL 散度等于 0,意味着草稿模型简直是目标模型的“复制脑”。
    DKL(p∥q)=0\displaystyle D_{KL}(p \parallel q) = 0

猜测验证流程:从草稿到定稿的完整链路

工作室的“草稿-审阅”流程慢慢固定成了标准动作:小李先一口气画出 K 笔草稿,张老师接到草稿后从头到尾扫一遍,看到满意的就点头通过,看到第一处不满意的就亲笔改掉,改完这一笔,后面没看的草稿全部作废,从改过的地方重新开始。整个过程行云流水,形成一条固定流水线。

推测解码的流程与之完全对应,可以拆成三步。第一步:草稿序列生成。草稿模型以前缀为起点,用标准的自回归方式快速生成 K 个 token。因为模型小,这一步很快。第二步:批量并行验证。目标模型把前缀和 K 个草稿 token 拼在一起,一次性前向传播,同时得到 K+1 个位置的预测分布——注意是一次,不是 K 次。第三步:接受决策。从第一个草稿 token 开始逐位检查,遇到第一处不匹配的位置就停下来:接受之前的全部 token,用目标模型的预测纠正当前位,然后丢弃后续所有草稿,以纠正后的 token 为新的起点进入下一轮。

每轮验证实际产出的 token 数是一个随机变量,它的期望值有一个优美的闭合解。设每一步的接受率为 \(\gamma\)(gamma),草稿长度为 K,则期望产出 \(L\) 为:

这条流水线跑顺之后,张老师发现自己的“审阅”从逐笔变成了逐批。原本需要亲自落笔十次的工作,现在只需要在几个关键节点上把一把关,剩下的交给小李的草稿和快速批改——这就是“批量把关”四个字的真正分量。

E[L]=∑k=0KPr⁡(L>k)=1−γK+11−γ\displaystyle \mathbb{E}[L] = \sum_{k=0}^{K} \Pr(L > k) = \frac{1 - \gamma^{K+1}}{1 - \gamma}
这个公式是推测解码收益的“总账本”:接受率 \(\gamma\) 越接近 1、草稿长度 K 越长,期望产出的 token 越多,加速效果越明显。
  1. 接受率\(\gamma\) 表示每个草稿 token 被目标模型采纳的概率,它是整个流程的灵魂指标。
    γ\displaystyle \gamma
  2. 草稿长度K 是一次猜测的 token 数,小李一次画几笔。K 越大,每轮潜在产出越多。
    K\displaystyle K
  3. 等比求和\(\frac{1 - \gamma^{K+1}}{1 - \gamma}\) 来自等比数列求和,它把“每一步都可能随时停下来”的概率累积成了期望值。
    11−γ\displaystyle \frac{1}{1 - \gamma}
  4. 边际递减\(\gamma^{K+1}\) 随着 K 增大迅速衰减,意味着第 K 步之后几乎不可能再延续下去,草稿越长,尾部收益越薄。
    1−γK+1\displaystyle 1 - \gamma^{K+1}

接受率优化:让助理更懂专家的心思

小李的草稿一开始并不好用。他画得快,但十笔里有四笔和张老师的想法南辕北辙。张老师改得手酸,甚至想放弃这个方案。后来小李学聪明了:他把张老师过去改过的画稿都翻出来,研究老师下笔的偏好和规律,调整自己的画风去“贴”老师。慢慢地,十笔里能中八笔,合作一下子顺畅了。

接受率 \(\gamma\) 就是那个“十笔里中几笔”的命中率,它直接决定了推测解码能不能跑起来。影响 \(\gamma\) 的因素集中在两方面:草稿模型和目标模型的分布重叠度,以及解码参数(如采样温度)。分布重叠越大,草稿猜中的概率越高;温度设置不当则可能放大偏差,让草稿“飘”得更远。

接受率和分布重叠度之间有一个非常直观的数学关系。设目标模型分布为 \(p\),草稿模型分布为 \(q\),则:

明白了这个公式,优化方向就清晰了。一是微调草稿模型,让它模仿目标模型的输出分布,相当于小李研究张老师的画稿;二是自适应调整 K:当接受率在句子开头较高、句子后半段偏低时,动态缩短草稿长度,避免在低接受率区域浪费时间;三是尝试多草稿策略,同时让好几个候选草稿“投标”,提高命中的机会。这些手段,本质上都是让助理越来越懂专家的心思。

γ=∑x∈Vmin⁡(p(x),q(x))=1−12∑x∈V∣p(x)−q(x)∣\displaystyle \gamma = \sum_{x \in \mathcal{V}} \min(p(x), q(x)) = 1 - \frac{1}{2} \sum_{x \in \mathcal{V}} |p(x) - q(x)|
这个公式把接受率翻译成两句话:两个分布重叠的面积越大,接受率越高;分布距离越大,接受率损失越多。优化接受率,本质就是拉近两个分布。
  1. 逐词取小\(\min(p(x), q(x))\) 表示对每个词取两个模型概率中较小的那个——专家和助理都认可的部分才算数。
    min⁡(p(x),q(x))\displaystyle \min(p(x), q(x))
  2. 重叠总和把所有词上“共同认可”的概率加起来,得到的就是总体接受率。
    ∑x∈Vmin⁡(p(x),q(x))\displaystyle \sum_{x \in \mathcal{V}} \min(p(x), q(x))
  3. 分布距离\(|p(x) - q(x)|\) 是每个词上两个模型的概率差,差距越大,说明助理越不懂专家。
    ∣p(x)−q(x)∣\displaystyle |p(x) - q(x)|
  4. 距离换算差值的总和除以 2,就是从 1 里扣掉的接受率损失,两者此消彼长。
    1−12∑x∈V∣p(x)−q(x)∣\displaystyle 1 - \frac{1}{2}\sum_{x \in \mathcal{V}} |p(x) - q(x)|

性能对比分析:快多少,用公式算

小李的草稿方案运行了一段时间,张老师想知道到底快了多少。他做了一组对照实验:用老办法——自己一笔一笔画——画 30 笔,要思考 30 次;用新办法——小李猜 5 笔,他验 1 次——如果平均每轮能确认 4 笔,那么画 30 笔只需要 6 轮思考加几次纠正。粗粗一算,快了三到五倍。

加速比的数学表达也很直白。设标准解码生成一个 token 需要一次前向传播,耗时 \(t_{decode}\);推测解码一轮需要草稿模型生成 K 步(耗时 \(t_{draft}\))加上目标模型一次验证(耗时约等于一次 \(t_{decode}\))。假设每轮平均产出 \(\mathbb{E}[L]+1\) 个 token(包含最后那个被纠正的),那么加速比为:

实际工程中,这个加速比并不是 K 越大越美丽。原因有二:其一,\(\mathbb{E}[L]\) 对 K 的依赖是边际递减的,草稿长度翻倍,期望产出并不会翻倍;其二,草稿模型每生成一个 token 都是有成本的,K 太大意味着草稿成本快速上升。经验上,K 取 4 到 8 是比较常见的甜蜜点。张老师最终把“小李一次画几笔”定为 6 笔——再长,后面几笔的命中率就明显掉下来了。

S=(E[L]+1)⋅tdecodetdraft(K)+tdecode\displaystyle S = \frac{(\mathbb{E}[L] + 1) \cdot t_{decode}}{t_{draft}(K) + t_{decode}}
分子是标准模式产出同样多 token 的总耗时,分母是推测模式的实际耗时。\(S > 1\) 表示变快,\(S\) 越大收益越高。
  1. 标准耗时\((\mathbb{E}[L] + 1) \cdot t_{decode}\) 表示如果让大模型自己一步步生成这么多 token,一共需要这么多次前向。
    (E[L]+1)⋅tdecode\displaystyle (\mathbb{E}[L] + 1) \cdot t_{decode}
  2. 草稿成本\(t_{draft}(K)\) 是草稿模型连续生成 K 个候选的总时间,通常远小于一次大模型前向。
    tdraft(K)\displaystyle t_{draft}(K)
  3. 验证成本\(t_{decode}\) 是目标模型一次批量验证的时间,它只算一次,这是加速的核心来源。
    tdecode\displaystyle t_{decode}
  4. 收益条件当且仅当 \(\mathbb{E}[L] \cdot t_{decode} > t_{draft}(K)\) 时,\(S > 1\),也就是说省下的前向次数必须超过草稿的额外开销。
    E[L]⋅tdecode>tdraft(K)\displaystyle \mathbb{E}[L] \cdot t_{decode} > t_{draft}(K)

工程实现方案:把协作流程搬进生产线

工作室的业务越接越多,张老师和小李的“两人作坊”也要变成“标准流水线”:小李负责先画、张老师负责终审、助理调度员负责排期。谁先谁后、批次怎么合并、出了岔子怎么兜底,都要有明确的制度。推测解码在生产环境的落地,同样是这套逻辑。

部署架构上,需要同时部署目标模型服务和草稿模型服务。调度器接收推理请求后,先让草稿模型快速产出候选序列,再把候选序列拼接到请求上下文中,交给目标模型做批量验证。特别地,KV Cache 优化在这里发挥着关键作用:草稿模型和目标模型的 KV Cache 可以独立维护,目标模型验证时直接复用已有的 cache,避免前缀部分重复计算,进一步压低验证延迟。

批处理调度是提升吞吐的另一大杠杆。在线服务同时处理多个请求时,调度器可以把多个请求的草稿验证合并成一个大 batch,用一次 GPU kernel 调用同时验证多个请求的候选序列——GPU 的并行算力在这里被压榨得淋漓尽致。配合动态 K 值:接受率高的请求可以保持较长的草稿,接受率低迷的请求自动缩短草稿,避免无效计算。系统的综合吞吐可以用下式评估:

生产环境还有最后一道防线:兜底与监控。线上推理偶尔会出现草稿模型效果骤降的情况,系统必须能检测到接受率异常并动态回退到标准解码模式,保证服务不降级。同时要持续监控接受率、加速比、延迟分位数等指标,把它们接入告警体系。毕竟,让助理草拟、让专家把关的流水线再顺滑,也要确保每一份交付到客户手里的成品,都经过专家的眼睛。

Throughput=B⋅(E[L]+1)tdraft+tverify\displaystyle \text{Throughput} = \frac{B \cdot (\mathbb{E}[L] + 1)}{t_{draft} + t_{verify}}
B 是合并验证的请求数(batch size)。这个公式表明:吞吐量与批大小、每轮产出 token 数成正比,与单轮耗时为反比。
  1. 批大小\(B\) 是一次合并验证的请求数量,把多个请求的草稿捆在一起验证,GPU 算力才不浪费。
    B\displaystyle B
  2. 单轮产出\(\mathbb{E}[L] + 1\) 是每个请求每一轮平均新增的 token 数,包含修正的那一个。
    E[L]+1\displaystyle \mathbb{E}[L] + 1
  3. 总产出\(B \cdot (\mathbb{E}[L] + 1)\) 是一轮 batch 验证下来,所有请求加起来产出的 token 总量。
    B⋅(E[L]+1)\displaystyle B \cdot (\mathbb{E}[L] + 1)
  4. 单轮耗时分母 \(t_{draft} + t_{verify}\) 是一轮的总时间,草稿阶段和验证阶段是串行的,两者之和决定轮次节奏。
    tdraft+tverify\displaystyle t_{draft} + t_{verify}

AI 应用场景

在线聊天助手低延迟响应

阶段:推理服务优化

解决的问题:Chatbot 类产品对首 token 延迟和每 token 延迟极其敏感,用户每多等一秒都有流失风险。标准自回归生成在长对话中每步都要完整前向,延迟随上下文增长而恶化。推测解码让小模型先顶上草稿、大模型批量验证,单 token 延迟可降低 40%~60%。

具体案例:某客服机器人厂商在接入推测解码后,将草稿模型设为目标模型的同源蒸馏小模型(约 1/10 参数量),K 设为 5,线上实测平均接受率 0.72,每轮平均产出 4.2 个 token,首屏响应时间缩短一半,GPU 成本同步下降。

内容平台批量生成与摘要提取

阶段:离线批处理加速

解决的问题:内容平台每天需要对海量文章生成摘要、标签和推荐语,离线批处理虽然不要求极低延迟,但吞吐量直接决定服务器成本和电费。推测解码将原本“每步一次大模型前向”变成“草稿模型快跑 + 大模型批量验证”,配合多请求 batch 合并,吞吐可提升 2~3 倍。

具体案例:某新闻聚合平台使用独立训练的轻量 Transformer 作为草稿模型,在 8 卡 A100 上跑离线摘要任务,batch size 保持 32 不变,日均处理文章量从 120 万篇提升到 310 万篇,单位 token 成本降低约 55%。

边缘侧小算力设备上的模型加速

阶段:端侧推理优化

解决的问题:手机、平板等边缘设备内存和算力有限,跑不动大模型。借助推测解码,端侧只部署一个极小草稿模型,云端大模型负责批量验证,通过网络请求一次验证多个候选 token,把端云协同的通信往返次数压缩到原来的四分之一。

具体案例:某智能输入法团队在端侧部署 50M 草稿模型,云端 BERT 级模型做验证。用户每输入一次候选句,端侧猜 4 个词、云端一次返回验证结果,输入法联想延迟从 380ms 降至 120ms,流量消耗反而减少。

Python 演示

python75 行
"""推测解码教学演示: 草稿模型猜测 + 目标模型批量验证"""import random VOCAB = list("ab")  class TargetModel:    """目标模型: 权威大模型, 按固定偏好模式生成, 每次验证记一次前向"""     def __init__(self, pattern="abaabb"):        self.pattern = pattern        self.forwards = 0     def verify(self, text):        """模拟一次前向传播, 批量给出每个位置的答案"""        self.forwards += 1        return "".join(            self.pattern[i % len(self.pattern)] for i in range(len(text))        )  class DraftModel:    """草稿模型: 大部分时候能猜中目标模型的偏好, 偶尔猜错"""     def __init__(self, target, good_ratio=0.8):        self.target = target        self.good_ratio = good_ratio     def sketch(self, k):        """快速猜出 k 个候选 token"""        out = []        for i in range(k):            expected = self.target.pattern[i % len(self.target.pattern)]            if random.random() < self.good_ratio:                out.append(expected)            else:                out.append("a" if expected == "b" else "b")        return "".join(out)  def speculative_decode(draft, target, k):    """核心流程: 草稿 -> 批量验证 -> 接受或纠正"""    guessed = draft.sketch(k)    answers = target.verify(guessed)    accepted = ""    for token, expert in zip(guessed, answers):        if token == expert:            accepted += token        else:            accepted += expert            break    return guessed, accepted  def run_benchmark(total_chars=400, k=5):    target = TargetModel()    draft = DraftModel(target, good_ratio=0.8)    produced = ""    verify_count = 0    while len(produced) < total_chars:        _, accepted = speculative_decode(draft, target, k)        produced += accepted        verify_count += 1    baseline_forwards = len(produced)    speedup = baseline_forwards / verify_count    return verify_count, speedup, produced  if __name__ == "__main__":    verify_count, speedup, produced = run_benchmark()    print("目标: 生成 400 个 token")    print("标准解码 forward 次数: 400")    print("推测解码 forward 次数:", verify_count)    print("加速比: %.2f 倍" % speedup)    print("输出预览:", produced[:24], "...")
目的:用两个玩具模型完整演示推测解码的“草稿-验证-纠正”循环,并对比标准自回归解码的前向次数,直观看到加速收益。
  1. answers = target.verify(guessed)大模型一次性批量验证全部候选 token,这是加速的关键,一次前向顶多次。
  2. if token == expert:逐位比对草稿猜测与专家判断,一致的直接接受。
  3. accepted += expert遇到第一处不一致就用专家答案纠正,保证输出质量。
  4. break纠正后立刻停止,后面的草稿全部作废,避免错上加错。
  5. self.forwards += 1每调用一次 verify 记为一次前向传播,用于对比标准解码。
  6. baseline_forwards / verify_count标准解码总前向数与推测解码总前向数之比,就是加速比。

常见误区

误区“反正验证是批量的,草稿模型猜得越多,每轮产出就越多,K 当然设得越大越好。我把 K 设到 100,不是直接起飞?”

正解K 增大会让 \(\mathbb{E}[L]\) 增加,但增加幅度按 \(\gamma^K\) 指数衰减,K 过了甜蜜点(通常 4~8)后,多出来的草稿 token 几乎全是白猜。更糟的是,草稿模型每生成一个 token 都有耗时,K 太长导致草稿成本 \(t_{draft}(K)\) 飙升,加速比反而缩水。就像小李一次画一百笔草稿,张老师看五十笔全要改,改到崩溃。

为何常见:人们容易把“批量验证”误解为“批量免费验证”,忽略了草稿模型本身也是要算的。

误区“草稿模型的接受率越高,加速越明显。那我直接拿一个参数量稍小的模型当草稿,不是更稳?”

正解草稿模型的价值前提是“快”。如果草稿模型只比目标模型小一点点,它的生成耗时 \(t_{draft}(K)\) 接近大模型的前向耗时,省下的验证次数全被草稿开销吃掉了。选草稿模型是“快、准、便宜”三者平衡,而不是单一追求准。

为何常见:大家长期习惯了“模型越大效果越好”的直觉,容易忽视推理系统中“单位时间成本”的视角。

误区“小模型猜了一部分词,大模型只负责批改,输出的质量肯定和原来不一样了,长文生成会不会越跑越偏?”

正解不会。拒绝采样机制保证了最终输出分布与直接用大模型自回归生成的分布严格一致。猜对的部分被原样保留,猜错的位置由大模型修正,且每个位置都经过了大模型的分布校准。它不是“降级”,而是“换了一条等价的捷径”。

为何常见:直觉上“多了一个小模型参与”就容易联想“质量变差”,但拒绝采样的数学保证恰恰打破了这种直觉。

误区“我数了一下草稿模型每步预测对了几次,接受率不就是这个准确率吗?”

正解接受率是草稿概率与目标概率比值决定的,不是简单的“预测对错”。草稿模型猜的 token 哪怕不是目标模型的 argmax,只要它的概率没有显著超过目标模型的概率,依然可能被接受。反过来,即使草稿猜中了目标模型的高概率 token,也可能因为概率比不够高而被拒绝。它是分布层面的共识,不是点估计层面的对错。

为何常见:分类任务的“准确率”概念深入人心,但生成任务的分布匹配比分类准确率复杂得多。

误区“推测解码是通用的加速器,我只要把目标模型换成任意大模型,随便配一个小模型,加速效果就能立刻出来。”

正解推测解码的效果高度依赖“草稿与目标的分布匹配度”和“推理系统的基础设施”。如果草稿模型与目标模型分布差异大,接受率低迷,加速比可能小于 1,即比标准解码更慢。工程上还必须处理 KV Cache 复用、批处理调度、动态回退等配套机制,不是简单挂两个模型就能跑。

为何常见:看到几篇成功案例就以为开箱即用,忽略了成功案例背后大量针对性的调优工作。

面试题

Q1. 推测解码的基本思路是什么?

单选题 · easy

  • A.用更大的模型直接生成所有 token
  • B.小模型快速猜测、大模型批量验证← 正确答案
  • C.通过剪枝压缩模型参数来提速
  • D.改造注意力机制提升计算并行度

答案:B。推测解码的核心是“猜-验”框架:草稿模型快速猜 K 个候选 token,目标模型一次性前向验证并纠正。它不改变模型结构,也不依赖剪枝,而是通过减少目标模型的前向次数实现加速。

Q2. 草稿模型的核心职责是什么?

单选题 · easy

  • A.独立产出最终输出文本
  • B.快速生成候选 token 序列← 正确答案
  • C.对生成结果进行润色改写
  • D.缓存历史的 KV 状态信息

答案:B。草稿模型的任务是快速自回归生成 K 个候选 token,就像实习生先画草稿。它不负责最终输出,也不做润色或缓存管理。最终输出一定经过目标模型的验证与把关。

Q3. 拒绝采样中接受概率 r 的正确计算方式是?

单选题 · mid

  • A.r = min(1, p(候选)/q(候选))← 正确答案
  • B.r = max(1, p(候选)/q(候选))
  • C.r = min(1, p(候选)+q(候选))
  • D.r = max(0, p(候选)-q(候选))

答案:A。接受概率取目标概率与草稿概率的比值,再用 1 截断。草稿概率 q 低而目标概率 p 高时比值大,说明猜中了专家的心思,接受概率高;而 B、C、D 都无法正确刻画这种分布层面的共识。

Q4. 接受率 γ 在推测解码中的含义是?

单选题 · mid

  • A.草稿 token 被目标模型采纳的比例← 正确答案
  • B.草稿模型每次前向的推理速度
  • C.目标模型输出词表的规模大小
  • D.目标模型训练数据的覆盖范围

答案:A。γ 是每个草稿 token 通过验证的概率,它直接决定每轮期望产出多少 token。速度、词表、训练数据都与 γ 无关。γ 越高,加速比越接近理论上限。

Q5. 草稿模型与目标模型分布越接近,会发生什么?

单选题 · mid

  • A.接受率越高、加速效果越明显← 正确答案
  • B.接受率下降但生成速度更快
  • C.加速比不受分布影响
  • D.输出质量反而显著变差

答案:A。接受率由两个分布的匹配程度决定,分布越接近,草稿猜中的概率越高,每轮产出越多,加速越明显。这与生成速度无关,也不会损害输出质量,因为拒绝采样保证了分布一致性。

Q6. 期望接受长度 E[L]=(1-γ^(K+1))/(1-γ) 中,当 K 不断增大时会发生什么?

单选题 · hard

  • A.E[L] 始终线性增长不受任何限制
  • B.E[L] 增加但边际收益逐渐递减← 正确答案
  • C.E[L] 出现先减少后增加的趋势
  • D.E[L] 完全不受接受率 γ 影响

答案:B。γ 小于 1 时,γ^(K+1) 随 K 增大指数衰减,E[L] 趋近于 1/(1-γ),增加幅度越来越小。这就是为什么 K 设得过大不划算——尾部草稿几乎不可能被接受,徒增草稿模型的计算成本。

Q7. 推测解码保证生成分布不改变的关键机制是?

单选题 · easy

  • A.随机采样比目标模型更多的 token
  • B.拒绝采样并纠正未通过验证的位置← 正确答案
  • C.提高草稿模型的参数量到与目标一致
  • D.降低目标模型解码时的采样温度

答案:B。拒绝采样在“接受”时保留草稿 token、在“拒绝”时用目标模型重新采样,这一流程在数学上保证了输出分布与纯自回归解码完全一致。采样更多 token、加大模型、调温度都不构成等价保证。

Q8. 下列哪些因素会影响推测解码的接受率?

多选题 · mid

  • A.草稿模型与目标模型的分布匹配程度← 正确答案
  • B.草稿长度 K 的设定值大小← 正确答案
  • C.服务器机房的地理位置远近
  • D.解码时的采样温度等参数设置← 正确答案

答案:ABD。接受率的核心是分布匹配程度,K 影响草稿后段的置信度,温度等解码参数会改变实际采样的分布形状。机房地理位置只影响网络延迟,与概率分布无关,不影响接受率。

Q9. 工程化落地推测解码时,需要重点关注哪些问题?

多选题 · hard

  • A.草稿模型与目标模型的联合调度编排← 正确答案
  • B.多请求候选序列的批处理合并验证← 正确答案
  • C.直接用草稿模型替换目标模型来响应
  • D.接受率监控与草稿长度 K 的动态调整← 正确答案

答案:ABD。落地时调度器要编排两个模型;多个请求的草稿可以合并成一个大 batch 验证,提升 GPU 利用率;线上还要监控接受率并动态调整 K。直接用草稿模型替代目标模型等于放弃质量保障,不属于推测解码的范畴。

Q10. 推测解码相比标准自回归解码的优势包括哪些?

多选题 · easy

  • A.减少目标模型的前向传播次数← 正确答案
  • B.降低单个 token 生成的延迟← 正确答案
  • C.提升 GPU 计算资源的利用率← 正确答案
  • D.降低目标模型的训练成本

答案:ABC。推测解码把多次前向压缩成一次批量验证,直接减少前向次数,从而降低延迟、提升利用率。训练成本是模型训练阶段的事,与推理阶段的加速方案无关,D 说法错误。