【纯闲着】2700 块的洋垃圾跑 QFN:MI50 16G×2 + 128G DDR3,从装系统到 54 tok/s,这可能是目前价格最低的洋垃圾方案。
-
这个8卡是不是可以跑ds v4.1 flash了
-
-
-
1T的NVMe硬盘不计入可不行。这个不便宜。按小黄鱼价加上电源算1000不过分。
加上1000,这也是很有性价比了。 -
這卡有潛力, 已經有大神做strata優化:
https://github.com/Niko1221/Strata/pull/5361 -
這卡有潛力, 已經有大神做strata優化:
https://github.com/Niko1221/Strata/pull/5361 -
,
T terry 固定了此主题
-
-
-
-
-
-
-
调优再进一步
上一篇写到 54.0 tok/s 就收尾了。
吃晚饭的时候,我又去挖了挖潜力。
先把结论放在前面:
同一台机器、同一份模型文件、同样的量化档(IQ3_S),decode 从 54.0 提到 65.1 tok/s,峰值可以突破100tok/s,prefill 从 571 提到 752 tok/s,峰值850 tok/s。
均值65.1 是官方 2×MI50 参考机(49.2)的 1.32 倍,是我自己首跑(28.3)的 2.3 倍。
代价只有一个:引擎版本从 0.1.55 退到 0.1.52+PR。



一、线索:一个没人评审的 PR
上一篇之后我看到:
這卡有潛力, 已經有大神做strata優化:
https://github.com/Niko1221/Strata/pull/5361作者是 4×MI50 32GB 的机器,报出来的数字是 decode 125 tok/s、prefill 8K 1250 / 32K 1766——差不多是我 54 的两倍多。我第一反应是"32G 版显存大,全驻,不奇怪",但里面有些数字对不上:我判负过的
--prefill-pipe,在他那儿是 +73% @8K、+109% @32K。这个 PR 的状态很说明问题:22 个 commit、30 个文件、+5046/−147,整个 PR 只有两条评论,都是 bot 在提醒"标题要加 [Engine] 前缀",没有一行人工评审。作者自己在描述里写着"基于 0.2.7,main 已经前进约 4k commits"。
也就是说:这东西质量未必差,但没人验过,也不会自动合进来。想用只能自己来。
二、第一次找错了地方
我让模型去读这个 PR 的提交列表,它挑了
e4f4027说:"这条值得参考,IQ3 的 gate/up 走 repacked GEMM,bitwise 等价,GEMM 从 0.85ms 降到 0.63ms。"听起来很对口——我用的正是 IQ3_S。于是我把这个分支完整编译了一遍(0.1.52,165/165 目标通过),然后做了个隔离实验:
STRATA_PF_RP_IQ3=0把这个改动关掉,看差多少。结果:
臂 配置 decode prefill 分支默认 repack 开着 50.1 690 同一分支 STRATA_PF_RP_IQ3=0关掉它53.4 721 关掉反而更快。 也就是说这条提交在我这台机器上测不出收益,方向甚至是反的(都在噪声里)。
但它不是白读的——它把我引到了 PR 自带的
docs/AMD_MI50.md,那里面有一句被我(和模型)一路略过去的话:Each new switch is off by default. When a switch is off, that kernel runs exactly as before.
三、转折:收益在"默认关着"的那一整块里
docs/AMD_MI50.md的推荐配置里,env有 21 个开关。默认全关,全关时"kernel 和以前完全一样"。这意味着:我前面用分支默认态跑出来的 50.1,等于只免费蹭到了 prefill 栈(默认开),decode 一个开关都没吃到。
把 21 个全打开之后:
臂(同一协议,空转 90s) 引擎 decode 中位 prefill 冷启动 上一篇的生产版 0.1.55(0.2.9) 47.0 521 75s 分支默认态 0.1.52+PR 50.1 690 84s 分支 + 关掉那条提交 0.1.52+PR 53.4 721 54s 分支 + 21 个开关全开 0.1.52+PR 61.3 701 57s decode +30%、prefill +34%。
顺带说清楚一件事:为什么同一台机器上一篇测 54.0,这一轮基线只有 47.0。因为口径变了——上一篇收尾时用的是官方口径(1.6K prompt / 128 token / temp 0),这一轮统一成 3×512 token + 14K token 长 prefill,两者不可直接比。下面所有数字都在这一个口径里。
四、不等作者,自己把分支拉下来编
作者只在 PR 分支上,fork 也不会被合并。但这件事根本不需要作者配合:
curl -L --proxy http://192.168.2.2:7890 \ -o int6.tar.gz \ https://codeload.github.com/rpcribari/Strata/tar.gz/refs/heads/int631,216,899 字节,解压到
/src/Strata-int6。三个意外的好消息:- ggml 的 pin 没变(还是
3cf03257f2),所以我上一轮为 0.2.9 下的/src/llama.cpp直接复用,不用重下 37MB。 - 这个分支自带了我上一篇手补的那两个宏,而且在
dflash2.cpp:198把 guard 改成了#if defined(STRATA_USE_HIP) || defined(STRATA_HIP_GFX906)——比我"补两个 #define"的土办法干净,说明作者踩过同一个坑。 project(strata VERSION 0.1.52),编译 165/165 全过,约 3 分钟。
编译命令和上一篇完全一样,只把源码目录换掉:
cmake -S . -B build-906 -G Ninja \ -DSTRATA_HIP_GFX906=ON -DCMAKE_HIP_ARCHITECTURES=gfx906 \ -DSTRATA_GGML_DIR=/src/llama.cpp \ -DCMAKE_C_COMPILER=/opt/rocm/llvm/bin/clang \ -DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++ \ -DCMAKE_BUILD_TYPE=Release ninja -C build-906 strata注意:这里有一个反直觉的取舍——我为了 +30% 把引擎从 0.1.55 退回了 0.1.52。 新版本里 DFlash2 的改进、
--draft mtp那套新键,全都用不上了。但我是走 MTP + 流水线路线的,DFlash2 本来就用不了(上一篇第五节),所以这个代价对我是零。
五、空转时间本身就是个变量
社区那份 gfx906 调优台账里有一句我当时没在意的话:
重启后与每次换负载后都有约 5 个请求的冷启动爬坡,且是 10 分钟量级、值得 3.7 tok/s 的进程级效应。
于是我把同一套配置的等待时间从 90 秒拉到 540 秒,重测:
空转 decode 中位 三次样本 prefill 90 s 61.3 58.4 / 64.9 / 61.3 701 540 s 65.1 57.6 / 66.9 / 65.1 751.9 +6%,一分钱没花。
这条值得单独记住:冷启动不是"等一会儿就好",而是一条 10 分钟的爬坡曲线。 空转 90 秒去比两个配置,等于在两条不同形状的爬坡曲线上各取一个点做比较——数字看着挺整齐,结论可能是错的。我前面几轮"某开关无收益"的判断里,至少有一部分要打这个折扣。
六、最后一个选项,判负
那条提交还留了个选项:
STRATA_PF_RP_IQ3=2,让 IQ2_S 也走 repacked GEMM(作者报该算子 +12–21%,非 bitwise 但相对误差 1.7e-7)。我们的 pack 是混合量化(层 0/16 是
IQ3_XXS/IQ4_NL、层 8 是IQ2_S/Q2_0、层 24/32 是IQ2_S/IQ4_NL、层 40 是IQ3_S/IQ4_NL),IQ2_S 占比不小,值得一试。同样 540 秒空转:臂 decode 中位 prefill 21 个开关 65.1 751.9 22 个(多 RP_IQ3=2)60.8 754.4 decode −4.3、prefill 持平。 判负。作者那个 +12–21% 是在他那种"同类专家集中"的 pack 上测的,我这种层间混排的 pack 把 IQ2_S 从 MMQ 挪走反而更亏。
七、现在的生产配置
{ "exe": "/src/Strata-int6/build-906/strata", "args": [ "--pack", "/src/models/packs/iq3s", "--native", ".../IQ3_S-00001-of-00002.gguf", "--ple-gguf", ".../IQ3_S-00002-of-00002.gguf", "--expert-profile", "/src/models/learned-iq3s.bin", "--expert-profile-save", "/src/models/learned-iq3s-mtp.bin", "--expert-profile-save-every", "3", "--expert-cache", "auto", "--prefill", "auto:16384", "--prefill-pipe", "350", "--spec", "3", "--max-context", "131072", "--kv", "int8", "--kv-resident", "32768", "--layer-split", "27", "--trim-stage-weights", "--mtp", "/src/models/mtp/rt", "--pipeline-windows", "2", "--pool-workers", "32", "--pcie-frac", "0", "--vram-reserve-mib", "1024" ], "env": { "STRATA_RESIDENT_HEADROOM_GIB": "6", "STRATA_MTP_STAGE0": "0", "STRATA_RESIDENT_PIN": "0", "STRATA_GR_NORM_FAST": "1", "STRATA_IQ_STAGE_GRID_MMVQ": "1", "STRATA_IQ_MMVQ_XLDS": "1", "STRATA_IQ_MMVQ_RB": "16", "STRATA_IQ_MMVQ_R2": "1", "STRATA_MMVQ_XLDS": "1", "STRATA_MMVQ_WPB": "8", "STRATA_MMVQ_Q6X4": "1", "STRATA_MMVQ_Q4X4": "1", "STRATA_EXP_X4": "1", "STRATA_EXP_GU_H2": "1", "STRATA_EXP_LDS_Q50": "1", "STRATA_GR_DOWN_TG": "a", "STRATA_GR_DOWN_PF": "1", "STRATA_MMVF_ROWS": "1", "STRATA_GFX906_ATTN_QUERY_SWIZZLE": "1", "STRATA_GFX906_ATTN_REDUCE12": "1", "STRATA_HIP_SWIGLU_FUSED": "1" } }实测:decode 65.1 tok/s / prefill 752 tok/s / 128K 上下文 / 命中率 0.96–0.98 / 冷启动约 60 秒。冒烟抽查("机械效率 + 斜面")输出结构完整、带摩擦力的因果解释。
顺便说一句:
STRATA_GFX906_ATTN_QUERY_SWIZZLE和STRATA_GFX906_ATTN_REDUCE12这两个开关,我上一轮单独测它们是判负的(48.1/47.8,都低于基线 49.3)。现在它们进了全开组合,整体反而更快——这大概是"单开没用、和别的 kernel 一起才有用"的典型,也说明单开关 A/B 在 kernel 层是会骗人的。
八、三条可复用的教训
1. 收益常藏在"默认关闭 + 文档里一句话"里
我两次踩同一个坑:
--adapt-every 0:官方冒烟命令就带着,我继承了,偷走 27%;- 21 个
STRATA_*:默认全关,文档写得很清楚"off by default",但我先只编了分支就跑,白跑了 20%。
判据很简单:一个功能如果"默认关",它的作者就是在等你读文档。 拿到新分支,先
grep -n "env" docs/*MI50*.md,别急着ninja。2. 任何"某开关无效"的结论,先去日志里确认它真的生效
我在上一篇写过这条,这次又验证了一遍:
--pipeline-windows 2没有 MTP 会被静默关掉,日志里那句is off: it needs the MTP drafter躺在几万行里。判据就看三类行:is off/kept as asked/ 启动 banner。3. 测速的空转时间必须够长
90 秒和 540 秒能差 6%。这条对谁都成立,不是我这台老机器的特例——社区在同一份台账里写了"10 分钟量级"。
九、代价与回滚
诚实列出:
- 引擎版本倒退:0.1.52+PR < 0.1.55 < 0.1.57。如果哪天官方把 PR 的 kernel 合进 main,我立刻回去。
- 回滚成本几乎为零:
/src/models/strata-iq3smtp.json(0.1.55 + MTP + 流水线,54.0)和/src/Strata/build-906/strata都留着,改个exe路径重启就能退回。 - 分支是 untested 的:一个人维护、没人评审、基于 0.2.7。我只能用"编译通过 + 冒烟正常 + 输出结构正确"来担保,长跑稳定性还没验证(这点和上一篇的待办一样)。
十、第 9 个台阶后的横向对比
平台 卡 decode 备注 本机(本轮) 2×MI50 16G 65.1 int6 分支 + 21 开关 + IQ3_S + MTP + 流水线 本机(上一篇) 2×MI50 16G 54.0 0.1.55 + MTP + 流水线 官方参考机 2×MI50 16G 49.2 IQ3_XXS,Ryzen 5700X + DDR4-3600 社区同卡 2×Radeon Pro VII 16G 47.8 IQ3_S,Ryzen 5 2600 + DDR4-2133 单卡 4080 SUPER 1×16G 58.8 IQ3_XXS,i7-12700 + DDR4-3200 同机 llama.cpp 2×MI50 16G 26.3–26.6 Qwen3.8-27B UD-Q4_K_M 我这台 2700 块的洋垃圾,现在的 decode 已经超过了单卡 4080 SUPER 的公开数据(58.8),而那张卡的价格够配三台这机器。
而且这是在 DDR3-1333 约 30 GB/s 的前提下跑出来的。这也侧面说明:MoE 的 decode 瓶颈主要不在显存带宽,而在专家回落到内存时的那条路有没有被榨干——这条路一旦通了,便宜的 DDR3 也能顶住。
十一、待办(更新)
- 质量仍然只有冒烟和风格样本,没有正式评测。 3bit 在中文长文上的失效模式是重复、断段、术语漂移,必须真材料 A/B 才算数——这是我现在唯一的硬闸门。
- 长跑稳定性:分支版连续跑满 24 小时没有掉速/OOM 才算数。
- 没测并发(官方与社区都说这条路径并发不行)。
--prefill-pipe在"专家全驻"场景(换 Coder IQ1_M 那种塞得进 32GB 显存的档)还没复测——PR 里它 +73% @8K 的前提就是全驻。- 层切分仍只用了官方给的 27/21,没穷举。
十二、一句话总结
上一篇的 54 是"把开关打开",这一篇的 65 是"发现开关根本没打开"。
真正值钱的不是那 11 tok/s,而是这两次都指向同一件事:这套引擎的默认值是给"能跑起来"准备的,不是给"跑得快"准备的。
--adapt-every 0是一处,21 个 env 是另一处,下一处大概率还写在某个没人读的docs/*MI50*.md里。项目地址:Niko1221/Strata
分支:rpcribari: int6
- ggml 的 pin 没变(还是
-
-
我只能说太牛了,这套调优其实就是“把每一块硬件的脾气摸透,让它们各司其职”:
- 贵的显存跑计算,便宜的内存当仓库:把需要高频计算的核心零件死死锁在极速的显存里,把体积庞大但只需要查询的辅助数据塞进便宜的内存里,用最少的钱买到了最大的容量。
- 每次只动一小部分,不搞全员大集合:利用 MoE 架构“激活小部分”的特点,每次生成只调用一小撮专家,把原本几十个人才能干的活压缩到几个人干,直接避开了内存搬运速度慢的死穴。
- 干掉假把戏,开关全拉满:把软件里那些表面开着、实际在偷懒的机制通通揪出来,同时把隐藏在底层的加速开关全部手动打开,不让硬件浪费哪怕一微秒。
- 耐心等机器“热身”好:就像跑马拉松前要热身一样,刚开机数据还没理顺,等它空转跑个几分钟、把缓存全部命中之后,性能就能稳稳冲到最高点。
-
-
我觉得把一些东西放在内存当查表,这个思路是最核心的
-
-
-
最早32G版本的價格可是跟標題現在的16G差不多,前一陣子突然快跟V100 32G看齊了,有Strata 和 LLM搞定後台,真的變成有VRAM便是娘了
-
,系统 取消固定了此主题

奖励通知:感谢提供 MI50 / MI60 的优化信息(Strata 分支),对折腾这批卡的同好很有参考价值,奖励 +3 积分。
,这个不用较真
本帖参与讨论人数已达 10+,入选热议,作者 +3 积分奖励!