诞生背景
在MTP出现之前,LLM的推理流程的复杂程度是:
InputToken×TFBlockLength×NIter InputToken \times TFBlock Length \times NIter InputToken×TFBlockLength×NIter
因此你会发现:真正会影响LLM图例速度的点在于Transformer Block在LLM模型中的深度,即使当我们仅仅输入了一个Token,如果Transformer Block足够深,那么它也会计算很长时间。更何况现实是我们与LLM聊天时,并不会仅仅输入一个Token。而这也是MTP所要亟待解决的问题。
技术介绍
多Token预测(MTP)将在每个位置上的Token从原来的1个扩展到N个,N由推理引擎配置文件提供。MTP通过增加额外的预测目标来提升推理引擎的吞吐量,即Token/s,同时也可能促使表示学习提前预测未来的Token。
计算复杂程度变成了:
InputToken×TFBlockLength×MTPSizeNIter+InputToken×NIter InputToken \times TFBlockLength \times MTPSizeNIter + InputToken×NIter InputToken×TFBlockLength×MTPSizeNIter+InputToken×NIter
下图展示了Deepseek-v3中MTP的应用示例:

通过上图可以清楚的看到,Deepseek-v3由一下三个模块组成:
- 主模型,负责优先处理基本的输入Token
- MTP模块1,负责接收来自主模型输出头的Embedding向量
- MTP模块2,负责接收来自MTP模块输出头的Embedding向量
在这个架构中,主模型的深度往往决定了后面MTP模块输出的质量,因此我们可以很清晰的看到主模型的深度是:
Depth=Transformer Block×Layer \text{Depth} = \text{Transformer Block} \times \text{Layer} Depth=Transformer Block×Layer
在主模型推理完成后,MTP将截胡 来自主模型输出头的向量,来用于自己的二次推理。但为了保证上下文的逻辑与时间一致性,MTP模块不得不要重新计算输入的Token。
在接收到原始输入Embedding和主模型的Embedding后,MTP模块通过RMSNorm对其进行归一化和FC映射,以确保MTP模块中的Transformer块进行预测,不过由于主模型已经为MTP模块打了非常坚实的基础,因此MTP模块的Transformer块只有一层。经过MTP模块,我们会至少得到:
OutputToken=Tmain+(Tmain+draft-n-max)×mtpsize \text{OutputToken} = T_{main} + (T_{main} + \text{draft-n-max}) \times \text{mtpsize} OutputToken=Tmain+(Tmain+draft-n-max)×mtpsize
测试
为了方便对比,将使用Llama.cpp针对Qwen3.6-27B-MTP在开启MTP和未开启MTP状态下进行吞吐量测试
测试平台采用AutoDL GPU实例:英特尔至强 铂金8470Q , 90G RAM, RTX 5090 32G
我将以如下方式启动llama.cpp:
bash
llama-server -hf unsloth/Qwen3.6-27B-MTP-GGUF:IQ4_XS \
--alias qwen3.6-27b-mtp \
--port 8000 \
--spec-type draft-mtp \
--spec-draft-n-max 3 \
--spec-draft-n-min 0.3 \
--temp 0.6 \
--repeat-penalty 1.05 \
-fa on
其中,控制MTP行为的参数为:
- spec-type:当使用draft-mtp时,表明llama.cpp将激活GGUF模型中的MTP模块(前提是模型本身支持MTP)
- spec-draft-n-max:指定最大将生成多少个草稿Token
- spec-draft-n-min:最低的容忍置信度
接下来,我们得到了如下图片:

你可以发现,在开启MTP多Token预测模式下,推理性能提升了约1.3倍。
同样的:同一个chat请求,在开启MTP推理后,反而其触发解码的次数要比非MTP解码的次数少了整整4次!这样也能保证在资源受限的情况下,推理速度变得更快

结论
所以,我们可以显而易见的发现:MTP其实也是一种基于空间换时间的优化方法。它在主模型的基础上引入了MTP模块的概念,虽然单个MTP模块的网络深度并不算深,基本是:
- 一个Embedding头
- 两个RMSNorm模块
- 一个Transformer块
- 和最后接手的FC输出头
但是因为主模型开了个"好头",所以MTP的输出质量是并不需要额外担心。