一台 30GB 内存的老实 Linux 盒子,2 张 Radeon AI PRO R9700(32GB ×2 / gfx1201 / RDNA4),跑 83.8GB 的 Qwen3.8-Flash-Next UD-Q3_K_XL —— 3.0x 我自己原来那版。
一句话结果
| 指标 | 原始基线(Vulkan 128K) | 最终版(ROCm + MTP,144K/160K) | 提升 |
|---|---|---|---|
| 数学推理(Thinking) Decode | 24.1 tok/s | 65.1 ~ 72.2 tok/s | 最高 3.0x |
| Smoke Code | 25.2 tok/s | 66.4 ~ 68.1 tok/s | 2.7x |
| 中文百科问答 Decode | 25.2 tok/s | 52.4 ~ 57.6 tok/s | 2.3x |
| 代码局部改写 | 26.8 tok/s | 64.8 tok/s | 2.42x |
bench.py 32000 总耗时 |
~125 s | 56 ~ 57.7 s | -55% |
| 冷启动就绪 | ~104 s | 18 ~ 20 s | -81% |
完整对照表(基准 → 方案1 → 方案2+3 → 方案4)见文末。
最终版到底做了什么
结论先行:80% 靠两件事 —— ① 换 ROCm 7.14 + RDNA4 gfx1201 定制算子融合;② 上官方共享 MTP 草稿头做投机解码。而这一切的前提是:把 84GB 模型塞进 64GB 显存,系统内存只有 30GB。
1. 从 Vulkan 迁到 ROCm 7.14(gfx1201 专用分支)
- 用了
JohnTDI-cpu/llama.cpp-flash-next-rdna4分支编译的运行时(gfx1201 专用融合算子,GGML_JOHNV8_HCBLOCK=1、GGML_JOHNV8_MMQ_ID_JMAX=32)。 - 这是 RDNA4 卡真正吃满的开关:同样的卡,单是这一迁,decode 翻倍级起步。
2. 官方共享 MTP 草稿头做投机解码(Concept 56 同源)
- 官方
--spec-type draft-mtp,用共享权重 MTP 草稿模型(Q4_K_M,仅 1.78GB)放第二卡,--spec-draft-ngl all。 --spec-draft-n-max 4 / n-min 1 / p-min 0.75:最多一次投机 4 token,显著抬高每步产出。- MTP 草稿头不是普通小模型裸猜 —— 它和主模型共享同一套 Expert/上下文,猜测命中率比独立小 draft 高一个量级,投机收益才真正落地。
3. 内存只有 30GB,怎么把 84GB 塞进 64GB 显存 —— 按行读的 PLE 表
- 核心洞察(Qwen3.8-Flash-Next 这个架构太适合它了):26.82GB 的 n-gram/PLE 表(
per_layer_token_embd)每个 token 只读一行 4KB,带上它token_embd也按行读,一起--override-tensor "^(per_layer_token_embd|token_embd)\.weight$=CPU"扔 CPU。 - 于是 全部 36 层线性注意力(SSM)状态 + 全部 KV Cache + 几乎所有权重 100% 驻留物理显存;每 token 从 DDR5 拉 4KB 行,带宽没有压力。
- 结果就是双卡 零 GTT 溢出,每张卡还被压到只剩 ~300-400MiB 的余地:
Card 0: VRAM 30.89 / 31.86 GiB,GTT 0.02 GiBCard 1: VRAM 31.49 / 31.86 GiB,GTT 0.01 GiB
4. 上下文打到 144K(备用档 192K)
- 生产档
--ctx-size 147456(144K),q4_0KV,-fa on,b1024 / ub256,threads 12/16。 - 想挑战长的就切到 Vulkan + MTP +
on-direct备份脚本的 192K:同样零 GTT。
彩蛋:冷启动 18 秒
换引擎后冷启动就绪只要 18~20 秒(原来 104 秒),GPU 全干活的体感直接从"泡面"变成"微波炉"。
全阶段演进对比表
| 场景 | 原始基线(Vulkan 128K) | 方案1 ngram-mod(Vulkan 256K) |
方案2+3 Vulkan+MTP+on-direct(192K) | 方案4 ROCm+MT P(生产,144K/160K) |
|---|---|---|---|---|
| 数学推理 Decode | 24.1 | 24.4 | 57.1 | 65.1~72.2 |
| Smoke Code | 25.2 | 25.4 | 50.1 | 66.4~68.1 |
| Python 快排+二分 | 33.5 | 33.7 | 55.0 | 54.0 |
| 中文百科 | 25.2 | 25.3 | 36.1 | 52.4~57.6 |
| 代码改写 | 26.8 | 38.9 | 52.3 | 64.8 |
| bench 2000 pp | 321.0 | 322.4 | 347.9 | 622~947 |
| bench 2000 pd | 31.7 | 31.8 | 39.4 | 83.9~93.3 |
| bench 32000 pp | 262.0 | 263.5 | 264.6 | 526~542 |
| bench 32000 pd | 31.6 | 31.6 | 38.5 | 67.0~67.7 |
(tok/s,越高越好;pp=prefill,pd=decode)
环境清单
- Ubuntu 24.04,30 GiB RAM,2 × AMD Radeon AI PRO R9700 32GB(gfx1201,双槽 64GB 显存总额)
- 模型:UD-Q3_K_XL 83.8GB + 共享 MTP Q4_K_M 1.78GB
- 运行时:
JohnTDI-cpu/llama.cpp-flash-next-rdna4(ROCm 7.14,gfx1201);备份档为 Vulkan PR#28243(MTP)+ PR#29030(on-direct) - 关键参数:
--split-mode layer --tensor-split 1,1 --fit off --override-tensor "^...=CPU" --spec-type draft-mtp --spec-draft-device ROCm1 --ctx-size 147456 -fa on -ctk q4_0 -ctv q4_0 -b 1024 -ub 256
感慨
显卡钱一分没多花、内存 30G 顶到现在,同一个 84GB 模型,从 24 到 72 tok/s。RDNA4 在 Vulkan 上吃的亏,ROCm 7.14 + 定制融合算子补齐了还没脾气。期待下一版上游把 MTP/on-direct 直接合入,省得我留一堆备份脚本。跑起来再也不会有人偷偷说我"双卡花瓶"了。