25GB 内存也能跑 744B MoE?Colibrì 的磁盘流式推理完全指南
本地跑大模型时,最常见的判断是:权重装不进显存或内存,就没有开始推理的资格。这个判断对稠密模型大多成立,但对 Mixture-of-Experts(MoE)模型并不完整。MoE 每个 token 只会路由到一小部分专家;难点不只是“模型有多大”,而是如何让当前需要的专家及时抵达计算位置。
Colibrì 是一个 Apache-2.0 许可的纯 C 运行时,针对 GLM-5.2 的 int4 容器实现了另一种取舍:把快速内存、系统内存与 NVMe 看作一条分层存储路径。项目 README 给出的目标很激进——在约 25GB RAM 的消费级机器上运行 744B 参数 MoE;这不意味着笔记本会获得交互式速度,而是以很慢的首 token / 解码速度换取“能够正确运行”的下限。
关键不在把全部专家塞进内存
Colibrì 将模型拆成两类数据。注意力、共享专家和 embedding 等稠密部分保持在 RAM;按路由选择的专家则可以留在磁盘,根据 token 的路由结果按需读取。项目文档给出的 GLM-5.2 int4 布局中,常驻稠密部分约 9.9GB,75 个 MoE 层加 MTP head 的 19,456 个路由专家约占 370GB 磁盘。
这种设计的核心边界很明确:存储层级应该影响速度,不应悄悄改变计算语义。 Colibrì 的默认策略是不因内存不足而自动降低精度或改写路由。于是,同一模型可以有三种体验:
| 放置方式 | 主要资源 | 适用目标 | 代价 |
| — | — | — | — |
| 专家主要流式读取 | RAM + NVMe | 验证能否本地运行、离线试验 | 磁盘 miss 会显著拖慢解码 |
| 热专家缓存 | RAM,按使用历史学习 | 重复使用的个人工作负载 | 冷启动与新任务仍可能慢 |
| GPU / 全量常驻 | VRAM + RAM | 稳定交互、服务化 | 需要更多硬件与能耗预算 |
这也解释了为什么“25GB 能跑”不能直接翻译为“25GB 能用”。官方基准页列出的 25GB 开发机冷态吞吐约为 0.05–0.1 tok/s;README 同时列出 128GB CPU-only 主机热态约 1.8 tok/s。两者的差异不是模型换了,而是专家数据是否能从缓存命中、内存与更快的设备中取得。
为磁盘 miss 设计的推理路径
如果每层等路由完成后再同步读盘,MoE 推理会被 I/O 串行化。Colibrì 使用了几项针对这个问题的实现策略:同一专家的三块矩阵相邻存放,尽量用一次 pread 读取;一个 token 批次内重复命中的专家只读取一次;异步 I/O 让缺失专家加载和已常驻专家的计算重叠;还可以利用下一层路由的预测进行预取。
它还维护 .coli_usage 使用记录,把工作负载经常路由到的专家放入 hot-store。这个机制很适合“反复在同一代码库或同一语言域做本地助手”的场景:第一次先付出冷启动成本,后续再让缓存逐步贴近自己的请求分布。但它不适合宣称固定性能;换一个领域、清空缓存、NVMe 性能不同,结果都会改变。
另一个容易被忽略的点是 KV 状态。项目说明其 MLA KV 表示使用每 token 576 floats,而不是 32,768 floats,并能保存到 .coli_kv。这能减少重启后重复 prefill 的成本,但它是会话状态优化,不会消除专家权重的磁盘访问成本。
从只读检查开始,而不是直接开聊天
运行时本身不依赖 Python;仓库的 setup.sh 会检查 gcc/OpenMP、编译并执行自检。模型转换是一次性步骤,之后再通过 COLI_MODEL 指向已准备的模型目录。首次部署时,建议先看规划和诊断信息,再启动交互:
cd c ./setup.sh export COLI_MODEL=/nvme/glm52_i4 ./coli doctor ./coli plan ./coli chat
doctor 是只读就绪检查,plan 用于查看计划中的 VRAM、RAM 与磁盘放置;它们比一上来等待 chat 更适合排查路径、内存预算和设备发现问题。文档还提供 ./coli serve --model /nvme/glm52_i4 的 OpenAI-compatible API-only 入口;如果需要浏览器面板,则是 ./coli web --model /nvme/glm52_i4。这两个命令的职责不同,不要把 web 面板误当成必需组件。
先做一轮可复现的容量与延迟实验
把 Colibrì 当作“能否运行”的演示,最容易得到乐观但无法复现的结论。更实用的做法是把第一次实验拆成容量、正确性和体验三层,并让每层都有独立记录。
容量层先确认磁盘而非只看内存。模型目录、转换过程的临时文件和操作系统都需要空间;NVMe 的持续读取能力也会直接影响冷态。将模型放在网络盘、机械硬盘或空间接近耗尽的分区,即使 doctor 通过,也会让读盘等待掩盖运行时设计本身的效果。plan 的价值正是在启动前显示 placement;它是配置审阅工具,而不是性能保证。
正确性层建议用固定提示词做两次短生成:一次刚启动时运行,一次在相同模型目录和相同参数下重复运行。这里不应期待两次用时相同,反而要观察热专家缓存是否改变了延迟。若在准备结构化 JSON、函数参数或受约束文本,项目提供了 grammar-forced draft 的文档;先验证输出格式和请求路径,再考虑是否开启推测解码,能避免把“格式约束导致的接受率变化”误判成模型质量问题。
体验层才是决定是否长期使用的部分。记录首 token 时间、连续生成的 token 速度、磁盘 I/O、内存占用和 cache 状态;同时把 CPU-only、GPU tier 与完整常驻的结果分开。对本地代码助手而言,冷态回答一次很慢未必没有价值:可以先用它做离线批处理、长上下文阅读或夜间任务;但若每次交互都在等待专家从磁盘装载,就应该降低模型规模或增加更快的内存层,而不是反复微调提示词。
两个会直接影响结果的细节
第一,模型容器与 MTP head 的量化配置不可随意混用。项目 README 特别提示应使用 int8 MTP heads;它将 int4 head 与低接受率问题关联。对这类“推测解码看起来不快”的故障,先检查模型资产和项目的 benchmark / issue 说明,比继续调环境变量更可靠。
第二,不要把缓存升温后的速度写成机器的固定指标。应至少记录 CPU、RAM、NVMe、是否启用 GPU tier、模型目录位置、冷/热状态和生成参数。Colibrì 的价值正在于把“模型无法全部常驻”变成可观测的 placement 问题;它并没有让存储带宽的物理限制消失。
监控指标要围绕瓶颈,而不是只盯 token/s
对于磁盘流式 MoE,单一的平均 token/s 很容易掩盖问题。至少应把首 token 时间、冷/热两种解码速度、磁盘读取量、缓存命中趋势和内存余量并列记录。若首 token 偶发很慢,要先分辨是模型初始化、KV prefill、专家 miss,还是底层存储的队列拥塞;它们对应的改进手段完全不同。也不要把一次短提示词的热缓存结果外推到长上下文、代码补全或多轮对话。用固定请求集逐步增加上下文长度,才能看清瓶颈从计算还是 I/O 开始转移。
适合谁,何时该换方案
如果你希望在一台已有 NVMe 的机器上研究大型 MoE 的真实路由、缓存和分层放置,或者需要一个依赖少、可读性强的 C 运行时,Colibrì 很值得试验。它的单文件核心与 plan、doctor 命令,尤其适合先理解资源规划再做性能实验。
但若目标是低延迟多用户服务、稳定高吞吐或短时间内完成大量代码生成,优先选择能让更多专家常驻的 GPU / RAM 配置,或采用更小的模型。把“可以运行”与“适合生产交互”分开,才是评估本地 MoE 工程方案最重要的尺度。
相关链接