首页
/ vLLM MTP 投机解码:免独立草稿模型的多 Token 预测加速实战

vLLM MTP 投机解码:免独立草稿模型的多 Token 预测加速实战

2026-09-06 17:58:55作者:秋泉律Samson

MTP(Multi-Token Prediction,多 Token 预测)是 vLLM 中一类特殊的投机解码方法:目标模型本身原生携带 MTP 预测头,因此无需像 EAGLE 或 draft model 方案那样额外准备一个草稿模型。读完本文,你将掌握 --speculative-config '{"method":"mtp", ...}' 在离线推理与在线服务两种场景下的完整配置方式,理解 Gemma 4 assistant 检查点在 vLLM 中的 MTP 处理路径,并能从 SpeculativeConfig 的源码层面弄清 MTP 各模型族的注册与映射机制。

什么是 MTP 投机解码,适合什么场景

MTP 的核心特点是:模型在训练时就原生支持"一次预测多个后续 token",推理时这些额外的预测头可以直接充当投机解码的草稿源。与基于草稿模型(draft model)的方法相比,MTP 的最大优势是配置最简——不需要下载、管理、部署一个独立的 draft 模型。

适合使用 MTP 的典型情形有两类:

  • 你的目标模型原生支持 MTP(模型权重中自带 MTP 层);
  • 你希望以最小额外配置获得基于模型本体的投机解码加速。

需要注意的是,MTP 只对 vLLM 中明确支持 MTP 的模型族生效。如果你的模型不支持 MTP,应改用 EAGLE 或 draft model 等其他投机解码方法。

从源码结构看,vLLM 当前支持 MTP 的模型族数量相当可观。vllm/config/speculative.py 中定义了 MTPModelTypes 字面量类型,覆盖了一组具体的 MTP 实现:

MTPModelTypes = Literal[
    "deepseek_mtp",
    "dots3_note_mtp",
    "mimo_mtp",
    "mimo_v2_mtp",
    "glm4_moe_mtp",
    "glm4_moe_lite_mtp",
    "glm_ocr_mtp",
    "ernie_mtp",
    "nemotron_h_mtp",
    "exaone_moe_mtp",
    "exaone4_5_mtp",
    "qwen3_next_mtp",
    "qwen4_exp_mtp",
    "qwen3_5_mtp",
    "longcat_flash_mtp",
    "bailing_hybrid_v3_mtp",
    "minimax_m3_mtp",
    "bailing_hybrid_mtp",
    "mtp",
    "kimi_k3_mtp",
    "pangu_ultra_moe_mtp",
    "step3p5_mtp",
    "hy_v3_mtp",
    "hy_v4_mtp",
    "gemma4_mtp",
    "inkling_mtp",
    "glm5_next_mtp",
    ...
]

这意味着 DeepSeek、MiMo、GLM、Qwen、Gemma 4、MiniMax、Kimi K3 等众多模型族都可以通过 method: "mtp" 启用投机解码。

核心配置项说明

MTP 的投机解码配置通过 --speculative-config(在线服务)或 speculative_config 参数(离线 LLM)传入,常用字段如下:

字段 说明 示例取值
method 投机解码方法,MTP 路径固定为 "mtp" "mtp"
num_speculative_tokens 投机深度,即每次迭代尝试验证的额外 token 数。官方建议从较小的值(如 1)开始 1
model 仅 Gemma 4 assistant 场景需要:填入 assistant 检查点名称(注意:它不是通用 draft 模型,尽管复用了 model 字段) "gg-hf-am/gemma-4-E2B-it-assistant"

num_speculative_tokens 控制投机深度,是调优的主要旋钮;对 MTP 而言,1 是一个稳妥的默认起点。

Gemma 4 Assistant 模型的 MTP 路径

这是当前文档重点覆盖的一个特殊场景:Gemma 4 assistant 检查点走的是 vLLM 的 Gemma 4 MTP 路径,而不是通用 draft model 路径——即使它们是通过 --speculative-configmodel 字段传入的。

配置示例

使用 "method": "mtp" 配合 assistant 检查点服务 Gemma 4:

vllm serve google/gemma-4-E2B-it \
    --tensor-parallel-size 1 \
    --max-model-len 8192 \
    --speculative-config '{"method":"mtp","model":"gg-hf-am/gemma-4-E2B-it-assistant","num_speculative_tokens":1}'

其中 --max-model-len 8192 限制最大序列长度,num_speculative_tokens: 1 表示每轮投机 1 个 token。

支持的检查点范围

  • E2B、E4B、12B、26B-A4B、31B 的 Gemma 4 IT assistant 检查点均受支持;
  • Tower 型变体的 model_typegemma4_assistant,无编码器(encoder-free)的 Gemma 4 Unified 变体(12B)为 gemma4_unified_assistant
  • vLLM 在内部将两者统一映射为 Gemma4MTPModel,并把 assistant 的层接线为与目标模型共享 KV cache

源码印证:assistant 如何被识别为 MTP

vllm/config/speculative.py 中可以看到这一映射的实现:当 HF 配置的 model_typegemma4_assistantgemma4_unified_assistant 时,SpeculativeConfig 会将其改写为 gemma4_mtp,并设置 n_predict=1

if hf_config.model_type in ("gemma4_assistant", "gemma4_unified_assistant"):
    hf_config.model_type = "gemma4_mtp"
    text_config = getattr(hf_config, "text_config", hf_config)
    # The assistant runs all decoder layers in a single forward
    # call to produce one draft token, so n_predict=1.
    # num_kv_shared_layers must be 0: cross-model KV sharing is
    # set up by the proposer after model construction.
    if hasattr(text_config, "num_kv_shared_layers"):
        text_config.num_kv_shared_layers = 0
    hf_config.update({"n_predict": 1, "architectures": ["Gemma4MTPModel"]})

源码注释明确说明了两点设计决策:

  1. assistant 在单次 forward 中跑完全部 decoder 层来产出一个草稿 token,所以 n_predict=1
  2. num_kv_shared_layers 必须置 0——跨模型的 KV cache 共享是由 proposer 在模型构建之后接线的,而不是靠 HF 配置里的共享层数声明。

架构名到具体实现的映射在 模型注册表 中完成:Gemma4MTPModel 指向 gemma4_mtp 模块下的 Gemma4MTP 类,其实现位于 vllm/model_executor/models/gemma4_mtp.py

版本兼容提示

如果你使用的是较老的 vLLM 版本,日志中针对 Gemma 4 assistant 检查点打印出 SpeculativeConfig(method='draft_model', ...),说明该版本把 assistant 当作了通用草稿模型——对多模态 Gemma 4 目标模型而言,这种处理方式可能在初始化阶段直接失败。正确的做法是升级到带 Gemma 4 MTP 支持的版本,使配置走 method='mtp' 路径。

离线推理示例(Python API)

对于原生支持 MTP 的模型(文档以 XiaomiMiMo/MiMo-7B-Base 为例),离线推理只需在 LLM 构造时传入 speculative_config,无需任何 model 字段:

from vllm import LLM, SamplingParams

prompts = ["The future of AI is"]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

llm = LLM(
    model="XiaomiMiMo/MiMo-7B-Base",
    tensor_parallel_size=1,
    speculative_config={
        "method": "mtp",
        "num_speculative_tokens": 1,
    },
)
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

要点说明:

  • method: "mtp" 告诉 vLLM 使用目标模型自带的 MTP 层作为草稿源,MTP 权重已经包含在目标检查点内,因此这里不再需要 model 字段;
  • num_speculative_tokens: 1 是推荐的初始深度;
  • tensor_parallel_size=1 表示单卡运行,多卡场景可相应调大。

对应到源码侧,MiMo 的 MTP 实现通过 vllm/model_executor/models/mimo_mtp.py 中的 MiMoMTP 类承载,并在注册表中以 "MiMoMTPModel": ("mimo_mtp", "MiMoMTP") 登记(见 registry.py)。

在线服务示例(vllm serve)

在线服务场景与离线 API 等价,只是把投机配置以 JSON 字符串形式传给 CLI:

vllm serve XiaomiMiMo/MiMo-7B-Base \
    --tensor-parallel-size 1 \
    --speculative-config '{"method":"mtp","num_speculative_tokens":1}'

服务启动后,OpenAI 兼容的 /v1/chat/completions 等接口即自动带上 MTP 投机解码能力,客户端无需任何改动。

实践注意事项与选型建议

  • 模型族限制:MTP 只对 vLLM 中支持 MTP 的模型族有效。是否支持,可先查 vllm/config/speculative.py 中的 MTPModelTypes 列表,或查 模型注册表 中是否存在对应的 *MTP* 架构;
  • 投机深度num_speculative_tokens 建议从小值(1)起步,再视接受率与吞吐表现逐步调大;
  • 不支持 MTP 的替代路线:如果模型没有原生 MTP 层,可选 EAGLE(基于额外训练头的草稿预测)或 draft model(独立草稿模型)方案,相关文档见 docs/features/speculative_decoding/eagle.mddocs/features/speculative_decoding/draft_model.md
  • Gemma 4 特别注意:assistant 检查点必须通过 "method": "mtp" 启用,且仅在支持 Gemma 4 MTP 的版本中才能正确初始化(老版本会误走 draft_model 路径)。

小结

MTP 投机解码把"草稿"能力内置进了目标模型本身:一个 "method": "mtp" 加一个 num_speculative_tokens,即可让支持 MTP 的模型族(MiMo、Gemma 4 assistant 等)在不引入独立草稿模型的前提下获得加速。其内部机制——SpeculativeConfig 对 HF 配置的 MTP 类型改写、模型注册表到具体 MTP 实现类的路由、Gemma 4 assistant 与目标模型之间的 KV cache 共享——均可在 vllm/config/speculative.pyvllm/model_executor/models/registry.py 中逐行查证,便于在自定义模型族时参考其映射模式。

登录后查看全文
热门项目推荐
相关项目推荐