更多 Qwen3.6-27B MTP 的成功案例,但这次是在双路 Mi50 上
摘要
本文在双路 Mi50 GPU 上,使用多令牌预测(MTP)和张量并行技术对 Qwen3.6-27B 模型进行了基准测试,展示了通过 llama.cpp 实现的显著加速效果。
**简而言之:** 这热度确实是实打实的!速度提升了 1.5 倍。结合张量并行(Tensor Parallelism)后,速度提升可达 2 倍!读完 PR 后,我立即寻找支持 MTP 的 Q4_1 量化模型(它们在算力较弱的老显卡上能带来小幅速度提升),但没找到。幸运的是,我遇到了[这篇帖子](https://www.reddit.com/r/LocalLLaMA/comments/1t6r1ny/extracted_mtp_tensor_ggufs_smaller_donor_models/),它详细介绍了如何将 MTP “移植”到你自己的量化模型上,于是我便将其应用到了我现有的 Bartowski 量化模型上。
# 环境设置
* CachyOS (Arch Linux)
* ROCm 7.2
构建了 [llama.cpp](https://github.com/skyne98/llama.cpp-gfx906) 的分支(针对 gfx906),并合并了 PR [https://github.com/ggml-org/llama.cpp/pull/22673](https://github.com/ggml-org/llama.cpp/pull/22673),然后使用 PR 中包含的基准测试脚本运行了以下命令:
```bash
llama-server -m ~/models/Qwen3.6-27B-MTP-Q4_1.gguf \
--temp 1.0 --min-p 0.0 --top-k 20 --top-p 0.95 \
--jinja --presence-penalty 1.5 \
--chat-template-kwargs '{"preserve_thinking": true}' \
-ub 2048 -b 2048 \
-fa 1 -np 1 \
--no-mmap --no-warmup \
-dev ROCm0,ROCm1 --fit on -fitt 256
```
# 脚本基准测试
**未启用任何优化(Stock):**
| 测试项 | pred | draft | acc | rate | tok/s |
| :--- | :--- | :--- | :--- | :--- | :--- |
| code_python | 192 | 0 | 0 | n/a | 26.2 |
| code_cpp | 192 | 0 | 0 | n/a | 26.2 |
| explain_concept | 192 | 0 | 0 | n/a | 26.3 |
| summarize | 192 | 0 | 0 | n/a | 26.4 |
| qa_factual | 192 | 0 | 0 | n/a | 26.4 |
| translation | 192 | 0 | 0 | n/a | 26.4 |
| creative_short | 192 | 0 | 0 | n/a | 26.4 |
| stepwise_math | 192 | 0 | 0 | n/a | 26.3 |
| long_code_review | 192 | 0 | 0 | n/a | 26.0 |
**启用 MTP 后:** `--spec-type mtp --spec-draft-n-max 2`
| 测试项 | pred | draft | acc | rate | tok/s |
| :--- | :--- | :--- | :--- | :--- | :--- |
| code_python | 192 | 144 | 119 | 0.826 | 39.6 |
| code_cpp | 192 | 156 | 113 | 0.724 | 36.5 |
| explain_concept | 192 | 154 | 113 | 0.734 | 36.7 |
| summarize | 192 | 138 | 121 | 0.877 | 40.7 |
| qa_factual | 192 | 144 | 119 | 0.826 | 39.4 |
| translation | 192 | 152 | 115 | 0.757 | 37.5 |
| creative_short | 192 | 156 | 113 | 0.724 | 36.6 |
| stepwise_math | 192 | 146 | 118 | 0.808 | 39.0 |
| long_code_review | 192 | 150 | 115 | 0.767 | 37.8 |
**汇总数据:**
```json
{
"n_requests": 9,
"total_predicted": 1728,
"total_draft": 1340,
"total_draft_accepted": 1046,
"aggregate_accept_rate": 0.7806,
"wall_s_total": 51.42
}
```
**启用张量并行后:** `-sm tensor`
| 测试项 | pred | draft | acc | rate | tok/s |
| :--- | :--- | :--- | :--- | :--- | :--- |
| code_python | 192 | 0 | 0 | n/a | 35.0 |
| code_cpp | 192 | 0 | 0 | n/a | 34.8 |
| explain_concept | 192 | 0 | 0 | n/a | 34.6 |
| summarize | 192 | 0 | 0 | n/a | 34.6 |
| qa_factual | 192 | 0 | 0 | n/a | 34.7 |
| translation | 192 | 0 | 0 | n/a | 34.7 |
| creative_short | 192 | 0 | 0 | n/a | 34.7 |
| stepwise_math | 192 | 0 | 0 | n/a | 34.6 |
| long_code_review | 192 | 0 | 0 | n/a | 34.3 |
**同时启用 MTP 和张量并行:**
| 测试项 | pred | draft | acc | rate | tok/s |
| :--- | :--- | :--- | :--- | :--- | :--- |
| code_python | 192 | 142 | 120 | 0.845 | 59.8 |
| code_cpp | 192 | 148 | 116 | 0.784 | 56.6 |
| explain_concept | 192 | 146 | 117 | 0.801 | 56.8 |
| summarize | 53 | 42 | 31 | 0.738 | 54.5 |
| qa_factual | 192 | 148 | 117 | 0.790 | 56.8 |
| translation | 192 | 146 | 117 | 0.801 | 57.3 |
| creative_short | 192 | 154 | 114 | 0.740 | 54.8 |
| stepwise_math | 192 | 140 | 121 | 0.864 | 59.6 |
| long_code_review | 192 | 148 | 117 | 0.790 | 56.2 |
**汇总数据:**
```json
{
"n_requests": 9,
"total_predicted": 1589,
"total_draft": 1214,
"total_draft_accepted": 970,
"aggregate_accept_rate": 0.799,
"wall_s_total": 32.24
}
```
# 真实世界基准测试
上面的数据看起来简直令人难以置信,然而在真实场景中,这种加速效果会迅速减弱——更不用说预填充(prefill)速度目前还存在性能回退问题,不过该问题正在修复中。我运行了这个 [18k token 的编程提示词](https://github.com/alexziskind1/machine_tests/blob/main/ml/auto_prompter/prompts/extra_long_programming_code_heavy_17947t.txt),很明显,60 tok/s 的速度仅在极短提示词下可见,但结合 MTP 和张量并行确实带来了大幅度的 2 倍速度提升。
**未启用任何优化(Stock):**
```text
prompt eval time = 53173.24 ms / 19191 tokens ( 2.77 ms per token, 360.91 tokens per second)
eval time = 337695.94 ms / 7791 tokens ( 43.34 ms per token, 23.07 tokens per second)
total time = 390869.18 ms / 26982 tokens
```
**启用 MTP 后:**
```text
prompt eval time = 84388.11 ms / 19191 tokens ( 4.40 ms per token, 227.41 tokens per second)
eval time = 260732.83 ms / 8408 tokens ( 31.01 ms per token, 32.25 tokens per second)
total time = 345120.94 ms / 27599 tokens
```
**启用张量并行后:**
```text
prompt eval time = 41925.27 ms / 19191 tokens ( 2.18 ms per token, 457.74 tokens per second)
eval time = 253262.25 ms / 8104 tokens ( 31.25 ms per token, 32.00 tokens per second)
total time = 295187.53 ms / 27295 tokens
```
**同时启用 MTP 和张量并行:**
```text
prompt eval time = 49696.04 ms / 19191 tokens ( 2.59 ms per token, 386.17 tokens per second)
eval time = 155821.64 ms / 7440 tokens ( 20.94 ms per token, 47.75 tokens per second)
total time = 205517.69 ms / 26631 tokens
```
相似文章
MI50s 上的 Qwen 3.6 27B @52.8 tps TG @1569 tps PP(无 MTP,无量化)
在 AMD MI50 GPU 上使用自定义 vllm 分支运行 Qwen 3.6 27B 的基准测试结果,实现了 52.8 tokens/s TG 和 1569 tokens/s PP,无量化或 MTP,证明了在 2018 年硬件上用于代理任务的可行性。
@Snixtp: https://x.com/Snixtp/status/2055734339346768225
某用户使用llama.cpp在单张RTX 3090上对Qwen3.6 27B的MTP变体与普通版本进行了基准测试,发现MTP在长上下文(32k-64k)下生成速度最高可提升2.37倍,但预填充较慢且暂不支持并发。
在 Qwen3.6 - RTX 5090 上测试 llama.cpp 的 MTP 支持
在 RTX 5090 上使用 Qwen3.6 模型对 llama.cpp 的新多标记预测(MTP)支持进行技术测试,比较不同提示和 GGUF 量化下开启和关闭 MTP 的性能表现。
Qwen3.5-122B-Q5-MTP - Qwen3.5-122B-Q6-MTP
在Strix Halo上使用llama.cpp进行多token预测的Qwen3.5-122B Q5和Q6量化模型的基准对比,吞吐量分别为20.24 t/s和17.17 t/s。
我在 vLLM 和 llama.cpp 上对 Gemma 4 和 Qwen 3.6 测试了 MTP —— 推理速度提升 3.34 倍,这是我的发现(RTX 6000 PRO)。
使用 vLLM 和 llama.cpp 对 Gemma 4 31B 和 Qwen 3.6 27B 进行的多令牌预测(MTP)基准测试显示,推理速度最高提升 3.34 倍,最优推测令牌数量因模型和引擎而异。