老旧的 4060 8G 显卡的笔记本用 LM Studio 跑 MoE 模型的加载参数测试
-
手头有一台2024年1月的华硕天选5 pro笔记本,硬件的主要配置如下:
- CPU:intel i9-13980HX
- 显卡:4060 8G
- 内存:32G DDR5
本着废物利用的原则,也想折腾一下,处理一些不方便上网或受限制的简单任务。经过认真拜读和学习本坛各位大神的帖子后,调试了几天,现在基本上能凑合着用了,总结分享如下:
1. 运行环境
- windows 11 专业版
- LM Studio 0.4.25
- runtime:CUDA llama.cpp (Windows) 2.44.0 和 2.66.0
平时主用windows,不想装双系统,试过wsl+ubuntu+llama.cpp,但性能损耗比较大,prefill和decode的表现不如直接用LM Studio。
此外,LM Studio查询和下载模型非常方便,如果不是追求极致性能的话,LM Studio也挺好的。
2. 模型选择
8G显存就不要想Qwen 3.8-27B之类的了,基本上吐字比打字机还慢。
只能考虑MoE类型的,比如Qwen3.6-35B-A3B系列、Gemma4-26B-A4B系列和Ornith-1.5-35B-A3B系列等。
至于4B、9B、12B的小模型,只能陪你聊天,如果想用于智能体调用,只能说看你想做什么了。
目前感觉Ornith-1.5-35B-A3B系列的综合表现比较符合我的要求,所以重点基于该系列模型进行了测试。其中:
- 原版:ornith-ai/Ornith-1.5-35B-A3B-GGUF · Hugging Face
- huihui版(mradermacher 量化) :mradermacher/Huihui-Ornith-1.5-35B-A3B-abliterated-GGUF · Hugging Face
- SC117版:SC117/Ornith-1.5-35B-A3B-Heretic-MTP-APEX-GGUF · Hugging Face
总体来讲,上述各模型的prefill和decode的速度表现相差不大,主要看自己的用途和喜好。
3. 参数配置
贫穷的硬件条件有限,无法将全部内容都加载到显存中,因此,哪些放显存、哪些放内存?是追求速度还是要安静稳定?要不要处理图像?难以兼顾的情况下,这就是个人的选择了。
(1)在LM Studio加载模型时应优先要满足的参数
-
Context Length (对应llama.cpp的 --ctx-size / -c)
如果想满足智能体调用,上下文长度至少32K,而64K相对稳妥些。实测结果32K时decode可以达到40 t/s 上下,64K时可达36 t/s 左右。
16K不是绝对不行,但经常会超限。而超过64K,对显存的需求和推理速度的影响比较大,需要取舍的内容就更多了。
极端一点儿,不加载mmproj、把所有的MoE都放在内存、把上下文开到256K,也一样能跑,无非是prefill和decode慢一些。
-
GPU Offload (对应llama.cpp的 --n-gpu-layers / -ngl)
一定要拉满,全部放入GPU。
-
Evaluation Batch Size 和 Physical Batch Size(对应llama.cpp的 --batch-size / -b 和 --ubatch-size / -ub)
这两个参数对prefill的影响非常大,太大或太小,都影响处理效率。经过对各种组合的实测,在 eval=16384 / phys=4096 时,prefill 速度可维持在900 - 1100 t/s 左右。
但是,这两个数值越大,消耗的显存越多。建议 phys 不要低于2048,eval ≥ phys,最好 eval 是 phys 的 2 - 4 倍。具体表现以在自己的机器上实测数据为准。
个人认为优先满足prefill的速度更重要,值得多分配一些显存。但太高也没必要,一是性价比不值得;二是本身显存就小,需要斤斤计较。
-
Offload KV Cache to GPU Memory (对应llama.cpp的 --no-kv-offload / -nkvo)
这个一定要开,对decode的速度影响很大。放在显存中比放在内存中差不多要快一倍。
需要注意的是:LM Studio中的设置和llama.cpp的参数所代表的含义恰好是相反的!在LM Studio的参数一定设置为开,意味着在llmam.cpp的参数一定不要加。
-
FlashAttention (对应llama.cpp的 --flash-attn / -fa)
一定要开,否则下面的 K/V cache 量化类型没法设置。
-
K Cache Quantization Type 和 V Cache Quantization Type (对应llama.cpp的 --cache-type-k / -ctk 和 --cache-type-v / -ctv)
都设置成 Q8_0 ,没毛病。由Q8_0改Q4_0,省下的显存不一定能多装一层MoE,但反而带来精度等问题,不太划算。
(2)在LM Studio加载模型时可以进行个性化选择的参数
-
Number of layers for which to force MoE weights onto CPU (对应llama.cpp的 --n-cpu-moe)
这个参数对于decode的速度有影响。原则应该是尽量让更多的MoE层留在显存,但通常最多也就保留10层左右,更多的还是要放在内存中。
对于Ornith系列 Q4_K_M 的模型,通常每个MoE层约占显存400~500M,每多保留一层在显存,可能会对decode速度提升1-2%。
尽管这个参数对decode的速度很重要,但也没必要太在意,毕竟硬件条件有限,只有大幅度改变该数值时,才会有明显感受,否则可能都比不过噪声或抖动。
-
mmproj的加载 (对应llama.cpp的 --mmproj )
对于mmproj文件,LM Studio默认是自动加载的,只要模型的文件夹里有与模型文件主名相同的mmproj文件。通常如果一个模型支持vision,则在LM Studio中下载时,相应的mmproj文件会自动随gguf文件下载到本地同一个文件夹中。
如果需要让智能体识别图像,当然要加载 mmproj 文件。但mmproj文件也算要占显存的,比如Ornith-1.5-35B-A3B系列模型BF16格式的mmproj文件大约880M左右,如果只是处理纯文本,不加载它则有可能在显存里多放两层MoE层,有利于提升decode的速度。
如何才能不让LM Studio自动加载呢?之前很多网传做法是移除mmproj文件或改名,这样比较麻烦。也有说法是在model.yaml增加设置 metadataOverrides: vision: false 来禁止加载mmproj,但实测无效。
在新版的LM Studio中,在模型加载页面的下面增加了 Ilama.cpp Arquments Override 的开关,只要开启这个选项,然后取消 --mmproj 的勾选即可。以后如果需要vision功能,再关闭这个开关或勾选 --mmproj即可,操作简便。
-
MTP (对应llama.cpp的 --spec-type draft-mtp)
这个不好一概而论。开启MTP是要占大量显存的,而且每次推断都要调用MoE进行计算,这都是要消耗系统资源的。而关闭MTP的话,则有可能争取多留MoE层在显存。两者经常是根据实际情况一起调整,以确保剩余的显存不被撑爆。
根据本机的实测结果,开启MTP并设Max draft tokens=1是值得的,尤其长上下文。但Max draft tokens设为2以上时,draft 越长,验证步要读的专家量越大,投机收益被吃掉,不一定划算。
具体哪种情况好,可自行测试。
-
CPU Thread Pool Size (对应llama.cpp的 --threads / -t)
要看具体的硬件情况。本机是8个大核+16个小核,通常设 8 即可。有一种说法是大小核混用时会被小核拖慢整体速度。试过一次 t=12,decode速度大概慢了5 - 8%。但未作更多测试。
-
Max Concurrent Predictions (对应llama.cpp的 --parallel)
单机个人使用的话,设为1,省显存,省一点是一点。
4. 小结
(1)运行结果
-
ctx=65536 prefill 汇总
模型:huihui-ornith-1.5-35b-a3b-abliterated(Q4_K_M),ngl=999999、KV q8_0 在 GPU、batch 16384/4096、th=8、增强电源模式。每格为单轮实测值(t/s)。
表 A:64K prefill 吞吐(t/s),按 MTP 档与 ncmoe 排列
序号 MTP ncmoe GPU 专家层 @3276 @13107 @26214 1 关 33 7 1026.7 1082.2 1101.3 2 关 35 5 1084.7 1066.5 1042.7 3 1 36 4 944.1 985.8 1022.8 4 1 38 2 867.4 931.8 943.6 5 1 39 1 881.2 931.4 929.9 注:"GPU 专家层"按运行时
--n-cpu-moe N反算,可用层数 40(blk.40 为 MTP 草稿层,MTP 关闭时不加载); MTP 开启时草稿层是否计入该口径需另行说明 ,否则同一 ncmoe 会差 1 层。读数:prefill 随 GPU 专家层数增加而 整体 变好,但只有最大档 @26214 严格单调;最小档 @3276 噪声较大(ncmoe 35 的 1084.7 反而高于 ncmoe 33 的 1026.7),不要按单点排序解读。5 行里 MTP=1 组的 prefill 整体偏低,原因是它们把更多专家层留在了 CPU,而非 MTP 本身拖慢 prefill。
-
ctx=65536 decode 汇总
同一批 5 轮的 decode 结果。“@26214 上下文” 指先把 26150 个 token 灌入 KV 后再解码,是跨参数组最稳的锚点档。
表 B:64K decode 吞吐(t/s)与 MTP 接受率
序号 MTP ncmoe GPU 专家层 @128 @512 @1024 @26214 上下文 接受率 1 关 33 7 36.3 37.4 38.2 31.9 — 2 关 35 5 36.6 36.0 36.6 31.6 — 3 1 36 4 38.9 38.1 36.7 36.4 0.65–0.83 4 1 38 2 42.3 39.7 38.5 36.1 0.72–0.88 5 1 39 1 39.4 38.8 37.1 32.9 0.65–0.79 读数:MTP=1 的长上下文 decode(36.1–36.4)明显高于 MTP 关闭(31.6–31.9);MTP=1 组内部短档差异(38.9 / 42.3 / 39.4)落在 ±10% 噪声内,不要按 ncmoe 排序解读。
-
MTP 效应:最接近的单变量配对
64K 档案里唯一“只差 1 层专家落位”的 MTP 配对是 ncmoe=35(MTP 关) 与 ncmoe=36(MTP=1)。两轮相隔约 2.4 小时,机器处于相近热态。
表 C:ncmoe 35 → 36(MTP 关 → MTP=1)的逐档变化
指标档位(上下文) MTP 关(ncmoe 35) MTP=1(ncmoe 36) Δ prefill@3276 1084.7 944.1 ↓ −13.0% prefill@13107 1066.5 985.8 ↓ −7.6% prefill@26214 1042.7 1022.8 ↓ −1.9% decode@128 36.6 38.9 ↑ +6.2% decode@512 36.0 38.1 ↑ +5.8% decode@1024 36.6 36.7 ↑ +0.4% decode@26214 31.6 36.4 ↑ +15.2% 读数:ncmoe 从 35 加到 36 意味着少放 1 层专家到 GPU,单这一项就会让 decode 略微变慢。因此 MTP=1 的真实收益不低于表 C 中的 Δ。反之,prefill 的下降与 ncmoe 单调关系一致,主要不是 MTP 造成的。(注意:prefill@3276 的 −13.0% 远大于 prefill@26214 的 −1.9%,单层专家落位解释不了这个幅度,最小档的批处理效率与噪声占主导,该行不宜当作"ncmoe 影响 prefill"的量化依据。)
(2) 需注意的事项
-
噪声、散热和稳定性
当前系统下,CPU和内存是瓶颈,因为有大量的内容在内存中,需要CPU疯狂运算,温度直冲95度高烧不退。而GPU温度和显存的使用率则很低,明显是在等CPU侧的结果。
由此的问题就是,如果采用增强模式,确实速度快一些,但噪声和散热都是问题,担心CPU扛不住。
因此,当前采取是限制CPU和GPU温度和功率的手动模式,损失了约15-20%的性能,宁可慢一些,能长时间运行就好。
-
显存的剩余空间
原则上显存至少要剩余500-600M空间,否则很容易爆掉。而且,最好是用nvidia-smi来查看,windows的性能管理器中显示的GPU数值不一定准,很多时候偏小。
-
电源模式的影响
不插原配的交流电源而改用 USB Type-C 供电时,哪怕电源 140W 也无法激活增强模式,某一次的实测数据表明 decode 约低 22.5%。
但此时系统负荷也没那么大,CPU温度也相对低些,未尝不是好事。
-
Limit Model Offload to Dedicated GPU Memory
新版LM Studio的设置->Hardware中,有个选项“Limit Model Offload to Dedicated GPU Memory”。如果显存不够,希望按自己的心意调整MoE在显存和内存的分配时,该选项建议要关闭,否则它可能会强行更改你在加载界面上设置的参数,以确保显存的安全。这个很隐蔽,如果你不注意看加载时的log文字,不注意计算内存和显存的变化,很可能被蒙过去。
(注:本人仅仅是个瞎折腾的业余爱好者,上面的一些观点、说法都不一定对,仅供参考。希望抛砖引玉,能让垃圾显卡发挥更大的作用。)