论文描述机制和实验, 仓库暴露实现必须满足的接口. 一个 MoE 层在论文中可以写成路由与专家计算, 到代码中还要处理 token 分发, 节点拓扑, 数据类型, 缓冲区和失败条件; MLA 在公式中减少 KV cache, 到 kernel 中还要匹配 GPU 架构, batch 形状与分页缓存. 本章把仓库视作技术设计的一部分, 关注组件在整条训练和推理路径中的位置.
当前收录的五个仓库覆盖存储, 数据处理, 专家通信, 矩阵乘法和注意力 kernel. 每个仓库对应一组不同的性能指标: 3FS 关心聚合带宽和元数据路径, smallpond 关心数据任务调度, DeepEP 关心 all-to-all 通信, DeepGEMM 关心矩阵计算, FlashMLA 关心注意力的解码与预填充. 阅读时先确定「输入输出」与「部署边界」, 再看内部优化.
这五层之间还有一条更重要的线: 模型语义必须逐层变成机器能够消费的执行表示. MLA 的压缩状态会变成带有页表、长度和精度约束的 KV cache; MoE 的专家选择会变成 token 到 rank 的映射、连续缓冲区和 grouped GEMM 的分组信息; 训练语料会变成文件、Parquet 分区以及可重跑的任务图. 只有表示对得上, 结构上的节省才可能落到吞吐、显存或容量上. 接口若要求额外转置、量化、重排或同步, 节省下来的成本就会被搬到相邻环节.
仓库也给论文叙述划出边界. 论文可以讨论一种普遍机制, 实现却会写清支持的 GPU 代际、数据类型、矩阵布局、batch 形状与通信域. 这些限制不推翻算法结论, 但决定公开性能能否复现. 更要留意时间: 仓库会持续重构和扩充支持矩阵, 今天出现的接口不能倒推为早期模型当时使用过的实现. FlashMLA 当前主分支甚至明确提示新版本已经移除 Hopper 与若干前代模型支持, 并改变 KV cache 格式. 分析 V2、V3 或 V3.2 时, 应回到对应发布说明或历史提交, 不能拿最新 README 替换历史证据.
同一个仓库内也要把「语义兼容」与「二进制兼容」分开. 算法名称保持不变, kernel 的参数、scale 编码和缓存字节布局仍可能变化; 新硬件上增加某种精度路径, 也只能证明该版本已经支持, 无法证明旧训练或旧推理曾经采用. 最稳妥的证据链是模型发布时间、仓库 release 或 commit、接口支持矩阵三者能够互相对上. 若只对上其中一项, 可以讨论设计联系, 不宜把它写成确定的生产依赖.
1. 存储与数据准备
1.1. 3FS 提供共享数据底座
3FS 是面向 AI 工作负载的分布式文件系统. 大规模训练既要顺序读取数据分片, 也要写 checkpoint 和中间结果; 推理与数据处理还会产生不同大小和并发模式的请求. 3FS 将存储设备, 网络传输和文件语义组织成共享服务, 目标是在大量客户端下保持高聚合吞吐.
文件系统性能不能只看单客户端峰值. 元数据操作, 小文件, 并发读写, 故障恢复与数据重建都会影响生产负载. 阅读 3FS 时应先区分控制路径和数据路径, 再观察客户端怎样定位数据, 数据怎样跨网络传输, 副本或恢复策略怎样影响可用容量. 这些条件决定论文或基准数字能否迁移到另一套集群.
1.2. smallpond 把计算调度靠近数据
smallpond 面向大规模数据处理, 将任务拆分, 调度与 3FS 数据访问连接起来. 预训练数据清洗, 去重, 转换和统计通常需要扫描海量文件; 如果分片不均或频繁搬运数据, CPU 与网络会先于 GPU 训练成为瓶颈.
smallpond 的阅读重点是任务图和分区语义. 一个操作怎样切成并行任务, 中间结果怎样保存, 失败任务怎样重跑, 这些机制决定数据流水线的可重复性和资源利用率. 它与 3FS 的关系是计算层与存储层的配合: 文件系统提供共享数据面, 调度框架决定工作在何处执行以及读取哪些分片.
3FS 官方说明把训练样本随机读取、并行 checkpoint、数据准备和推理 KV cache 都列为目标负载. 这说明「共享存储」并不等于把普通文件系统换得更快: 访问模式从大文件顺序扫描跨到随机读取、小型元数据操作和高并发写入, 系统必须在同一命名空间中处理差异很大的请求. 3FS 采用解耦架构, 以 SSD 与 RDMA 聚合资源, 又以强一致文件语义降低上层程序处理并发状态的难度. 强一致、冗余与恢复会消耗网络和容量, 换来的是 checkpoint、数据产物与缓存状态更容易推理.
smallpond 官方仓库把 DuckDB 的单任务执行能力接到分布式任务与 3FS 数据上. repartition 这样的接口很能说明问题: SQL 中的一次聚合, 落到集群以后先要决定键如何分区、每个分区写到哪里、后续任务怎样读取. 分区能够增加并行度, 也会制造 shuffle 和中间文件; 分区过细会放大调度与元数据开销, 分区过粗又会产生长尾. 所以 smallpond 的收益来自「把可并行的数据语义显式化」, 并借共享存储交换中间结果. 它依赖 3FS 承受读写压力, 3FS 的高带宽也依赖任务划分提供足够并发, 两边是一组互相校准的设计.
2. MoE 通信路径
2.1. DeepEP 执行 token 分发
DeepEP 为 MoE 提供高吞吐, 低延迟的 all-to-all 通信. 路由器为 token 选择专家以后, token 表示必须发送到专家所在 GPU, 计算完成后再返回原顺序. 通信量, 消息大小和节点边界随 batch 和路由结果变化, 通用集合通信不一定适合这些稀疏负载.
DeepEP 区分训练与推理解码等工作模式, 因为大 batch 的吞吐目标和小 batch 的低延迟目标不同. 缓冲区布局, NVLink 与 RDMA 路径, 发送接收重叠都会影响结果. 阅读基准时需要确认 GPU 型号, 节点数, token 数量, top-k 与数据类型, 这些参数直接决定消息粒度.
2.2. 算法均衡与通信实现相互约束
第二章的无辅助损失负载均衡减少专家拥塞, DeepEP 则高效搬运路由后的 token. 如果路由严重偏斜, 少数专家会形成计算和接收热点, 通信库无法完全消除等待; 如果为了均衡强行改变路由, 又可能损害模型目标. 两层必须通过明确的容量和统计接口配合.
MoE 的理论激活 FLOPs 不能直接等同于端到端速度. token 打包, 跨节点传输, 专家计算和结果合并都位于关键路径. 阅读 DeepSeekMoE 或 V3 后进入 DeepEP, 可以把「激活少量专家」还原成完整的分布式执行过程.
DeepEP 官方接口把这段过程分成 dispatch 与 combine, 并进一步区分高吞吐和低延迟路径. 路由结果先变成每个 rank、每个专家接收多少 token 的布局信息, token 再按布局发送; 专家输出必须按原来的 token 关系合并回来. 新版 EPBuffer 还把展开布局直接对接 grouped expert GEMM. 通信库交付的是下一枚矩阵算子能够直接读取的有序表示. 如果中间还要重新排序或复制, all-to-all 的带宽数字再高也无法代表整层延迟.
DeepEP 使用 GPU SM 执行 dispatch 和 combine, 官方说明也明确写出 EP 路径并非 zero-SM. 通信与计算重叠因此会占用同一批 GPU 执行资源; 分给通信的 SM 越多, 消息推进可能越快, 留给专家 GEMM 的资源却会减少. 跨节点 RDMA、节点内 NVLink、低延迟小消息和吞吐型大消息也需要不同调度. 这里的「成本转移」非常具体: MoE 减少每个 token 的参数计算, 同时引入路由布局、缓冲区容量、网络流量和负载长尾.
3. 低精度矩阵计算
3.1. DeepGEMM 服务 FP8 训练与推理
DeepGEMM 提供针对 NVIDIA Hopper GPU 的 FP8 GEMM. V3 使用低精度提高训练吞吐, 但输入缩放, 分块方式, 累加精度和输出格式都需要与模型数值方案一致. kernel 必须在保持误差可控的同时利用张量核和显存层级.
仓库中的接口形状反映了模型工作负载. 常规 dense GEMM, MoE grouped GEMM 与不同量化粒度需要不同调度. grouped GEMM 要处理各专家 token 数不相等的情况, 负载分布会影响块调度和占用率. 因此单个规则矩阵上的峰值不能代表 MoE 训练的实际表现.
3.2. 从数据格式追踪数值边界
阅读 DeepGEMM 时可沿数据格式追踪: 输入以什么精度存储, 缩放因子按张量还是按块生成, 乘法在哪里执行, 累加使用什么精度, 输出何时转换. 每一步都关系到误差和吞吐. 模型报告中的 FP8 配方给出数值策略, kernel 仓库给出硬件执行方式.
性能条件同样需要保留. GPU 架构, CUDA 版本, 矩阵尺寸和对齐方式都会改变结果. DeepGEMM 是为明确硬件与工作负载定制的实现, 其设计经验可以迁移, 具体数字不能脱离环境复制.
DeepGEMM 官方 README给出的接口比「支持 FP8」更有解释力. 常规 GEMM 需要明确 NT、TN、NN 或 TT 布局, 不同 GPU 代际支持矩阵并不相同; 缩放因子的格式和排列也随架构变化. 对 MoE 而言, contiguous grouped GEMM 把不同专家的 token 沿 M 维拼在一起, N 与 K 保持一致. 这恰好对应「专家网络形状相同、各专家 token 数不同」的模型语义. 路由偏斜会改变每组的 M, 小矩阵与长尾专家很难像规则大矩阵那样吃满张量核.
接口还说明转置、FP8 转换和 scale 布局可能由调用者提前准备. kernel 内部少做一步, 峰值会更漂亮, 代价却不会消失; 它可能落到前一枚 kernel、额外显存写回或权重预处理阶段. 因此应沿完整路径计算 cast → layout transform → GEMM → output 的时间与流量. 若权重可以离线重排, 推理能够摊薄一次性成本; 激活随 batch 动态变化, 在线重排就更难隐藏. 数据布局是模型张量与硬件 tile 之间的契约, 也是判断基准能否迁移的第一道筛选条件.
4. MLA 注意力执行
4.1. FlashMLA 将压缩结构落实为 kernel
FlashMLA 为 MLA 提供高效计算. MLA 将键值状态压缩为潜变量, 减少 cache 容量, 但解码时仍要完成查询与压缩表示之间的计算. kernel 需要组织潜变量, RoPE 相关分量, 分页 cache 和不同长度序列, 才能把结构优势转成延迟与吞吐收益.
预填充和逐 token 解码的形状差异很大. 预填充有较长查询序列, 更容易形成大规模并行; 解码通常每个请求只有少量新 token, 更受内存访问, 调度和 batch 组织影响. FlashMLA 的不同路径应分别评估, 不能用一个吞吐数字概括.
4.2. 模型压缩与系统缓存共同决定容量
V2 的 MLA 从模型结构上减少每个 token 保存的状态, FlashMLA 优化每次读取和计算, DualPath 则在更大尺度上安排 KV cache 的存储位置. 三者依次作用于「表示」「kernel」「服务系统」. 任一层单独优化, 都可能受下一层瓶颈限制.
V2 技术报告定义压缩后保存的张量, FlashMLA 实现消费这些张量的 kernel, DualPath 再处理大量请求状态的跨设备管理. 三份材料连起来, 正好覆盖从模型公式到生产数据路径的三个层次.
FlashMLA 当前接口把稀疏注意力的候选位置显式放在 indices 张量中, 解码路径还接收分页 KV cache 的位置编码. 这把注意力选择器与核心 attention kernel 的分工暴露出来: 上游负责找出候选 token, kernel 按索引 gather 状态并完成 softmax 与加权求和. 稀疏化减少被读取和计算的 KV 数量, 同时新增 indexer 计算、索引存储、不规则访存和无效位置处理. topk 过大时省不下多少工作, 太小时又可能损伤模型质量; 候选分布零散时, 理论计算量下降也未必形成同等的硬件收益.
数据格式同样限定结论. 当前解码接口只支持特定量化 KV cache, 不同模型版本的每 token 字节布局、scale 粒度和 RoPE 分量处理已经变化. 融合 Q-norm、RoPE、attention、输出变换与量化能够减少中间张量读写和 kernel launch, 但要求 Q 与输出投影权重预先置换. 这再次出现相同规律: 融合把在线开销移到权重布局和部署准备, 并把多个算子绑定到更窄的模型形状. 所以 FlashMLA 既是 MLA 或稀疏注意力获得系统收益的证据, 也是其硬件与格式边界的证据.
5. 组合成完整执行栈
5.1. 训练数据到参数更新
训练开始前, 3FS 保存原始数据和处理结果, smallpond 执行清洗与转换. 训练节点读取分片以后, DeepGEMM 执行主要矩阵计算, DeepEP 在 MoE 层分发 token. checkpoint 再写回存储系统. 这些组件的吞吐必须大致匹配, 否则最快的一层会等待最慢的一层.
排查训练性能时可按这条路径逐段测量: 数据读取是否让 GPU 等待, dense 与 grouped GEMM 是否达到目标占用率, all-to-all 是否与计算重叠, checkpoint 是否造成周期性停顿. 仓库解析提供接口和关键实现, 第三章的系统论文提供全局拓扑, 两者结合才能定位端到端瓶颈.
5.2. 长上下文推理与 agent 执行
推理阶段, 权重加载和输入数据仍依赖存储, FlashMLA 负责注意力主路径, MoE 层由 DeepEP 通信. 当上下文持续增长时, KV cache 进入 DualPath 一类分离系统. agent 强化学习还要把模型输出交给 DSec 沙箱执行, 结果作为奖励返回训练器.
五个仓库在系统中的位置不同: 3FS 提供数据底座, DeepEP、DeepGEMM 与 FlashMLA 进入模型关键路径, smallpond 负责数据处理. 推理部署还涉及 V2 的 MLA 与 DualPath; 训练侧则可结合 V3 Insights, 将存储、数据、通信和计算放回同一条资源链中考察.
一次 MoE 训练迭代能够完整呈现跨仓库链路. smallpond 把语料操作变成分区任务, 产物落到 3FS; dataloader 从共享文件读取样本, 模型的 dense 投影与专家计算进入 DeepGEMM; 路由产生的 token 布局交给 DeepEP, 通信后的连续表示再喂给 grouped GEMM; checkpoint 定期回写 3FS. 任一接口多出一次 materialize、重排或跨节点传输, 都会沿链路放大. 真正有意义的系统收益是 GPU 等待减少、单位 token 成本下降或可用容量上升, 并且没有把不可接受的代价推给数据准备与恢复窗口. 只有把稳态迭代与周期性保存放在一起计时, 吞吐数字才接近训练任务实际支付的成本.
推理链路换成另一组形状. FlashMLA 消费模型产生的 Q 与 KV 表示, 分页缓存决定状态放置, MoE 层仍在 DeepEP 与 DeepGEMM 之间往返. 长上下文让 KV 容量和搬运成为主角, 高并发又放大调度碎片与尾延迟. 这时 3FS 或远端 KV 路径提供更大容量, 代价是网络访问和状态生命周期管理. 算子峰值、通信带宽、存储吞吐必须在同一请求分布下对齐; 分别挑选各仓库最漂亮的数字, 拼不出一套真实系统.
读开源仓库时可以连续追问三个问题: 模型里的哪一种语义被交给它, 这份语义被编码成什么数据布局和接口, 优化后又把成本推向哪里. FlashMLA 回答注意力状态怎样被选择和消费, DeepEP 回答路由关系怎样跨设备搬运, DeepGEMM 回答张量怎样贴合硬件 tile, 3FS 回答共享状态怎样获得容量与一致性, smallpond 回答数据变换怎样获得分布式并行. 五个答案接起来, 才能从仓库代码反推论文机制真正落地时必须满足的条件.