vLLM 推出无需置信头的在线拟合接受估计器,让 EAGLE、MTP 等草稿模型可用 Adaptive Verification
Adaptive Verification Without a Confidence Head
vLLM 支持 confidence scoring 扩展到所有基于草稿模型的投机类型,通过在线拟合的 logistic 回归从草发者 logits 推导 logit(q_max) 特征来预测目标模型的接受概率,作为 Adaptive Verification 的置信分。
原文给出无置信头草稿模型启用 Adaptive Verification 的在线估计方法、设计取舍和实测数据,方法可直接在 vLLM 中配置复用。

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 的对数几率——来估计每个草稿 token 的接受概率。每个草稿位置有一个共享斜率和截距,因此一个 K token 的草稿模型总共需要 K + 1 个参数。这些参数从目标模型在正常验证期间已经产生的接受/拒绝决策中在线拟合。任何现有的草稿检查点都能免费获得 AV。
本节剩余部分涵盖该设计的两个部分:估计器对什么量进行评分,以及其系数在服务期间如何拟合。
对分布进行评分
给定草稿 token 的置信度分数使用逐位置逻辑回归进行估计:
其中 ω 是在所有草稿位置上共享的拟合斜率,βi 是拟合的逐位置截距,q 是草稿分布。另一种对数几率形式使这一关系更加清晰:
logit(qmax) 是该估计器的特征,即草稿最可能 token 的对数几率。直观地说,它表示草稿模型对其预测的置信程度。它被系数 ω 和 βi 线性变换,以预测草稿被目标模型接受的对数几率。其 sigmoid 值即为 p,即估计的接受率,用作 AV 的置信度分数。
其他考虑过的特征
还考虑过若干备选特征,但出于各种原因被否决。在评估特征时,我们最关注的四个主要维度是:
- 无损性 —— 该特征是否会在投机解码过程中使输出分布产生偏差。
- 曲线下面积(AUC) —— 随机选取的一个被接受的草稿得分高于随机选取的一个被拒绝草稿的概率。这衡量的是应被接受与应被拒绝草稿之间的区分度。值越高表示区分能力越强,0.5 表示随机猜测。
- 对数损失 —— 预测接受概率的平均负对数似然,它对自信的错误答案进行惩罚,并奖励良好的校准。值越低表示预测给定草稿真实接受概率的能力越强。
- 期望校准误差(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 的过程中收集的约 450 万个带标签草稿上测得的,涵盖五个数据集:SPEED-Bench 2k 低/高熵、GSM8K、HumanEval 和 MT-Bench。最后两行是参考项而非拟合特征:直接使用草稿器的 qmax 作为接受概率而不进行拟合,以及训练好的置信度头的得分。
| 特征 | 无损 | AUC | 对数损失 | ECE |
|---|---|---|---|---|
| log(qmax) | 是 | 0.8069 | 0.4813 | 0.0592 |
| log(qmax) − log(q2nd)(top-2 差距) | 是 | 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 |
| 训练后的置信度头 | 是 | 0.8191 | 0.4449 | 0.0052 |
logit(qsampled) 和 −log(−log(qsampled)) 在 AUC 方面明显优于表中选用的特征,但未被采用,因为基于它们进行裁剪会导致输出分布有偏。两者都读取 qsampled,即 drafter 实际抽取的 token 的概率。基于该值的函数对草稿进行裁剪,会使在位置 i 是否验证的决策依赖于 xi 本身,因此经过裁剪后存活的草稿不再服从 q 分布。标准拒绝采样以概率 min(1, p/q) 接受一个 token,期望 q 是草稿 token 被采样时所服从的分布。但基于 qsampled 进行裁剪会使输出的分布偏向 drafter 置信度更高的 token。1
qmax 的“不拟合”行说明了我们为何要进行拟合,而不是像 EAGLE-2 在构建草稿树时那样直接使用 drafter 自身的概率。直接使用时,drafter 的 top-token 概率对草稿的排序实际上优于训练后的置信度头(AUC 0.8259 对 0.8191)。然而,它校准得不好。在带标签的草稿上,其平均预测值为 0.784,而观测到的接受率为 0.723,且其 ECE 比实际采用的 logit(qmax) 特征差 7 倍(0.0736 对 0.0100)。drafter 的 top-token 概率只反映 drafter 对自身预测的置信程度,而不反映目标模型是否会认同。这种认同还进一步受到采样设置和工作负载的影响。在线拟合直接从目标的接受/拒绝决策中学习这种映射,从而获得更好的校准,而预算决策正是依赖于此。
我们最终选择了 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,而草稿模型从未接受过超出该范围的训练,因此那里的草稿本身质量就变差了。
由于生存概率是一个连乘结果,而第一个草稿位置总是承载着请求的最高分数,所以它较少成为预算裁剪的对象。估计器的优势恰好出现在发生裁剪的地方,这也解释了为什么估计器能在端到端性能上与置信度头持平。
拟合系数
系数 ω 和 βi 在请求的实时服务过程中被持续重新拟合。上一个解码步骤中提出的草稿 token 会在下一个解码步骤中被目标模型验证。只有直到第一次拒绝(如果有的话)之前的草稿 token 才有资格用于训练,因为目标模型已明确为它们打上了标签(接受或拒绝)。
我们使用迭代重加权最小二乘法(IRLS)来最小化预测值与标签之间的对数似然损失。该最小化是在对数似然损失的二阶泰勒近似上进行的。ω 和 βi 的优化步骤通过求解以下方程组获得:
其中 Δθ 是共享斜率 ω 和逐位置截距 βi 的增量,H 是损失函数的 Hessian 矩阵,形状为 (K + 1) × (K + 1),g 是损失函数的梯度,大小为 K + 1。
每经过固定的 N 个解码步骤后就会进行一次重新拟合。在该区间内的每个解码步骤中,我们会累积 Hessian 和梯度值,这些值来源于该轮中收集的系数、特征和标签。这样做将一轮内的内存占用上界控制在 O(K²),相比之下,如果改为收集原始标签,则内存占用为 O(N × B × K)。在该轮的最后一步,求解方程组并更新系数。
正如人们所料,较深的草稿比较浅的草稿被接受的频率更低。因此,在一轮中,较深的草稿位置可能会缺乏标签。为了减轻这对重新拟合过程的影响,我们做出了两项设计决策:
- 共享斜率:斜率在所有草稿位置之间共享,以防止因深度数据稀疏而导致的噪声更新。预测对斜率误差的敏感度远高于对截距误差的敏感度,因此共享斜率使牛顿步能够被良好地确定。此外,实证测量表明,共享斜率在准确度方面几乎没有代价(仅损失 0.0002 AUC 和 0.0003 对数损失)。
- 步长阻尼:每个系数的更新量根据支持证据的数量进行缩放,使用公式 n / (n + 常数),其中 n 是已评分草稿的数量。这确保了标签较少的较深位置更新更为保守,防止基于噪声进行更新。
斜率与截距的角色
我们在多个模型/数据集组合上跟踪了拟合出的系数,发现这两类参数的行为差异很大。
固定模型对,改变工作负载:在五个工作负载上分别独立拟合 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 | 斜率 ω | ω 标准差 | 截距 β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 关闭与开启、温度 1.0、top-p 0.95、并发 64 的条件下,在四个数据集上测得的。

与固定验证相比,在相同推测长度下,在线估计器在所有基准数据集上都有优势。然而,仅凭这一增益并不能说明全部情况。通常,在特定并发度下,可以找到一个更小的固定长度,其表现优于最大推测长度下的 AV。下面的帕累托曲线是在 DSV4 + DSpark 上,对一系列固定推测长度以及最大推测长度下的 AV 进行扫描得到的:

在所有测量的并发度下,在线估计器和置信头在性能上大致相当。然而,在线估计器并非旨在替代置信头,而是在缺少置信头时作为即插即用的替代方案。让我们看看它在一个目前缺少置信头的模型对上的表现。下面是 MiMo-V2.5-Pro-FP4 + DFlash 在一系列固定推测长度和 AV 下的帕累托曲线:

在 7 个并发度中的 5 个上,AV 位于吞吐量-交互性前沿。
局限性
- 目标模型的注意力后端必须支持可变长度验证。这与 DSpark AV 已有的前提条件相同。
- 与 DFlash 和 DSpark 相比,MTP 和 EAGLE 从 AV 中获得的收益更少。这是因为这些自回归投机器为起草可能在验证前被裁剪的 token 付出了按比例更大的成本。
vLLM 用法
AV 通过投机配置启用。在(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 之上。
脚注
-
一个使用简单双 token 词汇表 [a, b] 的例子可以用来说明这种偏差。假设 p = [0.5, 0.5],q = [0.2, 0.8],并且如果 q(x) < 0.5,则草稿 token 会从验证中被裁剪。抽到 a 会导致裁剪,目标模型从其自身分布 p(x) 中采样一个 token。然而,抽到 b 会导致验证:该 token 以概率 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] 不同,违反了投机解码的无损保证。↩
来源:vLLM 官方博客 · vllm.ai