音乐
暂未播放
Medusa 完全拆解:多头树式候选如何用一次验证解码多个 Token
问题:为什么自回归解码总在等待下一个 Token#
大语言模型的生成阶段有一个很难绕开的依赖:只有得到第 t 个 token,才能把它送进模型并计算第 t+1 个 token。假设最终要生成 N 个 token,标准自回归解码就要串行执行大约 N 次模型前向。GPU 可以在一次前向内部并行计算矩阵乘法,却不能提前知道尚未生成的 token,这使时间维度上的并行性几乎为零。
单请求、低 batch 的 decode 往往又不是算力受限,而是显存带宽受限。每一步只处理一个新 token,但线性层仍要读取庞大的模型权重。以参数量为 P、权重每参数占 b 字节为例,忽略缓存命中与张量并行通信,一次解码前向至少要搬运约 Pb 字节权重。每次只产出一个 token 时,权重读取的成本无法被更多 token 摊薄。
这也是投机解码的基本机会:让一个便宜的提议器先猜多个 token,再由目标模型一次并行验证。若一次目标模型前向最终提交了 A 个 token,理想情况下串行步数就从 N 降为约 N/A。真正的加速比还要扣除提议器、候选验证、采样和 KV Cache 整理的开销,所以关键不是“猜得越多越好”,而是让平均接受长度的增益超过单步延迟的增长。
传统投机解码通常还要维护一套独立草稿模型。草稿模型太小,预测与目标模型分布相差大,接受率低;草稿模型太大,自己就会消耗可观的算力和显存带宽。多模型部署还会带来额外权重、并行切分和调度复杂度。Medusa 的切入点是:不再运行第二个 Transformer,而是在目标模型最后一层隐藏状态上挂几个很轻的预测头。
Medusa 由普林斯顿大学、Together AI、伊利诺伊大学厄巴纳-香槟分校等团队提出,论文发表于 ICML 2024。它把一次迭代拆成三个动作:多头产生候选、Tree Attention 并行验证、接受一条候选路径的最长前缀。论文报告的重点是 batch size 1 的低延迟场景;这点很重要,因为高并发吞吐服务的瓶颈与收益曲线并不相同。
Medusa 的核心思路与系统位置#
Medusa 不是“一个头直接吐出一句话”。它仍然保留目标模型的自回归校验,只是把未来几个位置的候选组织成树,让目标模型在一次前向中同时判断多条路径。整个数据流如下图所示。

图源:Medusa 论文与官方 arXiv 源文件。蓝色区域是原模型,红色区域是附加的 Medusa Heads。所有头读取同一个末层隐藏状态,却分别预测不同的未来位置;右侧 Top-k 结果组合成候选,随后目标模型选出可接受的最长路径。图中一次提交了 “It is difficult”,因此一次验证替代了三次普通解码迭代。
给定当前上下文 x1:t,目标模型最后一层在位置 t 的隐藏状态记为 ht∈Rd。原 LM Head 给出下一 token 的分布:
pt(0)=softmax(WLMht).Medusa 再添加 K 个头。第 k 个附加头预测更远的 xt+k+1,论文采用带残差的一层前馈变换:
pt(k)=softmax(W2(k)(SiLU(W1(k)ht)+ht)),k=1,…,K.这里 d 是隐藏维度,V 是词表大小;按列向量记法,W1(k)∈Rd×d,W2(k)∈RV×d。W1(k) 负责对共享隐藏状态做轻量变换,残差项 +ht 保留原模型已经形成的语义表示,W2(k) 再把它投影到词表。
要区分两个容易混淆的“多头”。Transformer 的 multi-head attention 是把同一层注意力拆成多个 Q/K/V 子空间;Medusa Heads 是挂在模型输出端、预测不同未来位置的词表分类器。二者所处层级和职责完全不同。
作为背景,论文给出只适配附加头的 Medusa-1 与主干共同适配的 Medusa-2 两种配置;后文只讨论两者共享的推理路径。
多个 Medusa Head 如何产生候选树#
若每个未来位置只取 argmax,K 个头只能给出一条长度 K 的候选。问题是各头并不是条件自回归的:第 2 个附加头在产生 xt+3 的分布时,并没有先看到第 1 个附加头猜出的 xt+2。一个早期位置猜错,后面的整条链都会失效。Medusa 因而对每个头保留多个高概率 token,并把组合看成候选树。
设第 k 层保留 sk 个候选。如果机械取笛卡尔积,深度 k 会有
nk=i=1∏ksi个节点,整棵树需要验证的新增节点数是
Ntree=k=1∑Ki=1∏ksi.例如两层分别保留 2 和 3 个候选,会形成 2+2×3=8 个节点,对应 6 条长度为 2 的完整路径。它比把 6 条序列各自展开为 12 个 token 少,因为相同的第一层前缀只保存和计算一次。这种前缀共享正是“树”比“候选 batch”更合适的原因。
但规则笛卡尔积很快爆炸。若 4 层都取 top-4,节点数为 4+16+64+256=340。目标模型虽然只前向一次,却要处理 340 个查询位置,线性层和注意力都会从“顺手多算一点”变成显著计算负担。因此论文实际采用校准集统计不同头、不同排名的命中概率,并在固定节点预算下构造不平衡稀疏树。
记第 k 个头第 i 名预测恰好正确的概率为 ak(i)。在论文的独立性近似下,一条排名路径 (i1,…,ik) 的概率估计为
q(i1,…,ik)=j=1∏kaj(ij).每加入一个合法节点,它对期望接受长度的边际贡献可用对应的 q 估计。于是可以从根开始,每次加入“父节点已存在且估计概率最大”的节点,直到耗尽节点预算。这样产生的树通常在浅层较宽、深层只保留少数强路径,因为越远的头越不确定,概率连乘也会快速衰减。

图源:Medusa 论文 arXiv 源文件中的稀疏树示例。灰边表示被并行验证的候选,红线是最终接受路径。它直观展示了固定预算不该平均分给每个分支:高概率前缀值得继续向深处扩展,低概率分支保留一两层即可。
手算一棵两层候选树#
用符号例子可以把索引关系说清楚。设原 LM Head 给出的根 token 是 a,第一个 Medusa Head 的 top-2 是 (b,u),第二个头的 top-2 是 (c,v)。规则组合会得到四条路径:
(a,b,c),(a,b,v),(a,u,c),(a,u,v).树式存储不复制公共前缀,可以展平为 7 个节点:a, b, u, c|b, v|b, c|u, v|u。竖线后的字符表示父节点,不属于 token 内容。若把四条路径直接作为 batch,则要放入 4×3=12 个 token;树布局只需 7 个节点。
设已确认上下文长度为 L,这些节点的位置编号依次是 L、两个 L+1、四个 L+2。节点 c|u 的可见候选集合只能是 {a, u, c|u};它不能看到 b,也不能看到另一个 c|b。目标模型验证后,若它在处理 a 时认为下一 token 应为 u,在处理路径 (a,u) 时认为再下一 token 应为 c,那么本轮就提交 (a,u,c)。候选 (a,b,c) 即便最后的 c 概率很高,也会因为 b 在前一位置失败而只能接受根部 a。
Tree Attention:把一棵树压进一次并行前向#
候选树解决了“猜哪些 token”,接下来要解决“怎样让目标模型一次验证整棵树”。不能直接把树节点当普通序列送入因果注意力。普通下三角 mask 会让排在后面的节点看到所有更早节点,包括其他分支;这样得到的条件概率对应一条根本不存在的混合序列。
Tree Attention 的规则是:一个节点只能看到既有上下文、自己以及自己在树上的祖先,不能看到兄弟、堂兄弟或其他分支的后代。将树节点按深度展开成一维张量后,可以定义验证区内部的布尔掩码
Muv={0,−∞,v∈Ancestors(u)∪{u},其他情况.其中 u 是当前 query 节点,v 是候选区中的 key 节点。加上原提示词的 KV Cache 后,每个候选节点还可以访问全部已确认历史。将 M 加到缩放点积注意力的分数上,softmax 后不合法边的概率为零:
Attention(Q,K,V)=softmax(dhQK⊤+M)V.dh 是单个注意力头的维度。这个掩码不是近似;它保证每个节点的隐藏状态与“单独把从根到该节点的序列送入目标模型”得到的因果上下文一致。多路径因此可以共享一次批量矩阵计算,同时保持条件依赖正确。

图源:Medusa 官方论文图。左边两枚第一层节点是不同前缀,右侧掩码中的每一行对应一个 query。第二层的 “is” 只连接自己和所属的 “It”,另一个分支的第二层 “is” 则只连接自己和 “I”。图中对角线与祖先位置有勾,其他候选节点之间全部屏蔽。
位置编码也必须随树深度而不是展平下标递增。若已确认上下文长度为 L,第一层候选的位置都是 L,第二层都是 L+1,第 k 层都是 L+k−1。对于 RoPE,这意味着同一深度的兄弟节点使用相同旋转位置。若错误地采用展平后的连续位置,兄弟节点会被伪装成先后出现的 token,验证结果就不再等价于各自的真实路径。
官方实现把这套静态结构预编译成四类缓冲:
medusa_attn_mask:记录节点到祖先的可见关系;tree_indices:从各头 top-k 的扁平候选表中取出每个树节点的 token;medusa_position_ids:按节点深度生成位置编号;retrieve_indices:把展平树重新整理成一条条根到叶路径,供接受阶段比较。
这四个张量只取决于树形配置,不依赖提示词内容,可以在启动时生成并驻留 GPU。在线迭代只需填入本轮 top-k token,避免在 Python 侧反复遍历树。可参考官方仓库中 generate_medusa_buffers 的实现。
Tree Attention 并没有消灭计算,它把多条候选的验证变成一个更宽的目标模型前向。其价值来自现代 GPU 的一个不对称事实:低 batch、单 token 前向通常没有喂满计算单元,多处理几十个候选节点增加的延迟远小于重复读取几十次权重。候选继续增大后,线性层和注意力转为 compute-bound,单步延迟会明显上升,所以树大小存在最优点。
接受机制:从无损拒绝采样到典型接受#
目标模型完成树式前向后,每条根到叶路径都得到了逐位置的目标分布。此时不能因为某个深层 token 概率高就跳过它前面的错误 token;可提交部分必须是连续前缀。这是维持自回归语义的核心约束。
在温度为零的贪心解码中,规则最简单。设候选路径为 c1,c2,…,cm,目标模型在对应位置的 argmax 为 g1,g2,…,gm。该路径的接受长度为
A(c)=max{a:cj=gj, ∀j≤a}.在所有路径中取 A(c) 最大者;若多条路径一样长,可按目标模型似然择优。由于只接受与目标模型逐步 argmax 完全一致的前缀,输出 token 与普通贪心解码相同。所谓 Medusa-1 的“无损”首先应在这个明确口径下理解,而不是把任何放宽规则都称为无损。
对于随机采样,若目标是严格保持目标分布 p,可以采用标准投机解码的拒绝采样。草稿分布为 q 时,候选 x 的接受概率是
α(x)=min(1,q(x)p(x)).候选被拒绝后,从校正分布中补采样:
pcorr(x)=∑ymax(0,p(y)−q(y))max(0,p(x)−q(x)).这套规则的价值是最终样本严格服从 p,代价是温度升高时,即使 p 与 q 很接近,两次独立采样也可能选择不同 token,接受长度随之下降。多分支树还能增加候选覆盖,但不能取消概率校正本身。
Medusa 另给出 typical acceptance。它不要求逐样本精确复现目标分布,而是接受目标模型看来“足够典型”的 token。对位置 j 的目标分布 pj,先计算熵
H(pj)=−v=1∑Vpj(v)logpj(v),再定义阈值
τj=min(ϵ,δexp(−H(pj))).当 pj(cj)>τj 时,候选 token 通过该位置。epsilon 是硬概率上限,deltaexp(−H) 是随不确定性变化的阈值:分布熵高时,exp(−H) 小,系统允许更多合理分支;分布尖锐时阈值升高,只有少数高概率 token 会通过。官方实现中的默认参数名是 posterior_threshold=0.3 和 posterior_alpha=0.09,分别对应这里的 ϵ 与 δ,但它们是需要按模型、温度和质量目标校准的工程参数,不是普适常数。
为保证每轮至少推进一步,根部 token 来自原 LM Head,并无条件提交;typical acceptance 只判断其后的附加头候选。系统最终选择通过阈值的最长连续前缀,长度相同时再比较路径似然。
这里存在必须说清的质量边界:typical acceptance 改变了原始采样过程,因此不是分布意义上的无损解码。论文在 MT-Bench 的 writing 与 roleplay 子集上观察到相近质量,但这属于经验结果,不能推出所有任务、温度与阈值下都等价。要求可复现、严格保持目标分布时,应使用贪心精确匹配或带校正的拒绝采样;允许在质量预算内换取更低延迟时,才考虑 typical acceptance。
一次完整解码迭代#
把数据结构和概率规则合起来,一轮 Medusa 解码可以沿以下路径执行:
- 用已确认序列的最后隐藏状态同时计算原 LM Head 和 K 个 Medusa Head。原头决定根 token,附加头各自产生未来位置的 top-k 候选。
- 根据预先搜索好的稀疏树配置,用
tree_indices把 top-k 候选填入展平树。树结构本身不在热路径上动态搜索。 - 给候选节点配置按深度递增的 position ID,并启用只允许访问祖先的 Tree Attention mask。目标模型对整棵树执行一次前向,得到每个节点后继位置的 logits 和临时 KV。
- 用
retrieve_indices恢复各条候选路径,按贪心匹配、拒绝采样或 typical acceptance 求每条路径的连续接受长度,选出最佳路径。 - 把被接受路径的 token 追加到输出,并把对应节点的 KV 从树式临时布局紧凑复制到连续已确认区。未接受分支的 KV 作废;最后一个已接受位置的 logits 与 Medusa logits 成为下一轮候选生成的起点。
第 5 步经常被概念图省略,却是实现正确性的关键。验证整棵树时,KV Cache 中会短暂出现不同分支的状态;下一轮只允许看到选中路径。如果只是移动长度指针而没有按路径索引整理 KV,模型会读到兄弟分支的缓存。官方 update_inference_inputs 会用 retrieve_indices[best_candidate] 计算源位置,再把被接受节点的 KV 原地复制到已确认区尾部,最后更新当前长度。
还要留意一个计数细节:代码中的 accept_length 往往表示附加匹配的边数,而本轮实际追加 token 数是 accept_length + 1,因为根部原 LM Head token 总会提交。比较不同实现的“平均接受长度”时,必须先确认指标是否包含这个保底 token。
速度为什么会提升:收益、成本与上限#
评价 Medusa 不能只看“每轮接受几个 token”,还要看一轮变慢了多少。设普通自回归一步延迟为 TAR,Medusa 一轮平均提交 Aˉ 个 token,其延迟可拆成
TM=Theads+Ttree verify+Taccept+TKV commit.忽略首轮预填充,近似加速比为
S≈TMAˉTAR=γAˉ,γ=TARTM.Aˉ 是平均每轮实际提交数,γ 是 Medusa 相对普通一步的延迟膨胀。扩大候选树通常会提高 Aˉ,也会提高 γ;只有前者的相对增幅更大时,总延迟才会下降。例如平均提交 3.47 个 token、单轮开销为普通一步的 1.22 倍,对应的粗略上限是 3.47/1.22≈2.84 倍,而不是 3.47 倍。
论文在 Vicuna-7B 与 Vicuna-13B、ShareGPT 适配数据、MT-Bench 生成场景上报告了以下 wall-time 结果。基线是当时的 Hugging Face 默认实现,因而数字不应直接外推到今天不同 kernel、量化方式或服务框架。

图源:ICML 2024 Medusa 论文。Medusa-1 在 7B 和 13B 上分别达到 2.18 倍与 2.33 倍,Medusa-2 在两种尺寸上均为 2.83 倍。后者命中率更高,但需要改变主干模型;前者只加头,部署边界更清晰。
论文的组件消融给出一条更有解释力的链条:仅有 Medusa Heads、没有树注意力时约 1.5 倍;加入树注意力约 1.9 倍;再采用优化稀疏树约 2.2 倍;使用命中率更高的 Medusa-2 约 2.8 倍。这说明收益不是“多几个输出层”自动产生的,候选覆盖、共享前缀验证和树形预算缺一不可。
为什么“多算几十个节点”可能只慢一点#
以一个形状为 m×n 的线性层权重和 q 个候选输入为例,矩阵乘大约需要 2mnq 次浮点运算。若权重元素占 bw 字节,并暂时忽略激活与缓存,读取权重约需 mnbw 字节,算术强度近似为
I(q)≈mnbw2mnq=bw2qFLOP/Byte.普通单 token 解码对应 q=1,每读一次权重只服务一个输入向量;树式验证把 q 提高到几十,权重 tile 可在片上被多个候选复用,算术强度随 q 增长。这就是 Medusa 用闲置算力换串行步数的硬件基础。
这个近似也解释了为什么收益不会无限增长。候选激活、词表 logits 和中间结果会随 q 增加;当 GEMM 跨过 Roofline 的转折点成为算力受限后,再扩大树会近似线性增加计算时间。注意力部分还要让多个 query 分别读取历史 KV,其带宽并不会像权重那样完全摊薄。模型越小、batch 越大、上下文越长,转折点通常越早到来。
树大小的消融也揭示了上限:在论文设置中,64 节点的优化稀疏树可以取得比 256 节点随机稠密树更好的接受率。节点继续增加时,接受率的改善逐渐趋缓,tokens/s 却因矩阵乘与注意力计算增长而下降。换句话说,候选树优化的目标不是最大化命中率,而是在给定硬件上最大化 Aˉ/γ。
Medusa 对低 batch 更有吸引力,因为普通解码此时算术强度低,树式验证可利用闲置计算资源。batch 已经很大时,目标模型的 GEMM 本来就接近饱和;再把每个请求扩成几十个树节点,可能直接推高计算量和 KV 工作集。论文主实验聚焦 batch size 1,虽然框架后来支持更大 batch,但生产服务仍应分别测量单请求延迟、不同并发下吞吐与尾延迟,不能拿单流加速比代替集群容量结论。
工程实现与参数选择#
Medusa 的参数并不少,但可以按“先保证正确,再找性能点”的顺序调试。
头数与树深#
论文经验上认为最多配置 5 个附加头已足够,在线推理常只使用其中 3 到 4 个。远期头预测难度更高,增加的候选深度若很少被接受,只会扩大验证前向。已有 5 个头的模型可以在部署时忽略尾部头。
附加头并非零成本。每个头包含 d×d 残差变换和 d×V 词表投影;当词表很大时,后者的参数、显存读取与 logits 写出都不可忽略。实现若能复用、分片或融合词表投影,收益会明显不同。多卡张量并行下,还要让 Medusa Head 采用与原 LM Head 一致的词表切分与归约语义,否则“轻量头”可能引入新的跨卡通信。
树形不是一组 top-k 数字#
规则树可以用 (s1,s2,…) 描述,但优化稀疏树本质上是一组路径,例如 [0]、[1]、[0,0]、[0,1]、[1,0]。路径中的整数表示该深度选用第几名候选。必须满足前缀闭包:若 [0,1,0] 存在,则 [0] 和 [0,1] 都必须存在,否则节点没有合法祖先。
校准时应使用接近线上提示词、温度和采样策略的数据。代码生成中标点、关键字和缩进可预测性高,长路径更容易命中;开放式写作的合理后继更多,同一棵树的边际收益会不同。论文也观察到 extraction 和 coding 类别加速更高,这不是模型计算量变了,而是 token 条件熵与候选可预测性不同。
Mask、位置和 KV 必须一起验证#
单元测试不应只比最终文本,还应逐节点比对隐藏状态和 logits:把每条树路径单独做一次普通前向,再与 Tree Attention 对应节点比较。若出现差异,优先检查三处:祖先 mask 是否包含自身、position ID 是否按深度设置、RoPE 或 ALiBi 后端是否真正使用传入的位置。
KV Cache 最好预留最大树节点的临时区域,并在接受后只提交选中路径。静态地址有利于 CUDA Graph 和减少分配开销,但会增加显存占用;动态申请更省空间,却可能把 CPU 分配与同步重新带回热路径。可采用“固定最大槽位 + 实际节点数 mask”的方式折中。分页 KV 系统还要区分临时页和已确认页,避免失败分支被前缀缓存或其他请求引用。
把 Python 控制流赶出热路径#
官方参考实现便于理解,但生产系统需要关注 top-k、树索引、接受长度归约和 KV compact 的 kernel 启动次数。若每轮都在 CPU 上构树、同步读取接受长度,再发起多次小复制,节省的模型前向可能被控制开销抵消。静态树缓冲、设备端接受判定、融合索引与 KV 提交,以及可重放执行图,通常比继续增加一个预测头更值得优先实现。
调优时至少记录以下量,而不只记录 tokens/s:
- 每轮提交 token 数的分布,而非只有均值;
- 候选树节点数、最大深度与每层宽度;
- 头部计算、目标验证、接受判定、KV 整理各自延迟;
- 不同输入长度下验证注意力的耗时,因为 KV 读取随上下文增长;
- batch、温度、top-p、任务类别与输出长度;
- 严格接受与 typical acceptance 各自的质量口径。
没有这些分项,看到加速下降时无法判断是候选命中变差、目标验证转为 compute-bound,还是控制面同步过多。
与 EAGLE、传统投机解码的边界#
三类方法都遵循“便宜提议、昂贵验证”,差别主要在提议器如何获得条件信息。
| 方法 | 提议器 | 候选之间的依赖 | 额外系统状态 | 典型优势 | 主要代价 |
|---|---|---|---|---|---|
| 独立草稿模型 | 更小的完整语言模型 | 草稿阶段自回归,后一个候选看到前一个 | 第二套权重与 KV Cache | 分布建模完整,严格拒绝采样成熟 | 草稿延迟、显存和多模型维护 |
| Medusa | 共享末层隐藏状态的多个输出头 | 各未来头并行,彼此不条件依赖 | 附加头、候选树缓冲 | 无需第二个 Transformer,提议延迟低 | 远期头相关性弱,树验证会膨胀 |
| EAGLE | 预测目标模型下一步特征的轻量自回归模块 | 每步使用前一步 token 与特征 | 特征草稿模块及其状态 | 条件依赖更强,通常有更好的远期提议 | 草稿仍需逐步运行,集成更复杂 |
Medusa 的并行头在延迟上很干净,但它们都只看同一个 ht。第 3 个头无法根据第 1、2 个头实际选中的 token 修正自己,这是一种条件独立近似。候选树用多分支覆盖这种不确定性,却以目标验证节点数为代价。
EAGLE 则在特征空间自回归地产生草稿,每一步能够条件于前面的候选,因此更擅长建模 token 间依赖。它用顺序草稿开销换更高质量的候选。关于特征草稿、树验证和后续 EAGLE-2/3 的演进,可参考 EAGLE 完全拆解。两者不是简单的“头多”和“头少”,而是在提议器延迟、条件建模能力与验证树规模之间选择不同工作点。
DeepSeek 的 MTP 也预测多个未来 token,但其预测模块按未来深度顺序连接,会融合前一未来 token 的表示,并且作为模型原生结构参与适配;它不是把多个完全独立词表头并排挂到同一个隐藏状态上。相关结构可参考 MTP 完全拆解。在工程上,原生 MTP 与 Medusa 都可充当自投机提议器,但 checkpoint 兼容性、头部计算图和接受统计并不相同。
Tree Attention 也不是 Medusa 独有。SpecInfer 等工作可把一组草稿序列自底向上合并成树;Medusa 则利用多头 top-k 组合自顶向下生成树。树式验证是通用执行技术,Medusa Heads 是一种候选来源,二者应分开理解。
局限与适用场景#
Medusa 最适合以下组合:低 batch 或交互式延迟敏感服务、权重读取占主导、模型输出具有较强局部可预测性,并且可以接受为目标模型准备专用附加头。代码、结构化抽取和模板化文本往往比高熵创作更容易获得长接受前缀。
它不是“给任意 checkpoint 打开一个开关”。附加头必须与目标模型、词表和输出风格匹配;领域或对齐风格发生偏移后,远期头的排名统计与最优树形都可能变化。即使主干模型不改,也仍需拿到与该 checkpoint 匹配的附加头。
长上下文下,树中每个 query 都要读取历史 KV。虽然不同候选共享权重前向,注意力部分的流量仍随上下文长度和节点数增长。模型权重占主导时树验证很划算;历史 KV 已经成为主要瓶颈时,扩大树可能放大带宽压力。实际最优节点数应随上下文长度变化,固定一棵树未必覆盖从短对话到十万 token 上下文的全部区间。
typical acceptance 的速度来自放宽分布保持要求。开放式对话中“质量相近”不等于逻辑、代码或安全约束下等价;阈值必须以任务级指标验证。若业务要求目标分布不变,应把它关掉,并接受严格规则下更短的平均接受长度。
最后,论文数字基于特定模型、软件基线和硬件环境。更强的目标 kernel 会降低普通自回归的基线延迟,也可能改变 γ;量化减少权重带宽后,候选验证更容易进入算力受限;高并发调度又会改变空闲算力。Medusa 是一种把串行步数换成单步并行宽度的方法,而不是与硬件和工作负载无关的固定倍数加速器。
小结#
Medusa 的关键不是“同时猜几个 token”这句口号,而是一条完整的推理闭环:附加头从同一个隐藏状态低成本提出多个未来位置的候选;稀疏树把有限验证预算放到高概率路径;Tree Attention 用祖先 mask 和深度 position ID 保持每条路径的因果语义;接受器只提交一条路径的连续前缀;KV Cache 再从临时树布局收拢为已确认序列。
从性能模型看,真正要优化的是平均提交数 Aˉ 与单轮膨胀 γ 的比值。更多头、更宽树、更松阈值都可能提高 Aˉ,也分别带来词表投影、目标验证和质量偏移的代价。Medusa 的工程价值,正在于它把投机提议器压缩成目标模型上的几个头,并把剩余复杂性明确暴露为树形、掩码、接受规则与缓存提交四个可测量模块。
参考资料#
- Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads(ICML 2024)
- Medusa arXiv 论文与源文件
- FasterDecoding/Medusa 官方实现
- Together AI:Medusa 技术解读
- Fast Inference from Transformers via Speculative Decoding
- Accelerating Large Language Model Decoding with Speculative Sampling
- SpecInfer: Accelerating Generative Large Language Model Serving with Speculative Inference and Token Tree Verification
- Blockwise Parallel Decoding for Deep Autoregressive Models
- Truncation Sampling as Language Model Desmoothing
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
评论区
分享你的想法,与大家交流讨论
音乐
暂未播放



