🚀 llama.cpp MTP 模型性能优化
llama.cpp b9245 (2026-05-20) · Qwen3.6-35B-A3B APEX-MTP · 2×V100 16GB · X99 · 100K ctx
🧠 MTP 是什么
MTP (Multi-Token Prediction) = 在模型内部嵌入轻量级预测头,让模型一次预测多个未来 token,再通过 llama.cpp 的推测解码(speculative decoding)机制验证并加速生成阶段。
传统推测解码需要两个模型文件(大模型 + 独立小型 draft 模型如 Qwen3.5-0.8B)。MTP 的预测头直接嵌入在同一个 GGUF 文件里,无需第二个文件。
MTP 加速哪个阶段?
- ✅ Decoding / Generation(生成输出):MTP 加速的是逐 token 生成阶段。传统方式每步一个 forward pass → 1 个 token。MTP 每步 draft 3 个候选 → 一次验证 → 接受 ~2.3 个 token。生成速度(output t/s)提升 ~2-2.5×
- ❌ Prefill / Prompt Processing(处理输入):MTP 不影响 prefill 速度。因为 prefill 是一次性并行计算所有输入 token,不存在逐 token 生成瓶颈。input t/s 不变
总结:MTP 增加的一直是输出生成速度(TG),不是输入处理速度(TP)。
三种推测解码方案对比
| 方案 | 需额外文件 | 典型 draft 数 | 接受率 | 生成速度提升 |
|---|---|---|---|---|
MTP 自推测spec-type=draft-mtp | ❌ 无需(MTP head 在 GGUF 中) | 2-5 | ~72-83% | ~2-2.5× |
传统推测解码spec-type=draft-model--spec-draft-model x.gguf | ✅ 独立 draft 模型 | 16-64 | 取决于 draft 质量 | 1.5-3× |
MTP + ngram 叠加spec-type=draft-mtp,ngram-mod | ❌ 无需 | — | 更高 | 更高 |
三个参数的角色
| 参数 | 说明 | 是否 MTP 独有 |
|---|---|---|
spec-type = draft-mtp | 指定推测解码策略。draft-mtp 这个值才是 MTP 专用的;draft-model 是传统方式 | ❌ 通用参数,值 draft-mtp 是 MTP 专用 |
spec-draft-n-max = 3 | 每次推测生成的 draft token 上限。MTP 一般 3 最佳,传统推测可达 64 | ❌ 推测解码通用参数 |
spec-draft-n-min = 1 | 最低保证 draft 数,避免因 draft 太少加速不明显 | ❌ 推测解码通用参数 |
📦 目标模型:Qwen3.6-35B-A3B APEX-MTP
| 属性 | 值 |
|---|---|
| 架构 | Qwen3_5MoeForCausalLM (MoE) |
| 总参数量 | 35B |
| 激活参数量 | 3B/token |
| 层数 | 40 trunk + 1 MTP head |
| Hidden size | 2048 |
| 专家 | 256 routed + 1 shared, 8 active/token |
| MTP 文件开销 | 仅比非 MTP 版大约 2.5% |
可用量化变体
| 变体 | 文件大小 | 推荐度 | 说明 |
|---|---|---|---|
| F16 | 71.1 GB | ❌ | 远超 VRAM |
| I-Balanced | 25.9 GB | ❌ | 双卡 16GB 无法装入 |
| I-Quality | 23.3 GB | ❌ | 双卡 16GB 无法装入 |
| I-Compact | 16.9 GB | ⭐ 首选 | 100K 下需配合 KV Q4_0 精准装入 2×16GB |
| I-Mini | 13.7 GB | ⚠️ | 能装,但质量损失明显 |
💻 硬件分析与 VRAM 计算
显存预算 (2×V100 16GB = 32GB)
KV Cache 计算(100K tokens, Qwen3-35B-A3B, 40层)
- 每个 token: 2 (K+V) × 40 layers × 2048 hidden = 163,840 floats
- FP16 (2 byte): 32.8 GB — 超出总显存,不可行
- Q8_0 (1 byte): 16.4 GB → pipeline 分摊 ~8.2 GB/卡
- Q4_0 (0.5 byte): 8.2 GB → pipeline 分摊 ~4.1 GB/卡
- Q6_K (~0.75 byte): 12.3 GB → pipeline 分摊 ~6.15 GB/卡
Pipeline parallelism 卡均占用(40+1 层 ≈ 20.5 层/卡)
| 量化变体 | 权重/卡 | + KV Q8_0 | + KV Q4_0 | 结论 |
|---|---|---|---|---|
| I-Balanced (25.9G) | ~12.95 GB | 23.2 GB ❌ | 19.1 GB ❌ | 不适用 |
| I-Quality (23.3G) | ~11.65 GB | 21.9 GB ❌ | 17.8 GB ❌ | 不适用 |
| I-Compact (16.9G) | ~8.45 GB | 18.7 GB ❌ | 14.6 GB ✅ | ⭐ 唯一可行 |
| I-Mini (13.7G) | ~6.85 GB | 17.1 GB ❌ | 13.0 GB ✅ | 可行但质量差 |
结论:100K 上下文下,只有 I-Compact + KV Q4_0(~14.6 GB/卡)能稳定装入 2×16GB。
📝 --models-preset INI 设计
创建 preset-qwen3-mtp.ini 文件:
; ==========================================================
; llama.cpp --models-preset 配置文件
; 目标:Qwen3.6-35B-A3B APEX-MTP · 2×V100 16GB · X99 · 100K ctx
; llama.cpp >= b9245
; ==========================================================
[*]
mmap = 1
fit = on
verbose = 0
; ──────────────────────────────────────────
; 方案 A:默认 — 100K 上下文的唯一可行配置
; I-Compact + KV Q4_0 = ~14.6 GB/卡
; MTP 增益:生成速度 ~2×(output t/s),不影响 prefill
; ──────────────────────────────────────────
[mtp-100k]
hf = mudler/Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled-APEX-MTP-GGUF:I-Compact
spec-type = draft-mtp
spec-draft-n-max = 3
spec-draft-n-min = 1
ctx-size = 100000
flash-attn = on
cache-type-k = q4_0
cache-type-v = q4_0
n-gpu-layers = all
split-mode = layer
tensor-split = 1,1
no-mmproj = true
main-gpu = 0
batch-size = 1024
ubatch-size = 512
; ──────────────────────────────────────────
; 方案 B:降上下文换 KV 精度
; I-Compact + KV Q8_0,降至 ~65K 方可装入
; ──────────────────────────────────────────
[mtp-65k]
hf = mudler/Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled-APEX-MTP-GGUF:I-Compact
spec-type = draft-mtp
spec-draft-n-max = 3
spec-draft-n-min = 1
ctx-size = 65000
flash-attn = on
cache-type-k = q8_0
cache-type-v = q8_0
n-gpu-layers = all
split-mode = layer
tensor-split = 1,1
no-mmproj = true
main-gpu = 0
batch-size = 2048
ubatch-size = 1024
; ──────────────────────────────────────────
; 方案 C:最小显存占用
; 适合和其他任务共享 GPU
; ──────────────────────────────────────────
[mtp-light]
hf = mudler/Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled-APEX-MTP-GGUF:I-Mini
spec-type = draft-mtp
spec-draft-n-max = 2
spec-draft-n-min = 1
ctx-size = 100000
flash-attn = on
cache-type-k = q4_0
cache-type-v = q4_0
n-gpu-layers = all
split-mode = layer
tensor-split = 1,1
no-mmproj = true
main-gpu = 0
batch-size = 1024
ubatch-size = 512
🚀 使用方式
直接 CLI 启动
llama-server \
-m Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled-APEX-MTP-I-Compact.gguf \
--spec-type draft-mtp \
--spec-draft-n-max 3 \
--spec-draft-n-min 1 \
-c 100000 \
-fa on \
--cache-type-k q4_0 \
--cache-type-v q4_0 \
-ngl all \
-sm layer \
-ts 1,1 \
--no-mmproj \
--host 0.0.0.0 \
--port 8080
使用 preset 文件
llama-server --models-preset ./preset-qwen3-mtp.ini
# API 调用时选择方案
# POST /v1/completions
# { "model": "mtp-100k", "prompt": "...", "n_predict": 512 }
⚙️ 参数详解
| 参数 | 值 | 说明 |
|---|---|---|
spec-type | draft-mtp | 推测解码策略。值是 MTP 专用,参数本身是通用系统参数 |
spec-draft-n-max | 3 | 最大 draft token 数。3 在速度/质量间平衡最好 |
spec-draft-n-min | 1 | 最低 draft 数 |
flash-attn | on | 100K 上下文必须开启 |
cache-type-k/v | q4_0 | 关键:100K+双卡16GB 下必须用 q4_0 才能装入 I-Compact |
split-mode | layer | Pipeline parallelism。MoE 不支持 tensor split |
tensor-split | 1,1 | 相同 GPU 间均分 |
no-mmproj | true | 禁用视觉分支,省 300-500 MB |
🔧 性能调优技巧
- MTP draft 步数实验:spec-draft-n-max 从 2 到 5 测试。16GB 显存下建议不超过 3,否则额外缓存可能超限
- KV cache 精度实验:先用 q4_0 跑通 100K,如有余量逐步升到 q6_k 或 q8_0(优先降 ctx-size 来换取精度)
- batch-size 调优:V100 16GB 从 512 起步,超过显存会 fallback 到 CPU,速度暴跌
- GGML_CUDA_P2P:试试
GGML_CUDA_P2P=1,减少某些 PCIe 配置下的卡间拷贝 - 构建选择:
-DGGML_CUDA_NCCL=ON(默认)构建,NCCL 多卡通信优于 CUDA IPC - 清理显存:启动前检查
nvidia-smi,确保无残余进程占用
📊 预期性能
| 方案 | 模型 | KV | 每卡 | output t/s | input t/s |
|---|---|---|---|---|---|
| mtp-100k | I-Compact | Q4_0 | ~14.6 GB | 10-15 | 不变 |
| mtp-65k | I-Compact | Q8_0 | ~15.5 GB | 12-18 | 不变 |
| mtp-light | I-Mini | Q4_0 | ~13.0 GB | 12-18 | 不变 |
📚 参考
- llama.cpp:
github.com/ggerganov/llama.cpp— v3.1.0 / b9245 (2026-05-20) - MTP PR: PR #22673 @am17an
- 模型:
huggingface.co/mudler/Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled-APEX-MTP-GGUF