llama.cpp 让没命中的 MoE 专家直接在 CPU 上算,还配了个调参脚本
llama.cpp 合并的 llama_moe_cache 把缓存未命中的专家交给 CPU 计算,绕开 PCIe 拷贝等待,同时带来一个标定脚本和一个 trace 开关。
显存不够、又想跑 MoE 模型的人,大多试过把一部分专家权重放到内存里。llama.cpp 原来的做法是:推理时某个专家不在显存里,就得先从主机内存经 PCIe 拷进显卡,等传输完成再算。单流 token 生成的时候,这段等待往往比计算本身还长。
Reddit 用户 jacek2023 发帖提到了 am17an 的 PR #30966,标题是 llama_moe_cache:把没命中的专家放到 CPU 上算,另外附了一个调参脚本。帖子里有人提到 Strata 早先也有类似的调优机制,思路接近。

改动本身不难理解:缓存命中的专家留在显存里正常走 GPU,没命中的那些不再卡在拷贝上,直接交给 CPU 计算。对 PCIe 带宽紧张、显存只够塞一部分专家的机器,收益集中在单流生成阶段。跟帖里 oyren-ai 的分析说得挺直白,这种场景下 PCIe 延迟的占比高过 CPU 的算力开销。
麻烦的是判断哪些专家该留在显存里。PR 附带了一个脚本,用有代表性的 prompt 跑一遍专家激活频率,算出接近最优的参数。am17an 在回复里说,脚本用法写在 PR 里,他正在做 auto 模式,把这块体验收拾干净。想看细节的话,环境变量 LLAMA_MOE_CACHE_TRACE=1 可以打开 trace,观察缓存命中和抖动情况。有人在跟帖里要的正是这些数据,说没有测量就没法优化。
EbbNorth7735 的疑问挺有代表性:读完 PR 不太确定该拿什么上下文去跑脚本,输出又该怎么解读。am17an 的回应是脚本能给出接近最优的参数,剩下的交给 auto 模式。
也有维护者视角的补充。Acceptable-Cycle4645 说自己维护过 audio.cpp,终于理解好 PR 为什么经常压着不动:通用框架要兼顾兼容性、回归和长期可维护性,垂直引擎可以只盯一两个模型或硬件跑得飞快。am17an 接着补了一句,ggml/llama.cpp 还得作为库供下游项目依赖,不能随便野。他说打算把这套思路借到 audio.cpp 去,那边目前只有三个 MoE 模型:Drama3、Ming3-Audio、Nemotron 3.5 Transcribe,规模比 LLM 小,但更大的音频 MoE 在路上。
有意思的是他开场那句:别急着又骂 llama.cpp,我知道还没到那一步,正在做。
发布时间: 2026-11-08 00:25