第 4 章 · 01 三级层级与放置哲学 本节摘要:Colibrì 把 VRAM、RAM、NVMe 当成同一道"放置问题"的三层候选,而不是"能不能装下"的二选一。稠密部分(attention/shared/embedding 约 17B)常驻 RAM,以 int4 量化后约 9.9GB;19456 个路由专家放磁盘按需流式,约占 370GB;可选的 VRAM 层在全驻留时让磁盘彻底退出解码路径。核心哲学只有一句:有限高速内存只改速度,不改语义。 内容来源:原项目源码 、 (L186-209) ⚠️ 注意:本章是 Colibrì 系统设计的灵魂章节。三级层级不是硬件清单,而是一种"放置哲学"——同样一个专家权重,放哪一层最快?答案取决于路由热度和物理带宽,而不是"是否放得下"。
本节摘要:Colibrì 把 VRAM、RAM、NVMe 当成同一道"放置问题"的三层候选,而不是"能不能装下"的二选一。稠密部分(attention/shared/embedding 约 17B)常驻 RAM,以 int4 量化后约 9.9GB;19456 个路由专家放磁盘按需流式,约占 370GB;可选的 VRAM 层在全驻留时让磁盘彻底退出解码路径。核心哲学只有一句:有限高速内存只改速度,不改语义。
内容来源:原项目源码
c/tier.h、README.md(L186-209)
⚠️ 注意:本章是 Colibrì 系统设计的灵魂章节。三级层级不是硬件清单,而是一种"放置哲学"——同样一个专家权重,放哪一层最快?答案取决于路由热度和物理带宽,而不是"是否放得下"。这一哲学直接决定了 tier.h 的四个函数为什么写成那样。
很多引擎把"放显存还是放内存"当成容量问题——能装下就装,装不下就报错。Colibrì 的视角完全不同:VRAM、RAM、NVMe 是同一段权重在"放哪一层最快"上的三个候选,本质是一道放置问题。
这套哲学的根源在于 GLM-5.2 的 MoE 结构:稠密部分(attention、shared 专家、embedding)只有约 17B 参数,但每次 token 都要全量走一遍;而 19456 个路由专家虽然总数庞大,却每次只激活其中极少数。两类权重的访问模式天差地别,自然应该放在不同层。
稠密 17B 以 int4 量化后约 9.9GB,完全可以常驻 RAM;19456 个路由专家按 int4 算约 370GB,根本塞不进内存,但每次推理只需其中几个——所以放磁盘、按需流式读取,这是唯一合理的选择。
稠密部分 17B → 常驻 RAM int4 ~9.9GB 每 token 全量访问 路由专家 19456 → 落 NVMe int4 ~370GB 每 token 按需流式
关键在于:这两个放置决策是正交的。换一台机器,稠密部分可能挪到 VRAM,专家可能部分常驻——但前向语义一个字节都不变。引擎永远正确,只是快慢不同。
这里有一个常被忽视的细节:稠密部分为什么不直接放 VRAM?因为 VRAM 容量小且金贵(典型 16-24GB),要留给 KV cache、激活值、以及最热的少数专家。把 9.9GB 稠密权重铺到 VRAM,会挤占 KV cache 空间,反而拖累长上下文。放 RAM 是性价比最高的折中——DRAM 带宽(双通道 DDR5 约 80GB/s)远高于 NVMe(单盘 3-9GB/s),对每 token 都要全量访问的稠密部分足够快,又不挤占 VRAM。
Colibrì 同一份代码可以横跨两个极端。在一台只有 25GB 空间的笔记本上,专家全部走磁盘流式读取——慢,但完全正确,输出和数据中心一模一样。这正是"放置哲学"的体现:磁盘不是"装不下才用"的退路,而是默认的一层。
在另一端,一台大内存主机可以让整个专家集合常驻:设置 CUDA_EXPERT_GB=auto、PIN_GB=all,所有热点专家连同稠密部分全部进入 RAM 或 VRAM,磁盘彻底退出解码路径,decode 阶段不再有一次磁盘读。
25GB 笔记本 → 全磁盘流式 慢但正确 大主机 PIN_GB=all → 专家全驻留 磁盘退出 decode 路径 中间档 → 部分驻留 + 部分流式 tier.h 决定谁进谁出
中间档才是大多数真实场景:RAM 只够装一部分热点专家,剩下的留在 NVMe。这时候 tier.h 的替换策略(tier_pick_swap、tier_pick_lfru)就开始决定哪些专家进热存、哪些被换出——这是下一节深潜的内容。
注意三个档位之间是连续过渡而不是离散切换。引擎不需要重启,工作负载变化时热存内容会动态调整:某个专家持续被路由,heat 累积超过 25% 滞后门槛,就被换进热存;某个专家长期冷,heat 被衰减到低于候选,就被换出。整个调度完全由路由热度驱动,不需要用户介入。
💡 深潜要点:三级层级不是静态配置,而是动态调度。引擎自己测量两块 SSD 的带宽、自己跟踪路由热度、自己决定谁驻留谁换出。用户只给一个模型路径,剩下的全交给引擎。
这是本章最重要的一句话。整个 Colibrì 设计——tier.h 的替换策略、双 SSD 带宽翻倍、io_uring 异步 IO、读写算重叠——都是围绕这条哲学展开的。
含义有两层。第一,语义永远不变:不论你用 25GB 笔记本全磁盘流式,还是大主机全驻留,前向算出来的 token 序列一个字节都不差。第二,速度可调:有 VRAM 就用 VRAM,有两块 SSD 就带宽叠加,什么都没有就老老实实走单盘流式。
这条哲学直接解释了为什么 Colibrì 拒绝"假装存储延迟免费"。很多引擎默认权重都在显存里,把 I/O 当成一次性加载成本;Colibrì 反过来承认 I/O 是解码循环的一部分,所以才会专门设计 io_uring、O_DIRECT、批量专家联合读取、PILOT 路由预取——这些机制都是为了让"磁盘层"尽可能逼近"内存层"的速度。
"只改速度不改语义"还有一个工程上的重大收益:可移植性。一份代码同时跑在 25GB 笔记本、64GB 工作站、256GB 服务器、带 GPU 的大主机上,不需要分支、不需要配置不同的二进制。开发者只需关心语义正确性,速度交给 tier.h 的自适应调度和 I/O 工程去榨取。这是 Colibrì 用纯 C 写就、零依赖、单二进制跨全档位硬件的根本设计前提。
在多 socket 主机上,还有一个常被忽视的细节:RAM 物理上分布在多个内存控制器(每个 socket 一组)。如果常驻权重全部 numa-local 分配,跨 socket 访问会走 inter-socket 总线,带宽打折。
Colibrì 用 COLI_NUMA=1 开启跨内存控制器交错(interleave)。这是 issue #82 跟踪的优化:把常驻权重交错分配到所有 numa 节点,让任何线程的访问都能就近命中某个控制器,而不是固定走某一个 socket。对于大模型的全驻留场景,这一项能把有效内存带宽拉满。
NUMA 是"有限高速内存只改速度不改语义"哲学的又一个例证:开不开 NUMA,前向结果一样,只是带宽利用率不同。
三级层级不是任意划分,背后有清晰的物理依据。每一层的带宽量级和延迟量级差一到两个数量级,正好匹配不同权重的访问模式。
VRAM 带宽 ~500-1000 GB/s 延迟 ~微秒 容量 ~16-80 GB RAM 带宽 ~50-100 GB/s 延迟 ~十纳秒 容量 ~32-512 GB NVMe 带宽 ~3-9 GB/s 延迟 ~十微秒 容量 ~1-8 TB
稠密 17B 部分每 token 全量访问,需要的带宽最凶——单 token 前向要走完所有稠密层,每层的 attention、shared expert、embedding projection 都得读一遍。把它放 NVMe 是灾难(带宽差 10 倍以上),放 VRAM 又挤占 KV cache,所以 RAM 是黄金档。9.9GB int4 在 80GB/s 双通道 DDR5 下,单 token 的稠密前向约 125 微秒,可接受。
路由专家的访问模式完全相反:每 token 只激活 19456 中的 8 个(top-8 路由),且不同 token 激活不同专家。这意味着单个专家的访问频率很低,但一旦被路由就需要快速读取。把它们全部塞进 RAM 不现实(370GB),塞进 VRAM 更不可能。NVMe 的 3-9GB/s 配合 PILOT 预取和 io_uring 异步,足以在计算下一层时把所需专家流式拉进热存——延迟被重叠掉了。
所以三级层级不是"硬件清单",而是"访问模式 ↔ 物理带宽"的精确匹配。稠密部分匹配 RAM 的高带宽 + 中等容量;路由专家匹配 NVMe 的大容量 + 可重叠延迟;VRAM 留给真正需要极低延迟的东西(KV cache、激活值、极热专家)。这套匹配是 Colibrì 在 5 万行 C 里反复打磨的核心系统设计。

下一节:我们深潜
tier.h的四个函数——tier_pick_swap的 25%+4 滞后防乒乓、tier_lfru_score的频率优先近期破平、tier_pick_lfru、tier_decay的衰减,看清这套替换策略如何决定"谁进热存、谁被换出"。