dSpark:让扩散语言模型学会先翻哪张牌的调度蒸馏术
想象你在做一张填字游戏。每个空格你大概都能猜个八九不离十,但总有一些空格你特别有把握,另一些则模棱两可。现在问题来了:如果你只能一次揭开三个空格的答案,你应该先揭哪三个?
目录
dSpark:让扩散语言模型学会"先翻哪张牌"的调度蒸馏术
一个填字游戏引发的思考
想象你在做一张填字游戏。每个空格你大概都能猜个八九不离十,但总有一些空格你特别有把握,另一些则模棱两可。现在问题来了:如果你只能一次揭开三个空格的答案,你应该先揭哪三个?
直觉告诉你,先揭你最有把握的那三个。毕竟,越确定的答案越不容易错。但仔细想想,填字游戏的乐趣在于交叉线索——某个你不太确定的横向词汇,可能恰好是解开整片纵向区域的关键。如果你先揭开那个"中等把握"的横向词,它带来的交叉信息能让后面五六个空格瞬间变得确定。反过来,如果你先揭三个彼此不相干的、虽然很确定的词,它们对后续解题的帮助可能微乎其微。
这就是扩散语言模型(diffusion LLM)今天面临的困境。它们能并行生成多个 token,但"先翻哪张牌"这个看似简单的问题,却藏着深刻的效率瓶颈。
扩散语言模型的承诺与瓶颈
先说清楚扩散语言模型是什么。传统自回归模型(GPT、Claude 这类)生成文本时是一个 token 接一个 token 往外吐,生成长度为 L 的回复需要 L 次前向计算。这种严格的从左到右依赖限制了并行度。
扩散语言模型走的是另一条路。它从一个全部被 mask 的序列开始,每轮把若干位置"解掩码"——也就是承诺这些位置的 token。每轮可以同时解掩码多个位置,因此理论上有巨大的并行加速潜力。LLaDA、Dream 等模型已经证明这条路在语言建模、推理、代码生成上都能达到接近自回归模型的质量。
但理论归理论,实际跑起来有个核心瓶颈:解掩码调度(unmasking schedule)。每轮应该承诺哪些 token?承诺太多,错误会不可逆地污染后续预测;承诺太少,又浪费了并行计算的优势。
现有的策略大多基于"置信度"——哪个位置的预测概率分布最尖锐,就先揭哪个。这个直觉和填字游戏里"先填最有把握的"一样自然。但它真的对吗?
可预测性 ≠ 有用性
dSpark 的核心洞察用一句话就能讲清楚:最容易预测的 token 不一定是最该承诺的 token。
论文举了这样一个例子。考虑两个被 mask 的位置 i 和 j。位置 i 的预测分布已经极度尖锐,模型几乎确定它是什么词。但揭示 i 之后,其他位置的预测难度几乎不变——i 携带的信息和别处关联不大。位置 j 则不同,它本身可能只有中等把握,但一旦揭示,它会强烈暗示周围好几个位置的答案。在数学推理和代码生成这种结构化任务里,这种"中间决策引发下游依赖"的现象尤其明显。
基于纯置信度的调度会把早期承诺浪费在"安全但信息冗余"的 token 上,而那些真正能解锁后续预测的关键位置却被拖到很晚才揭示。结果就是:要么需要更多轮次才能完成生成,要么为了减少轮次而激进承诺,引入不可逆错误。
dSpark 的解法是:不要问"哪些 token 现在能预测",而要问"揭示哪些 token 能让剩下的 token 更容易预测"。把解码看作一个上下文构造过程——每个被承诺的 token 不仅解决一个位置,还改变了所有剩余位置的预测问题。
调度蒸馏:让模型自己学会"先翻哪张牌"
知道该承诺哪些 token 是一回事,让模型实际做到是另一回事。dSpark 用的是调度蒸馏(schedule distillation)。
思路分两步。第一步是构造"好的调度"——离线评估候选承诺对剩余位置不确定性的影响,挑选那些揭示后能让多个位置变确定的 token,形成优先级排序。第二步是把这个调度策略蒸馏进模型本身——用 KL 散度正则化,让模型在相同前向次数下输出更接近"好调度"的预测分布。
这里有个精妙之处:构造好调度本身需要额外计算,但蒸馏之后,模型在推理时并不需要重复这个构造过程。模型已经内化了"先翻哪张牌"的直觉,推理时直接按学到的分布走就行。
这和人类解题的经验一致。新手做填字游戏时会反复掂量每个空格的把握程度,老手则一眼看出哪个空格是"解锁关键"——这种判断已经变成了肌肉记忆,不需要每次重新推理。
数据说话:10 倍加速不是吹的
dSpark 在四个基准上测了两个骨干模型:
| 基准 | 骨干 | 加速比 | 准确率 |
|---|---|---|---|
| GSM8K | LLaDA-8B | 10.12× | 78.9%(base 78.8%) |
| GSM8K | Dream-7B | 5.12× | 83.6%(base 82.1%,还涨了 1.5%) |
| MATH | LLaDA-8B | 6.03× | 32.0%(base 31.7%) |
| HumanEval | LLaDA-8B | 6.73× | 39.6%(base 38.1%) |
| MBPP | Dream-7B | 3.77× | 56.0%(base 57.0%) |
GSM8K 上 10.12 倍加速、准确率不掉反升。这不是"用质量换速度"的妥协,而是"好调度本身让生成更准"的证明。当模型先揭示有信息量的 token 时,后续预测有了更可靠的上下文,整体准确率反而受益。
和 d3LLM 对比。d3LLM 是此前最先进的并行解码方法之一。dSpark 在 GSM8K 上的 AUP(accuracy under parallelism)比 d3LLM 高 33.3%。更关键的是,d3LLM 和 dParallel 在错误预测上的"自信率"分别是 22.9% 和 21.7%,而 dSpark 只有 15.5%——也就是说,dSpark 的自信预测中有 91% 是对的,比对手高出不少。
KL 正则化的作用。蒸馏让模型敢于并行承诺更多 token,但同时也可能让模型对错误预测也变得过于自信。KL 正则化在这里起到了"刹车"作用——让模型在激进并行和保守准确之间找到平衡点。消融实验显示,去掉 KL 权重后,准确率显著下降。
为什么这个思路重要
dSpark 的意义不只是"又快了 10 倍"。它揭示了一个更深刻的道理:在生成式 AI 里,"先做什么"和"怎么做"同样重要。
自回归模型回避了这个问题——它只能从左到右,没得选。但一旦你打开了并行生成的大门,调度的质量就成了新的瓶颈。而这不只是扩散模型的问题。任何"分步决策、后续依赖前面"的系统——思维链推理、工具调用序列、Agent 行动规划——都面临同样的困境:你应该先确定哪一步?
dSpark 的答案是:不要贪图眼前的确定性,而要看重未来的信息增益。这个原则在填字游戏里成立,在扩散语言模型里成立,在更广泛的 Agent 工程里大概也成立。
另一个值得玩味的点是"蒸馏"这个手段。直接在推理时计算每个 token 的信息增益太贵了,但通过蒸馏可以把这种"高级直觉"固化进模型参数。这和 AlphaGo 的思路一脉相承——蒙特卡洛树搜索太贵,但蒸馏进策略网络后,模型直接就有了"该走哪步"的直觉。
诚实的局限
论文也坦承了一些局限。首先,实验只在数学推理和代码生成上做了,这两个任务的 token 间依赖比较强。对于更自由的开放域生成(写故事、聊天),"信息增益"的度量可能没那么清晰,调度蒸馏的收益可能打折扣。
其次,10.12 倍加速是在"每轮承诺多少 token 由阈值决定"的设定下测的。实际部署时,阈值的选择需要根据任务调整——太松会引入错误,太紧会损失并行度。论文给了消融但没有给出"一刀切"的最佳阈值,这意味着实际使用还需要一些任务相关的调参。
最后,dSpark 目前是离线蒸馏的——它需要一个"教师调度"来学习。如果模型部署后任务分布发生漂移,学到的调度直觉可能不再适用。在线适应是一个尚未探索的方向。
结语
dSpark 给扩散语言模型装上了"先翻哪张牌"的直觉。这个直觉不是来自更聪明的启发式规则,而是来自把"信息增益"作为第一性原理,然后用蒸馏把它固化进模型。
10 倍加速是实打实的数字。但更让人兴奋的是它指向的方向:当生成不再被从左到右的锁链束缚时,"先做什么"本身就成了一个值得学习的问题。而好的调度,不只是更快,还能更准。
论文:Learning When to Commit: Schedule Distillation for Fast Diffusion Language Models 作者:Aidar Myrzakhan, Zhiqiang Shen (VILA Lab, MBZUAI) arXiv:2610.35804 代码:github.com/VILA-Lab/dSpark