本地大模型部署记录:Qwen3.6-27B MTP 在双 7900 XTX 上的推理优化
-
感謝大大的測試分享,好人一生平安

-
感謝大大的測試分享,好人一生平安

-
--spec-draft-n-max 6
官方建议不超过3 , 6的话基本没法好好用了
另外 Q4 量化(尤其有 NVFP4 的话)貌似不比 Q8 差多少, 速度还快, 不需要超长复杂编程的话不需要用Q8, 如果真的心理有想法的话, Q6 也足够了
-

本地大模型部署记录:Qwen3.6-27B MTP 在双 7900 XTX 上的推理优化
硬件:X99 主板 + Intel Xeon E5-2666 v3 + 双 AMD Radeon RX 7900 XTX (各 24GB VRAM)
系统:Ubuntu 24.04 LTS,ROCm 7.2.3,PyTorch 2.12.0
模型:Qwen3.6-27B-UD-Q8_K_XL.gguf (33GB,内置 MTP 规范解码头)
推理引擎:llama.cpp (upstream,支持 ROCm HIP)
一、背景与目标
在一台配备双 7900 XTX (各 24GB) 的 PC 上部署 Qwen3.6-27B 模型,目标是达到 35+ tokens/s 的推理速度,并支持粤语对话及工具调用。
最初使用 DFlash(一个基于 llama.cpp 的 fork),利用其 dual GPU + spec decode 实现加速。但在运行过程中发现 spec decode 失效,速度从原本的 ~35 t/s 跌至 ~23 t/s。
二、硬件与系统配置
硬件规格
- CPU:Intel Xeon E5-2666 v3 (Haswell-E, 10C/20T)
- 主板:X99-CD3 GAMING (山寨板,BIOS 解锁 PCIe 4.0)
- GPU 0:RX 7900 XTX (24GB) — 05:00.0,PCIe 4.0 x16
- GPU 1:RX 7900 XTX (24GB) — 08:00.0,PCIe 4.0 x16
- 内存:126GB DDR4
PCIe 总线分析
为什么这是 PCIe 4.0?
两张显卡均运行在 PCIe 4.0 x16 (16 GT/s)。这是通过以下方式确认的:
确认方法 1 — lspci(需要 sudo):
sudo lspci -vvv -s 05:00.0 | grep -E 'LnkSta|LnkCap'输出:
LnkCap: Port #0, Speed 16GT/s, Width x16
LnkSta: Speed 16GT/s, Width x16LnkSta 显示的是实际协商后的链路状态,不是理论最大值。数值含义:
- 8 GT/s = PCIe 3.0 (每通道 8 GigaTransfers/秒)
- 16 GT/s = PCIe 4.0 (每通道 16 GigaTransfers/秒)
当前协商结果为 16 GT/s x16 = PCIe 4.0 无误。
确认方法 2 — sysfs(无需 sudo):
cat /sys/class/drm/card0/device/current_link_speed输出:16.0 GT/s PCIe
第二张显卡同理:
cat /sys/class/drm/card1/device/current_link_speed输出:16.0 GT/s PCIe
两张卡均运行于 PCIe 4.0 x16,双向带宽约 32 GB/s。
为什么 X99 主板能跑 PCIe 4.0?
按照 Intel 官方规格,X99 芯片组 + Haswell-E CPU (E5-2666 v3) 只支持 PCIe 3.0。那么为什么这张主板能跑 PCIe 4.0?
关键在于这块 X99-CD3 GAMING 是所谓的"寨板"——由国内小厂(Huananzhi、Machinist 等)生产的 X99 兼容主板。
Haswell-E CPU 内部的 PCIe 控制器物理上实际能支持 16 GT/s 的信号速率。Intel 在官方产品中通过 BIOS/固件将其锁定在 8 GT/s(PCIe 3.0),可能是出于平台稳定性或产品线划分的考虑。这些寨板厂商通过修改 BIOS,解除了 Intel 施加的这一软件限制,让 PCIe 控制器跑到了其物理能够达到的 16 GT/s。
换句话说:这不是"魔改"硬件,而是解除了软件封印。Haswell-E 的 PCIe 控制器从设计上就具备 PCIe 4.0 的能力,只是 Intel 官方选择将其关闭。
这对双 GPU 推理意味着什么
PCIe 4.0 x16 提供约 32 GB/s 的双向带宽,是 PCIe 3.0 x16 (16 GB/s) 的两倍。在 dual GPU layer split 模式下:
- 每步推理需要在 GPU 0 和 GPU 1 之间传输 activation tensors
- 27B 模型约 60 层,每层 activation 约 200MB
- 短 prompt (30 tokens):只传输几次,带宽差异不明显
- 长 prompt (200 tokens):200+ 次累加传输,PCIe 4.0 的带宽翻倍能将 sync 延迟缩短约一半
- 对于千 token 级别的生成长度,差距更加显著
如果运行在 PCIe 3.0 上,长 prompt 的速度预计会再下降 10-25%。
软件栈
- ROCm 7.2.3 (系统级安装,无需额外配置)
- llama.cpp:从上游源码编译,启用 -DLLAMA_HIPBLAS=ON
- 双 GPU tensor split:--tensor-split 1,1 + --split-mode layer
三、推理引擎选型历程
3.1 第一阶段:DFlash (失败)
DFlash 是 llama.cpp 的一个 fork,主打 dual GPU + spec decode 加速。初期曾达到 ~35 t/s 的速度。
问题:
- Spec decode 的 acceptance rate 从正常的 ~60% 暴跌至 14-28%
- 速度降至 ~23 t/s
- 粤语输出出现乱码 (mojibake)
- 尝试更新 submodule、加参数均无效
根因分析:
DFlash 的 spec decode 实现基于 llama.cpp 的旧版本 commit 7d9a95d。官方 llama.cpp 已在 GitHub issue #23268、#23544 中修复了 spec decode 超时和低 acceptance rate 的问题,但 DFlash 没有合并这些修复。尝试 cherry-pick upstream fix d14ce3d 时发现大量冲突,放弃修复。结论: 问题不在 ROCm 版本或 GPU 配置,而是 DFlash 自身的 implementation bug。开源社区也确认了这一点。
3.2 第二阶段:切换至上游 llama.cpp + MTP
MTP (Multi-Token Prediction) 是 Qwen3.6 模型内置的规范解码 (speculative decoding) 能力:
- 模型本身包含多个预测头,可以直接生成多个候选 token
- 不需要外部 draft model
- 与 --spec-type draft-mtp 配合使用
选择 UD-Q8_K_XL (33GB) 量化:
- 用户指定,质量远高于 Q4_K_M
- Q8 保留了更好的精度,适合粤语和复杂指令
- 代价是 VRAM 占用大,几乎占满两张 24GB 显卡
四、最终配置
llama-server 启动参数
llama-server
--model Qwen3.6-27B-UD-Q8_K_XL.gguf
--port 8080
--host 0.0.0.0
--n-gpu-layers 99
--flash-attn on
--split-mode layer
--tensor-split 1,1
--ctx-size 65536
--batch-size 2048
--ubatch-size 512
--spec-type draft-mtp
--spec-draft-n-max 6
--temp 0
--parallel 1
--no-mmap
--reasoning off关键参数说明:
- --split-mode layer:按层分割到双 GPU (比 row 模式更好)
- --tensor-split 1,1:平均分配到两张显卡
- --spec-type draft-mtp:启用 Qwen3.6 内置的 MTP 规范解码
- --spec-draft-n-max 6:每步生成 6 个 draft tokens (1/2)
[2026/5/23 下午7:33] HKT_Bot: - --ctx-size 65536:最大上下文 64K tokens - --flash-attn on:启用 Flash Attention 节省 VRAM
Systemd 服务配置
[Unit]
Description=llama-server
After=network.target[Service]
Type=simple
User=ic
ExecStart=/home/ic/llama.cpp/build/bin/llama-server
--model /home/ic/.cache/huggingface/hub/models--unsloth--Qwen3.6-27B-MTP-GGUF/snapshots/b3a58239d8d40b953e34936c9afeb28baa518230/Qwen3.6-27B-UD-Q8_K_XL.gguf
--port 8080 --host 0.0.0.0 --n-gpu-layers 99 --flash-attn on
--split-mode layer --tensor-split 1,1 --ctx-size 65536
--batch-size 2048 --ubatch-size 512
--spec-type draft-mtp --spec-draft-n-max 6
--temp 0 --parallel 1 --no-mmap --reasoning off
Restart=on-failure
RestartSec=5[Install]
WantedBy=default.target
五、性能测试结果
5.1 速度基准
- 短 prompt (~30 tokens):35-57 t/s,~92% MTP Acceptance,最高峰值,cold start 后稳定
- 中 prompt (~100 tokens):40-45 t/s,~65%,典型日常使用场景
- 长 prompt (~200 tokens):20-23 t/s,~21%,长生成时 draft 偏移,reject 增多
- 粤语对话 (150 tokens):~22 t/s,~21%,粤语输出正常,无乱码
5.2 与 DFlash 对比
- 速度 (短):DFlash ~25 t/s → llama.cpp 35-57 t/s
- 速度 (长):DFlash ~23 t/s → llama.cpp 20-23 t/s (持平)
- 初始延迟:DFlash 低 → llama.cpp 较高 (33GB 模型加载慢)
- 模型质量:DFlash Q4 (损失大) → llama.cpp Q8 (几乎无损)
- 粤语支持:DFlash
乱码 → llama.cpp
正常 - 稳定性:DFlash
spec decode 间歇性崩溃 → llama.cpp
稳定运行
5.3 长短 prompt 速度差异分析
长 prompt (200 tokens) 速度明显低于短 prompt (30 tokens),原因有三:
-
MTP acceptance rate 随生成长度下降
- 短 prompt:draft token 与 main model 的分布接近,~92% 被接受
- 随着 context 增长,draft 预测偏离 main model 越来越大,acceptance 降至 ~21%
- 更多 reject → 更多 main model evaluation → 更慢
-
KV Cache 增长
- 30 tokens:attention matrix 小,VRAM bandwidth 充足
- 200 tokens:attention matrix 增长 ~44 倍,GPU 需要搬运更多数据
- Q8 33GB 模型已经几乎占满 dual 24GB VRAM,KV cache 空间紧张
-
双 GPU layer split 的 PCIe 同步开销
- 每步推理需要在 GPU 0
1 之间传输 activation data - 短 prompt:只传输几次,开销可忽略
- 长 prompt:200+ 次累加传输,PCIe latency 显著
- 每步推理需要在 GPU 0
5.4 GPU 资源使用
- GPU 0:VRAM 24GB 总量,~22.7 GB (95%) 使用,剩余 ~1.3 GB,PCIe 16.0 GT/s x16
- GPU 1:VRAM 24GB 总量,~18.9 GB (79%) 使用,剩余 ~5.1 GB,PCIe 16.0 GT/s x16
剩余 VRAM 约可容纳 5-20K tokens 的 KV cache。超过此量会 spill 到系统 RAM (126GB),导致速度进一步下降。
六、遇到的关键问题
6.1 DFlash spec decode 失效
- 症状: acceptance rate 14-28%,速度 ~23 t/s
- 根因: DFlash 基于旧版 llama.cpp (commit 7d9a95d),未合入上游修复 (d14ce3d #23268 #23544)
- 处理: 放弃 DFlash,转用上游 llama.cpp + MTP GGUF
6.2 Qwen3.6 粤语支持
最初在 DFlash 上粤语输出为乱码 (mojibake)。切换到 llama.cpp MTP Q8_K_XL 后,粤语完全正常:
"你好呀!今日天氣幾好,你有冇出街行下?"6.3 Qwen3.6 工具调用限制
Qwen3.6 模型的工具定义数量有限 —— 实测约 6-7 个 tool definitions 为上限,超过后会进入无限重复循环。这与 Hermes Agent 使用的 30+ 工具不兼容。
6.4 上下文长度设置
配置了 --ctx-size 65536 (64K tokens),但实际可用长度受限于 VRAM:
- 33GB Q8 模型已占用绝大部分 VRAM (GPU0 95%, GPU1 79%)
- 剩余 VRAM 不足以支持满 64K 的 KV cache
七、总结
从 DFlash 切换到上游 llama.cpp + MTP GGUF 是一个正确的决策:
- 速度:短 prompt 提升至 35-57 t/s,恢复原有水平
- 质量:Q4 → Q8,精度大幅提升
- 粤语:
→
完美支持 - 稳定性:
频繁崩溃 →
持续稳定运行 - 维护性:DFlash 已停更多年的 fork → upstream 持续更新
最终 verdict: Qwen3.6-27B Q8_K_XL 在双 7900 XTX 上通过 llama.cpp + MTP 实现了高性能本地推理,短 prompt 达到 35-57 t/s,长 prompt 20-23 t/s,粤语正常。
剩余 VRAM 不足以支持满 64K 的 KV cache
KV cache 做 TurboQuant 量化,看你的配置應該可以放到 256K context
-
系统 于 取消固定此主题

