第 3 章 · 01 ColiExpertStore 抽象与 lease 租约契约 本节摘要:本节深潜 Colibrì 的权重 JIT 核心—— (99 行)。它定义了"专家流式缓存"的抽象接口: 定位一个专家(layer, expert), 是它的可读视图(gate/down/up 三个 tensor + 一个 lease 句柄)。核心是 lease 租约契约—— 成功后必须 恰好一次, 不可 copy, 时 debug 构建会断言零活跃 lease。这套契约保证"一个专家在被用期间不会被缓存驱逐"。所有具体实现(LRU 缓存、学习型热存)通过 虚函数表接入——这是 expertstore.h 唯一允许的"虚函数"风格,与第 1 章 02 节"纯 C 无引擎依赖"形成精妙平衡。
本节摘要:本节深潜 Colibrì 的权重 JIT 核心——
c/expert_store.h(99 行)。它定义了"专家流式缓存"的抽象接口:ColiExpertKey定位一个专家(layer, expert),ColiExpertView是它的可读视图(gate/down/up 三个 tensor + 一个 lease 句柄)。核心是 lease 租约契约——lookup成功后必须release恰好一次,ColiExpertView不可 copy,destroy时 debug 构建会断言零活跃 lease。这套契约保证"一个专家在被用期间不会被缓存驱逐"。所有具体实现(LRU 缓存、学习型热存)通过ColiExpertStoreOps虚函数表接入——这是 expert_store.h 唯一允许的"虚函数"风格,与第 1 章 02 节"纯 C 无引擎依赖"形成精妙平衡。读完本节,你理解了 Colibrì 权重 JIT 的契约骨架。
内容来源:原项目源码
c/expert_store.h(99 行,完整精读)、c/tensor.h(47 行,ColiTensorView定义)。
⚠️ 注意:线程安全是 implementation-specific——
expert_store.h:52-55明说,调用者不能假设lookup/release/prefetch/stats/destroy在同一 store 上并发安全,除非具体实现文档保证。views绝不能从多线程并发用。这是 Colibrì 把并发责任推给具体实现(LRU/学习型热存各自决定加不加锁)的设计选择。
阅读完本节,你应当能够:
ColiExpertKey(layer, expert)与 ColiExpertView(key/gate/down/up/lease)。destroy 在 debug 构建里断言零活跃 lease。ColiExpertStoreOps 虚函数表的五个函数(lookup/release/prefetch/stats/destroy)。ColiExpertStore{ops, state} 的两字段结构(虚函数表 + 不透明状态)。coli_expert_lookup/coli_expert_release 内联包装的容错逻辑。第 1 章 01 节讲过,Colibrì 把 19456 个路由专家放磁盘(~370GB)按需流式加载,只把热点专家留在高速层。这个"按需流式加载 + 缓存"的全部抽象,就是 expert_store.h。它是一份接口契约,不是具体实现——具体实现(每层 LRU 缓存、学习型固定热存)各自实现这套接口,接入引擎。
expert_store.h:1-12 的开头是标准的 include guard 和 C++ extern 包装:
1 #ifndef COLIBRI_EXPERT_STORE_H 2 #define COLIBRI_EXPERT_STORE_H 3 4 #include <stddef.h> 5 #include <stdint.h> 6 #include <string.h> 7 8 #include "tensor.h" 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif
它 include tensor.h(第 2 章 02 节讲过 ColiTensorView),因为专家视图里的 gate/down/up 三个 tensor 是 ColiTensorView 类型。string.h 是为了内联包装里的 memset(下面会看到)。
expert_store.h:14-27 定义两个核心数据结构:
14 typedef struct ColiExpertStore ColiExpertStore; /* 不透明前置声明 */ 15 16 typedef struct { 17 int layer; /* 哪一层(0..74) */ 18 int expert; /* 该层的第几个专家(0..255) */ 19 } ColiExpertKey; 20 21 typedef struct { 22 ColiExpertKey key; 23 ColiTensorView gate; 24 ColiTensorView down; 25 ColiTensorView up; 26 void *lease; /* 租约句柄,实现内部使用 */ 27 } ColiExpertView;
ColiExpertKey 是专家的"坐标"——(layer, expert) 二元组,定位 19456 个专家里的一个。注意它不包含 MTP 头的 layer 编号约定——具体编码留给出层(75 MoE 层 + MTP 头)。
ColiExpertView 是"一个专家的可读视图"。MoE 专家内部是三个矩阵:
(具体 MLP 拓扑因模型族而异,GLM 的 SwiGLU 是 gate/up 并行后激活再 down,但 expert_store.h 抽象层不关心这些——它只承诺"给你这三个 tensor 的视图,lease 有效期内可读"。)三个视图都是 ColiTensorView(tensor.h:30-41),里面带 format/scale_format/data/scales/data_bytes/rows/columns 等——这是第 2 章 02 节 quant.h 解码所需的全部信息。
第五个字段 void *lease 是租约句柄,类型故意用 void *——具体实现(LRU/学习型热存)把它指向自己的内部结构(如 LRU 节点指针)。抽象层不解释它,只承诺"release 时把它和 view 一起清零"。
expert_store.h:40-58 的注释是 expert_store.h 的灵魂——lease 租约契约。把英文注释提炼成五条铁律:
五条铁律逐条拆:
exactly once,不是引用计数)。配套约束:不可 copy ColiExpertView(lease 不可共享);不可把已有活跃 lease 的 view 传给 lookup(会被误覆盖)。coli_expert_lookup 包装的容错逻辑呼应)。views 绝不能从多线程并发用。并发责任推给具体实现。第 6 条关于 prefetch:它是 advisory(建议性),不持 lease,且不能驱逐仍持活跃 lease 的 slot——这条与第 3 章 02 节的"预取不驱逐活跃 slot"直接挂钩。
💡 深潜要点:lease 契约的核心目的是保证一个专家在被用期间不会被驱逐。设想没有 lease:LRU 缓存可能在你读 gate 矩阵时,把 down/up 矩阵驱逐了——因为 LRU 不知道你"正在用这个专家"。lease 把"我正在用"显式化:lookup 拿 lease → 用 gate/down/up → release 还 lease;持 lease 期间,缓存实现承诺不驱逐这个专家的 slot。这是权重 JIT 能"语义不变"的关键保障——专家数据在被读期间必须完整、稳定。
expert_store.h:59-69 定义虚函数表 ColiExpertStoreOps,这是 expert_store.h 唯一允许的"面向对象"风格:
59 typedef struct { 60 /* Returns zero on success. The view remains valid until release(). */ 61 int (*lookup)(ColiExpertStore *store, ColiExpertKey key, 62 ColiExpertView *view); 63 void (*release)(ColiExpertStore *store, ColiExpertView *view); 64 /* Prefetch is advisory. Unsupported or rejected requests return zero. */ 65 int (*prefetch)(ColiExpertStore *store, const ColiExpertKey *keys, 66 size_t count); 67 void (*stats)(const ColiExpertStore *store, ColiExpertStoreStats *stats); 68 void (*destroy)(ColiExpertStore *store); 69 } ColiExpertStoreOps;
五个函数指针,每个都是"具体实现要提供的回调":
ColiExpertStoreStats(第 3 章 02 节详讲八指标)。这套虚函数表是 expert_store.h 与具体实现(LRU/学习型热存/全驻留)的契约边界。每个具体实现写一份 ColiExpertStoreOps,把函数指针填上自己的实现,然后通过 ColiExpertStore 暴露给引擎。这与 C++ 的 vtable 同构,但用纯 C 函数指针实现——这是第 1 章 02 节"纯 C 零依赖"与"需要多态"之间的折衷。
expert_store.h:71-74 定义 store 本体,只有两个字段:
71 struct ColiExpertStore { 72 const ColiExpertStoreOps *ops; /* 虚函数表,指向具体实现的 ops */ 73 void *state; /* 不透明状态,具体实现自由解释 */ 74 };
ColiExpertStoreOps。const 表示虚函数表本身不可变(典型用法是每个具体实现有一份 static const 的 ops)。void *,具体实现的内部状态(LRU 实现里指向 LRU 表;学习型热存里指向热存 + 历史记录;全驻留实现里可能就是 NULL)。抽象层不解释。这种"ops + state"模式是 C 里实现多态的标准手法——等价于 C++ 的 vtable + this,但 this 被显式拆成"虚函数表指针"和"数据指针"两部分。它的好处是:引擎代码只用 ColiExpertStore * 抽象指针,不需要知道具体实现类型。换缓存策略(LRU → 学习型)只换 ops 和 state,引擎代码不变。
expert_store.h:29-38 定义统计结构,共八个字段,这里速览(第 3 章 02 节详讲):
| 分组 | 字段 | 含义 |
|---|---|---|
| 命中率 | requests/hits/misses |
总请求/命中/未命中,命中率 = hits/requests |
| 预取效果 | prefetched/prefetch_hits |
预取数/预取命中数,准确度 = prefetch_hits/prefetched |
| I/O 量 | bytes_read |
从磁盘读的字节,衡量磁盘压力 |
| 内存占用 | resident_bytes/capacity_bytes |
当前常驻/总容量,衡量饱和度 |
这些指标是 Colibrì "诚实研究"在缓存层的落地——每个数字都可观测、可 A/B,用户/贡献者能直接据此判断缓存策略是否有效。具体含义和派生用法在第 3 章 02 节展开。
expert_store.h:76-93 提供两个 static inline 包装,它们是引擎代码实际调用的入口:
76 static inline int coli_expert_lookup(ColiExpertStore *store, 77 ColiExpertKey key, ColiExpertView *view) { 79 if (!store || !store->ops || !store->ops->lookup) { 80 if (view) memset(view, 0, sizeof(*view)); return -1; } 83 int result = store->ops->lookup(store, key, view); 84 if (result != 0 && view) memset(view, 0, sizeof(*view)); /* 失败兜底清零 */ 85 return result; 86 } 88 static inline void coli_expert_release(ColiExpertStore *store, ColiExpertView *view) { 90 if (store && store->ops && store->ops->release) store->ops->release(store, view); 92 if (view) memset(view, 0, sizeof(*view)); /* release 后清零 */ 93 }
注意三层容错:(1) 入口检查 store/ops/ops->lookup 都非空,否则清零 view 返回 -1(让"store 没初始化"也能优雅失败);(2) 调具体实现的 lookup,失败时(result != 0)再清零一次 view(双保险,即使具体实现忘了清,包装层兜底);(3) coli_expert_release 即使 store/ops/release 为空,也照样清零 view——这让"对一个从未 lookup 成功的 view 调 release"也安全(no-op)。这套包装让引擎代码可以放心写 if (coli_expert_lookup(...) == 0) { 用 view; coli_expert_release(...); },失败路径不需要 release,容错和清零全部在包装层兜底。
⚠️ 注意:
coli_expert_release末尾的memset(view, 0, ...)(expert_store.h:92)是 lease 契约的关键执行点——它确保 release 后 view 不可再用(任何字段都归零),从根上杜绝"use-after-release"。这是 Colibrì 用纯 C 实现 RAII 风格资源管理的典型手法。
下一节,我们看 expert_store.h 的第一个具体实现——每层 LRU 缓存,以及"一层前瞻预取"怎么用 prefetch 把磁盘 I/O 藏在 compute 后面。