再过几天就是 2026 年了,对即将过去的 2025 年做个小总结吧;
虽然前些年对机器学习有些知识储备,但系统性的进行“复健”,是从年初deepseek爆火之后才开始的;同时因为平日里工作已经非常卷了(特别最近休息的都很差),也只能再去挤那为数不多的个人时间,精力确实有限,虽然各个方向都有所涉猎,但没办法做到很深入,自己定的 todo list 上还有好几页没有完成…
但 25 年一共输出了 26 篇博客(确实不少,佩服自己这方面的坚持),也只是今年收获的一小部分,记录在自己小本本上的东西远大于这些内容;对机器学习、强化学习、大模型训推都形成了自己的理解,算是收获满满;
还是那句话,兴趣驱动可以走的更远,希望自己 26年继续努力,早日结成元婴~
今天继续 vLLM 推理框架,核心思想的第四篇,前三篇文章分别介绍了:
- ① 分页注意力 paged attention(点积查看)
- ② 动态批处理 continuous batching(点积查看)
- ③ Kernel内核优化(attn backend、cuBLAS、CUTLASS)(点积查看)
还是按照官方提供的"卖点",今天盘一盘 vLLM 的投机解码;以下内容来自 【投机解码的论文】 与 vLLM源码;

1. 投机解码原理
1.1 投机解码 vs 投机采样
首先回顾一下投机解码的原理,但在开始前先谈谈 投机解码(speculative decoding) 和 投机采样(sepculative sampling):
投机解码 speculative decoding:核心的是decoding投机采样 sepculative sampling:核心的是sampling
它们本质上确实不是一个东西,前者是训推优化的一种手段,优化的是decoding,后者是算法,是如何进行sampling;
但实际上完全不需要较真,平日里大家99%都把这俩当成同一个东西来讲;
1.2 核心原理
用下面这幅图简单阐述下投机解码的核心原理:
- 左面的图片,展示的是正常NTP自回归解码,局限性在于,一次只能生成一个token(别说MTP)
- 右面的图片,就是
投机解码,核心是有两个部分draft和verify,也就是先草稿-后验证的范式,由草稿模型/draft model一次性的生成多个token,然后再由目标模型/verify model并行验证,最终实现一次性的得到多个token的目标

整体上可以分成两个阶段:
- 首先是
草稿阶段,也就是草稿模型一次性生成多个token,从公式上看:
- 给定输入 x 1 , x 2 , . . , x t x_1,x_2,..,x_t x1,x2,..,xt 和 草稿模型 M d r a f t M_{draft} Mdraft
- 草稿模型生成输出序列token的公式为: x ~ 1 , x ~ 2 , . . . , x ~ k ∼ p 1 , p 2 , . . . p k = M d r a f t ( x < t + 1 ) \tilde{x}_1,\tilde{x}_2,...,\tilde{x}_k \sim p_1,p_2,...p_k=M_{draft}(x_{<t+1}) x~1,x~2,...,x~k∼p1,p2,...pk=Mdraft(x<t+1),也就是预测了下 k k k 个token,以及 p p p 的条件概率
这里对比正常目标大模型生成下一个token的公式为: x t + 1 ∼ q t + 1 = M t a r g e t ( x ∣ x < t + 1 ) x_{t+1} \sim q_{t+1} = M_{target}(x|x_{<t+1}) xt+1∼qt+1=Mtarget(x∣x<t+1),其中 q q q 是条件分布概率,从 q q q 采样得到输出token x x x
- 然后是
验证阶段,也就是目标模型 M t a r g e t M_{target} Mtarget根据规则检验 M d r a f t M_{draft} Mdraft的输出是否可接受,从公式上看:
- q i ∼ M t a r g e t ( x ∣ x < t + 1 , x ~ < k + 1 ) q_i \sim M_{target}(x|x_{<t+1}, \tilde{x}_{<k+1}) qi∼Mtarget(x∣x<t+1,x~<k+1)
- 也就是目标模型,根据原始用户 query 和 草稿模型输出序列,一次性的并行得到这 k k k 个输出token的条件概率,然后用验证规则进行验证
1.3 草稿模型
由上述流程可知,草稿模型的好坏对整个流程有着很大影响,主要体现在两个方面:
- 推理速度:草稿模型都是小模型,架构简单、参数量小,所以可以保证推理延时低、资源占用少
- 推理质量:为了保证质量,一般可以使用和目标模型 同源同系列 的小模型,有能力的话,可以从目标模型 蒸馏出 一个小模型;甚至有的还会用原始目标模型,但调整温度、批次等配置,无需引入额外模型;这些手段的目的都是 对齐 目标模型和草稿模型,如果没对齐的话,不同架构、不同数据分布、不同语义理解的两个模型,输出偏差较大,会导致验证阶段的通过率低,反倒是降低整体推理能力
1.4 验证策略
草稿模型输出的每一个token,都要经过并行验证,整体验证策略可分成两类:贪婪 vs 投机采用;
贪婪:每次只选择概率最大的作为输出token,也就是去验证目标模型输出 q i = x ~ i q_i=\tilde{x}_i qi=x~i,遇到的第一个验证失败的token位置,叫做分叉点,在分叉点之后的草稿模型的输出,会被直接丢弃,而分叉点处的token,由目标模型概率最大的token替代,但贪婪策略接受率较低,因为需要最大概率的token完全相同才会被接受;投机采样: r < m i n ( 1 , q i ( x ~ i ) p i ( x ~ i ) ) r<min(1,\frac{q_i(\tilde{x}_i)}{p_i(\tilde{x}_i)}) r<min(1,pi(x~i)qi(x~i)),也就是为了保证更高的接受率,同时保证最终输出分布与目标模型一致,用 随机数 r r r 和两个模型条件概率比值进行比较,判断是否接受,同时在遇到分叉点后,使用 修正采样(拒绝了草稿模型的这个token,但不拒绝这次生成),从调整后的分布中重新进行随机得到最终token
2. vLLM中的使用
在 vLLM 中,投机解码主要有以下2块核心内容:
draft modeltarget model与rejection_sampling
整体流程为:
- 初始化配置
- 草稿token生成
- 目标模型执行
- 拒绝采样验证
- 结果处理
下面就不一行行的看代码了,就挑核心的列一下
2.1 配置
SpeculativeConfig 是投机解码的配置类,可以配置各种投机解码方法,例如:轻量级MLP的eagle、mtp(这里看到了我团的 longcat_flash_mtp 甚是喜欢啊~),除此之外还有,生成多少个token、TP_size 等一系列配置

2.2 草稿 Proposer
vLLM 为每种投机方法都设计了对应的 proposer,下面就是 eagle 的草稿模型

2.3 目标模型与拒绝采样
核心是 rejection_sample 类,用于验证 草稿模型 生成的投机token,包括:计算概率分布、执行拒绝采样、确定接受的token、如果有拒绝的token则生成恢复token…

其中有分别有 贪婪策略 与 随机投机采样策略 两种实现:



5045

被折叠的 条评论
为什么被折叠?



