colibri 技术解读:29,000 行 C 代码之外,一块普通 NVMe 如何喂饱一个 744B 模型

744B 参数的模型,在 25 GB 内存、一块普通 NVMe 的机器上能跑吗?GitHub 上的 colibrì 项目给出了一个可复现的答案:能,只是慢。这个 2026 年 7 月创建的开源项目在两个月内涨到 29,233 star,Apache-2.0 协议,核心是一个零依赖的纯 C 文件。它做的事情用一句话概括:把 VRAM、内存和 NVMe 固态硬盘当作同一个内存层级的三个层,让一个 744B 的 MoE 模型在这套层级上流式运行——模型不需要「装进」内存,只需要被「放置」好。
MoE 的稀疏性:为什么这件事在数学上成立
colibrì 选择流式方案的前提,是 MoE(Mixture of Experts,混合专家)架构的稀疏激活特性。以 GLM-5.2 为例:总参数 744B,但每个 token 只激活约 40B 参数——75 层 MoE 层,每层从 256 个路由专家中选 8 个,加上注意力、共享专家和嵌入层组成的约 17B 稠密部分。
项目 README 里有一组关键数字(来自 docs/media/sparse.png 的官方图表):每个 token 激活约 40B 参数,占全部参数的 5.4%;而这 40B 里,从一个 token 到下一个 token 真正发生变化的只有约 11 GB(int4 精度下的路由专家权重)。稠密部分在每次前向传播中都要用,路由专家只有被路由器选中时才用。
这意味着两件事可以分开对待:约 17B 的稠密部分(注意力、共享专家、嵌入)必须常驻,int4 精度下约 9.9 GB,放进普通内存没有压力;而 19,456 个路由专家(75 层 × 256 个,加上 MTP 头,每个约 19 MB)总计约 370 GB,全部留在磁盘上,按需流式读取。一个冷 token 的读取成本约为 11 GB 磁盘读——75 层 × 每层 8 个专家 × 每个约 19 MB。
数学上成立,工程上的问题随之而来:NVMe 的顺序读带宽 3-7 GB/s,但这里需要的是随机读。0.05-0.1 tok/s 的冷解码速度就是这么来的——每秒生成不到十分之一个 token。colibrì 的全部工程努力,都在把这个数字往上推。
引擎结构:一个 C 文件,五步 token 路径
colibrì 的引擎是单个 C 文件(GLM-5.2 对应 c/colibri.c),没有 BLAS、没有运行时 Python、不需要 GPU。运行时的 Python 只出现在两个地方:一次性的模型转换器,和可选的 OpenAI 兼容 API 网关。九个模型家族各自对应一个同构的 C 文件——GLM-5.2/5.3、GLM-5.3-Flash、Inkling(975B)、Kimi K3(2.8T)、DeepSeek V4 Flash(284B)、DeepSeek V4.1 Flash(552B)、Qwen3.8-Flash-Next、Qwen3.6-35B-A3B、OLMoE(7B)——共用同一套 coli chat / coli serve / coli web 前端,启动器读取模型目录里的 config.json 自动选择对应的引擎二进制。

每个 token 的每一层都走同样的五步(README 称之为 route → union → place → overlap → learn):路由器选出专家;同一批次里重复选中的专家合并为一次读取(batch-union,一个专家只读一次);放置层决定专家从 VRAM、RAM 还是磁盘来;异步 I/O 池在常驻专家计算的同时读取缺失的专家(PIPE=1,默认开启);最后记录路由结果,供缓存学习。
这里有三个值得展开的机制。
学习缓存。 引擎把每次路由的结果写进 .coli_usage 文件(每轮更新),统计哪些专家在你的工作负载里最热,然后自动把最热的专家固定(pin)在空闲内存里。官方的说法是 colibrì「越用越快」——缓存学习的是你的工作负载的路由分布。基准数据支持这个说法:一台 Ryzen AI Max+ 395 从纯 LRU 缓存起步测得 0.16 tok/s,五轮运行后学习到的 pin 集达到 47.6 GB,速度升到 0.40 tok/s,专家命中率从 57% 升到 71%。
单层预测 prefetch。 PILOT=1 开启一个路由前瞻线程,提前读取下一层的专家。依据是一个实测结论:路由在单层跨度上的可预测性是 71.6%。也就是说,看着当前层的路由结果,下一层会选中哪些专家,七成的情况能猜对。
双盘镜像。 专家权重是只读的,所以如果有第二块 SSD,可以把模型完整复制一份,让引擎同时从两块盘流式读取。每个专家由确定性哈希按带宽权重分配到某一块盘,聚合带宽是两块盘之和。一个干净的对照实验(issue #1249):Threadripper PRO 7965WX 上两块独立控制器上的 NVMe,单盘 0.80 tok/s,双盘 1.10 tok/s,提升 37.5%。同文中一个有趣的负面结果:用符号链接把 shard 文件拆到两个挂载点,只带来 5.5% 提升——文件级拆分并行化的是本来就在并发执行的读取,而块级条带化和引擎的镜像机制并行化的是每次 19 MB 读取的内部。5% 和 37% 的差价,就是「拆文件」和「条带化」的机制差距。
精度与语义:速度可以牺牲,语义不能
colibrì 的 README 里有一条设计原则值得单独一节:对速度不作 SLA 承诺,对语义作硬性保证。内存不够,速度可以降;但默认策略绝不静默改变模型精度或路由语义——从 VRAM 里拿出来的专家和从磁盘上流过来的专家,参与计算的字节是同一份。
前向验证的口径是:与 transformers 实现做 teacher-forcing 对比,通常 30-32/32 层 token 精确一致(另有两个位置是浮点近似平局,依赖工具链版本)。MLA 注意力的 KV 状态压缩到每 token 576 个浮点数,对比密集表示的 32,768 个,缩小 57 倍,且持久化到 .coli_kv——重启后对话直接恢复,不需要重新 prefill。
量化容器的选择被写成了警告:必须用 group-scaled(gs64)int4 容器加 int8 MTP 头。旧的 per-row int4 镜像在质量测试中差约 9 个百分点,并且是 issue #455 里「思考模式循环、永不终止生成」的根因;MTP 头用 int4 则会让草稿接受率跌到 0-4%(issue #8)。
投机解码的章节标题用了「honestly」这个词。GLM-5.2 的原生 MTP 头起草 token,主模型一次批量前向验证,换来 2.2-2.8 tokens/forward——但项目同时写明了它不起作用的条件:issue #163 记录了草稿和验证必须计算同一个函数(SPEC_PIN=1 现在是默认值)的完整排查过程;而在专家命中率约 85% 的场景下,MTP 实测损失 32%。默认策略是:缓存冷的时候 MTP 值得开,缓存热到接近全常驻时 DRAFT=0 反而更快。
实测数据:从 0.05 到 6.8 tok/s 的完整阶梯
项目把社区提交的实测数据整理成了公开表格(docs/benchmarks.md),同一引擎、同一 int4 容器,硬件只改变专家住在哪一层。选取几行有代表性的:
| 硬件 | 关键配置 | 实测解码速度 |
|---|---|---|
| WSL2 开发机(12 核,25 GB RAM,NVMe) | 默认,冷缓存 | 0.05–0.1 tok/s |
| Mac Mini M4 Pro(48 GB 统一内存) | Metal 后端,--ram 38 | 0.30 tok/s |
| Apple M5 Max(128 GB) | Metal + 39.7 GB pin | 1.83 tok/s(命中 66%) |
| Apple M1 Ultra(128 GB) | Metal,46.9 GB 冻结 pin | 1.50 tok/s(命中 78.7%) |
| EPYC 7443(430 GB RAM) | 77.5 GB pin | 1.00 tok/s(命中 98%,磁盘退出解码路径) |
| AMD EPYC 9V45(Azure,504 GB,4×NVMe) | int4 gs64,CPU only | 2.83 tok/s(命中 97%),warm 后 6.91 |
| 6× RTX 5090(251 GB 主机) | 全专家常驻 VRAM+RAM | 5.8–6.8 tok/s,TTFT 约 13 s |
| Apple M3(16 GB) | OLMoE int8 | 3.69→4.18 tok/s |

这张表里藏着几个结论,项目自己在 takeaways 里写得很坦率。
小内存机器的瓶颈是内存上限,不是磁盘。 24 GB 内存让引擎把专家缓存自动压到每层 2 槽,解码始终是冷的——盘再快也没用。
磁盘换机的回报可以算出来。 9950X 那组对照是最干净的瓶颈实验:同一台机器、同一份路由历史,只换硬盘,PCIe Gen3 QLC 换成 PCIe 5.0 的 9100 PRO,带宽 1.51 GB/s 升到 8.81 GB/s(5.8 倍),token 速度从 0.10 升到 0.28(2.9 倍),而瓶颈占比从 66% 磁盘 / 翻转为 57% 矩阵乘。带宽翻 5.8 倍只买到 2.9 倍 token,因为瓶颈已经移到了 CPU 内核。
GPU 只在 CPU 是短板时才值得上。 9800X3D(AVX-512)的对照里,CPU 专家矩阵乘和 RTX 5090 打平,CUDA 专家层的边际收益约 0%。而 Zen 3(只有 AVX2)的机器上,任何 I/O 优化都不动速度——内核先于磁盘成为瓶颈。Apple Silicon 上同理:M1 Ultra 和 M5 Max 的 GPU 核心数接近(48 对 40),解码速度却差 33%,因为 M1 Ultra 的解码时间里 57% 在等 SSD——专家从磁盘流过来时,定速度的是盘,不是 GPU。
16 GB 是大模型的硬地板。 一台 16 GB 内存、无 DRAM 缓存的 QLC 盘 Windows 本能通过自测,但没有任何可报告的解码数字——冷 token 需要 11 GB 读取而内存里几乎留不下任何常驻。这个尺寸的机器该跑 OLMoE(7B,M3 的 16 GB 实测 3.69-4.18 tok/s)或 Qwen3.6。
集群模式与开放问题清单
单机之外,colibrì 提供了一个可选的本地集群模式:协调者保持 token 生成、路由和 KV 状态在本机,磁盘上的专家工作者在其他 Mac 上执行被路由到的前馈计算。一层的批量专家合并为一次持久 TCP 请求,避免一个 token 每个专家一次往返。传输层不配置工作者就不启用,单机路径不受影响。
README 用一张表列出了六个「开放假设」:路由历史能否胜过普通 LRU、多 SSD 带宽能否转化为解码速度、硬件感知规划器能否逼近人工调参、有损表征能否在质量门内减少权重搬运、路由感知投机在什么命中率下回本、CPU/GPU 重叠能否真的隐藏传输。每一条都附了「目前已有的证据」和「还缺什么实验」,并明确邀请社区认领——包括发表阴性结果。这种把未验证的优化一律当作假设处理的姿态,和它把负面数据点(5.5% 的文件拆分、32% 的 MTP 损失、16 GB 地板)原样写进文档的做法,是同一个东西的两面。
对谁有用
这套东西的实际价值取决于你手上有什么。一块 2 TB NVMe 放 GLM-5.2 的 int4 容器(372 GB,HuggingFace 有现成转换),16-32 GB 内存的机器就能以每秒零点几 tok 的速度正确运行它;内存到 128 GB、再加一块好盘,进入 1-3 tok/s 的可用区间;全常驻 6×5090 的方案是另一个价位的游戏。推理速度不追求实时对话的场景——批量文本生成、离线数据处理、过夜任务——低配机器的实用阈值比直觉低得多。
对推理系统的学习者,这个仓库的价值在文档本身:每个性能数字挂着 issue 编号,每个优化声明挂着实验条件,阴性结果和混淆变量的修正(比如那张 Vulkan vs ROCm 的表格,第一版有混杂变量,报告者自己更正)全部留档。想验证任何一行数字,tools/datapoint.py 一条命令在自己的机器上复现。
仓库地址:https://github.com/JustVugg/colibri
(说明:本文所有数据来自项目 README、docs/benchmarks.md 及其引用的 issue 记录,实测数字均为项目社区在各硬件上的公开报告,非本文作者复测。)