LLM WIKI · 课程精读

LEARNING UNIT · 11

采样、投机解码与多 Token 预测

从采样退化条件、拒绝采样和概率树证明出发,理解投机解码与 MTP 的无损性和加速边界。

已整理章节
11 节
单元来源
10 条视频
总时长
31:17
状态
已发布
学习位置
11 / 20
01

主题讲解 · 02:27

Temperature、Top-k 与 Top-p 何时等价于贪婪解码

学习目标

  • 能写出 Temperature 对 logits 的缩放公式,并解释高温与低温的效果。
  • 能区分“把 T=0T=0 代入公式”和“令 T0+T\to0^+”这两种说法。
  • 能说明 Top-k、Top-p 如何先筛候选、再重归一化和采样。
  • 能给出三类采样策略退化为贪婪解码的充分条件。
  • 能识别并列最大值、最小保留数和 warper 顺序带来的实现边界。

前置与衔接

语言模型在每个生成位置先输出词表上的 logits:

z=(z1,z2,,zV).z=(z_1,z_2,\ldots,z_V).

贪婪解码直接选最大 logit 对应的 token:

x=argmaxizi.x^*=\arg\max_i z_i.

随机采样则先把 logits 变成概率分布,再从中抽样。

Temperature、Top-k 与 Top-p 都不改变模型参数;它们改变的是“怎样从当前 logits 得到最终候选分布”。

图 1

Temperature 通过 softmax(z/T) 调整同一组 logits 的相对尖锐程度,而不改变 logits 的排序。

原视频 · 00:20 ↗

本课的问题是:这些看似随机的策略,在什么条件下只剩一个可选 token,从而与贪婪解码等价?

核心讲解

1. Temperature 缩放 logits

Temperature 采样使用

pi(T)=exp(zi/T)jexp(zj/T),T>0.p_i(T)=\frac{\exp(z_i/T)}{\sum_j\exp(z_j/T)},\qquad T>0.

除以同一个正数不会改变 logits 的大小顺序,却会改变差值在指数函数中的尺度。

对任意两个 token i,ji,j

pi(T)pj(T)=exp ⁣(zizjT).\frac{p_i(T)}{p_j(T)} =\exp\!\left(\frac{z_i-z_j}{T}\right).

因此:

  • T>1T>1 时,logit 差异被压缩,分布更平;
  • 0<T<10<T<1 时,logit 差异被放大,分布更尖;
  • TT\to\infty 时,在有限 logits 下趋近均匀分布;
  • T0+T\to0^+ 时,概率集中到最大 logit 上。

2. 为什么不能把 T=0 直接代入

公式包含 zi/Tz_i/T,所以字面上的 T=0T=0 会除零,数学上没有定义。

视频板书用“T=0T=0”表达极低温的直觉;严谨写法应是正温度极限:

T0+.T\to0^+.
图 2

当 T 从正数趋近 0 时,最大 logit 的概率质量占据主导;若最大值并列,极限质量会在并列项之间分配。

原视频 · 00:40 ↗

若最大 logit 唯一,设它是 zmz_m,则对任意 imi\ne m

pi(T)pm(T)=exp ⁣(zizmT)0.\frac{p_i(T)}{p_m(T)} =\exp\!\left(\frac{z_i-z_m}{T}\right)\to0.

所以 pm(T)1p_m(T)\to1,抽样结果趋于贪婪选择。

工程实现常把 temperature=0 当作一个开关,直接绕过 softmax 随机采样并执行 greedy;这属于 API 约定,不是把 0 代入上式。

3. 并列最大值是低温极限的例外

如果有多个 token 的 logit 并列最大,低温极限不会自动选定其中某一个。

在理想精确计算下,概率质量会留在并列最大项之间;若它们 logits 完全相同,极限通常在这些项上均分。

而具体 greedy 实现需要一个 tie-break 规则,例如选择词表索引最小的项。

因此,“低温等于 greedy”还隐含一个条件:最大值唯一,或两种路径采用相同的并列处理规则。

4. Top-k:只保留最大的 k 个候选

Top-k 先按分数或概率排序,只保留最高的 kk 个 token,把其余 token 的分数设为负无穷,再重新归一化。

图 3

Top-k 仅保留概率最高的 k 个候选并屏蔽其余候选;k=1 时只剩一个可采样 token。

原视频 · 01:00 ↗

设保留集合为 SkS_k,过滤后的分布为

p~i={pijSkpj,iSk,0,iSk.\tilde p_i= \begin{cases} \dfrac{p_i}{\sum_{j\in S_k}p_j}, & i\in S_k,\\ 0, & i\notin S_k. \end{cases}

k=1k=1 时,集合里只剩最高概率 token,重归一化后其概率为 1。

所以在没有并列处理差异、且实现确实允许只保留一个 token 时,Top-k 的 k=1k=1 与贪婪解码等价。

5. Top-p:保留累计概率达到阈值的最小前缀

Top-p 又称 nucleus sampling。

先把概率降序排列:

p(1)p(2)p(V).p_{(1)}\ge p_{(2)}\ge\cdots\ge p_{(V)}.

再选择满足下式的最小 mm

i=1mp(i)pthreshold.\sum_{i=1}^{m}p_{(i)}\ge p_{\text{threshold}}.

最后仅在前 mm 个 token 中重归一化并采样。

图 4

Top-p 按概率降序累加,保留累计概率首次达到阈值 p 的最小前缀,再在该前缀中采样。

原视频 · 01:20 ↗

若阈值满足

0<pthresholdp(1),0<p_{\text{threshold}}\le p_{(1)},

那么第一个 token 已经达到阈值,最小前缀只含一个 token,结果便与贪婪解码等价。

“令 p0+p\to0^+”是一个容易记住的充分条件,但不是唯一条件;只要阈值不超过当前最高概率,标准 Top-p 就会留下单个候选。

6. 为什么过滤后还要重归一化

Top-k 与 Top-p 把部分候选概率变为 0 后,剩余概率之和通常小于 1。

采样前必须重新除以剩余总质量。

图 5

Top-k 或 Top-p 屏蔽候选后,需要在剩余集合上重新归一化;集合只有一个元素时采样结果确定。

原视频 · 01:40 ↗

当剩余集合恰好只有一个元素时,无论过滤前它的概率是 0.2 还是 0.9,重新归一化后都会变成 1。

真正使输出确定的不是“原概率已经接近 1”,而是“最终可采样集合只剩一个元素”。

7. 三种退化条件放在一起看

图 6

低温极限、k=1 与只保留最高概率 token 的 Top-p 阈值都可得到贪婪等价结果,但字面 T=0、p=0 和并列最大值仍取决于实现约定。

原视频 · 02:00 ↗

在唯一最大值和标准实现约定下,三种常用充分条件是:

  1. Temperature:T0+T\to0^+,或 API 显式切换到 greedy;
  2. Top-k:k=1k=1
  3. Top-p:阈值使最小 nucleus 只包含最高概率 token,例如 0<pp(1)0<p\le p_{(1)}

它们的共同本质是:最终分布的支撑集缩小到一个 token。

8. 多个 logits warper 组合时要看顺序

真实推理框架常同时使用 Temperature、Top-k、Top-p、重复惩罚和最小保留 token 数。

这些变换通常按固定顺序执行。

Temperature 不改变排序,却会改变概率值,因此可能改变 Top-p 需要保留多少个 token。

Top-k 先删掉候选后,再做 Top-p,结果也可能不同于先对完整词表做 Top-p。

若框架设置 min_tokens_to_keep > 1,即使 Top-p 阈值很小,也可能强制保留多个候选。

所以“参数满足某个数值”只有连同实现顺序和最小保留规则一起看,才能断言等价于 greedy。

跟练与练习

原视频定位

编者练习

某一步的概率按降序为 (0.52,0.25,0.13,0.10)(0.52,0.25,0.13,0.10)。分别判断 Top-p 阈值为 0.50、0.60、0.90 时会保留几个 token;哪一种与贪婪解码等价?

查看参考答案

阈值 0.50 时,第一个概率 0.52 已达到阈值,只保留 1 个 token,与贪婪解码等价。阈值 0.60 时,需保留前 2 个,累计为 0.77。阈值 0.90 时,需保留前 3 个,累计恰为 0.90。

编者练习 2

两个 token 的 logits 并列为最大值。为什么 T0+T\to0^+ 仍不能保证与一个采用固定词表索引 tie-break 的 greedy 实现逐次输出相同?

查看参考答案

低温极限只会把质量集中到所有并列最大项上,并不会从数学上指定其中某一个。随机采样仍可能在并列项之间抽取,而 greedy 实现会按自己的 tie-break 固定选一个;除非额外统一并列规则,否则两者不逐次等价。

常见误区

  • 误区:把 T=0T=0 直接代入 softmax。纠正:公式要求 T>0T>0;严格说法是 T0+T\to0^+,或实现绕过公式执行 greedy。
  • 误区:低温一定得到唯一 token。纠正:最大 logit 并列时,极限仍可能保留多个最大项。
  • 误区:Top-p 的阈值越接近 1,输出越确定。纠正:阈值越大通常保留越多候选;小阈值才更容易只保留最高项。
  • 误区:Top-p 只有 p=0p=0 才退化。纠正:标准定义下,只要正阈值不超过当前最高概率就会留下单个候选;字面 p=0p=0 可能被拒绝或钳制。
  • 误区:过滤后无需归一化。纠正:剩余质量必须重标定为和 1,才能构成采样分布。
  • 误区:单看一个参数就能判断最终策略。纠正:重复惩罚、warper 顺序和最小保留数都可能改变最终候选集。

本课小结

  • Temperature 用 softmax(z/T)\operatorname{softmax}(z/T) 调整分布尖锐度,但 T=0T=0 不能直接代入公式。
  • 唯一最大值时,T0+T\to0^+ 使概率集中到最大 logit,趋近贪婪解码。
  • Top-k 在 k=1k=1 时只剩一个候选。
  • Top-p 在阈值不超过当前最高概率时,最小累计前缀只含一个候选。
  • 三种策略的共同本质是把最终采样分布的支撑集缩到一个 token。
  • 并列最大值、阈值约定、最小保留数和变换顺序决定了工程实现是否真正等价。
02

主题讲解 · 03:52

投机解码的接受概率与残差重采样

学习目标

  • 能区分 Draft 提案分布 qq 与 Target 目标分布 pp
  • 能计算单个候选的接受概率 min(1,p(x)/q(x))\min(1,p(x)/q(x))
  • 能在拒绝后构造正残差分布 (pq)+(p-q)_+
  • 能用完整路径概率核对校正后的输出分布等于 pp
  • 能准确解释投机解码中的“无损”含义及其成立条件。

前置与衔接

投机解码希望用较小、较快的 Draft 模型提出 token,再让较大 Target 模型校验。

若直接接受 Draft 样本,输出会服从 qq,而我们真正想保留的是 Target 分布 pp

图 1

投机解码先由 Draft 提案,再由 Target 用接受或拒绝加残差重采样校正候选分布。

原视频 · 00:00 ↗

因此验收不是简单判断“两个模型的 argmax 是否相同”,而是一套严格的接受—拒绝—重采样规则。

本课用三个 token 的数值例,把每一步的概率质量算清楚。

核心讲解

1. 数值例:Draft 与 Target 分布不同

候选集合为 {A,B,C}\{A,B,C\}

Draft 分布是

q=(0.1,0.1,0.8),q=(0.1,0.1,0.8),

Target 分布是

p=(0.2,0.4,0.4).p=(0.2,0.4,0.4).
图 2

数值例中 Draft 分布 q=(0.1,0.1,0.8),Target 分布 p=(0.2,0.4,0.4)。

原视频 · 00:40 ↗

对比可见:

  • Draft 对 AA 少分配了 0.10.1
  • Draft 对 BB 少分配了 0.30.3
  • Draft 对 CC 多分配了 0.40.4

概率总和都为 1,所以缺口总量 0.1+0.30.1+0.3 恰等于盈余总量 0.40.4

校正的任务就是:削掉 CC 多出来的质量,再把它按缺口比例补给 AABB

2. 接受概率为什么是 min(1,p/q)

Draft 先采样一个候选 XqX\sim q

对采到的 xx,接受概率定义为

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

候选经“Draft 采到并被接受”这条直接路径输出的概率质量为

q(x)α(x)=min(q(x),p(x)).q(x)\alpha(x)=\min(q(x),p(x)).

这个等式是整套校正的核心。

它保证直接路径最多保留 Target 允许的质量,不会把 Draft 的过度自信带进最终分布。

3. Draft 低估的 A、B 为什么总是接受

AA

p(A)q(A)=0.20.1=2,α(A)=1.\frac{p(A)}{q(A)}=\frac{0.2}{0.1}=2, \qquad \alpha(A)=1.

BB

p(B)q(B)=0.40.1=4,α(B)=1.\frac{p(B)}{q(B)}=\frac{0.4}{0.1}=4, \qquad \alpha(B)=1.

Draft 本来就没有给够 AABB,所以直接采到它们时没有必要再拒绝。

但“总是接受”只保留了 q(A)=0.1q(A)=0.1q(B)=0.1q(B)=0.1,仍不足以达到 Target 的 0.20.20.40.4

缺少的部分要靠拒绝其他候选后的重采样补回来。

4. Draft 高估的 C 只接受一半

Draft 对 CC 的质量为 0.8,而 Target 只允许 0.4。

图 3

Draft 对 C 分配 0.8,而 Target 只分配 0.4;C 的多余概率质量必须通过随机拒绝削掉。

原视频 · 01:00 ↗

所以

α(C)=p(C)q(C)=0.40.8=0.5.\alpha(C)=\frac{p(C)}{q(C)} =\frac{0.4}{0.8}=0.5.
图 4

提案为 C 时,以 min(1,p(C)/q(C))=0.5 接受,直接保留下来的 C 质量恰为 0.8×0.5=0.4。

原视频 · 01:40 ↗

直接输出 CC 的总概率是

q(C)α(C)=0.8×0.5=0.4,q(C)\alpha(C)=0.8\times0.5=0.4,

恰好等于 p(C)p(C)

其余 0.8×0.5=0.40.8\times0.5=0.4 进入拒绝分支。

5. 拒绝后不能直接从 p 重新采样

如果拒绝 CC 后再直接从完整 Target 分布 pp 采样,CC 还会再次获得概率质量。

但它的 Target 额度已经由直接接受路径完整提供了。

因此拒绝后必须只补 Target 相对 Draft 的缺口,使用正残差:

d(x)=(p(x)q(x))+,d(x)=(p(x)-q(x))_+,

其中 (u)+=max(u,0)(u)_+=\max(u,0)

本例中

d=(0.1,0.3,0).d=(0.1,0.3,0).

正残差总量为

D=0.1+0.3=0.4.D=0.1+0.3=0.4.

归一化后的残差分布是

r(x)=d(x)D=(0.25,0.75,0).r(x)=\frac{d(x)}{D}=(0.25,0.75,0).
图 5

拒绝 C 后从正残差 (p-q)+ 重采样:A、B 的未归一化质量为 0.1、0.3,归一化后为 0.25、0.75。

原视频 · 02:40 ↗

因此拒绝后以 0.25 选择 AA,以 0.75 选择 BB,不会再选择 CC

6. 用所有路径核对最终输出

最终输出 CC 只有直接接受路径:

Pout(C)=0.8×0.5=0.4.P_{\text{out}}(C)=0.8\times0.5=0.4.

输出 AA 有两条互斥路径:

  1. Draft 直接提案 AA:概率 0.10.1
  2. Draft 提案 CC、拒绝、再采到 AA:概率 0.8×0.5×0.25=0.10.8\times0.5\times0.25=0.1

所以

Pout(A)=0.1+0.1=0.2.P_{\text{out}}(A)=0.1+0.1=0.2.

输出 BB 同样有两条路径:

Pout(B)=0.1+0.8×0.5×0.75=0.4.P_{\text{out}}(B) =0.1+0.8\times0.5\times0.75 =0.4.
图 6

直接接受与拒绝校正两类路径相加后,A、B、C 的最终概率分别恢复为 0.2、0.4、0.4。

原视频 · 03:40 ↗

最后得到

Pout=(0.2,0.4,0.4)=p.P_{\text{out}}=(0.2,0.4,0.4)=p.

7. 一般形式

对有限离散词表,只要 p,qp,q 都是归一化分布,直接接受质量为

a(x)=min(p(x),q(x)).a(x)=\min(p(x),q(x)).

总拒绝质量为

R=1xa(x)=x(q(x)p(x))+.R=1-\sum_x a(x) =\sum_x(q(x)-p(x))_+.

归一化守恒还给出

R=x(p(x)q(x))+.R=\sum_x(p(x)-q(x))_+.

R>0R>0,拒绝后从

r(x)=(p(x)q(x))+Rr(x)=\frac{(p(x)-q(x))_+}{R}

采样,则

Pout(x)=min(p(x),q(x))+Rr(x)=p(x).P_{\text{out}}(x) =\min(p(x),q(x))+Rr(x) =p(x).

R=0R=0,则 p=qp=q,所有候选都接受,也无需定义或使用残差分布。

8. “无损”不等于每次 token 都相同

这里的无损指:遵循上述随机校正规则后,最终输出的条件分布精确等于 Target 分布。

它不表示:

  • 与单独运行 Target 时使用同一随机数会得到相同 token;
  • 每轮候选都会被接受;
  • 输出文本逐次确定不变;
  • 一定获得加速。

多 token 投机解码会在每个位置使用对应前缀下的条件 pi,qip_i,q_i 顺序验收;第一次拒绝后,后续草稿基于已失效分支,不能继续提交。

若实现使用近似概率、不同采样过滤、量化误差或修改过的验收规则,严格分布等价也需要重新审查。

跟练与练习

原视频定位

编者练习

沿用 q=(0.1,0.1,0.8)q=(0.1,0.1,0.8)p=(0.2,0.4,0.4)p=(0.2,0.4,0.4)。计算最终输出 BB 的两条路径,并解释为什么不能只计算 Draft 直接提案 BB 的概率。

查看参考答案

直接提案 BB 的质量是 0.10.1。另一条路径是 Draft 提案 CC、以 0.50.5 概率拒绝、再以残差概率 0.750.75 采到 BB,质量为 0.8×0.5×0.75=0.30.8\times0.5\times0.75=0.3。两者相加为 0.4=p(B)0.4=p(B)。若只看直接路径,就漏掉了从 Draft 盈余质量转移来的 0.3。

编者练习 2

p=qp=q,接受率、拒绝质量和残差分布分别怎样处理?

查看参考答案

所有有正概率的候选都有 p(x)/q(x)=1p(x)/q(x)=1,因此全部接受;总拒绝质量 R=0R=0。残差分布的分母为 0,但它根本不会被访问,所以实现应直接跳过拒绝重采样分支,而不是强行计算 0/00/0

常见误区

  • 误区:Target 概率更高的 token 应该更容易被拒绝。纠正:p(x)q(x)p(x)\ge q(x) 时接受率截断为 1;它还需要从拒绝分支补足缺口。
  • 误区:拒绝后直接从 pp 采样。纠正:应从归一化正残差 (pq)+(p-q)_+ 采样,否则会重复给已满足的 token 加质量。
  • 误区:p/qp/q 可以大于 1 作为概率。纠正:接受率使用 min(1,p/q)\min(1,p/q)
  • 误区:只核对 C 的 0.4 就证明了无损。纠正:必须对每个可能输出汇总所有互斥路径。
  • 误区:无损意味着逐次输出相同。纠正:它是分布等价,不是随机轨迹相同。
  • 误区:分布等价自动带来加速。纠正:速度还取决于 Draft 成本、验收成本与接受长度。

本课小结

  • Draft 从 qq 提案,Target 希望最终输出仍服从 pp
  • 接受率 min(1,p/q)\min(1,p/q) 让直接路径只保留 min(p,q)\min(p,q) 的质量。
  • 拒绝后从正残差 (pq)+(p-q)_+ 的归一化分布重采样,补齐 Target 的缺口。
  • 数值例中,C 的盈余 0.4 被拒绝并按 1:3 补给 A、B。
  • 汇总直接与校正路径后,输出分布逐点恢复为 pp
  • “无损”是严格规则下的分布等价;近似概率、过滤顺序和实现改动都属于额外边界。
03

主题讲解 · 02:51

用概率树证明投机解码保持目标分布

学习目标

  • 能把投机解码的一次验收画成“提案—接受或拒绝—残差重采样”的概率树。
  • 能区分 Draft 低估的 deficit token 与 Draft 高估的 surplus token。
  • 能按互斥路径相加计算每个最终 token 的输出概率。
  • 能从三 token 例推广到一般离散分布的逐点证明。
  • 能说明总缺口等于总盈余以及 R=0R=0 时的边界处理。

前置与衔接

设 Draft 的提案分布为 qq,Target 的目标分布为 pp

投机解码先采样

Xq,X\sim q,

再以

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

接受候选;若拒绝,则从归一化正残差 (pq)+(p-q)_+ 中采样替代 token。

上一课可以直接算公式,本课改用概率树把“最终 token 到底从哪条路径来”展开。

图 1

概率树例使用 Target p=(0.2,0.4,0.4) 与 Draft q=(0.1,0.1,0.8),把每个最终 token 的来源拆成不同路径。

原视频 · 00:20 ↗

数值例仍取

p=(0.2,0.4,0.4),q=(0.1,0.1,0.8).p=(0.2,0.4,0.4),\qquad q=(0.1,0.1,0.8).

核心讲解

1. 概率树的三层结构

第一层是 Draft 提案:

  • 以 0.1 提案 AA
  • 以 0.1 提案 BB
  • 以 0.8 提案 CC

第二层是 Target 验收:每个提案按 α(x)\alpha(x) 分到接受或拒绝分支。

第三层只在拒绝时出现:从残差分布 rr 采一个替代 token。

最终输出某个 token 的概率,等于树上所有到达该 token 的互斥叶路径概率之和。

2. 先按 deficit 与 surplus 划分 token

定义 Draft 低估集合

D={x:p(x)q(x)},D=\{x:p(x)\ge q(x)\},

以及 Draft 高估集合

S={x:p(x)<q(x)}.S=\{x:p(x)<q(x)\}.
图 2

A、B 属于 Target 概率高于 Draft 的缺口项,C 属于 Draft 概率高于 Target 的盈余项。

原视频 · 01:40 ↗

本例中:

D={A,B},S={C}.D=\{A,B\},\qquad S=\{C\}.

AABB 的 Target 柱高高于 Draft,它们有待补的 deficit。

CC 的 Draft 柱高高于 Target,它携带需要削掉的 surplus。

3. deficit token 的直接提案全部接受

xDx\in D,则 p(x)/q(x)1p(x)/q(x)\ge1,因此

α(x)=1.\alpha(x)=1.

所以 AABB 被 Draft 直接提案时都沿接受边输出。

这条直接路径给 xx 的质量是

q(x)×1=q(x).q(x)\times1=q(x).

q(x)<p(x)q(x)<p(x),尚缺的 p(x)q(x)p(x)-q(x) 要由树的拒绝分支补齐。

4. surplus token 按 p/q 分流

xSx\in S,则 p(x)/q(x)<1p(x)/q(x)<1

本例对 CC

α(C)=0.40.8=0.5.\alpha(C)=\frac{0.4}{0.8}=0.5.
图 3

对 q(C)>p(C) 的 C,接受概率为 p(C)/q(C)=0.5,另一半质量进入拒绝分支。

原视频 · 01:00 ↗

概率树上,先走到 CC 的概率是 0.8,然后:

  • 以 0.5 接受,直接输出 CC
  • 以 0.5 拒绝,进入残差重采样。

直接输出 CC 的路径质量是

0.8×0.5=0.4=p(C).0.8\times0.5=0.4=p(C).

5. 总拒绝质量来自 Draft 的盈余

对一般 surplus token xx,拒绝概率为

1p(x)q(x).1-\frac{p(x)}{q(x)}.

乘上 Draft 提案概率,进入拒绝分支的质量为

q(x)(1p(x)q(x))=q(x)p(x).q(x)\left(1-\frac{p(x)}{q(x)}\right) =q(x)-p(x).
图 4

只有被 Draft 过度分配的候选会产生拒绝质量;这部分质量随后按 Target 的正残差重新分给缺口项。

原视频 · 02:00 ↗

把所有 surplus token 相加,得到总拒绝质量

R=xS(q(x)p(x)).R=\sum_{x\in S}(q(x)-p(x)).

本例只有 CC,所以

R=0.80.4=0.4.R=0.8-0.4=0.4.

6. 为什么总缺口必等于总盈余

因为 ppqq 都归一化:

xp(x)=xq(x)=1.\sum_x p(x)=\sum_x q(x)=1.

所以

x(p(x)q(x))=0.\sum_x(p(x)-q(x))=0.

把正项与负项移到等式两边:

xD(p(x)q(x))=xS(q(x)p(x))=R.\sum_{x\in D}(p(x)-q(x)) =\sum_{x\in S}(q(x)-p(x)) =R.

这条质量守恒保证:拒绝分支拿到的总质量,恰好足够填满所有 deficit。

7. 残差分布把拒绝质量按缺口比例分配

R>0R>0,定义

r(x)=(p(x)q(x))+R.r(x)=\frac{(p(x)-q(x))_+}{R}.

本例中

r(A)=0.10.4=0.25,r(B)=0.30.4=0.75,r(C)=0.r(A)=\frac{0.1}{0.4}=0.25, \qquad r(B)=\frac{0.3}{0.4}=0.75, \qquad r(C)=0.

于是整个拒绝分支给 AA 的质量为

Rr(A)=0.4×0.25=0.1,Rr(A)=0.4\times0.25=0.1,

BB 的质量为

Rr(B)=0.4×0.75=0.3.Rr(B)=0.4\times0.75=0.3.

8. deficit token 有两类到达路径

图 5

缺口 token 的最终概率由 Draft 直接提案路径与拒绝盈余后重采样到该 token 的校正路径共同组成。

原视频 · 02:20 ↗

AA 为例:

  • 直接路径:Draft 提案 AA 并接受,质量 0.1;
  • 校正路径:提案 surplus token、被拒绝、残差采到 AA,总质量 0.1。

所以

Pout(A)=0.1+0.1=0.2.P_{\text{out}}(A)=0.1+0.1=0.2.

同理

Pout(B)=0.1+0.3=0.4.P_{\text{out}}(B)=0.1+0.3=0.4.

9. surplus token 只有直接接受路径

残差分布对 surplus token 的概率为 0,因为 (p(x)q(x))+=0(p(x)-q(x))_+=0

因此 CC 不会从校正分支再次出现,只能由直接接受路径输出:

Pout(C)=0.8×0.5=0.4.P_{\text{out}}(C)=0.8\times0.5=0.4.
图 6

沿树把所有到达同一 token 的互斥路径概率相加,可分别得到 Target 指定的 0.2、0.4、0.4。

原视频 · 02:40 ↗

三项合起来正好是

(0.2,0.4,0.4)=p.(0.2,0.4,0.4)=p.

10. 一般逐点证明

对任意 token xx,直接接受路径贡献

q(x)α(x)=min(p(x),q(x)).q(x)\alpha(x)=\min(p(x),q(x)).

所有拒绝路径汇合后,再采到 xx 的贡献是

Rr(x)=(p(x)q(x))+.Rr(x)=(p(x)-q(x))_+.

两者相加:

Pout(x)=min(p(x),q(x))+(p(x)q(x))+=p(x).P_{\text{out}}(x) =\min(p(x),q(x))+(p(x)-q(x))_+ =p(x).

这个等式同时覆盖 deficit 与 surplus 两类 token。

11. R=0 的边界

R=0R=0,归一化守恒意味着没有 deficit,也没有 surplus,因此 p=qp=q

所有提案都以概率 1 接受。

此时 r(x)r(x) 的表达式会出现 0 作分母,但拒绝事件概率本身为 0;正确实现应跳过残差分支,而不是计算一个不会使用的 0/00/0

12. 概率树证明的范围

这棵树证明的是单个条件采样位置。

在多 token 投机解码中,需要对每个草稿位置使用该位置对应前缀下的 pip_iqiq_i 顺序验收。

一旦某位置拒绝,之后候选基于被拒绝分支,不能继续沿原树提交。

“保持目标分布”仍依赖精确计算这些条件概率和残差规则;它不承诺固定随机序列或固定性能收益。

跟练与练习

原视频定位

编者练习

q=(0.6,0.3,0.1)q=(0.6,0.3,0.1)p=(0.3,0.4,0.3)p=(0.3,0.4,0.3)。求总拒绝质量 RR、残差分布 rr,并核对第一个 token 的最终输出概率。

查看参考答案

第一个 token 是唯一 surplus,R=0.60.3=0.3R=0.6-0.3=0.3。正残差为 (0,0.1,0.2)(0,0.1,0.2),归一化后 r=(0,1/3,2/3)r=(0,1/3,2/3)。第一个 token 只能从直接接受路径输出,概率为 0.6×(0.3/0.6)=0.30.6\times(0.3/0.6)=0.3,等于 Target 概率。

编者练习 2

对上题第二个 token,分别计算直接路径和校正路径的质量。

查看参考答案

第二个 token 属于 deficit。直接提案并接受的质量为 q2=0.3q_2=0.3;拒绝分支再采到它的质量为 Rr2=0.3×1/3=0.1Rr_2=0.3\times1/3=0.1。总质量 0.40.4,等于 p2p_2

常见误区

  • 误区:概率树只画 Draft 提案分支即可。纠正:还必须展开接受、拒绝和拒绝后的残差重采样。
  • 误区:deficit token 只有校正路径。纠正:它先保留全部 Draft 直接提案质量,再由校正路径补缺口。
  • 误区:surplus token 也可从残差分布采到。纠正:其正残差为 0,只能由直接接受路径输出。
  • 误区:总拒绝质量是所有候选拒绝概率的简单和。纠正:必须乘上各候选的 Draft 提案概率,得到 (qp)+\sum(q-p)_+
  • 误区:R=0R=0 时算法失效。纠正:此时 p=qp=q,所有提案直接接受,残差分支无需执行。
  • 误区:单位置证明自动说明任何改版算法无损。纠正:树结构、条件前缀和验收规则发生改变时需要重新证明。

本课小结

  • 概率树把一次投机验收拆成 Draft 提案、Target 验收和拒绝后残差重采样。
  • deficit token 的直接提案全接受,并通过校正路径补齐 pqp-q
  • surplus token 按 p/qp/q 接受,只保留 Target 允许的质量。
  • 归一化保证总 deficit 等于总 surplus,也等于总拒绝质量 RR
  • 对每个 token 汇总互斥路径,可得 min(p,q)+(pq)+=p\min(p,q)+(p-q)_+=p
  • 该结论是条件分布等价;多 token 验收仍要按前缀顺序处理首次拒绝。
04

主题讲解 · 03:20

用概率质量柱状图证明投机解码无损

学习目标

  • 能把 Target 分布 pp 与 Draft 分布 qq 分解为重叠、缺口和盈余质量。
  • 能由归一化证明总缺口质量等于总盈余质量。
  • 能分别证明 Draft 高估和低估的 token 最终都得到 p(x)p(x) 的输出质量。
  • 能用一个逐点恒等式概括接受与残差重采样。
  • 能说明柱状图证明对离散分布和连续分布的不同表达方式。

前置与衔接

投机解码的一次校正使用两个条件分布:

  • Draft 提案分布 q(x)q(x)
  • Target 目标分布 p(x)p(x)

候选 xqx\sim q

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

接受;若拒绝,则从

r(x)(p(x)q(x))+r(x)\propto(p(x)-q(x))_+

重采样。

概率树能逐条枚举路径,但 token 多时会变得繁琐。

柱状图方法不依赖只有三个 token,而是直接比较每个 token 上的概率质量。

图 1

把 Target 柱高 p(x) 与 Draft 柱高 q(x) 叠放,可把每个 token 分成重叠质量、Target 缺口或 Draft 盈余。

原视频 · 00:20 ↗

核心讲解

1. 每根柱子分成共同质量与差额

对固定 token xx,把 p(x)p(x)q(x)q(x) 两根柱叠在一起。

共同覆盖的高度是

c(x)=min(p(x),q(x)).c(x)=\min(p(x),q(x)).

p(x)>q(x)p(x)>q(x),上方还缺一段 Target 质量:

d(x)=(p(x)q(x))+.d(x)=(p(x)-q(x))_+.

q(x)>p(x)q(x)>p(x),则 Draft 多出一段盈余:

s(x)=(q(x)p(x))+.s(x)=(q(x)-p(x))_+.

对每个 xxd(x)d(x)s(x)s(x) 不会同时为正。

2. 总缺口等于总盈余

因为两个分布都归一化:

xp(x)=1,xq(x)=1.\sum_x p(x)=1, \qquad \sum_x q(x)=1.

因此

x(p(x)q(x))=0.\sum_x(p(x)-q(x))=0.

把正差与负差分开,就得到

xd(x)=xs(x).\sum_xd(x)=\sum_xs(x).
图 2

因为 p、q 都归一化为 1,所有 Target 缺口面积之和必等于所有 Draft 盈余面积之和。

原视频 · 00:40 ↗

记这个共同总量为

R=xd(x)=xs(x).R=\sum_xd(x)=\sum_xs(x).

它既是 Draft 多分配的总质量,也是验收规则产生的总拒绝质量。

3. 接受步骤保留两根柱的重叠部分

候选 xx 被 Draft 采到的概率为 q(x)q(x)

再乘接受概率:

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

所以接受步骤的几何意义非常直接:对每根 Draft 柱,只保留它与 Target 柱重叠的部分。

多出来的 Draft 柱高会按概率被裁掉。

4. 先证明 Draft 高估的 token

q(x)>p(x)q(x)>p(x),这个 token 有 surplus。

它的正残差为

(p(x)q(x))+=0,(p(x)-q(x))_+=0,

因此不可能从拒绝后的残差分布再次采到。

图 3

对 q(x)>p(x) 的盈余 token,正残差为零,最终保留它的质量只来自直接接受路径。

原视频 · 01:20 ↗

它唯一的输出来源是直接接受:

Pout(x)=q(x)p(x)q(x)=p(x).P_{\text{out}}(x) =q(x)\frac{p(x)}{q(x)} =p(x).
图 4

盈余 token 的直接输出质量 q(x)×p(x)/q(x)=p(x),接受比值恰好消去 Draft 多分配的柱高。

原视频 · 01:40 ↗

接受比值 p/qp/q 恰好把高于 Target 的 Draft 柱裁到 Target 高度。

5. 再证明 Draft 低估的 token

p(x)>q(x)p(x)>q(x),接受概率被截断为 1。

所以直接提案路径先贡献

q(x).q(x).

它距离 Target 还差

p(x)q(x)=d(x).p(x)-q(x)=d(x).
图 5

对 p(x)>q(x) 的缺口 token,先保留直接提案的 q(x),再由总拒绝质量补入 p(x)-q(x)。

原视频 · 02:20 ↗

拒绝后的残差分布定义为

r(x)=d(x)R,R>0.r(x)=\frac{d(x)}{R},\qquad R>0.

整个拒绝事件发生的总概率正是 RR,所以校正路径给该 token 的质量为

Rr(x)=Rd(x)R=d(x)=p(x)q(x).Rr(x)=R\frac{d(x)}{R}=d(x)=p(x)-q(x).

两条路径相加:

Pout(x)=q(x)+p(x)q(x)=p(x).P_{\text{out}}(x) =q(x)+p(x)-q(x) =p(x).
图 6

每个缺口柱最终由 q(x)+(p(x)-q(x)) 恢复为 p(x),因此所有 token 的输出分布逐点等于 Target。

原视频 · 03:00 ↗

6. 一个恒等式覆盖所有 token

无需逐类讨论时,可以把结果写成

Pout(x)=min(p(x),q(x))直接接受+(p(x)q(x))+拒绝后校正.P_{\text{out}}(x) =\underbrace{\min(p(x),q(x))}_{\text{直接接受}} +\underbrace{(p(x)-q(x))_+}_{\text{拒绝后校正}}.

对任意实数 a,ba,b,都有

min(a,b)+(ab)+=a.\min(a,b)+(a-b)_+=a.

a=p(x),b=q(x)a=p(x),b=q(x),立即得到

Pout(x)=p(x).P_{\text{out}}(x)=p(x).

这就是投机解码单位置“无损”的逐点证明。

7. 为什么柱状图比特定概率树更一般

三 token 概率树容易让人误以为只有一个 surplus token 被拒绝,再补给两个 deficit token。

柱状图则允许:

  • 多个 surplus token;
  • 多个 deficit token;
  • 任意词表大小;
  • p(x)=q(x)p(x)=q(x) 的完全重叠项。

无论各有多少项,只要 p,qp,q 都归一化,所有盈余汇成的拒绝质量就等于所有缺口之和。

残差重采样不是从某一个特定红色柱子“直接跳”到另一个柱子,而是先汇总所有拒绝质量,再按所有正残差归一化分配。

8. p=q 与零概率的边界

p=qp=q,则 R=0R=0,所有柱子完全重叠,全部候选直接接受。

残差分布在形式上分母为 0,但拒绝事件不可能发生,算法直接跳过该分支。

q(x)=0q(x)=0,Draft 永远不会直接提案该 token,因此无需在实际提案路径计算 p(x)/q(x)p(x)/q(x);它可能通过正残差分支获得质量。

p(x)=0<q(x)p(x)=0<q(x),该候选接受概率为 0,一定被拒绝。

数值实现需要避免无条件计算所有位置的比值造成除零或 NaN。

9. 从离散柱子到连续密度

语言模型词表是有限离散集合,柱状图和求和表达最自然。

对连续分布,直觉可以类比为密度曲线下的面积,但需要把求和改成积分:

R=(q(x)p(x))+dx=(p(x)q(x))+dx.R=\int(q(x)-p(x))_+\,dx =\int(p(x)-q(x))_+\,dx.

此时讨论的是相对于同一基准测度的密度,而不是字面上无穷多根独立柱子。

10. 无损结论的算法边界

证明成立需要:

  • ppqq 是同一候选空间上的归一化条件分布;
  • 接受概率确实使用 min(1,p/q)\min(1,p/q)
  • 拒绝后确实从归一化正残差采样;
  • 每个多 token 位置使用对应因果前缀下的 pi,qip_i,q_i
  • 数值近似没有改变算法所声称的精确性。

“无损”只表示最终条件分布为 Target 分布,不表示随机轨迹、延迟或接受率不变。

跟练与练习

原视频定位

编者练习

设某 token 满足 q(x)=0.18q(x)=0.18p(x)=0.30p(x)=0.30,总拒绝质量 R=0.24R=0.24。计算它的直接输出质量、残差采样概率和校正输出质量。

查看参考答案

该 token 属于 deficit,直接提案全部接受,直接质量为 0.18。它的正残差为 0.300.18=0.120.30-0.18=0.12,所以残差采样概率 r(x)=0.12/0.24=0.5r(x)=0.12/0.24=0.5。校正质量为 Rr(x)=0.24×0.5=0.12Rr(x)=0.24\times0.5=0.12,总输出质量为 0.18+0.12=0.300.18+0.12=0.30

编者练习 2

为什么不能对每个被拒绝的 surplus token 单独只补给一个固定 deficit token?

查看参考答案

一般情况下有多个 surplus 和多个 deficit,固定一一配对会依赖人为配对方式,未必逐点恢复 pp。正确做法是汇总全部拒绝质量 RR,再按所有正残差 (pq)+(p-q)_+ 的比例分配;这样每个 deficit 恰好获得自己的缺口质量。

常见误区

  • 误区:两分布不同时,总缺口可能大于总盈余。纠正:只要二者都归一化,总正差必等于总负差的绝对值。
  • 误区:接受步骤保留完整的 Draft 柱。纠正:它只保留 min(p,q)\min(p,q) 的重叠质量。
  • 误区:surplus token 还能从残差分支返回。纠正:它的 (pq)+(p-q)_+ 为 0。
  • 误区:deficit token 只靠残差分支。纠正:它先有 q(x)q(x) 的直接质量,再补 p(x)q(x)p(x)-q(x)
  • 误区:R=0R=0 时必须构造均匀残差。纠正:此时不发生拒绝,残差分支不应被调用。
  • 误区:柱状图证明意味着任何近似验收都无损。纠正:改变接受率、残差分布或条件前缀后必须重新证明。

本课小结

  • 每个 token 的 Target 与 Draft 柱可拆成重叠、缺口和盈余质量。
  • 归一化保证总缺口等于总盈余,也等于总拒绝质量 RR
  • 直接接受路径贡献 min(p,q)\min(p,q)
  • 拒绝后的残差路径贡献 (pq)+(p-q)_+
  • 逐点恒等式 min(p,q)+(pq)+=p\min(p,q)+(p-q)_+=p 证明最终输出分布等于 Target。
  • 该证明面向标准验收规则的条件分布;连续情形需用密度和积分表述。
05

主题讲解 · 03:18

投机解码为何把串行 Decode 变成块状验证

学习目标

  • 能从 Prefill 与 Decode 的计算形态解释投机解码的潜在加速来源。
  • 能描述 Draft 串行提案和 Target 块状验证之间的分工。
  • 能解释 Target 验证为何能在一个因果前向中计算多个位置,而不是并行生成未知 token。
  • 能正确处理 Draft、Target 各自的 KV Cache 以及拒绝后的提交边界。
  • 能用简单成本模型判断何时可能加速,并识别视频示意调度的版本边界。

前置与衔接

自回归大模型推理通常分成两种阶段:

  • Prefill:一次处理一段已知输入 token,矩阵较大,并行度较高;
  • Decode:每次新增一个未知 token,只处理当前一步,常更受内存带宽与调度开销限制。

普通生成让大型 Target 模型连续执行 Decode。

投机解码则让便宜的 Draft 模型先串行生成一小段候选,再让 Target 把这段已知候选组织成一次块状验证。

图 1

Draft 与 Target 都先处理确认前缀,并各自建立独立 KV Cache;模型参数和缓存不能混用。

原视频 · 00:40 ↗

这里的目标不是减少 Target 参数量,而是改变大型模型一次前向所处理的 token 数和计算形态。

核心讲解

1. 普通 Decode 为什么难以充分并行

在普通自回归生成中,第 t+1t+1 个 token 必须等第 tt 个 token 被采样后才能确定输入。

所以大型模型按如下链条运行:

xt+1p(xt),x_{t+1}\sim p(\cdot\mid x_{\le t}),
xt+2p(xt+1),x_{t+2}\sim p(\cdot\mid x_{\le t+1}),

依次向后。

单次 Decode 的 query 长度通常为 1。

模型权重很大,却只为一个新位置执行计算,容易出现算术强度不高、硬件利用不足或 kernel 启动占比明显的情况。

不同模型、batch 和硬件的瓶颈不完全相同,因此不能把 Decode 一概写成某个固定百分比的 GPU 利用率。

2. 投机解码把便宜的串行工作交给 Draft

设 Draft 一轮提出 γ\gamma 个候选:

y1,y2,,yγ.y_1,y_2,\ldots,y_\gamma.

这些候选仍然具有因果依赖:

q(y1:γxt)=i=1γq(yixt,y<i).q(y_{1:\gamma}\mid x_{\le t}) =\prod_{i=1}^{\gamma} q(y_i\mid x_{\le t},y_{<i}).

因此 Draft 也要串行 Decode,并非同时独立猜出 γ\gamma 个 token。

图 2

Draft 通过便宜但仍有因果依赖的串行 Decode 提出候选,并把每步 K/V 追加到自己的缓存。

原视频 · 01:40 ↗

加速机会来自 Draft 每一步显著便宜:它可能参数更少、层数更浅,或采用其他低成本提案机制。

如果 Draft 并不便宜,这段额外串行工作反而可能抵消所有收益。

3. 候选一旦给定,Target 可以按块计算

Draft 生成后,y1:γy_{1:\gamma} 已经是已知输入。

Target 可以把这段候选接在已确认前缀的 KV Cache 之后,在一次带因果掩码的前向中处理多个位置。

这常被称为 chunked verification 或 incremental prefill。

对候选位置 ii,Target 需要的分布是

pi=p(xt,y<i).p_i=p(\cdot\mid x_{\le t},y_{<i}).

一个块状前向可同时产生这些位置的隐藏状态和对齐的 logits。

图 3

Target 对已知候选块做一次带因果掩码的增量 Prefill,并产生与候选位置错一位对齐的条件分布。

原视频 · 02:40 ↗

“同时产生”是计算调度层面的并行:causal mask 仍保证第 ii 行只能读取合法前缀。

它不是说 y1,,yγy_1,\ldots,y_\gamma 在概率上互相独立,也不是 Target 在一次操作里凭空生成了多个未知 token。

4. 为什么块状验证更像 Prefill

普通 Decode 的新 token 维度为 1,许多线性层更接近矩阵—向量或很瘦的矩阵乘。

块状验证一次输入 γ\gamma 个或更多已知位置,线性层和注意力投影可形成更宽的矩阵乘。

相对而言,这可能:

  • 提高对大模型权重读取的复用;
  • 提高 GEMM 的并行度;
  • 减少每个被验证 token 平均承担的启动和调度开销;
  • 让 Target 一次给出多个条件分布。

但它仍需要读取权重、计算多个位置并访问更长的 KV Cache。

所以“验证多个 token 几乎等于一次 Decode”只能作为某些硬件和长度范围的经验近似,不能当作复杂度恒等式。

5. 视频中的三 token 示例

视频采用一种便于板书说明的调度:Target 先从前缀末端 logits 采一个锚点,然后 Draft 串行产生两个候选,组成三个 token 的验证块。

图 4

视频采用 Target 前缀末端 logits 先采一个锚点的示意调度;标准实现也可直接让 Draft 从已确认前缀提出候选。

原视频 · 01:20 ↗

例如把这三个 token 记为

[a,y1,y2],[a,y_1,y_2],

其中 aa 是 Target 给出的锚点,y1,y2y_1,y_2 是 Draft 后续提案。

图 5

视频例把一个 Target 锚点与 Draft 随后生成的两个 token 组成三 token 验证块。

原视频 · 02:20 ↗

Target 对三个已知位置做增量 Prefill,可得到错一位对齐的后续分布:

  • aa 所在位置的 logits 检查 y1y_1
  • y1y_1 所在位置的 logits 检查 y2y_2
  • y2y_2 所在位置的 logits 可在全部接受时产生奖励 token。

6. 调度版本边界:并非都要 Target 先采锚点

更常见的标准投机解码描述是:从当前已确认前缀出发,Draft 直接提出 γ\gamma 个候选;Target 在一次块状前向中给出验证这些候选所需的条件分布,并在全接受时提供额外的下一 token 分布。

它不要求每轮都先由 Target 单独采一个新 token,再让 Draft 开始。

视频的锚点画法可以帮助解释 logits 与 token 的错位关系,也可能对应某种具体调度;但不能推广成所有实现的统一规则。

阅读框架代码时,应以真实输入块、缓存边界和 logits 对齐方式为准。

7. 全接受时为什么还可能多提交一个 token

Target 对候选块的最后一个位置也产生了“下一个 token”分布。

若所有 Draft 候选都通过验收,这份分布基于有效前缀,可以再采一个奖励 token。

图 6

若候选全部接受,Target 最后一个位置的分布还能采样奖励 token;若中途拒绝,只提交接受前缀与校正 token。

原视频 · 03:00 ↗

若 Draft 提出 γ\gamma 个候选,标准单链算法在全接受路径通常最多提交

γ+1\gamma+1

个 token。

但若第 jj 个候选被拒绝,之后候选都基于错误分支,只能提交已接受前缀,再从 Target 校正分布产生替代 token。

实际每轮提交数取决于接受长度,不固定等于 γ+1\gamma+1

8. Draft 与 Target 的 KV Cache 不能混用

两个模型参数不同,各层 K/V 的 head 数、维度、数值和层数也可能不同。

因此 Draft 和 Target 各自维护缓存:

  • Draft Cache 支持便宜的串行提案;
  • Target Cache 支持块状验证和后续正式生成。

候选被验证时,Target 会为候选位置算出新的 K/V,但只有最终接受的前缀可以提交为长期缓存状态。

若在第 jj 个候选拒绝:

  • 接受位置之前的 Target K/V 可以保留;
  • 被拒绝位置之后的投机 K/V 必须丢弃、回滚或通过框架的页表语义解除提交;
  • 校正 token 需要按实际调度追加到有效缓存。

Draft 的候选缓存也要与最终接受前缀重新对齐。

若无条件保留整个验证块的 K/V,后续注意力会读取未被接受的 token,语义就错了。

9. 一个简化的速度模型

设:

  • Draft 单步 Decode 时间为 tdt_d
  • Draft 每轮提案长度为 γ\gamma
  • Target 验证这段候选的时间为 tv(γ)t_v(\gamma)
  • 一轮期望提交的新 token 数为 mm
  • Target 普通单步 Decode 时间为 tTt_T

投机一轮的近似时间是

Tspecγtd+tv(γ)+toverhead.T_{\text{spec}}\approx\gamma t_d+t_v(\gamma)+t_{\text{overhead}}.

普通 Target 生成同样 mm 个 token 的时间约为

TbasemtT.T_{\text{base}}\approx m t_T.

只有当

γtd+tv(γ)+toverhead<mtT\gamma t_d+t_v(\gamma)+t_{\text{overhead}}<m t_T

时才获得加速。

这里 mm 由接受率和首次拒绝位置决定;Draft 越准确,平均接受长度通常越长。

10. 为什么草稿长度不是越大越好

增大 γ\gamma 有两面性:

  • 可能一次验证并提交更多 token;
  • Draft 串行成本增加;
  • Target 验证块更长;
  • 越靠后的候选越可能在前面已有拒绝后变成无效计算;
  • KV 临时空间和调度复杂度增加。

最优草稿长度与模型对、序列长度、batch、GPU、kernel、采样设置和业务延迟目标有关。

很多系统会根据近期接受长度动态调整 γ\gamma,而不是使用一个永远最优的固定值。

11. 分布无损与系统加速是两件事

接受—拒绝—残差重采样证明的是:正确实现时,最终输出条件分布保持 Target 等价。

Prefill/Decode 分析回答的是:这样的计算重排是否更快。

前者是概率正确性,后者是系统性能。

即使验收规则无损,也可能因 Draft 太慢、接受率太低、batch 已足够大或验证 kernel 不理想而没有加速。

反之,任何为了更快而改动概率、过滤顺序或验收近似的实现,都需要单独说明它是否仍保持严格分布等价。

跟练与练习

原视频定位

编者练习

某系统每轮让 Draft 提案 γ=4\gamma=4 个 token,Draft 单步耗时 0.2 ms,Target 验证块耗时 1.5 ms,其他开销 0.2 ms;Target 普通 Decode 每 token 1.0 ms。若一轮平均提交 3 个 token,是否比普通生成快?

查看参考答案

投机一轮耗时约为 4×0.2+1.5+0.2=2.54\times0.2+1.5+0.2=2.5 ms。普通 Target 生成 3 个 token 约为 3.0 ms,因此该简化模型下有约 3.0/2.5=1.23.0/2.5=1.2 倍加速。若平均只提交 2 个 token,普通基线是 2.0 ms,投机反而更慢。

编者练习 2

Target 一次验证 4 个候选,第二个候选被拒绝。哪些候选位置的 Target KV 可以提交?为什么不能保留后两个候选的 KV?

查看参考答案

只能提交拒绝位置之前已经接受的第一个候选对应 KV,并按具体实现处理第二个位置的校正 token。第三、第四个候选建立在“第二个候选已接受”的错误前缀上;既然第二个候选被拒绝,它们的 K/V 上下文已失效,必须丢弃或回滚。

常见误区

  • 误区:Draft 的多个候选是并行生成的。纠正:单链 Draft 仍按因果顺序串行 Decode。
  • 误区:Target 并行验证表示候选互相独立。纠正:候选已知后可在一个 causal forward 中计算,掩码仍保留依赖。
  • 误区:验证 γ\gamma 个 token 的时间恒等于一次 Decode。纠正:延迟取决于块长、上下文、batch、硬件和 kernel,只可能在特定区间摊薄成本。
  • 误区:每轮必须先由 Target 采一个锚点。纠正:这是视频的示意调度;常见标准描述允许 Draft 直接从确认前缀提案。
  • 误区:Draft 与 Target 共用一份 KV Cache。纠正:模型参数和层内表示不同,只能各自维护缓存。
  • 误区:Target 验证时生成的所有 K/V 都能保留。纠正:只能提交最终接受前缀,拒绝后的投机后缀必须回滚。
  • 误区:投机解码无损就一定更快。纠正:分布正确性与系统速度是两套独立条件。

本课小结

  • 普通 Target Decode 每次只处理一个未知位置,难以像 Prefill 那样形成宽矩阵计算。
  • 投机解码让便宜 Draft 串行提出候选,再让 Target 对已知候选块做一次因果增量 Prefill。
  • 块状验证并没有取消自回归依赖,只是把已知候选位置组织进同一个前向。
  • 全接受时,Target 最末分布还能提供奖励 token;中途拒绝时只能提交接受前缀和校正 token。
  • Draft、Target 分别维护 KV Cache,Target 只提交有效接受前缀。
  • 是否加速取决于 Draft 成本、验证成本、平均接受长度和系统开销;视频的锚点调度不是唯一实现。
06

主题讲解 · 02:41

为什么 K 个草稿最多产出 K+1 个 Token

学习目标

  • 能区分锚点 token、草稿 token 与奖励 token。
  • 能解释 Target 为什么一次得到 K+1K+1 份概率分布。
  • 能把每份分布与验收位置一一对齐。
  • 能说明 K+1K+1 是全接受路径的上界,而非每轮固定产出。
  • 能避免把 Target 的并行验收误解成并行自回归生成。

前置与衔接

投机解码让小型 Draft 模型先便宜地提出若干候选,再由大型 Target 模型批量验收。

设当前已经确认的最后一个 token 为锚点 xtx_t,Draft 接着提出

y1,y2,,yK.y_1,y_2,\ldots,y_K.

本课只追问一个计数问题:明明 Draft 只提出 KK 个候选,为什么最好的一轮却能提交 K+1K+1 个新 token?

图 1

当 K 个草稿 token 全部通过验收时,一轮投机解码最多可以提交 K+1 个 token。

原视频 · 00:00 ↗

答案不在 Draft 多猜了一次,而在 Target 的一次前向计算天然多得到一个“下一位置”的分布。

核心讲解

1. 从 Target Prefill 得到锚点

Target 模型先对 prompt 做 Prefill。

每一层都为 prompt 建立 K/V,最后一个位置的隐藏状态经过词表投影,得到下一个 token 的概率分布。

图 2

Target 模型先对 prompt 做 Prefill,逐层建立前缀 KV Cache,并在最后位置得到下一 token 分布。

原视频 · 00:40 ↗

从该分布采样出的 token 记为 xtx_t

视频强调:这个首个锚点由 Target 产生,不是让 Draft 从 prompt 末尾先猜一个再回头验收。

图 3

Prefill 结束后,首个锚点 token 由 Target 模型采样,再交给 Draft 模型继续提出候选。

原视频 · 01:00 ↗

这让后续 Draft 路径从一个已经受 Target 确认的上下文开始。

2. Draft 串行提出 K 个候选

Draft 收到 xtx_t 后开始普通自回归 Decode。

它先根据当前前缀采样 y1y_1,把 y1y_1 对应的 K/V 追加到自己的缓存,再采样 y2y_2,如此继续到 yKy_K

图 4

Draft 模型沿锚点 token 串行 Decode,每生成一个候选就把相应 K/V 追加到自己的缓存。

原视频 · 01:20 ↗

因此候选满足链式依赖:

q(y1:Kxt)=i=1Kq(yixt,y<i).q(y_{1:K}\mid x_{\le t}) =\prod_{i=1}^{K}q(y_i\mid x_{\le t},y_{<i}).

“提出 KK 个草稿”意味着 Draft 执行了 KK 个条件采样位置,而不是同时独立猜 KK 个词。

3. Target 把 K+1 个输入位置一起算

验收时,Target 接收

[xt,y1,y2,,yK].[x_t,y_1,y_2,\ldots,y_K].

在已有前缀 KV Cache 之后,这相当于一次长度为 K+1K+1 的 incremental prefill。

因果掩码保证每一行只能看到它左侧已经给出的 token,所以这些行可以在同一次矩阵计算中并行完成。

图 5

Target 模型把锚点与 K 个草稿 token 作为一次增量 Prefill,并行得到 K+1 个位置的概率分布。

原视频 · 02:00 ↗

长度为 K+1K+1 的输入,会产生 K+1K+1 个隐藏状态,也就对应 K+1K+1 份“下一个 token”分布。

4. 分布与候选怎样错一位对齐

把 Target 得到的分布记为 p1,,pK+1p_1,\ldots,p_{K+1}

其语义是:

  • 锚点 xtx_t 所在行的 p1p_1 用来检查 y1y_1
  • y1y_1 所在行的 p2p_2 用来检查 y2y_2
  • 依此类推,pKp_K 检查 yKy_K
  • yKy_K 所在行的 pK+1p_{K+1} 预测草稿序列之后的新位置。

可写成

pi=p(xt,y<i),1iK+1.p_i=p(\cdot\mid x_{\le t},y_{<i}),\qquad 1\le i\le K+1.

iKi\le K,存在草稿候选 yiy_i 可供验收。

i=K+1i=K+1,Draft 没有再提供候选,但 Target 已经把这一分布顺手算出来了。

5. 最后一份分布就是奖励 token 的来源

y1y_1yKy_K 全部通过验收,当前有效上下文已经延伸到 yKy_K

这时 pK+1p_{K+1} 正好是在该有效上下文之后的 Target 分布,可以直接从中采样奖励 token zz

zpK+1.z\sim p_{K+1}.
图 6

前 K 个分布用于验收草稿;若全部通过,最后一个仅由 Target 给出的分布可再采样一个奖励 token。

原视频 · 02:20 ↗

于是本轮提交

[y1,y2,,yK,z],[y_1,y_2,\ldots,y_K,z],

总数正好是 K+1K+1

6. 为什么不是 K+2

Target 这次只对 K+1K+1 个输入位置计算了隐藏状态。

最后一份分布能采样 zz,但要继续得到 zz 之后的分布,必须再把 zz 送入模型做一次新的前向计算。

因此当前批次没有足够信息再免费产生第二个奖励 token。

这也是 K+1K+1 上界的计算边界,而不是经验规则。

7. K+1 不是每轮固定吞吐

若第 jj 个草稿被拒绝,则 yjy_j 之后的草稿都基于错误分支,不能直接提交。

该轮通常只提交已经接受的前缀,再从 Target 对应的修正分布产生替代 token。

因此实际产出取决于接受位置:

  • 全部接受:最多 K+1K+1
  • 中途拒绝:接受前缀加一个替代 token;
  • 第一个就拒绝:仍可产出一个 Target 等价 token。

最后一种情况会在下一课专门展开。

8. 并行的是验收计算,不是条件依赖

Target 能一次算多行,是因为候选 token 已经由 Draft 给定。

这并没有取消因果关系。

每一行仍通过 causal mask 只读取合法前缀;只是 GPU 可以把这些已知输入行组织成 GEMM,而不必像未知 token 生成那样逐个采样。

所以更准确的表述是:

9. 版本与算法边界

本课解释视频展示的标准投机解码计数关系。

不同推理框架可能在调度、草稿树、验收规则或一次提出的候选结构上有所变化。

若算法不再是单链 KK 个草稿,输出上界需要按其实际验证图重新计算,不能机械套用 K+1K+1

跟练与练习

原视频练习

编者练习

Draft 提出 4 个 token,Target 一次验证输入包含锚点和这 4 个候选。若全部接受,本轮最多提交多少个新 token?第五个 token 来自哪里?

查看参考答案

最多提交 5 个。Target 对 5 个输入位置得到 5 份下一 token 分布;前 4 份分别验收 4 个草稿,最后一份是在第 4 个草稿之后的 Target 分布,可再采样 1 个奖励 token。

编者练习 2

为什么不能从最后一份分布连续采样两个奖励 token?

查看参考答案

第一次采样得到奖励 token 后,上下文发生了扩展。要得到它之后的条件分布,必须把该 token 再送入模型计算新的隐藏状态。现有前向只提供到第一个奖励 token 的分布,不能凭同一分布连续生成两个自回归位置。

常见误区

  • 误区:Draft 猜 K+1K+1 个,Target 只验 KK 个。纠正:Draft 只猜 KK 个,额外 token 来自 Target 最后一份分布。
  • 误区:锚点也属于本轮 KK 个草稿。纠正:它已由 Target 产生,是 Draft 提案的起点。
  • 误区:Target 并行算出 K+1K+1 个互相独立的 token。纠正:它并行评估已知候选位置,因果依赖仍由掩码保留。
  • 误区:每轮一定输出 K+1K+1。纠正:只有所有草稿都通过时才得到奖励 token。
  • 误区:最后一份分布可以无限继续采样。纠正:采样一个 token 后必须重新计算新的条件分布。
  • 误区:任何树状投机算法都满足同一个上界。纠正:K+1K+1 针对视频中的单链候选结构。

本课小结

  • Target 先产生锚点,Draft 再串行提出 KK 个候选。
  • Target 对锚点加 KK 个草稿做一次长度 K+1K+1 的增量 Prefill。
  • KK 份分布验收草稿,最后一份分布预测草稿末端之后的位置。
  • 全接受时可从最后一份分布采样奖励 token,因此最多提交 K+1K+1 个。
  • 中途拒绝时达不到上界;并行验收也没有取消自回归条件关系。
07

主题讲解 · 02:32

首个草稿被拒也能保证前进一步

学习目标

  • 能描述投机解码一轮的最好与最坏接受路径。
  • 能解释首个草稿被拒后,为什么后续候选全部失效。
  • 能指出 Target 已经计算好的哪份分布可以继续使用。
  • 能区分“直接从 Target 分布采样”与精确投机采样的修正分布。
  • 能说明“至少一个 token”是进度下界,不是固定吞吐。

前置与衔接

上一课已经得到最好情况:Draft 提出 KK 个候选且全部通过时,Target 可再从最后一份分布采样奖励 token,一轮最多提交 K+1K+1 个。

本课看相反极端:第一个草稿就被拒绝。

图 1

即使第一个草稿 token 就被拒绝,精确投机采样的一轮仍至少能产出一个 Target 等价 token。

原视频 · 00:00 ↗

直觉上,既然草稿一个都不能用,这轮似乎会“白跑”。

但 Target 的批量验收已经为第一个位置算出了真实分布,精确拒绝重采样可以据此产生替代 token,所以进度不会归零。

核心讲解

1. 先统一一轮投机解码的记号

设当前已确认前缀为 xtx_{\le t},Draft 分布为 qq,Target 分布为 pp

Draft 串行提出

y1,y2,,yK.y_1,y_2,\ldots,y_K.

Target 随后一次计算锚点与这些候选位置。

图 2

Draft 模型串行提出候选,Target 模型再通过一次增量 Prefill 并行计算验收所需分布。

原视频 · 00:20 ↗

于是 Target 得到

pi()=p(xt,y<i),p_i(\cdot)=p(\cdot\mid x_{\le t},y_{<i}),

其中 pip_i 用于判断候选 yiy_i 是否可以接受。

2. 第一个候选为何是最坏情况

y1y_1 被拒,真正输出的第一个新 token 就不会是 y1y_1

y2y_2 是 Draft 在“前一个 token 等于 y1y_1”的条件下生成的:

y2q(xt,y1).y_2\sim q(\cdot\mid x_{\le t},y_1).

一旦 y1y_1 被替换,y2y_2 所依赖的上下文分支就不再存在。

同理,y3y_3yKy_K 也都沿着被拒绝的分支生成,不能跳过 y1y_1 后继续提交。

图 3

若第一个草稿 token 被拒,后续候选因依赖了错误分支而失效,但第一个位置的 Target 分布已经算出。

原视频 · 02:00 ↗

所以从“接受草稿数量”看,首个候选被拒确实是零。

3. 但 Target 的第一次验证分布没有失效

Target 在验收批次里已经算出

p1()=p(xt).p_1(\cdot)=p(\cdot\mid x_{\le t}).

它只依赖已确认前缀,不依赖被拒的 y1y_1

因此即使整条 Draft 尾部失效,p1p_1 仍是合法的 Target 下一 token 分布。

这就是最坏路径仍能推进的计算基础。

4. 视频所说的“拒绝采样”在做什么

视频把拒绝后的动作概括为:利用 Target 已经算出的概率,重新采样一个 token,尤其补偿 Draft 低估的 token。

图 4

拒绝后从修正分布重采样替代 token,使输出分布保持与 Target 一致,并保证本轮仍前进一步。

原视频 · 02:20 ↗

这个替代 token 取代 y1y_1,成为本轮唯一提交的新 token。

下一轮再从它之后继续生成。

5. 编者补充:精确算法不是简单再采一次 p

下面给出经典精确投机采样的标准写法,作为视频直觉的公式补全。

若 Draft 从 qiq_i 提出 yiy_i,常见接受概率为

αi=min(1,pi(yi)qi(yi)).\alpha_i=\min\left(1,\frac{p_i(y_i)}{q_i(y_i)}\right).

若候选被拒,替代 token 不是无条件再从 pip_i 抽一次,而是从残差分布采样:

ri(x)=[pi(x)qi(x)]+v[pi(v)qi(v)]+,r_i(x)= \frac{[p_i(x)-q_i(x)]_+} {\sum_v[p_i(v)-q_i(v)]_+},

其中 [a]+=max(a,0)[a]_+=\max(a,0)

这个修正恰好把 Draft 过度提出的概率质量扣掉,把质量补到 Draft 相对低估的 token 上。

将“接受 Draft 候选”和“拒绝后从残差重采样”合在一起,最终边缘分布仍与 Target 的 pip_i 一致。

这段公式是编者依据经典精确投机采样补充;具体框架可能采用等价实现或不同验收变体。

6. 为什么至少能产出一个 token

现在可以分情况证明进度下界。

y1y_1 被接受,则本轮至少已经提交 y1y_1

y1y_1 被拒,则从 r1r_1 采样替代 token zz,本轮提交 zz

因此无论第一步接受与否,都会产生一个合法的新 token:

Noutput1.N_{\text{output}}\ge 1.

若采样结果是 EOS,它仍是一个生成 token,只是序列随即结束。

7. Target 一次计算覆盖最好与最坏路径

K=2K=2 为例,Target 输入锚点加两个草稿,会得到三份分布。

图 5

Target 对锚点和两个草稿做并行计算时得到三份分布:前两份验收候选,最后一份可在全接受时生成奖励 token。

原视频 · 01:40 ↗
  • p1p_1 验收 y1y_1
  • p2p_2 验收 y2y_2
  • p3p_3 在两者全接受时采样奖励 token。

最好情况使用三份分布,提交 y1,y2y_1,y_2 与奖励 token。

最坏情况只使用 p1p_1 对应的验收与残差分布,提交一个替代 token。

因此一轮产出范围是 1 到 K+1K+1,实际值取决于第一个拒绝位置。

8. 首 token 合并只是小型调度优化

视频还回顾了一个实现技巧:Target 先生成锚点,再把它追加到 Draft Prefill 输入。

图 6

把 Target 采样的锚点 token 并入 Draft Prefill,可以省去 Draft 的第一次独立 Decode。

原视频 · 01:00 ↗

这样 Draft Prefill 的最后一行可直接产生 y1y_1,省去一次独立 Draft Decode。

这项优化改变的是草稿生成的调度成本,不改变“拒绝后至少输出一个 token”的概率正确性证明。

后面的课程会单独分析它的前提和版本边界。

9. 进度下界不等于性能保证

“每轮至少一个 token”只说明算法不会因为拒绝而原地踏步。

若 Draft 与 Target 分布差异大,接受率低,许多轮都只输出一个 token,却仍付出 Draft 生成和 Target 批量验收的额外成本。

端到端是否加速还取决于:

  • Draft 生成成本;
  • Target 批量长度和内核效率;
  • 候选接受率;
  • 调度与 KV Cache 管理开销;
  • batch、硬件与服务负载。

进度正确性与系统加速是两个不同结论。

10. 算法与版本边界

本课的残差公式针对经典“保持 Target 分布不变”的精确投机采样。

某些近似解码、树状草稿、贪心验收或框架特定算法会使用不同规则。

判断实现时应查对应版本的验收代码或论文,不能只凭“speculative decoding”这一名称断定公式完全相同。

跟练与练习

原视频练习

编者练习

Draft 提出 y1,y2,y3y_1,y_2,y_3。若 y1y_1 被拒,为什么不能保留看起来概率很高的 y2y_2?本轮怎样继续?

查看参考答案

y2y_2 是在前缀包含 y1y_1 的条件下产生的。拒绝 y1y_1 后,实际上下文分支已经改变,y2y_2 的条件分布不再对应真实路径,因此连同后续候选一起失效。精确投机采样从第一个位置的残差分布产生替代 token,本轮仍提交一个 token。

编者练习 2

若 Draft 分布恰好等于 Target 分布,即 q=pq=p,接受率和最坏路径会怎样?

查看参考答案

对 Draft 实际采到的 token,接受概率 min(1,p/q)=1\min(1,p/q)=1,因此不会进入拒绝残差路径。单链的 KK 个候选会全部接受,再由 Target 的最后一份分布采样奖励 token。

常见误区

  • 误区:首个草稿被拒,这轮没有任何输出。纠正:Target 已算出首位置分布,可经修正重采样提交替代 token。
  • 误区:拒绝 y1y_1 后还能继续验收 y2y_2。纠正:后续候选依赖包含 y1y_1 的错误上下文。
  • 误区:精确拒绝路径就是简单从 pp 再采一次。纠正:经典算法使用归一化的正残差 [pq]+[p-q]_+
  • 误区:至少一个 token 说明一定加速。纠正:它只保证进度,不保证吞吐优于普通 Decode。
  • 误区:Target 的所有验收分布都会被使用。纠正:第一个拒绝位置之后的分布对应失效分支。
  • 误区:任何投机算法的验收公式都相同。纠正:近似、贪心与树状变体可能不同。

本课小结

  • 第一个草稿被拒后,所有依赖它的后续草稿都失效。
  • Target 对第一个新位置的分布只依赖已确认前缀,因此仍然合法。
  • 经典精确投机采样从正残差分布重采样替代 token,保持 Target 边缘分布。
  • 第一候选接受或拒绝,两条路径都至少提交一个新 token。
  • 一轮产出范围通常为 1 到 K+1K+1;进度下界不等于性能保证。
08

主题讲解 · 03:57

MTP 可视化:主模型、串行模块与错位标签

学习目标

  • 能从板书中区分深层主模型与轻量 MTP 辅助模块。
  • 能说明主模型每一行隐藏状态代表的前缀。
  • 能追踪 MTP1、MTP2 的隐藏状态与错位 token embedding。
  • 能解释为什么越深的预测级别,有效训练行越少。
  • 能区分串行多步条件预测与朴素独立多头投影。

前置与衔接

Multi-Token Prediction(MTP)希望一次主干计算为多个未来位置提供预测信号。

理解它的难点不在“多接几个分类头”,而在未来 token 之间仍有自回归条件关系。

本课跟随视频中的四 token 示例,把结构拆成三层视图:

  1. 普通 Decoder-only 主模型;
  2. 第一级 MTP1;
  3. 依赖 MTP1 的第二级 MTP2。

这里的“单层 MTP 模块”特指视频展示的架构,不代表所有名为 MTP 的实现都必须采用完全相同的层数与连接方式。

核心讲解

1. 主模型仍做标准 next-token prediction

设训练序列为

T1,T2,T3,T4.T_1,T_2,T_3,T_4.

主模型把各 token 映射为 embedding,经过多层 causal Self-Attention 与 FFN,得到最终隐藏状态

X1,X2,X3,X4.X_1,X_2,X_3,X_4.
图 1

MTP 的主模型仍是普通深层 Decoder-only Transformer:每个位置的最终隐藏状态预测下一个 token。

原视频 · 00:40 ↗

其中 XiX_i 编码前缀 T1:iT_{1:i},经词表投影后预测 Ti+1T_{i+1}

因此有效监督对齐为:

  • X1T2X_1\rightarrow T_2
  • X2T3X_2\rightarrow T_3
  • X3T4X_3\rightarrow T_4
  • X4T5X_4\rightarrow T_5,但示例序列里没有 T5T_5,所以该行不计 loss。

这就是所有后续错位操作的参照系。

2. MTP 模块接在主模型末层之后

视频展示的主模型是多层 Transformer,而 MTP1、MTP2 各画成一个轻量单层 Transformer 模块。

图 2

视频展示的 MTP 结构在主模型末层之后串接轻量辅助模块;这里每个 MTP 模块画成单层 Transformer。

原视频 · 01:00 ↗

其目的不是替代主模型,而是复用主模型已经算出的丰富前缀表示,继续预测更远的位置。

可以把预测深度理解为:

  • 主模型:预测下一 token;
  • MTP1:预测下下一个 token;
  • MTP2:预测再远一个 token。

“预测深度”与 Transformer 的主干层数不是同一个概念。

3. 为什么要引入右移的 token embedding

若只从 XiX_i 同时投影多个未来位置,较远预测没有显式看到中间 token 的取值。

但自回归分解要求:

p(Ti+2T1:i)=Ti+1p(Ti+1T1:i)p(Ti+2T1:i+1).p(T_{i+2}\mid T_{1:i}) =\sum_{T_{i+1}} p(T_{i+1}\mid T_{1:i}) p(T_{i+2}\mid T_{1:i+1}).

视频中的 MTP1 通过把中间 token 的 embedding 接进来,显式构造第二项需要的条件。

以第一行为例:

  • X1X_1 表示前缀 T1T_1
  • 再加入 E(T2)E(T_2)
  • 得到的组合表示用于预测 T3T_3

4. MTP1 的三行输入怎样构造

对长度 4 的序列,MTP1 取主模型的前三行

[X1,X2,X3][X_1,X_2,X_3]

和右移一位的真实 token embedding

[E(T2),E(T3),E(T4)].[E(T_2),E(T_3),E(T_4)].
图 3

第一级 MTP 将主模型隐藏状态与右移一位的真实 token embedding 沿特征维拼接,再投影回模型宽度。

原视频 · 02:00 ↗

每一对沿特征维拼接:

Ui(1)=[Xi;E(Ti+1)].U_i^{(1)}=[X_i;E(T_{i+1})].

若两部分宽度都是 dd,拼接后宽度为 2d2d

视频随后画出一个投影,把宽度降回模块使用的隐藏维度。

5. MTP1 内部仍执行因果 Transformer 计算

降维后的三行表示进入 MTP1 的 Q/K/V 投影、causal attention、输出投影与 FFN。

图 4

拼接并降维后的表示进入 MTP1 的因果 Self-Attention 与 FFN,产生更远一步的预测表示。

原视频 · 02:20 ↗

最终得到

H1(1),H2(1),H3(1).H_1^{(1)},H_2^{(1)},H_3^{(1)}.

它们分别用于预测:

  • H1(1)T3H_1^{(1)}\rightarrow T_3
  • H2(1)T4H_2^{(1)}\rightarrow T_4
  • H3(1)T5H_3^{(1)}\rightarrow T_5

示例中 T5T_5 不存在,所以第三行不会贡献有效监督损失。

注意:模型仍可计算这行表示;“不计 loss”不等于物理上必须删除整行计算。

6. MTP2 不能绕过 MTP1

第二级预测要再向未来走一步,因此不能只重新读取主模型的同一份输出。

视频展示的 MTP2 依赖 MTP1 的隐藏状态,模块之间形成串行链。

图 5

MTP2 依赖 MTP1 的输出,因此不同预测深度之间保持串行条件关系,而非彼此独立的多头分类。

原视频 · 02:40 ↗

这种结构保留了“先得到较近未来条件,再预测更远未来”的语义。

因此 MTP 的“多 token”不等于所有预测深度完全并行、互不依赖。

7. MTP2 的 embedding 再右移一位

为了预测更远的目标,MTP2 使用 MTP1 的前两行与

[E(T3),E(T4)][E(T_3),E(T_4)]

配对。

图 6

第二级 MTP 使用进一步右移的 token embedding,并因序列末端缺少更远标签而只保留更少有效行。

原视频 · 03:00 ↗

例如第一行把 H1(1)H_1^{(1)}E(T3)E(T_3) 结合,用来预测 T4T_4

第二行试图预测 T5T_5,但在长度 4 的示例中仍没有对应标签。

其目标对齐可以写成:

Hi(d)Ti+d+1,H_i^{(d)}\rightarrow T_{i+d+1},

其中主模型可看作深度 d=0d=0

8. 为什么每深入一级就少一行有效监督

长度为 NN 的序列,在预测深度 dd 时,目标下标为 i+d+1i+d+1

要使目标仍位于序列内,必须满足

i+d+1N.i+d+1\le N.

因此有效位置数为

Nd1.N-d-1.

N=4N=4 的例子里:

  • 主模型 d=0d=0:3 个有效 next-token 标签;
  • MTP1 d=1d=1:2 个有效标签;
  • MTP2 d=2d=2:1 个有效标签。

视频画面保留了部分无标签行来解释结构,但训练 loss 必须屏蔽越界目标。

9. 训练时为何能使用真实未来 token

训练序列全部已知,因此 E(T2)E(T_2)E(T3)E(T_3)E(T4)E(T_4) 可以通过 teacher forcing 直接提供。

这不会泄漏被预测目标本身:预测 T3T_3 时使用的是中间条件 T2T_2,而不是把 T3T_3 直接塞进同一行输入。

关键检查是每一级输入与目标的相对位移,而不是简单看到“未来 token”就认定泄漏。

10. 从图中读取 shape

若 batch 为 BB,有效序列行为 MM,隐藏宽度为 dd,则一次拼接可表示为

XRB×M×d,ERB×M×d,X\in\mathbb{R}^{B\times M\times d},\qquad E\in\mathbb{R}^{B\times M\times d},
[X;E]RB×M×2d.[X;E]\in\mathbb{R}^{B\times M\times 2d}.

随后线性投影 WR2d×dW\in\mathbb{R}^{2d\times d} 把最后一维恢复为 dd

序列行数随预测深度改变,特征宽度则在拼接后经投影保持为模块所需宽度。

11. 架构与版本边界

“MTP”描述一类多步预测目标,并不唯一指定模块数量、参数共享、归一化、投影方式或推理用途。

本课只忠实解释视频板书中的主模型 + 串行单层辅助模块方案。

阅读具体模型代码时,应重新核对:

  • 辅助模块是否真的为一层;
  • 是否复用 embedding 或输出头;
  • 隐藏状态在哪个位置归一化、拼接和投影;
  • loss mask 如何处理序列尾部;
  • 训练模块是否完整保留到部署阶段。

跟练与练习

原视频练习

编者练习

长度为 6 的训练序列,在主模型、MTP1、MTP2 上分别有多少个不越界的监督目标?

查看参考答案

使用 Nd1N-d-1:主模型 d=0d=0 有 5 个,MTP1 d=1d=1 有 4 个,MTP2 d=2d=2 有 3 个。越过序列末端的目标必须由 loss mask 排除。

编者练习 2

预测 T4T_4 时,为什么可以使用 T3T_3 的 embedding,却不能直接使用 T4T_4 的 embedding?

查看参考答案

T3T_3 是链式分解中的已知中间条件;训练时用真实 T3T_3 做 teacher forcing。T4T_4 本身是当前监督目标,若同一预测位置直接读到 E(T4)E(T_4),就会发生标签泄漏。

常见误区

  • 误区:MTP 只是从一个隐藏状态接多个独立词表头。纠正:视频结构显式注入中间 token,并串行连接不同预测深度。
  • 误区:MTP1 的三行都在四 token 示例中有标签。纠正:最后一行指向不存在的 T5T_5,不计 loss。
  • 误区:使用右移 token embedding 一定是标签泄漏。纠正:要检查它是中间条件还是当前预测目标。
  • 误区:主模型和 MTP 模块的“层”是同一含义。纠正:前者是网络深度,后者还承担不同未来步的预测级别。
  • 误区:所有 MTP 实现都用单层辅助 Transformer。纠正:这是视频所示方案的架构边界。
  • 误区:更深一级仍有相同行数的有效监督。纠正:越远目标越容易越过序列末端。

本课小结

  • MTP 保留普通深层主模型,再在末层表示之后接多步预测模块。
  • MTP1 将主模型隐藏状态与右移一位的 token embedding 拼接。
  • MTP2 串行依赖 MTP1,并使用进一步右移的中间 token 条件。
  • 预测深度为 dd 时,长度 NN 的序列有 Nd1N-d-1 个有效目标。
  • 视频中的单层辅助模块是具体架构示例,不能不经核对推广到所有实现。
09

主题讲解 · 03:18

MTP 如何用时序桥接预测更远 Token

学习目标

  • 能从隐藏状态的前缀语义推导 next-token prediction。
  • 能说明朴素并行多头缺少哪一项条件依赖。
  • 能用概率链式法则解释 MTP 的“时序桥接”。
  • 能区分训练时 teacher forcing 与推理时预测 token 输入。
  • 能客观看待 MTP 的计算收益与实际加速边界。

前置与衔接

上一课从结构图追踪了 MTP1、MTP2 的错位 embedding 与串行关系。

本课回答更本质的问题:为什么加入中间 token 的 embedding 后,就能在一次主干计算之后预测多个未来 token?

关键不是“输出头变多”,而是联合概率的链式分解被显式保留下来。

核心讲解

1. Decoder 隐藏状态代表一个前缀

在 causal Decoder 中,第 ii 行隐藏状态只能读取位置 11ii

因此主模型最后一层的表示可写作

hi=f(x1:i).h_i=f(x_{1:i}).
图 1

Decoder 第 i 行最终隐藏状态编码前缀 x1:ix_{1:i},标准语言模型用它预测 xi+1x_{i+1}

原视频 · 00:20 ↗

标准语言模型用 hih_i 预测下一 token:

p(xi+1x1:i)=softmax(Wohi).p(x_{i+1}\mid x_{1:i}) =\operatorname{softmax}(W_oh_i).

例如 h1h_1 表示 T1T_1,预测 T2T_2h2h_2 表示 T1,T2T_1,T_2,预测 T3T_3

2. 一次预测两个未来位置需要联合分布

若希望从前缀 xtx_{\le t} 得到接下来的两个 token,目标不是两个互不相干的分类问题,而是

p(xt+1,xt+2xt).p(x_{t+1},x_{t+2}\mid x_{\le t}).

自回归链式法则把它分解为

p(xt+1xt)p(xt+2xt,xt+1).p(x_{t+1}\mid x_{\le t}) p(x_{t+2}\mid x_{\le t},x_{t+1}).

第二项必须知道第一个未来 token xt+1x_{t+1} 的具体取值。

这就是 MTP 需要解决的时序条件问题。

3. 朴素多投影头缺少显式中间条件

一种直觉做法是让同一个 hth_t 接两个词表投影头,一个预测 xt+1x_{t+1},另一个预测 xt+2x_{t+2}

图 2

从同一隐藏状态直接接多个独立投影头,后一步预测无法显式条件于前一步实际 token。

原视频 · 01:20 ↗

两个头当然可以通过不同参数学习不同预测步的边缘统计。

问题是第二个头的输入仍只有 hth_t,没有显式条件于这次真正选中的 xt+1x_{t+1}

所以它没有按上述链式分解直接建模

p(xt+2xt,xt+1).p(x_{t+2}\mid x_{\le t},x_{t+1}).

更准确地说,缺口是条件依赖,而不是“两个头物理上无法区分标签”。

4. MTP 把中间 token 作为桥

视频用 T1,T2,T3,T4T_1,T_2,T_3,T_4 说明:若要在表示前缀 T1,T2T_1,T_2 的基础上预测 T4T_4,必须把中间的 T3T_3 引入条件。

图 3

若要预测更远的 T4T_4,模型需要把中间 token T3T_3 作为条件,恢复自回归链式依赖。

原视频 · 01:40 ↗

MTP1 构造

u2=[h2;E(T3)],u_2=[h_2;E(T_3)],

再经投影和轻量 Transformer 模块得到用于预测 T4T_4 的表示。

图 4

MTP1 将表示前缀 T1,T2T_1,T_2 的隐藏状态与 T3T_3 的 embedding 拼接,据此预测 T4T_4

原视频 · 02:00 ↗

h2h_2 提供 T1,T2T_1,T_2 的前缀信息,E(T3)E(T_3) 提供本次链式分解的中间条件。

两者合在一起,输入语义正好对应

(T1,T2,T3)T4.(T_1,T_2,T_3)\rightarrow T_4.

5. “桥接”恢复了顺序,不等于取消顺序

MTP 能在一个训练样本里同时监督多个未来深度,但这些深度仍有方向:

  • 先有主模型对较近 token 的表示;
  • 再把较近 token 作为条件交给 MTP1;
  • 若继续预测更远位置,再把 MTP1 的结果交给 MTP2。

所以 MTP 的并行收益来自复用深层主干计算,而不是让未来 token 互相独立。

辅助模块之间仍可能串行。

6. 训练时使用真实中间 token

训练序列已知,MTP1 可直接读取 ground-truth T3T_3 的 embedding。

图 5

训练时桥接 token 来自真实标签,推理时则来自模型已采样结果;两种阶段共享同一条件结构。

原视频 · 02:20 ↗

这属于 teacher forcing:

u2train=[h2;E(T3gold)].u_2^{\text{train}}=[h_2;E(T_3^{\text{gold}})].

它让模型在正确条件下学习 T4T_4 的预测。

只要当前目标是 T4T_4,读取前一个条件 T3T_3 不构成标签泄漏。

7. 推理时必须使用实际生成的中间 token

推理阶段没有 ground-truth T3T_3

模型先从较近一步分布采样或选择

T^3,\hat T_3,

再构造

u2infer=[h2;E(T^3)].u_2^{\text{infer}}=[h_2;E(\hat T_3)].

因此较近一步预测错误会改变更远一步的条件。

这也是训练与推理分布存在差异的来源之一:训练常见真实中间 token,推理看到模型自己的预测。

8. 多行 MTP 输出怎样对齐目标

对主模型隐藏状态 hih_i,第一级 MTP 可使用 E(xi+1)E(x_{i+1}) 来预测 xi+2x_{i+2}

一般写成

Hi(1)=MTP1(hi,E(xi+1)),H_i^{(1)}=\operatorname{MTP}_1(h_i,E(x_{i+1})),
Hi(1)xi+2.H_i^{(1)}\rightarrow x_{i+2}.

在短序列尾部,若 xi+2x_{i+2} 不存在,该位置必须从 loss 中屏蔽。

因此“多预测一步”和“监督标签右移一步”必须同步检查。

9. 计算收益来自少跑深层主干

普通自回归若要得到两个未来 token,通常需要先后两次运行完整模型的 Decode 路径。

视频展示的 MTP 方案先运行一次深层主模型,再用轻量辅助模块得到更远预测。

图 6

MTP 复用一次深层主模型计算,再用轻量辅助模块预测更远 token,减少重复运行完整主干的代价。

原视频 · 03:00 ↗

若主模型代价为 CmainC_{\text{main}},辅助模块代价为 CmtpC_{\text{mtp}},且

CmtpCmain,C_{\text{mtp}}\ll C_{\text{main}},

那么复用主干可能比重复完整模型更便宜。

但这只是结构动机,不自动等于端到端吞吐按预测 token 数成倍提升。

10. MTP 预测常需要验收

推理时,较远 token 由轻量模块产生,可能与完整主模型分布不一致。

若系统把 MTP 用作 speculative proposal,通常还需由 Target 主干验收。

实际速度取决于候选接受率:

  • 接受率高,减少完整主干调用的机会更多;
  • 接受率低,辅助预测和验收可能成为额外开销。

因此“能一次提出多个 token”和“能一次无条件提交多个 token”不是同一句话。

11. 一个更准确的心智模型

可以把 MTP 看成在主模型表示上搭建的条件预测阶梯:

  1. 主模型表示已确认前缀;
  2. 较近 token 的 embedding 补齐下一层条件;
  3. 轻量模块预测更远 token;
  4. 若继续向远处走,再把新条件传给下一级模块。

阶梯复用昂贵的底座,但每一级仍尊重自回归顺序。

12. 实现与版本边界

本课解释视频所画的串行辅助模块机制。

具体模型可能改变模块层数、参数共享、输入归一化、训练目标以及部署时是否保留所有预测头。

有些 MTP 主要作为训练辅助目标,有些会在推理时产生草稿候选。

判断实际加速能力时必须结合具体版本的推理链路,而不能从“MTP”名称直接推断。

跟练与练习

原视频练习

编者练习

已知 hth_t 表示前缀 xtx_{\le t}。若要预测 xt+2x_{t+2},MTP 辅助模块还需要哪项关键输入?为什么?

查看参考答案

需要中间 token xt+1x_{t+1} 的 embedding。链式分解的第二项是 p(xt+2xt,xt+1)p(x_{t+2}\mid x_{\le t},x_{t+1});只输入 hth_t 会缺少本次实际 xt+1x_{t+1} 的条件。

编者练习 2

若训练时使用真实 xt+1x_{t+1},推理时却使用模型预测的 x^t+1\hat x_{t+1},可能出现什么问题?

查看参考答案

推理时中间预测一旦偏离真实分布,较远预测会在不同条件上运行,误差可能向后传播。这是 teacher forcing 与自由运行之间的分布差异;若 MTP 用于草稿生成,Target 验收可以阻止错误候选直接提交,但会降低接受率和加速收益。

常见误区

  • 误区:同一隐藏状态接多个输出头就完整建模了多 token 联合分布。纠正:较远头没有显式条件于实际中间 token。
  • 误区:MTP 取消了未来 token 的先后顺序。纠正:它通过 embedding 和串行模块保留链式条件。
  • 误区:训练时使用真实中间 token 是标签泄漏。纠正:它是预测更远目标所需的先行条件。
  • 误区:推理时也能读取真实中间 token。纠正:推理只能使用模型已经采样或选择的结果。
  • 误区:一次提出多个候选就能全部直接提交。纠正:用作投机推理时通常仍需 Target 验收。
  • 误区:辅助模块轻量就必然成倍加速。纠正:还受接受率、内核、调度与缓存开销影响。

本课小结

  • Decoder 隐藏状态 hih_i 编码前缀 x1:ix_{1:i},标准输出头预测下一 token。
  • 多步联合分布要求较远预测显式条件于中间 token。
  • MTP 将前缀隐藏状态与中间 token embedding 结合,形成时序桥接。
  • 训练使用真实中间 token,推理使用模型已生成 token。
  • MTP 复用昂贵主干,但实际加速仍取决于具体架构、验收率与系统实现。
10

主题讲解 · 03:01

把首 Token 合进 Draft Prefill,省掉一次 Decode

学习目标

  • 能画出普通路径与首 token 合并路径的时序差异。
  • 能解释为什么 Draft Prefill 的最后一行可直接产生第一个草稿。
  • 能区分 token 传递与跨模型 KV Cache 共享。
  • 能说明该技巧只省去第一次 Draft Decode。
  • 能判断 Target-first 调度前提何时成立、何时需要回退。

前置与衔接

投机解码通常包含大型 Target 模型和小型 Draft 模型。

Target 对 prompt 完成 Prefill 后,先采样一个已由大模型确认的锚点 token。

Draft 再从该锚点之后提出候选。

图 1

Target 模型先完成 prompt 的 Prefill 并采样锚点 token,随后才把它交给 Draft 路径。

原视频 · 00:20 ↗

本课讨论一个很小但很具体的系统优化:既然锚点已经知道,能否把它直接追加到 Draft Prefill 的输入里,让 Prefill 顺便产出第一个草稿?

核心讲解

1. 先看普通的两模型路径

设 prompt token 为

x1,x2,,xn.x_1,x_2,\ldots,x_n.

Target Prefill 处理这 nn 个 token,在最后一行得到下一 token 分布,并采样锚点 aa

普通 Draft 路径可以拆成两步:

  1. Draft 对 x1:nx_{1:n} 做 Prefill,建立自己的前缀 KV Cache;
  2. Draft 再把 aa 作为一个单 token Decode 输入,得到第一个草稿 y1y_1

第二步是本课想省掉的那一次 Draft Decode。

2. 为什么不能直接复制 Target 的 KV

Target 和 Draft 通常参数、层数、hidden size、head 配置都不同。

同一 token 在两模型中产生的 K/V 不具有可直接互换的数值语义。

图 2

Target 与 Draft 是不同模型,各自计算并维护 KV Cache;优化只传递 token,不复制另一模型的 K/V。

原视频 · 01:00 ↗

因此 Draft 必须自己对 prompt 计算 K/V。

优化传递的是离散 token aa,不是把 Target KV Cache 拷贝到 Draft。

这是理解整个技巧最重要的边界。

3. 把锚点追加到 Draft Prefill

若 Target 已经产生 aa,Draft 的 Prefill 输入可以从

[x1,,xn][x_1,\ldots,x_n]

改为

[x1,,xn,a].[x_1,\ldots,x_n,a].
图 3

将 Target 采样的锚点 token 追加到 Draft Prefill 输入,使 Draft 一次处理 prompt 与锚点。

原视频 · 01:20 ↗

Draft 一次 Prefill 就为 prompt 和锚点共同建立自己的 KV Cache。

长度从 nn 变成 n+1n+1,causal attention 仍保证每行只看到合法左侧前缀。

4. Draft Prefill 最后一行能做什么

Draft 处理锚点 aa 的最后一行时,其可见上下文是

[x1,,xn,a].[x_1,\ldots,x_n,a].

这正是第一个草稿 y1y_1 所需的条件。

因此该行隐藏状态经过 Draft 的词表投影后,可以直接得到

q(y1x1:n,a).q(y_1\mid x_{1:n},a).

换句话说,原本独立 Decode 才能完成的工作,现在被并入了 Prefill 的最后一行。

5. 与未合并路径做一一对照

未合并时,Draft Prefill 只覆盖 prompt。

它的最后一行只能预测锚点位置,但实际锚点由 Target 给出。

Draft 还要再输入 aa 做一次 Decode,才能预测 y1y_1

图 4

若 Draft Prefill 只处理 prompt,还需再执行一次单 token Decode,才能得到第一个草稿候选。

原视频 · 01:40 ↗

合并后,Draft Prefill 直接处理 aa,最后一行立即预测 y1y_1

两条路径的 y1y_1 条件相同;变化的是计算调度,而不是概率定义。

6. 节省的是哪一段计算

记 Draft Prefill 为 PDP_D,一次 Draft Decode 为 DDD_D

普通路径为

PD(x1:n)+DD(a)y1.P_D(x_{1:n})+D_D(a)\rightarrow y_1.

合并路径为

PD(x1:n,a)y1.P_D(x_{1:n},a)\rightarrow y_1.

后者把单 token aa 纳入矩阵化 Prefill,省去一次单独的调度与 Decode kernel 路径。

但 Prefill 本身多处理了一行,所以收益不是“完全免费”,而是用一次稍长 Prefill 替代 Prefill 后的独立 Decode。

7. 后续草稿仍需串行 Decode

得到 y1y_1 后,若还要提出 y2y_2,Draft 必须把 y1y_1 送入下一次 Decode。

图 5

合并只省去第一次 Draft Decode;后续草稿 token 仍以单行 Query 对自身 KV Cache 串行解码。

原视频 · 02:00 ↗

此时 Query 只有新 token 对应的一行,K/V 则包含 prompt、锚点以及已经产生的草稿前缀。

因此合并技巧只省掉“锚点到第一个草稿”的一次 Decode,不会让后续 KK 个草稿全部在同一次 Prefill 中自动出现。

8. 必须先拿到 Target 的锚点

Draft Prefill 要把 aa 放进输入,前提是 Target 已经完成 Prefill 并采样出 aa

图 6

该技巧要求 Target Prefill 先结束并产生锚点;若 Draft 先完成,就无法把尚不存在的 token 并入其 Prefill。

原视频 · 02:20 ↗

所以时序必须满足

Target PrefillaDraft Prefill(x1:n,a).\text{Target Prefill}\rightarrow a\rightarrow\text{Draft Prefill}(x_{1:n},a).

这就是视频强调的关键前提。

aa 尚不存在,Draft 无法提前把它写进自己的 Prefill 输入。

9. 同时 Prefill 时为何可能用不上

一种调度方式是让 Target 与 Draft 同时对 prompt 做 Prefill,以增加重叠。

由于 Draft 通常更小,它可能先完成;此时 Target 还没有产生锚点。

Draft 若立即继续,就只能等待 aa 后再做普通单 token Decode。

系统也可以选择让 Draft 等待 Target,再执行合并后的 Prefill,但这会放弃原本的并行重叠。

因此这是调度权衡:

  • Target-first:可合并首 token,但 Draft Prefill 启动更晚;
  • 并行 Prefill:有计算重叠,但可能无法把锚点并入已经完成的 Draft Prefill。

哪条路径更快要由实际工作负载决定。

10. 为什么这项优化通常只是“小技巧”

它只省一次轻量 Draft 模型的 Decode,而整个投机解码还包含:

  • Target Prefill;
  • 多个 Draft 候选的后续 Decode;
  • Target 批量验收;
  • 接受或拒绝采样;
  • KV Cache 和调度管理。

所以单次节省可能有限,但在高并发、短草稿或调度开销明显时,仍可能有实际价值。

应通过端到端 latency、throughput 和 GPU 利用率测量,而不是只按少一次 kernel 就断定收益。

11. 与前两课的联系

首 token 合并改变的是 Draft 提出 y1y_1 的方式。

它不改变 Target 验收 KK 个草稿时得到 K+1K+1 份分布,也不改变首个候选被拒后的精确重采样规则。

因此可以分三层理解:

  • 生成层:怎样更便宜地产生 Draft 候选;
  • 验收层:怎样由 Target 批量计算概率;
  • 正确性层:怎样接受或修正,使输出保持目标分布。

首 token 合并只作用于第一层。

12. 框架与版本边界

视频把这一路径与 vLLM、SGLang 的 EAGLE 实现联系起来。

这里保留为“视频讨论的实现路径”,不声称当前所有 vLLM/SGLang 版本、后端和调度配置都默认采用相同流程。

推理引擎迭代很快,实际判断应核对目标版本中的 scheduler、speculative decoding worker 和缓存接口。

术语也可能不同:某些实现把追加锚点后的输入称为 extend,而另一些仍归入 prefill/chunked prefill 路径。

跟练与练习

原视频练习

编者练习

Target 已产生锚点 aa。写出普通 Draft 路径与合并路径在得到第一个草稿 y1y_1 前分别包含哪些计算。

查看参考答案

普通路径:Draft 先对 prompt 做 Prefill,再以 aa 做一次单 token Decode,得到 y1y_1。合并路径:Draft 直接对 prompt 加 aa 做 Prefill,由最后一行输出 y1y_1,省去独立的第一次 Draft Decode。

编者练习 2

若 Draft Prefill 已经先于 Target 完成,为什么不能事后把锚点的 Target KV 直接接到 Draft Cache?

查看参考答案

两模型参数和表示空间不同,Target 的 K/V 不是 Draft 可直接使用的缓存。Draft 必须用自己的层和投影计算锚点的 K/V;此时可走普通 Draft Decode,或重新安排能处理锚点的 extend 路径。

常见误区

  • 误区:首 token 合并是在两模型间共享 KV Cache。纠正:只传递 token,Target 与 Draft 各自计算 K/V。
  • 误区:合并后 Draft 不需要 Prefill。纠正:Draft 仍需为 prompt 与锚点建立自己的缓存。
  • 误区:一次 Draft Prefill 可以生成全部草稿 token。纠正:它只顺带得到第一个草稿,后续仍串行 Decode。
  • 误区:该技巧在并行 Prefill 时总能使用。纠正:Draft 启动时必须已经拿到 Target 锚点。
  • 误区:少一次 Decode 必然显著提速。纠正:还需权衡 Prefill 多一行、等待与并行重叠损失。
  • 误区:视频描述代表所有当前 vLLM/SGLang 版本。纠正:具体路径受版本、后端和 scheduler 配置影响。

本课小结

  • Target Prefill 先产生锚点,Draft 可把该 token 直接并入自己的 Prefill 输入。
  • Draft Prefill 最后一行据此输出第一个草稿,省去一次独立 Draft Decode。
  • 两模型缓存彼此独立;优化传 token,不传 K/V。
  • 后续草稿仍需自回归 Decode,优化收益只覆盖第一步。
  • 技巧成立要求 Target 先得到锚点,并与并行 Prefill 的调度重叠存在权衡。
11

单元综合

从目标分布到块状验证:投机解码与多 Token 预测的完整链路

单元能力目标

完成本单元后,应能把投机解码拆成四层:

  1. 采样层:最终希望严格服从哪个 Target 条件分布?
  2. 验收层:Draft 提案怎样被接受或由残差分布修正?
  3. 序列层:多 token 验收为何必须按前缀顺序处理首次拒绝?
  4. 系统层:Target 如何把候选块组织成增量 Prefill,KV Cache 怎样提交?

还应能区分投机采样与 MTP:前者是保持 Target 分布的推理解码框架,后者是训练模型产生更远 token 候选的一种架构路线。

概念连接

1. 先固定普通采样的退化条件

给定 logits ziz_i,Temperature 采样分布为

pi(T)=ezi/Tjezj/T,T>0.p_i(T) = \frac{e^{z_i/T}} {\sum_j e^{z_j/T}}, \qquad T>0.

当最大 logit 唯一时:

T0+T\to0^+

使概率集中到最大 logit,极限趋近 greedy。

不能把 T=0T=0 直接代入公式;工程 API 可能显式切换 greedy 路径。

Top-k 在 k=1k=1 时只保留一个候选。

Top-p 在阈值不超过最高概率、且实现采用最小累计前缀时,也可能只保留一个候选。

三者共同本质是最终采样支撑缩成一个 token,但并列最大值、最小保留数、阈值与 warper 顺序会影响实际行为。

2. 投机解码有两个条件分布

Draft 给出便宜的提案分布

q(x),q(x),

Target 给出最终必须保持的分布

p(x).p(x).

目标不是让 Draft 猜得像就直接替代 Target,而是利用 Draft 候选减少 Target 的串行调用,同时使最终 token 仍服从 pp

因此“无损”是分布等价,不是浮点逐位相同,也不是所有实现都自动正确。

3. 标准验收概率截取重叠质量

Draft 先采样候选 xqx\sim q

条件接受概率为

a(x)=min(1,p(x)q(x)).a(x) = \min \left( 1, \frac{p(x)}{q(x)} \right).

直接接受路径产生的无条件质量为

q(x)a(x)=min(p(x),q(x)).q(x)a(x) = \min(p(x),q(x)).

它正好保留 ppqq 的重叠部分。

q(x)p(x)q(x)\le p(x),该候选全部接受;若 q(x)>p(x)q(x)>p(x),只接受 Target 允许的比例。

4. 拒绝质量必须流向 Target 的缺口

定义正残差

r(x)=(p(x)q(x))+.r(x)=(p(x)-q(x))_+.

总残差为

R=x(p(x)q(x))+.R = \sum_x(p(x)-q(x))_+.

归一化残差分布为

r~(x)=(p(x)q(x))+R,\tilde r(x) = \frac{(p(x)-q(x))_+}{R},

前提是 R>0R>0

Draft 候选被拒绝后,从 r~\tilde r 采样校正 token。

如果 R=0R=0,则归一化分布无需构造,因为此时标准验收路径不会产生需要校正的拒绝质量。

5. 逐 token 质量证明最终分布等于 Target

对任意 token xx,最终概率由两条互斥路径组成:

  1. Draft 提案且直接接受:贡献 min(p(x),q(x))\min(p(x),q(x))
  2. 某候选被拒绝后从残差分布采到 xx:贡献 (p(x)q(x))+(p(x)-q(x))_+

两者相加:

min(p(x),q(x))+(p(x)q(x))+=p(x).\min(p(x),q(x)) + (p(x)-q(x))_+ =p(x).

这个逐点恒等式同时解释概率树和概率质量柱状图的证明。

6. 总缺口等于总盈余

因为 ppqq 都归一化:

xp(x)=xq(x)=1.\sum_xp(x)=\sum_xq(x)=1.

所以

x(p(x)q(x))=0.\sum_x(p(x)-q(x))=0.

正差之和等于负差绝对值之和:

x(pq)+=x(qp)+.\sum_x(p-q)_+ = \sum_x(q-p)_+.

Target 的缺口质量正好由 Draft 的盈余拒绝质量补齐。

这就是残差重采样保持分布的守恒账本。

7. 多 token 验收必须按前缀顺序进行

Draft 串行提出

x^1,x^2,,x^K.\hat x_1,\hat x_2,\ldots,\hat x_K.

jj 个候选的 Draft 与 Target 条件分布都依赖已确认前缀和前面候选:

qj(h,x^<j),q_j(\cdot\mid h,\hat x_{<j}),
pj(h,x^<j).p_j(\cdot\mid h,\hat x_{<j}).

一旦第 jj 个候选被拒绝,后续候选基于错误前缀生成,全部失效。

所以验收虽然可在一次 Target 前向中计算多个位置的 logits,提交决策仍受首次拒绝约束。

8. 首个草稿被拒仍能前进一步

第一个候选的 Target 分布只依赖已确认历史 hh,因此是合法分布。

若候选被拒,从其残差分布采样一个校正 token 并提交。

因此每一轮至少推进一个 token。

一轮进度范围通常为

1LcommitK+1.1\le L_{commit}\le K+1.

进度下界保证算法不会停滞,但不保证性能优于普通 Decode。

9. 为什么 K 个草稿最多提交 K+1 个 token

一种调度中,Target 先产生一个锚点,Draft 再提出 KK 个候选。

Target 对锚点加候选块执行长度 K+1K+1 的因果增量 Prefill。

得到的前 KK 份 Target 分布用于验收 KK 个草稿。

最后一份分布位于草稿末端之后,可在全部接受时再采样一个奖励 token。

所以全接受上界为 K+1K+1,中途拒绝则达不到该上界。

上界还依赖具体调度;不能把视频中的锚点顺序视为所有实现唯一规范。

10. Target 为什么可以块状验证

普通自回归 Decode 每次只有一个未知新 token,单请求下常表现为窄矩阵—向量路径。

Draft 先把候选 token 具体化后,Target 可以把多个已知候选位置作为一个因果块输入。

这类似增量 Prefill:

  • 块内仍使用 causal mask;
  • 每个位置只能看到前缀与块内更早 token;
  • 并未取消自回归条件依赖;
  • 只是把多个位置的 Target 计算组织进更宽的前向。

11. KV Cache 只提交有效前缀

Draft 与 Target 是两个模型,分别维护自己的 KV Cache。

Target 验证候选块时会计算各位置 K/V,但只有最终接受的前缀可以提交为后续历史。

首次拒绝后的候选依赖错误前缀,不能把对应缓存当作已确认历史继续使用。

具体实现可能回滚、截断或用块表管理未提交缓存,但逻辑边界相同。

12. 加速取决于接受长度与成本比

可粗略把一轮成本写成

Tround=Tdraft(K)+Tverify(K)+Tsystem.T_{round} = T_{draft}(K) +T_{verify}(K) +T_{system}.

平均提交长度为

E[Lcommit].\mathbb E[L_{commit}].

若 Draft 太慢、接受率太低、Target 块验证不够高效或调度开销过大,投机解码可能没有收益。

“分布无损”是正确性结论,“端到端更快”是需要实测的系统结论。

13. MTP 的目标是让模型预测更远 token

Multi-Token Prediction 保留主模型,并在末层表示后增加多步预测模块。

标准主模型隐藏状态 hih_i 编码前缀 x1:ix_{1:i},预测 xi+1x_{i+1}

为了预测更远 token,MTP 模块把 hih_i 与中间 token embedding 结合,形成时序桥接。

例如第一个模块使用真实的 xi+1x_{i+1} embedding 参与预测 xi+2x_{i+2},后续模块继续串联。

14. 训练与推理的中间 token 不同

训练时通常使用真实中间 token,属于 teacher forcing。

推理时只能使用模型已经预测或采样的中间 token。

这会带来 train–inference 条件差异。

多步头并不只是从同一个 hih_i 独立猜几个标签;显式中间 token 条件用于近似联合分布的链式结构。

15. MTP 与投机解码可以连接但不等同

MTP 可以生成多个候选 token,作为投机验证的 proposal 来源。

但:

  • MTP 是模型训练与架构机制;
  • 投机采样是 Target 分布保持与系统调度机制;
  • MTP 候选仍需验收才能保证 Target 分布;
  • 实际加速取决于候选质量、Target 验证和缓存实现。

16. Draft Prefill 可顺手产生第一个草稿

在 Target-first 调度中,Target Prefill 先得到锚点 token。

Draft 接收 prompt 时,可把该锚点直接追加到自己的 Prefill 输入。

Draft Prefill 的最后一行隐藏状态由此预测第一个草稿,省去一次独立 Draft Decode。

优化传递的是 token,不是 Target 的 K/V;两个模型的缓存不能直接共享。

后续草稿仍需自回归生成,因此收益只覆盖第一步,并需权衡 Target-first 的调度延迟。

对比与决策

1. 正确性审计顺序

  1. 明确过滤后还是过滤前的 p,qp,q
  2. 检查接受率是否为 min(1,p/q)\min(1,p/q)
  3. 检查拒绝后是否从 (pq)+(p-q)_+ 归一化分布采样。
  4. 检查多 token 是否在首次拒绝处停止提交。
  5. 检查 Target KV 是否只提交有效前缀。

任一环节改变都需要重新证明最终分布。

2. 性能审计顺序

  1. Draft 每 token 成本;
  2. Target 块验证相对串行 Decode 的成本;
  3. 平均接受长度;
  4. 奖励 token 产出概率;
  5. 缓存回滚、调度与 kernel 开销;
  6. batch、硬件和模型规模。

不能只报告接受率而不报告实际吞吐与延迟。

3. Draft 模型与 MTP 的选择

  • 独立 Draft:模型可单独优化,但需要独立权重和 KV Cache。
  • MTP:复用主干表示产生多步候选,但需要训练辅助模块并处理推理条件误差。
  • 两者都不能绕过 Target 验收的正确性要求。

综合训练

编者练习

设词表为 {A,B,C}\{A,B,C\},Target 分布 p=(0.5,0.3,0.2)p=(0.5,0.3,0.2),Draft 分布 q=(0.3,0.1,0.6)q=(0.3,0.1,0.6)。计算每个 token 的接受率、总拒绝质量和拒绝后的残差分布。

查看参考答案

接受率分别为 aA=1a_A=1aB=1a_B=1aC=0.2/0.6=1/3a_C=0.2/0.6=1/3。直接接受质量为 (0.3,0.1,0.2)(0.3,0.1,0.2),总计 0.6,所以拒绝质量为 0.4。正残差 (pq)+=(0.2,0.2,0)(p-q)_+=(0.2,0.2,0),归一化后为 (0.5,0.5,0)(0.5,0.5,0)。校正路径贡献 0.4(0.5,0.5,0)=(0.2,0.2,0)0.4(0.5,0.5,0)=(0.2,0.2,0),与直接路径相加恢复 (0.5,0.3,0.2)(0.5,0.3,0.2)

编者练习 2

Draft 提出 4 个候选,第 2 个被拒绝。说明哪些 token 可以提交、后续候选为何失效,以及本轮至少推进多少 token。

查看参考答案

第 1 个候选已接受,可以提交;第 2 个位置提交按标准残差规则采样的校正 token。第 3、4 个候选依赖被拒的第 2 个 Draft token,条件前缀已经错误,不能提交。该轮推进 2 个 token;一般若第一个候选就被拒,也仍提交一个合法校正 token,所以进度下界为 1。

编者练习 3

为什么 Target 一次计算 KK 个候选位置的 logits 不等于取消自回归依赖?

查看参考答案

候选 token 已由 Draft 具体给出,Target 可以在一个因果块中并行组织线性代数;但块内 causal mask 仍保证第 jj 个位置只看更早位置。验收也必须按前缀顺序处理,首次拒绝后更晚候选失效。因此并行的是已知候选的验证计算,不是把条件概率链改成互相独立预测。

进入下一单元前

  • 已能判断 Temperature、Top-k、Top-p 何时真正退化为单点支撑。
  • 已能推导接受质量 min(p,q)\min(p,q) 与残差质量 (pq)+(p-q)_+
  • 已能用逐点恒等式证明标准投机采样保持 Target 分布。
  • 已能解释首次拒绝、多 token 提交范围和 K+1K+1 上界。
  • 已能说明块状验证、causal mask 与 KV Cache 提交边界。
  • 已能区分 MTP 的训练架构与投机采样的验收机制。
  • 若仍把“无损”理解为浮点逐位相同,回看 P103、P106、P107。
  • 若仍把块状验证理解为非自回归生成,回看 P115、P118、P123。
  • 若仍想共享 Draft/Target KV,回看 P131 的缓存归属。