← 返回主题列表
✨步子哥
@steper · 2026年07月26日 07:30 · 0浏览

744亿参数塞进25GB内存:colibrì如何用1300行C代码把不可能变成可能

744亿参数塞进25GB内存:colibrì如何用1300行C代码把不可能变成可能

一道数学题:不可能的等式

先做一道数学题。

GLM-5.2 有 7440 亿参数。用 int4 量化(每个参数 4 比特),每个参数占 0.5 字节。7440 亿 × 0.5 = 372 GB。

你的笔记本有 25 GB 内存。

372 GB > 25 GB。差了 15 倍。

这是 2026 年 7 月 10 日之前所有 LLM 推理引擎面对这道题的答案:不可能。你要么买 H100 GPU 集群(一块 H100 的风扇价格都比你的笔记本贵),要么调用云端 API(每月账单比车贷还高)。

然后一个叫 JustVugg 的开发者发布了 colibrì——1300 行 C 代码,零依赖,在 25 GB 内存、无 GPU 的笔记本上跑起了 GLM-5.2。Hacker News 三小时 453 分。

这不是魔法。这是找到了一个漏洞

漏洞在哪里:MoE 架构的稀疏性

GLM-5.2 不是密集模型。它是 Mixture-of-Experts(MoE)架构——模型内部有 256 个"专家"子网络,每层 8+1 个被激活。对每个 token,只有约 400 亿参数参与计算,其余 7040 亿参数在睡觉

400 亿 × 0.5 字节 = 20 GB。20 GB < 25 GB。数学上可行了。

这就是 colibrì 钻的漏洞:你不需要把整个模型装进内存,你只需要装下每个 token 真正用到的那 5.4%

但这里有个工程难题:你不知道下一个 token 会激活哪些专家。路由器(router)在每个 token 的前向传播中动态决定调用哪 8 个专家。这意味着你需要的专家可能在内存里,也可能在 SSD 上——如果在 SSD 上,你得在几毫秒内把它读进内存。

这就是 colibrì 的核心工程挑战:如何让"从磁盘读专家"这个操作快到不拖垮推理

三层存储层级:colibrì 的内存架构

colibrì 把存储看作一个三层金字塔:

┌─────────────────────────────────────────┐
│  VRAM (GPU)        可选,最快           │
├─────────────────────────────────────────┤
│  RAM               9.9 GB 常驻          │
│  ─────────────────────────────          │
│  • 密集层(attention, shared experts)  │
│  • embeddings                          │
│  • 热门专家 LRU 缓存                    │
├─────────────────────────────────────────┤
│  NVMe SSD          370 GB              │
│  ─────────────────────────────          │
│  • 21,504 个路由专家                    │
│  • 每个专家 ~19 MB (int4)               │
│  • 按需流式加载                          │
└─────────────────────────────────────────┘

常驻 RAM 的 9.9 GB 包含:

  • 注意力层(MLA,Multi-head Latent Attention)
  • 共享专家(shared experts,每层都激活的那个"+1")
  • 词嵌入矩阵
  • 热门专家的 LRU 缓存
流式从 NVMe 加载的 21,504 个专家
  • 每个专家 19 MB(int4 量化后)
  • 总计约 370 GB 存在 SSD 上
  • 路由器请求时才加载
  • 用完不立即驱逐,进入 per-layer LRU 缓存
关键洞察:只有约 11 GB 的参数在 token 之间变化——那就是被路由的专家。其余 34 GB 是密集层,永远在内存里,不需要从磁盘读。

为什么 llama.cpp 的 mmap 跟不上

llama.cpp 是目前最流行的本地 LLM 推理引擎。它用 mmap(内存映射文件) 加载模型权重——操作系统按需从磁盘读取页面,RAM 满了就用 LRU 驱逐旧页面。

对密集模型,这套机制完美工作。访问模式是顺序的——每一层的权重按顺序读,OS 的预读(readahead)和页面缓存配合得天衣无缝。

但对 MoE 模型,访问模式变成了随机的。路由器在每个 token 选择 8 个专家,这 8 个专家可能分布在 370 GB 磁盘空间的任意位置。mmap 的三个致命问题暴露了:

1. OS 页面缓存不知道"专家"的边界。 一个专家 19 MB,OS 页面 4 KB,一个专家跨 4750 个页面。OS 的 LRU 以页面为单位驱逐,可能把一个专家的一半驱逐了,另一半还在——下次用这个专家时得重新读那一半。

2. OS LRU 不区分专家热度。 路由器有偏好——某些专家被频繁调用(71.6% 的路由是可预测的,根据 colibrì 的实验),某些专家几乎从不被调用。但 OS LRU 只看页面访问时间,不知道哪些页面属于同一个专家,无法做专家级的缓存决策。

3. OS 不做异步预读。 mmap 的预读是顺序的,但 MoE 的访问是随机的。OS 不知道下一个 token 会用哪些专家,只能等路由器决定了才开始读——每个 token 都要等磁盘 I/O。

colibrì 的解法是绕过 OS 的页面缓存策略,自己做专家级的缓存管理

  • per-layer LRU 缓存:每一层维护自己的专家 LRU 缓存,驱逐以整个专家为单位(19 MB 一整块),不会出现"半个专家"的情况
  • OS 页面缓存作为免费 L2:虽然 colibrì 自己管 L1,但 OS 页面缓存仍然在底层工作,作为第二层缓存
  • 异步专家预读(async readahead):在当前 token 计算时,异步发起下一个可能需要的专家的磁盘 I/O
  • 路由器前瞻预取(router-lookahead prefetch):实验性功能,用路由器的可预测性(71.6%)提前加载下一层可能需要的专家
  • 热门专家钉住(pinned hot-store):频繁使用的专家永久驻留 RAM,不参与 LRU 驱逐
这套层次化缓存让 colibrì 在 25 GB RAM 的机器上,把 370 GB 的模型"分页"管理得比 OS 自己更聪明——因为它知道 OS 不知道的事:哪些页面属于同一个专家,哪些专家会被频繁调用

MLA 注意力:把 KV 缓存压缩 57 倍

MoE 流式传输解决了"参数在磁盘上"的问题。但还有另一个内存瓶颈:KV 缓存

每个 token 生成时,模型要记住之前所有 token 的 Key 和 Value 向量。标准 Transformer 的 KV 缓存大小 = 层数 × 头数 × 头维度 × 2 × 序列长度。对 GLM-5.2 这种 744B 级别的模型,一个长对话的 KV 缓存可以轻松吃掉几个 GB。

GLM-5.2 用的是 MLA(Multi-head Latent Attention)——DeepSeek-V3 引入的注意力变体。MLA 把 KV 压缩成一个低维"潜变量"再存储,解码时再展开。

效果:每个 token 的 KV 缓存从 32,768 个浮点数压缩到 576 个——57 倍压缩

colibrì 忠实实现了 MLA,并且把 KV 缓存持久化到磁盘(.coli_kv 文件)。这意味着:关掉 colibrì,重启,对话可以接着上次的地方继续,零重新 prefill,字节级一致

这个细节很关键。一个 744B 模型在 25 GB 机器上跑,prefill(处理提示词)是最慢的部分——每个 prompt token 都要从磁盘读专家。如果每次重启都要重新 prefill,用户体验会极差。KV 持久化让"打开-对话-关闭-再打开"成为可能。

MTP 投机解码:2.2-2.8 个 token 一次前向

colibrì 还实现了 GLM-5.2 原生的 MTP(Multi-Token Prediction)头——一个小的"草稿"模型,和主模型共享嵌入层,可以一次预测多个 token,然后由主模型批量验证。

这是投机解码(speculative decoding)的一种。主模型一次前向传播可以验证草稿模型提出的多个 token,如果草稿对了,就一次接受多个 token;如果错了,就回退到第一个错误的位置。

colibrì 的 MTP 实现达到 2.2-2.8 tokens/forward——每次前向传播平均产出 2.2-2.8 个 token。这对一个 0.3 tok/s 的系统是巨大的提速——相当于把有效速度提到了 0.7-0.8 tok/s。

但这里有个血泪教训,colibrì 的 README 里特意标注了:

> MTP head must be int8 (int4 heads collapse to 0-4% acceptance, #8)

MTP 头必须用 int8 量化。如果用 int4,草稿接受率会从 2.2 崩到 0-4%——投机解码完全失效。原因在 issue #8 里有详细分析:int4 量化的误差在小模型(MTP 头只有几亿参数)上太大,草稿 token 几乎总是错的,主模型全部拒绝。

另一个规则:草稿和验证必须计算同一个函数。colibrì 用 SPEC_PIN=1 把两者钉在同一个 kernel family 上。issue #163 是完整的"法医报告"——如果草稿用一种量化方式,验证用另一种,两者的数值行为不一致,接受率会莫名下降。

这两条规则是用惨痛的调试时间换来的默认值。colibrì 的作者在 README 里特意写了,因为如果不写,每个新用户都会踩这两个坑。

诚实的基准测试:慢,但正确

colibrì 的 README 里有一句话:

> This is not fast. It is a 744B frontier-class model answering correctly on a machine that costs less than one H100 fan.

基准测试数据:

硬件速度备注
6× RTX 5090(全常驻)5.8-6.8 tok/sTTFT ~13s
128 GB CPU 桌面~1.8 tok/s暖缓存
M5 Max (128 GB, Metal)1.06-1.83 tok/s
Ryzen AI 9 HX 370 (128 GB)0.37 tok/s
25 GB 开发机0.05-0.1 tok/s冷启动,诚实的基线
对比:云端 H100 推理 30-50 tok/s。colibrì 慢 10-100 倍。

但 colibrì 正确。前向传播经过 token-exact 验证,和 transformers 参考实现 32/32 匹配。int4 量化的质量损失在 docs/benchmarks.md 里有详细测量。这不是"近似推理"——是精确推理,只是慢

为什么这很重要:三个层面的颠覆

技术层面:colibrì 证明了 MoE 模型的专家流式传输是可行的。这不是"把模型塞进小内存"的技巧——这是重新定义了"加载模型"的含义。传统推理引擎把"加载模型"理解为"把所有权重读进内存"。colibrì 把它理解为"建立一套按需读取的管道"。前者要求内存 ≥ 模型大小,后者只要求内存 ≥ 每次激活的参数量。

产业层面:前沿开源模型不再被数据中心锁死。GLM-5.2 是 MIT 许可、Zhipu AI 开放的权重。任何人都可以下载 370 GB 的模型,用 colibrì 在自己的笔记本上跑。你的代码不离开你的机器,你的对话不被记录,你的 API 账单归零。这对隐私敏感场景(医疗、法律、国防)意义重大。

哲学层面:colibrì 的 README 有一段话值得反复读:

> Frontier models should not be sealed inside datacenters. colibrì exists so that anyone curious enough can open one up: run a 744-billion-parameter mind on hardware you already own, watch every expert fire in real time, and change the code that does it. Not renting intelligence behind an API — holding it: probing it, measuring it, improving it.

"不是在 API 后面租用智能,而是握住它"——这句话点出了开源权重模型的真正意义。租用和拥有的区别不只是成本,而是你能打开它、能测量它、能改进它。colibrì 的 web 仪表盘把所有 19,456 个专家显示成一个"活 cortex"——颜色是存储层级,亮度是路由热度,每个被激活的专家会闪白光。你能看见模型在思考。

colibrì 揭示的三个工程原则

1. 知道 OS 不知道的事。 OS 的页面缓存是通用目的的,它不知道"专家"这个概念。colibrì 用应用层知识(哪些页面属于同一个专家、哪些专家会被频繁调用)做出了比 OS 更聪明的缓存决策。通用抽象的代价是丢失领域知识——当你有领域知识时,绕过通用抽象往往能获得数量级的提升。

2. 诚实测量,不假设质量。 colibrì 的 README 里每个性能数字都标注了来源(issue 编号、实验日志)。int4 量化的质量损失被测量而不是假设。MTP 投机解码的接受率被实测而不是假设。"质量被测量,不被假设"——这是工程诚实度的标准。

3. 默认值是血泪教训。 colibrì 的两条默认规则(MTP 头必须 int8、草稿和验证必须同 kernel)都是踩坑后写下的。好的默认值不是"最通用的配置",而是"新用户最不容易踩坑的配置"

一个更深的观察:MoE 改变了"加载模型"的定义

colibrì 揭示了一个被忽视的事实:MoE 不只是"参数效率"技术,它是"内存效率"技术

传统密集模型的参数利用率是 100%——每个参数在每个 token 都参与计算。所以加载模型必须加载全部参数。

MoE 模型的参数利用率是 5.4%——每个 token 只有 5.4% 的参数参与计算。这意味着 94.6% 的参数在任何给定时刻都是"冷数据"

冷数据不需要在 RAM 里。冷数据可以在 SSD 上、在磁带上、在云端存储上——只要在需要时能快速读取。

这彻底改变了"部署大模型"的经济学。以前,部署一个 744B 模型需要 1.5 TB 显存(int8)或 750 GB 显存(int4)——只有数据中心能负担。现在,只要 25 GB RAM + 370 GB NVMe——任何一台现代笔记本都能负担。

MoE 让"参数总量"和"内存需求"脱钩了。 参数总量决定模型的智力上限,内存需求决定部署成本。colibrì 证明了这两个量可以差 15 倍——只要你有足够快的磁盘和足够聪明的缓存。

colibrì 的未来:从"能跑"到"好用"

colibrì 现在是 v1.1.0,还是一个证明概念。25 GB 机器上 0.05-0.1 tok/s 是"能跑",不是"好用"。但路线图清晰:

  • 更好的预取:路由器前瞻现在 71.6% 可预测,如果能到 90%+,暖缓存命中率会大幅提升
  • GPU 加速 matmul:目前纯 CPU,如果加上 GPU 做矩阵乘法,密集层计算可以加速 10-50 倍
  • 多线程专家加载:当前是串行读取,如果并行加载多个专家,I/O 等待可以重叠
  • 专家压缩:int4 已经是 4 比特,如果加上结构化剪枝(去掉从不被激活的专家),磁盘占用可以再降
每一步都把"能跑"推向"好用"。但即使停在现在,colibrì 已经证明了一个重要的命题:前沿模型不需要前沿硬件——只需要前沿工程。

---

项目JustVugg/colibri(Apache 2.0) 模型:GLM-5.2(Zhipu AI,MIT 许可) 引擎:纯 C,零依赖,~1300 行核心代码 视频Devsplainers 原视频

暂无表态
💬 讨论回复 (0)
推荐

🌟 智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

🎁 领取 2000万 Tokens