news 2026/10/4 2:38:56

WARP权重分页核心技术解析:一个专家一次对齐读,NVMe流式加载MoE专家的完整设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WARP权重分页核心技术解析:一个专家一次对齐读,NVMe流式加载MoE专家的完整设计

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 GB29.1%0.56–0.58 tok/s
17.32 GB36.2%0.63 tok/s
29.32 GB41.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 check

make 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 的权重分页设计可以浓缩成四条可迁移的原则:

  1. 格式为 I/O 服务:一个专家一条 4 KiB 对齐记录,一次pread取回全部权重;
  2. 引擎自管缓存:绕过系统页缓存,用 LFRU 做有界专家缓存,预算按工作集分档;
  3. 用时间换空间:路由结果先于读取可知 → 预读流水线,再往前一步 → 路由器前瞻;
  4. 一切机制必须比特一致:只调度字节移动的时刻,绝不改变模型输出。

这套设计的完整测量与推导散布在 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 2:38:17

机场安检危险品自动识别:YOLOv8实战与数据不均衡优化

简介:这是一份基于深度学习的机场安检危险品自动识别系统Python源码,面向高校计算机、人工智能、信息安全等专业学生与教师,适合作为课程设计、毕业设计、期末大作业或初期项目立项演示使用。资源共179个文件,包括37个源码文件、5…

作者头像 李华
网站建设 2026/10/4 2:37:16

工业存储选型:用MRAM解决EEPROM与Flash的寿命和写入痛点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 2:36:39

目标检测后处理核心:NMS原理、实现与优化详解

最近在折腾检测模型后处理的时候,有好几个朋友问我:NMS到底是怎么把一个目标周围那一堆框收敛成一个的?其实NMS(Non-Maximum Suppression,非极大值抑制)这个算法,是目标检测里最不起眼却又最关键…

作者头像 李华
网站建设 2026/10/4 2:36:01

MR25H40CDF + STM32F215ZG:SPI MRAM实现工业数据掉电保存

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 2:34:43

MRAM×PIC24EP:高频数据记录与掉电不丢的工业存储方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 2:33:18

Conda虚拟环境中pip安装包路径错乱?一文厘清conda与pip的安装机制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华