WARP权重分页核心技术解析:一个专家一次对齐读,NVMe流式加载MoE专家的完整设计
【免费下载链接】warpRun the full 2.78-trillion-parameter Kimi K3 model, DeepSeek V4.1 Flash or GLM-5.3-Flash beyond available RAM by streaming activated weights directly from NVMe. A dependency-free, embeddable C inference engine.项目地址: https://gitcode.com/gh_mirrors/was/warp
WARP(Weight-Aware Runtime and Paging)是一个零依赖的 C 语言推理引擎,它用"权重分页"的思路解决了一个看似无解的问题:把 2.78 万亿参数的 Kimi K3 大模型跑在 64 GB 内存的笔记本上。核心机制是——共享主干驻留内存,MoE 专家权重按需从 NVMe 硬盘流式读取,剩余内存充当有界专家缓存。理解这套"一个专家一次对齐读"的设计,你就掌握了大模型本地推理中 I/O 工程的完整方法论。
为什么需要"分页"?💡
传统推理引擎要求模型权重全部装进内存,而 MoE(混合专家)模型恰好打破了这个前提:
| 事实 | 数据 |
|---|---|
| Kimi K3 总参数量 | 2.78 万亿 |
| 每个 token 实际激活的专家参数 | 仅约 4% |
| 转换后的 WARP 容器体积 | 982 GB |
| 在 64 GB MacBook Pro 上运行 | 约 0.6 token/s |
| 打开模型所需最低内存 | 29.19 GB |
也就是说:磁盘上躺着 982 GB 权重,CPU 每个 token 只需要其中十几 GB。WARP 借鉴了操作系统虚拟内存"分页"的思想——内存放不下就放磁盘,用到哪页读哪页。README.md 开篇就点明了这一设计目标:
把模型主干留在内存里,选中的专家直接从磁盘流式读取,剩余 RAM 作为有界的专家缓存。
容器布局:让每个专家只需一次对齐读 📦
WARP 的模型不是单个文件,而是一个精心编排的目录,布局定义在 docs/FORMAT.md:
model.waste/ manifest.json # 配置 + 主干张量索引 + 专家银行索引 trunk.bin # 常驻内存的稠密部分(注意力、路由器、共享专家…) experts-L{layer}.bin # 每层一个"专家银行"文件 codebooks.bin # 向量量化码本 tokenizer.model # 自包含的分词器这套布局的第一设计目标就写在文档里:One coalesced read per expert(一个专家一次合并读)。具体做了三件事:
1. 一个专家 = 一条完整记录。专家的 gate/up/down 三个矩阵在磁盘上物理相邻,一次pread就取回整个专家——在 K3 上这条记录是 12,406,784 字节,恰好 3029 个页面。
2. 4 KiB 对齐 + 整页大小。所有独立可读取的记录都对齐到 4 KiB 且大小为 4 KiB 整数倍,这样才能用O_DIRECT(Linux)/F_NOCACHE(macOS)绕过操作系统页缓存。打开专家银行文件时的对齐检查见 bank_open。
3. 同层专家按 ID 排序且连续存放。于是"第 e 号专家在磁盘哪个位置"是一个纯乘法:offset = e × rec_bytes,零查找直接定位。
在精度侧,专家权重用 3 位残差向量量化(VQ3R)压缩,比 4 位整数量化省 1/4 空间且误差可控(19.4%);更敏感的主干权重保留 4~8 位。转换工具 tools/convert.py 负责把发布权重重编码成这种布局。
有界专家缓存:LFRU 策略与缓存旁路 💾
磁盘再快,同一个专家被反复读也不划算。WARP 把"模型地板"之外的全部内存划给专家缓存,实现见 src/ecache.h 与 src/ecache.c:
- 淘汰策略用 LFRU(频率优先、最近性作平局裁决)。Gate 2 的测量证明:小缓存占比下朴素 LRU 命中率崩到 5%,而 LFRU 仍能拿到 29%。
- 刻意绕过系统页缓存(
F_NOCACHE/O_DIRECT/FILE_FLAG_NO_BUFFERING)。源码注释解释得很直白:引擎自己管理缓存,如果让内核也缓存一份,测出来的命中率就是"虚构的"。 - 内存预算有硬顶。
waste plan先算出地板(主干 27.28 GB + 状态 + KV + 最小缓存),剩余空间按"一个 token 工作集"的整数倍分配给缓存,且总预算不超过进程可用内存的 3/4。
这里有个反直觉的"分页悬崖",实测数据来自 README.md:
| 专家缓存 | 命中率 | 解码速度 |
|---|---|---|
| 3.32 GB | 29.1% | 0.56–0.58 tok/s |
| 17.32 GB | 36.2% | 0.63 tok/s |
| 29.32 GB | 41.3% | 0.07–0.08 tok/s |
缓存越大命中率越高,但超过机器能驻留的上限后,每次"缓存命中"都变成缺页中断——给进程更多内存,反而可能慢 8 倍。这就是为什么默认预算按工作集整档递减,而不是把内存吃满。
流水线预读:读盘与计算同时进行 ⚡
即使磁盘随机读已达 10.73 GB/s,同步"读完再算"的串行模式仍浪费了约一半时间。关键洞察是:MoE 层的路由器先于读取运行,16 个专家 ID 在第一笔读发生前就已全部确定。
于是 moe_layer 在选完 top-16 后立即调用 waste_ecache_hint,把这批 ID 交给缓存;后台读线程(WASTE_IO_THREADS)提前发起pread,矩阵乘法消费时数据多半已就位。效果是把"读 1.41s + 算 1.03s"的加法变成了取最大值的流水线。
测量结果(docs/EFFICIENCY.md §4A):
- K3 解码0.33 → 0.49–0.53 tok/s(约 1.6 倍),Kimi-Linear 约 1.21 倍;
- 两路读在途时磁盘带宽从 10.73 提到 12.89 GB/s;
- 输出与同步路径逐位一致——
tests/run.sh会字节级比对,预读只改变字节移动的时间,不改变结果。
路由器前瞻:预测下一层要读谁 🔮
层内预读是"确定的",跨层就得"猜"。一个朴素猜测(历史共现表)只召回 29%,被项目直接否决;而真正奏效的做法是去问路由器本身:用下一层的真实路由权重、在当前层的隐藏状态上跑一遍,得到下一层最可能需要的专家(predict_next_moe,源码见 src/model.c)。
实测 top-6 前瞻召回率59%,命中约四分之三,配合 waste_ecache_prefetch 在层边界发出推测性预取——真实路由器随后仍做最终决策,因此 logits 依然逐位不变。这就是"只改时序、不改结果"的又一例。
其他值得了解的工程细节 ✨
- 完整性校验:每条专家记录带 CRC32(src/crc32.c,ARM CRC 扩展下 33 GB/s),默认关闭(约 1% 开销);校验失败会指名道姓地报错,如"expert 412 of layer 37: checksum mismatch"。
- 学习热榜:
--learn把真实工作负载命中的专家写进usage.waste,下次打开预热加载,Kimi-Linear 上命中率 61% → 72%。 - 多盘分片:
WASTE_BANK_SHARDS=/mnt/a,/mnt/b让专家e落到e % N号盘,一个 token 的 16 个专家散列到多块设备并行读;分片工具见 tools/split_banks.py。 - 分块预填充:chunk 内 token 路由到高度重叠的专家集,去重后读盘量降 3.3 倍且 logits 不变。
- 存储是硬约束:内置 NVMe 持续 12.78 GB/s,而一块 USB 盒装盘只有 0.94 GB/s——容器务必放内置 NVMe。
快速上手:三步体验权重分页 🚀
git clone https://gitcode.com/gh_mirrors/was/warp cd warp && make && make checkmake check会用合成小模型跑完全部引擎测试(含预读 vs 同步读的比特一致性检查),无需下载权重。想跑真实模型,内存门槛最低的是 Kimi-Linear(19 GB 容器、1.32 GB 内存、约 14 tok/s);GLM-5.3-Flash 则只需 16 GB 内存 + 112 GB NVMe,完整步骤在 README.md 的 Quick start 一节。跑起来后留意输出行的专家命中统计——比如 GLM 的[56 tokens ... experts 17327 hit / 1489 miss = 92%],这就是整套分页系统工作状态的直接读数。
总结
WARP 的权重分页设计可以浓缩成四条可迁移的原则:
- 格式为 I/O 服务:一个专家一条 4 KiB 对齐记录,一次
pread取回全部权重; - 引擎自管缓存:绕过系统页缓存,用 LFRU 做有界专家缓存,预算按工作集分档;
- 用时间换空间:路由结果先于读取可知 → 预读流水线,再往前一步 → 路由器前瞻;
- 一切机制必须比特一致:只调度字节移动的时刻,绝不改变模型输出。
这套设计的完整测量与推导散布在 docs/FORMAT.md(磁盘布局)、docs/EFFICIENCY.md(I/O 优化账本)、docs/ENGINE.md(内存预算)与 docs/LEARNED.md(含所有被否决方案的负结果),是研究大模型推理系统 I/O 工程时少有的"连失败实验都公开"的参考资料。
【免费下载链接】warpRun the full 2.78-trillion-parameter Kimi K3 model, DeepSeek V4.1 Flash or GLM-5.3-Flash beyond available RAM by streaming activated weights directly from NVMe. A dependency-free, embeddable C inference engine.项目地址: https://gitcode.com/gh_mirrors/was/warp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考