llama.cpp MTP模型性能优化

🚀 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 size2048
专家256 routed + 1 shared, 8 active/token
MTP 文件开销仅比非 MTP 版大约 2.5%

可用量化变体

变体文件大小推荐度说明
F1671.1 GB远超 VRAM
I-Balanced25.9 GB双卡 16GB 无法装入
I-Quality23.3 GB双卡 16GB 无法装入
I-Compact16.9 GB⭐ 首选100K 下需配合 KV Q4_0 精准装入 2×16GB
I-Mini13.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 GB23.2 GB ❌19.1 GB ❌不适用
I-Quality (23.3G)~11.65 GB21.9 GB ❌17.8 GB ❌不适用
I-Compact (16.9G)~8.45 GB18.7 GB ❌14.6 GB ✅⭐ 唯一可行
I-Mini (13.7G)~6.85 GB17.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-typedraft-mtp推测解码策略。值是 MTP 专用,参数本身是通用系统参数
spec-draft-n-max3最大 draft token 数。3 在速度/质量间平衡最好
spec-draft-n-min1最低 draft 数
flash-attnon100K 上下文必须开启
cache-type-k/vq4_0关键:100K+双卡16GB 下必须用 q4_0 才能装入 I-Compact
split-modelayerPipeline parallelism。MoE 不支持 tensor split
tensor-split1,1相同 GPU 间均分
no-mmprojtrue禁用视觉分支,省 300-500 MB

🔧 性能调优技巧

  1. MTP draft 步数实验:spec-draft-n-max 从 2 到 5 测试。16GB 显存下建议不超过 3,否则额外缓存可能超限
  2. KV cache 精度实验:先用 q4_0 跑通 100K,如有余量逐步升到 q6_k 或 q8_0(优先降 ctx-size 来换取精度)
  3. batch-size 调优:V100 16GB 从 512 起步,超过显存会 fallback 到 CPU,速度暴跌
  4. GGML_CUDA_P2P:试试 GGML_CUDA_P2P=1,减少某些 PCIe 配置下的卡间拷贝
  5. 构建选择-DGGML_CUDA_NCCL=ON(默认)构建,NCCL 多卡通信优于 CUDA IPC
  6. 清理显存:启动前检查 nvidia-smi,确保无残余进程占用

📊 预期性能

方案模型KV每卡output t/sinput t/s
mtp-100kI-CompactQ4_0~14.6 GB10-15不变
mtp-65kI-CompactQ8_0~15.5 GB12-18不变
mtp-lightI-MiniQ4_0~13.0 GB12-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