
TL;DR
现在所有基于起草模型的投机执行器类型都支持置信度评分。在没有置信度头的情况下,一种 在线拟合估计器 会从起草模型的 logits 中提取一个特征,以预测目标模型接受它的概率,该概率直接用作自适应验证的置信度分数。估计器的系数被持续拟合,以适应传入的数据流量。该功能已在 PR #52228中合入,并通过 enable_adaptive_verification 为没有置信度头的起草模型启用。
背景
vLLM 的 自适应验证 (AV) 允许在投机解码期间仅对部分起草的 token 进行验证。接受概率较低的起草 token 会在运行目标模型前向传播之前从批次中剔除,从而节省计算量。这一优化在大批量服务时尤其有益,因为在这种情形下 GPU 会成为计算瓶颈。详情请参见 这篇 vLLM 博客文章 。
AV 需要对每个 token 的接受概率进行估计,这就是为什么到目前为止它只支持 DSpark 起草器。DSpark 模型通常带有置信度头:一个作用于起草模型每个位置隐藏状态的小型线性层,作为"目标模型是否会接受这个 token?"的二分类器进行训练。
问题
缺少置信度头的起草模型,例如 EAGLE、MTP、DFlash 以及一些 DSpark 检查点,完全无法使用 AV。要使用它,这些起草器需要逐 token 的接受概率估计,而添加置信度头意味着要重新训练起草器,这对于人们已经在服务的众多现有检查点来说是不可行的。
先前工作
使用起草模型自身的置信度作为接受概率的代理是公认的做法。 EAGLE-2 表明 EAGLE 的起草概率与接受率紧密相关,并利用它们来扩展和重排动态起草树。 Draft & Verify 以及若干后续工作则在起草模型的概率低于固定阈值时停止起草。 SpecDec++ 则训练一个专用的接受预测头,其思路类似于 DSpark 的置信度头。在这些方法中,从起草置信度到接受概率的映射要么被直接使用,要么在离线阶段学习。
AV 需要的不仅仅是一个好的排序。它的预算决策会对预测的接受概率求和,并与实测成本进行权衡,因此预测必须针对所服务的特定模型对和工作负载进行校准,这正是下一节中的在线拟合估计器所提供的。
解决方案:在线拟合接受估计器
我们添加了一个轻量级的逻辑回归,它从起草分布中导出的单个标量——即起草模型最可能 token 的对数几率(log-odds)——来估计每个起草 token 的接受概率。它有一个共享的斜率和每个起草位置各自的截距,因此一个 Ktoken 的起草器总共需要 K + 1 个参数。这些参数是在线拟合的,来源于目标模型在正常验证过程中已经产生的接受/拒绝决策。任何现有的草稿检查点都可以免费获得 AV。
本节的其余部分将介绍该设计的两个部分:估计器评分的量是什么,以及其系数如何在服务期间拟合。
对分布进行评分
给定草稿 token 的置信度分数是使用逐位置的逻辑回归来估计的:
其中 ω 是在所有草稿位置共享的拟合斜率,βi 是拟合的逐位置截距,而 q 是草稿分布。备选的对数几率(log-odds)形式使这一关系更加清晰:
logit(qmax) 是估计器的特征,也是草稿中最可能 token 的对数几率。直观地说,它表示草稿模型对其预测的置信程度。它由系数 ω 和 βi 进行线性变换,以预测草稿被目标模型接受的对数几率。其 sigmoid 值即为 p,即估计的接受率,它被用作 AV 的置信度分数。
其他考虑过的特征
我们考虑并因各种原因否决了若干备选特征。在评估一个特征时,我们最关心的四个主要维度是:
- 无损性 —— 该特征是否会在投机解码(speculative decoding)过程中使输出分布产生偏差。
- 曲线下面积(AUC) —— 随机选择的一个被接受的草稿得分高于随机选择的一个被拒绝草稿的概率。这衡量了在被接受草稿与被拒绝草稿之间的 区分能力 。数值越高表示区分能力越好,而 0.5 相当于随机猜测。
- 对数损失(Log-loss) —— 预测接受概率的平均负对数似然,它会惩罚自信的错误答案并奖励校准良好的预测。数值越低表示对给定草稿的真实接受概率的预测能力越好。
- 期望校准误差 (Expected Calibration Error, ECE) —— 根据每个草稿的预测接受概率将其分桶,然后在每个桶内测量平均预测值与平均观测频率之间的误差,并按桶占用率加权。这衡量的是 校准度,数值越低表示为草稿分配的概率与相似评分草稿的真实频率匹配的能力越好。
无损性是这些特征必须具备的不可妥协属性。否则,我们就破坏了投机解码输出目标模型精确分布这一根本保证。AUC 和 ECE 都对 AV 的裁剪决策很重要,但方式不同。AUC 对于存活概率的 局部排序 很重要:
survival = confidence_probs[idx_mapping].cumprod(dim=1)
...
winners = flat.topk(draft_budget).indicesAUC 确保更可能被接受的草稿 token 优先于较不可能被接受的草稿 token 被接纳。另一方面,ECE 对于 全局 预算决策很重要:
num_tokens_to_estimated_accepted_tokens = np.concatenate(
([num_sampling_requests], num_sampling_requests + np.cumsum(scores))
)
costs = draft_cost_ms[...] + verify_cost_ms[...]
...
draft_budget = int(np.argmax(num_tokens_to_estimated_accepted_tokens / costs))概率被求和后再除以测得的成本表。ECE 确保估计的接受 token 数量符合实际情况。
下表列出了各种实验过的特征,以及它们在四个类别上的得分。这些得分是在服务 DeepSeek-V4-Flash + DSpark(temp=1, top-p=0.95, conc=64)、不启用 AV 的情况下,在五个数据集上收集的约4.5M条带标签草稿上测得的: SPEED-Bench 2k low/high-entropy、GSM8K、HumanEval 和 MT-Bench。最后两行是参照而非拟合特征:分别是直接用作接受概率、未经拟合的 drafter 的 qmax ,以及训练好的置信度头的得分。
| 特征 | 无损 | AUC | log-loss | ECE |
|---|---|---|---|---|
| log(qmax) | 是 | 0.8069 | 0.4813 | 0.0592 |
| log(qmax) − log(q2nd) (top-2 margin) | 是 | 0.8156 | 0.4437 | 0.0105 |
| H(q)(熵) | 是 | 0.8321 | 0.4577 | 0.0638 |
| −log(−log(qmax)) | 是 | 0.8336 | 0.4289 | 0.0103 |
| logit(qmax)(已发布) | 是 | 0.8336 | 0.4284 | 0.0100 |
| logit(qsampled) | 否 | 0.8553 | 0.4040 | 0.0152 |
| −log(−log(qsampled)) | 否 | 0.8554 | 0.4075 | 0.0193 |
| qmax (未拟合,直接用作概率) | 是 | 0.8259 | 0.4880 | 0.0736 |
| trained confidence head | 是 | 0.8191 | 0.4449 | 0.0052 |
logit(qsampled) 和 −log(−log(qsampled)) 在 AUC 方面明显优于表中选定的特征,但没有采用,因为基于它们进行裁剪会导致输出分布有偏。两者读取 qsampled,即起草者实际抽取的 token 的概率。基于该值的函数对草稿进行裁剪,会使在位置 i 处是否验证的决定依赖于 xi 本身,因此经过裁剪后存活的草稿不再服从 q分布。标准拒绝采样以概率 min(1, p/q) 接受一个 token,期望 q 是草稿 token 被采样时的分布。但基于 qsampled 进行裁剪会使输出分布偏向起草者置信度较高的 token。1
The qmax "no fit" 行说明了为什么我们要进行拟合,而不是像 EAGLE-2 构建草稿树时那样直接使用起草者自身的概率。如果直接使用,起草者的 top-token 概率在草稿排序上其实优于训练出的置信度头(AUC 为 0.8259 vs 0.8191)。然而,它的校准效果不佳。在带标签的草稿上,其平均预测值为 0.784,而实际接受率为 0.723,且其 ECE 比已上线的 logit( 差 7 倍。qmax) 特征差 7 倍(0.0736 vs 0.0100)。起草者的 top-token 概率只反映起草者对自身预测的置信程度,而不能反映目标模型是否会认同。这种一致性还进一步受采样设置和工作负载的影响。在线拟合可以直接从目标的接受/拒绝决策中学到这一映射关系,从而获得更好的校准,而这正是预算决策所依赖的。
我们最终选择了 logit(qmax) 特征,它在合理成本下兼顾了良好的 AUC 和 ECE。这也是一个自然的选择,因为它与我们试图估计的量共享对数几率尺度和分辨率。
与训练出的置信度头的对比
如上表所示,对于 DeepSeek-V4-Flash + DSpark,估计器在 AUC 和对数似然损失上都优于置信度头,但在 ECE 上表现较差。下表总结了差异:
| AUC ↑ | log-loss ↓ | ECE ↓ | |
|---|---|---|---|
| 估计器 logit(qmax) | 0.8336 | 0.4284 | 0.0100 |
| 训练的置信度头 | 0.8191 | 0.4449 | 0.0052 |
| Δ (估计器 − 头) | +0.0146 | −0.0166 | +0.0048 |
然而,一旦我们排除第一个草稿,情况就发生了很大变化:
| AUC ↑ | log-loss ↓ | ECE ↓ | |
|---|---|---|---|
| 估计器 logit(qmax) | 0.8352 | 0.4420 | 0.0103 |
| 训练的置信度头 | 0.8075 | 0.4743 | 0.0090 |
| Δ (估计器 − 头) | +0.0278 | −0.0323 | +0.0013 |
此时头与估计器在校准上几乎持平。每个位置的 AUC 分解有助于解释原因:

置信度头是第一个草稿位置更好的预测器,但估计器从第二个位置起取得领先。差距随深度扩大,到最后一个位置时估计器领先 0.08 AUC。两个预测器在第五个位置之后也都出现下降。这可能是因为 DSV4-Flash 的 DSpark 声明的块大小为 5,而起草器从未在该长度之后接受过训练,因此草稿本身在那个位置之后变差了。
由于存活率是一个连乘积,且第一个草稿位置总是携带请求的最高分,因此该位置的 token 较少成为预算削减的对象。估计器的优势恰好位于裁剪发生之处,这解释了为什么估计器在端到端性能上能够匹敌置信度头。
系数拟合
系数 ω 和 βi 在请求的实时服务过程中被持续重新拟合。上一次解码步骤中提出的草稿 token 会在下一次解码步骤中由目标模型进行验证。只有到第一次拒绝(如有)为止的草稿 token 才可用于训练,因为目标模型已明确为它们标注了(接受或拒绝)。
我们使用迭代重加权最小二乘法(IRLS)来最小化预测与标签之间的对数似然损失。该最小化是通过对对数似然损失的二阶泰勒近似来进行的。ω 和 βi 的优化步骤通过求解方程组获得
其中 Δθ 是共享斜率 ω 和逐位置截距 β 的增量i, H 是损失函数的 Hessian 矩阵,形状为 (K + 1) × (K + 1),而 g 是损失函数的梯度,大小为 K + 1.
每隔固定的 N 个 decode 步骤后会进行一次 refit。在该区间内的每个 decode 步骤中,我们会累积由该轮收集的系数、特征和标签推导出的 Hessian 和梯度值。这样做将一轮内的内存上界限制在 O(K²),相比之下,如果我们改为收集原始标签,则会是 O(N × B × K)。在该轮的最后一步,求解该方程组并更新系数。
正如人们所预料的,较深的草稿比较浅的草稿更少被接受。因此,较深的草稿位置在一轮中可能会缺乏标签。为了减轻这种情况对 refit 过程的影响,做出了两个设计决策:
- Shared Slope:斜率在所有草稿位置之间共享,以防止深度处数据稀疏导致的噪声更新。预测对斜率误差比对截距误差敏感得多,因此共享使得牛顿步是良定的。此外,经验测量表明,共享斜率在精度上几乎没有损失(仅 0.0002 AUC 和 0.0003 log-loss)。
- Step Damping:每个系数的更新根据支持证据的数量使用公式 n / (n + constant) 进行缩放,其中 n 是被评分草稿的数量。这确保标签较少的较深位置更保守地移动,防止基于噪声的更新。
Slope vs Intercept Roles
我们在多个模型/数据集组合中跟踪了拟合出的系数,这两类参数的表现非常不同。
固定模型对并改变工作负载:在五个工作负载上分别独立拟合 DSV4-Flash + DSpark,斜率几乎不动(0.51 到 0.55),与工作负载的难度不相关(相对平均草稿熵 r = −0.08)。截距则相反:第一个草稿位置的截距与草稿熵的相关性为 r = −0.89,在较可预测的工作负载上约为 0.5–0.6,而在最不可预测的工作负载上降至 0 以下。
| 数据集 | 接受率 | 平均草稿熵 | 斜率 ω | 截距 β0 |
|---|---|---|---|---|
| gsm8k | 0.781 | 0.562 | 0.5365 | +0.478 |
| humaneval | 0.751 | 0.669 | 0.5135 | +0.486 |
| speed-bench 2k 低熵 | 0.755 | 0.703 | 0.5087 | +0.610 |
| mt-bench | 0.714 | 0.800 | 0.5495 | +0.181 |
| speed-bench 2k 高熵 | 0.642 | 1.077 | 0.5197 | −0.089 |
现在变换模型组合: 各组合之间的斜率范围为 0.45 到 0.59,而在每个组合内部保持紧凑。截距在各组合之间也不同,因此与斜率不同,它并非单独某一根轴的属性。
| 模型 | nspec | 斜率 ω | ω sd | 截距 β0 |
|---|---|---|---|---|
| DeepSeek-V4-Flash + DSpark | 5 | 0.5013 | 0.0250 | +0.279 |
| MiMo-V2.5-Pro-FP4 + DFlash | 8 | 0.5197 | 0.0415 | −1.000 |
| Inkling-NVFP4 + MTP | 8 | 0.5859 | 0.0349 | −0.572 |
| Muse-Glimmer-30B + DFlash2 | 7 | 0.4450 | 0.0323 | +0.167 |
综合来看,这两张表暗示了一种分工。斜率衡量草稿模型对自己何时正确的把握程度。这是目标/草稿模型组合以及草稿采样方法的属性,这就是为什么仅改变工作负载时它几乎不动。截距则吸收了其余部分:每个草稿位置的基础接受率,它随深度下降,在更不可预测的内容上进一步下降。该基础接受率既取决于模型组合也取决于工作负载,这就是为什么截距沿两根轴变化而斜率只沿一根轴变化。
基准测试
我们对三个此前完全无法使用 AV 的检查点(MiMo-V2.5-Pro-FP4 + DFlash、Inkling-NVFP4 + MTP 和 Muse-Glimmer-30B + DFlash2)进行了基准测试,并以 DSV4-Flash + DSpark + 估计器以及 DSV4-Flash + DSpark + 置信头作为参照。以下收益是在 AV 关闭与开启、temperature 1.0、top-p 0.95、并发 64 的条件下,在四个数据集上测得的。

与固定验证相比,在相同投机长度下,在线估计器在所有基准数据集上都是一种提升。然而,仅凭这一收益并不能说明全部情况。通常在特定并发下,可以找到一个更小的固定长度,使其在最大投机长度下优于 AV。下面的 Pareto 曲线是 DSV4 + DSpark 在一系列固定投机长度与最大投机长度下的 AV 上测得的:

在所有测得的并发下,在线估计器与置信头的性能大致相当。然而,在线估计器并不是要取代置信头,而是在缺少置信头时的即插即用替代方案。我们来看看它在一个目前缺少置信头的模型组合上的表现。下面是 MiMo-V2.5-Pro-FP4 + DFlash 在一系列固定投机长度与 AV 下的 Pareto 曲线:

AV 在 7 个并发中的 5 个位于吞吐量-交互性前沿上。
局限性
- 目标模型的注意力后端必须支持可变长度验证。这与 DSpark AV 已有的前提条件相同。
- MTP 和 EAGLE 从 AV 中获得的收益不如 DFlash 和 DSpark。这是因为那些自回归投机器为起草可能在校验前被裁剪的 token 付出了相对更大的代价。
vLLM 使用方法
AV 通过 speculative config 启用。在草稿模型 (1) 没有置信头且 (2) 其所有后端都支持可变长度注意力的情况下,会自动选择在线估计器:
vllm serve <target_model> \
...
--speculative-config '{
"model": "<draft_model>",
"method": "<method>",
"num_speculative_tokens": <num_speculative_tokens>,
"draft_sample_method": "probabilistic",
"enable_adaptive_verification": true
}'致谢
这项工作由 Giancarlo Delfin(Inferact)完成,并直接建立在 Lucas Wilkinson(Red Hat)和 Benjamin Chislett(NVIDIA)的 Adaptive Verification 之上。
脚注
-
一个仅有两个词元的简单词表 [a, b] 的例子可以用来说明这种偏差。假设 p = [0.5, 0.5], q = [0.2, 0.8],并且当 q(x) < 0.5 时,草稿词元会在验证中被修剪。抽取到 a 会导致修剪,而目标模型从其自身分布 p(x) 中采样词元。然而,抽取到 b 则会进入验证:该词元以概率 min(1, p(b)/q(b)) = 0.625 被接受,否则被拒绝并从残差 norm(max(0, p − q)) = [1, 0] 中重新采样,得到 a。在拒绝采样过程中我们得到 pout(a) = q(a)·p(a) + q(b)·(1 − 0.625) = 0.4 以及 pout(b) = q(a)·p(b) + q(b)·0.625 = 0.6。这与目标分布 [0.5, 0.5] 不同,违反了投机解码的无损保证。 ↩
