llama.cpp NGL 与 CPU Offload 问题复盘
背景
本次排查的核心问题是:页面与计算逻辑里,把两类不同机制混在了一起,导致配置切换和结果展示不稳定,尤其表现为“重新选择层后旧值丢失”与“模式含义不清晰”。
涉及的两个机制:
--n-gpu-layers(NGL)
- 含义:按层把一部分权重放入 GPU,剩余层在 CPU 内存。
- 特性:是 llama.cpp 的通用分层混合机制,不只针对 MoE。
--cpu-moe / --n-cpu-moe
- 含义:仅针对 MoE 的 expert 权重放 CPU。
- 特性:是 MoE 专用策略,和 NGL 不是同一层面的开关。
问题原因
之前逻辑的主要问题有三点:
- 机制耦合错误
- 将
cpuOffload 与 llama.cpp 的 NGL 混为同一个触发条件。
- 后果:NGL 是否生效受
cpuOffload 误控制,语义不一致。
- 默认值模型不合理
- NGL 默认按“总层数 50%”估算。
- 后果:与真实部署不一致,无法反映“按 VRAM 自动分层”的实际行为。
- UI 状态来源不统一
- NGL 滑块在自动模式下没有绑定真实 auto 计算结果,仅显示静态回退值。
- 后果:用户切换模型/框架/层数后,视觉上像“旧配置丢失”。
技术判断依据
基于 llama.cpp 文档与参数语义:
- NGL 是通用能力
-ngl, --n-gpu-layers N 用于设置放入 VRAM 的层数(可 auto/all/显式数值)。
- MoE CPU Offload 是独立能力
-cmoe, --cpu-moe 与 -ncmoe, --n-cpu-moe 仅用于 MoE expert。
- 两者可并存但不等价
- NGL 决定“层分布”;MoE offload 决定“expert 放置策略”。
结论
- 结论一:NGL 与 MoE CPU Offload 必须拆分建模,不能共用同一触发布尔条件。
- 结论二:NGL 默认值应由 VRAM 容量推导(auto),而不是固定 50%。
- 结论三:UI 显示应优先反映“计算得到的 autoNgl”,保证配置切换时状态可解释、可追踪。
- 结论四:若用户手动指定 NGL,手动值优先;切出 llama.cpp 再切回时,应重新进入 auto 推导逻辑(除非保留手动策略)。
建议落地策略(后续可按需恢复)
- 计算层
- 新增
effectiveNgl(calc 结果)输出给 UI。
nglCount == null 时走 auto 推导;有值时走手动覆盖。
- 交互层
- NGL 控件显示条件只依赖
framework === llamacpp(且非 pureCpu)。
- 不再依赖
cpuOffload 作为 NGL 开关。
- 状态层
- URL 状态保存
nglCount(手动值);auto 模式只保存 null。
- 渲染时由
autoNgl + nglCount 合成展示值,避免“看起来丢了”。
一句话总结
这次问题本质不是“算不准”,而是“把两种不同 offload 语义混成一个开关”,导致默认行为与展示状态都偏离真实 llama.cpp 部署机制。
llama.cpp NGL 与 CPU Offload 问题复盘
背景
本次排查的核心问题是:页面与计算逻辑里,把两类不同机制混在了一起,导致配置切换和结果展示不稳定,尤其表现为“重新选择层后旧值丢失”与“模式含义不清晰”。
涉及的两个机制:
--n-gpu-layers(NGL)--cpu-moe/--n-cpu-moe问题原因
之前逻辑的主要问题有三点:
cpuOffload与 llama.cpp 的 NGL 混为同一个触发条件。cpuOffload误控制,语义不一致。技术判断依据
基于 llama.cpp 文档与参数语义:
-ngl, --n-gpu-layers N用于设置放入 VRAM 的层数(可 auto/all/显式数值)。-cmoe, --cpu-moe与-ncmoe, --n-cpu-moe仅用于 MoE expert。结论
建议落地策略(后续可按需恢复)
effectiveNgl(calc 结果)输出给 UI。nglCount == null时走 auto 推导;有值时走手动覆盖。framework === llamacpp(且非 pureCpu)。cpuOffload作为 NGL 开关。nglCount(手动值);auto 模式只保存 null。autoNgl+nglCount合成展示值,避免“看起来丢了”。一句话总结
这次问题本质不是“算不准”,而是“把两种不同 offload 语义混成一个开关”,导致默认行为与展示状态都偏离真实 llama.cpp 部署机制。