主机硬件全景

一句话背景:我手里有一张 AMD Radeon AI PRO R9700(32GB 显存的工作站卡,RDNA4 架构),配一台 i5-9600KF + 32GB 内存的普通主机。我的目标就一个——在家跑本地大模型,跑得稳、跑得快、还安静。

接下来这几个月,我把风扇逐路拆开测、功耗锁了 50W、量化档位来回对撞、十几项系统开关全部试过。这篇文章是全部调优结束后的"终版答案":哪些调整真有用、哪些是白折腾、这台机器的真实天花板在哪。所有数字都是这台机器上反复实测的,不是跑分软件截图,不是理论值。

先给三个最重要的结论(没时间的就看这三条):

  1. 把功耗从默认 300W 锁到 250W,温度降 8°C,风扇转速掉 600 转(明显更安静),速度一点没掉——因为 AI 推理的瓶颈是"读数据"不是"拼算力",多给 50W 电换不来速度。
  2. 换更小的量化(IQ4_XS,权重小 13%)速度一点没变——瓶颈不在读权重,所以"压缩模型换速度"这条路对这套配置是封死的,别试。
  3. 前缀缓存命中时,读长 prompt 能快 32 倍(5.44 秒 → 0.17 秒)——如果你有固定的系统提示词/固定的 few-shot,这是白捡的最大加速。

1. 先说配置:一台不贵但够用的机器

MoE 模型拆开放在整台电脑上

32GB 显存意味着什么?一张 24GB 的消费卡塞不下的模型,它装得下。日常我按显存容量分三档加载(下表全部真加载验证过,不是估算):

档位 用途 量化 上下文 显存占用
64K(默认) 快——日常对话、给子智能体用 UD-Q4_K_M 65536 19.5 GB
128K 准——精度要求高的活 UD-Q5_K_M 131072 25.3 GB
262K 长——喂大文档 UD-Q4_K_M 262144 25.8 GB

2. 第一个难题:散热——风扇映射是"逐路停转"测出来的,不是猜的

风扇与散热系统

机箱风扇的接口和风扇的对应关系,厂商手册经常不写清楚。我的做法很笨但可靠:一次只让一路 PWM 停转,看哪几把扇子停了,6 个通道全部实测映射:

通道 管着哪些风扇 峰值转速
pwm1 顶部×2 排风 ~924
pwm2 前面×3 进风 + CPU 散热器(共用一路) ~1400
pwm3 / pwm4 空置(实测验证过) —
pwm5 后面×1 排风 ~1965
pwm6 底部×1 进风(正对显卡涡轮进气) ~1906

过程中踩了三个坑,都记下来给你省时间:

  1. pwm2 一路同时管前面 3 把风扇和 CPU 散热器——配曲线时必须照顾 CPU 发热的场景,不能只按显卡温度来。
  2. pwm6 原本插在 "M.2 FAN" 口上,那个口不受 PWM 控制(恒定满速),风扇换到受控口上才真正接管。
  3. CPU 散热器的口受 BIOS 保护(拔了开机就报 "CPU Fan Error" 要按 F1),所以它和前面进风共用一路,不能随意拔。

配好曲线后,验证过联动确实生效(真实运行数据):

显卡结温 底部进风风扇
29°C(凉) 812 转
69°C(热) 1578 转
82°C(更热) 1890 转
39°C(冷却后回落) 826 转

另外显卡自己的风扇我特意没接管——驱动自动控制得很好(空闲 1890 转 → 满载 3358 转),比任何软件都准,保持自动就行。

3. 第二个难题:功耗——锁 250W 是全文最值的一个调整

用 systemd 服务把功耗上限写到 250W(注意:必须用 systemd 服务,udev 规则会被驱动覆盖,因为 amdgpu 驱动加载时自己启用 runtime PM 的时序在 udev 事件之后)。然后 300W 和 250W 各跑稳态满载对比:

300W(默认) 250W(现在的设置)
显卡结温 96-97°C 89-90°C
显存温度 72°C 74°C
显卡风扇 3926 转 3340 转(明显更安静)
FP16 算力 127-148 TFLOPS 113-154 TFLOPS(无实质差异)

降 8°C、风扇少 600 转、算力零损失。 原因一句话:AI 推理的瓶颈是"数据搬运"(访存),不是"算得快",多给 50W 电只是让风扇更吵、温度更高。离热限(110°C)还有 20°C 余量,长期跑着很稳。

散热全景(250W 稳态):

状态 显卡结温 功耗 显卡风扇
空闲 —(边缘 25°C) 14-15W 1890 转
250W 满载 89-90°C 249W 3358 转
300W 满载 96-97°C 296-301W 3926 转

4. 到底能跑多快?——可复现的性能基线

读 prompt(喂长文本):1K 输入 859 tok/s,45K 输入 935 tok/s,61K 输入 734 tok/s——读一篇 32K 字的长文档大概 15 秒。

写答案(decode,带 MTP n2 推测解码):日常档 38-51 tok/s,比人阅读速度快;代码任务最高 154 tok/s。

推测解码怎么选(同提示词各跑 3 轮的真实对比):

配置 速度 接受率 结论
MTP n-max 2(采用) 33.0 0.50 最优点
MTP n-max 1 32.2 0.70 略慢
MTP n-max 3 31.0 0.39 接受率崩,反而更慢
DFlash2 n-max 3 / 7 26.2 / 17.6 0.27 / 0.12 在这张卡上不划算

量化对速度的影响(这是反直觉的一条):

深度 Q4_K_M IQ4_XS(少读 13% 权重)
prefill 869 / 938 / 735 865 / 944 / 738
decode(纯带宽) 28.35 / 21.64 / 20.03 28.48 / 21.62 / 20.03

IQ4_XS 少读了 13% 的权重字节,速度一点没变——说明瓶颈是 48 层 SSM 结构每写一个词的递推开销,不是读权重慢。结论很硬:想提速,压缩量化没用,只能上更大显存/更高带宽的卡。

前缀缓存(固定的系统提示词可以"记住"不用重读):

场景 prefill 耗时
冷启动(3834 token) 5.44s
完全相同的提示词 0.17s(32×)
只换了结尾 0.98s
换了中间一段 3.33s

5. 别再折腾了:一张"负面清单"

以下全部试过,没有一项有剩余空间,列出来给同样在调 ROCm / RDNA4 的人省时间:

试过的 结果
--setperflevel high 反而更差(-23%),功耗还从 20W 涨到 50W——默认 auto 就是最优
升级 ROCm 版本 无实测收益 + 有真实翻车先例(gfx1201 静默回退 CPU,70 → 10 tok/s)
换 Vulkan 后端 prefill -30%(Mesa 25.2.8 是已知的 RADV 回退版本)
llama.cpp 升级 55 个 commit(含 gfx1201 专用调优) 零性能变化
GGML_VK_ALLOW_GRAPHICS_QUEUE=1 dense 模型 -8%(且我们走 ROCm 不走 Vulkan)
GGML_HIP_MMQ_MFMA 在 gfx1201 上是空开关(源码里 CDNA 才定义)
强制 MMVQ 的编译选项 gfx1201 上 -9%
--draft-p-min 0.5 拖慢 4.5%
--cache-reuse 256 无增量(SSM 层不能部分截断)
vLLM / SGLang / TensorRT / ExLlamaV3 / LMDeploy / Ollama / OpenVINO 等 gfx1201 上全部有硬阻塞,别浪费时间试

一句话总结这一节:ROCm 7.2.4 + 默认 auto 性能级别 + 250W 锁功耗,就是这套配置的甜点位。

6. 总结:这套组合的真实天花板

原始数据(温度转速 CSV、图表、分析脚本)都留档在主机 /root/fan_setup/,watt250.csv 是 250W 锁定后的最终验证基线,想核对任何单点数字可以按文件名查。