1. EP 解决的不是“少算”,而是“专家放在哪里”

稀疏 MoE 层通常把一个 dense FFN 替换为大量专家网络和一个 router。给定 token hidden state,router 选出少量专家并给出门控权重;这降低了单个 token 的激活计算量,但模型的专家参数仍要存放在某些 GPU 上。Expert Parallelism,简称 EP,把专家 owner 分散到多个 rank,让任意 token 有机会访问整个专家池。

因此 EP 与数据并行不同。DP 复制模型、把请求分开;EP 把不同专家分片、把同一批中的 token 按路由结果交换。token 的目的地每一层都可能变化,而且不同请求、不同位置的 token 分布并不均匀。EP 的性能上限由最慢 owner rank 决定,而不是由平均 token 数决定。

2. 从 router 到专家:先建立正确的数学对象

设 batch 中有 N 个 token、专家数 E、top-k 为 k。router 产生 logits z ∈ R^(N×E),对每个 token 选择索引集合 I_t 与权重 g_t,e。输出是被选专家输出的加权和,常附加共享专家或残差支路。这里的稀疏性发生在 token 到专家的连接图,而不是在专家内部的矩阵乘法上。

y_t = Σ_{e ∈ I_t} g_{t,e} · Expert_e(x_t) tokens per expert: n_e = |{(t,e): e ∈ I_t}| critical work is controlled by max_e(n_e), not mean(n_e)

路由器的 top-k 是模型语义的一部分。运行时可以重新排列 token、压缩元数据、异步发送,但不能为了均衡网络负载把 token 改送给另一个专家。负载均衡需由训练时的辅助损失、router 策略或模型规定的冗余路径来完成,不能由 serving scheduler 在无语义保证的情况下擅自完成。

3. Dispatch 与 combine:两次 all-to-all 的含义

每个 source rank 先按目标 expert owner 对 token 编桶,形成可变长度消息。dispatch all-to-all 将 token hidden state、路由权重或必要的索引发到 owner rank;owner 将各专家的 token 排成适合 grouped GEMM 的布局,算完后再通过 combine all-to-all 把结果送回 source rank。source 依据原始 token 顺序和 gate 进行加权聚合。

all-to-all 的发送计数、接收计数、偏移和排序需要动态生成,与固定大小 all-reduce 的执行形态不同。若计数在 host 上同步,控制路径会吃掉 decode 的预算;若布局不连续,PCIe/NVLink/RDMA 传输和 GEMM 都难以满速。因此高性能实现会尽量把 metadata、token packing、传输和执行留在 GPU 异步路径上。

4. 容量因子与负载不均衡决定长尾

router 可能把大量 token 送向少数专家。训练常使用容量因子限制单 expert 每轮可接收的 token 数;过量 token 可以被丢弃、走备用路径或按模型规则处理。服务侧若假设均匀分布,只按 N×k/E 预留 buffer,真实热点就会溢出、触发临时分配或让一个 rank 成为整个层的 straggler。

imbalance = max_r(tokens_received[r]) / mean_r(tokens_received[r]) T_layer ≥ max_r(T_pack[r] + T_network[r] + T_expert_gemm[r] + T_unpack[r])

应同时观察 expert 粒度与 rank 粒度。多个热点专家若恰好同属一个 rank,rank 失衡会比 expert histogram 看起来更严重;反之,专家不均匀但 owner 映射合理时仍可能可接受。prefill 的大量 token 与 decode 的小量 token 也会出现不同模式,不能只在一种 batch shape 上调优。

5. DeepEP 的接口思想:把通信当作可调度的算子

DeepEP 提供面向 MoE 的 dispatch/combine 通信,并区分不同拓扑和运行模式。runtime 设计者需要先理解接口边界:输入是 token 布局与路由信息,输出是 owner-local 的可计算布局。通信完成事件和 buffer 生命周期也要明确,才能与 CUDA stream 和专家 GEMM 拼成正确的依赖图。单个版本的 benchmark 不能替代这些接口语义。

一个通信库若只提供“阻塞地把数据发完”,上层几乎无法隐藏延迟。若它暴露异步 handle、可复用 buffer、可预测的 layout 和完成信号,runtime 才能把下一批的 pack、当前批的传输、上一批的 GEMM 同时推进。性能数字会随 GPU、NIC、SM 配额、消息形状和 commit 改变,因此任何比较都应记录官方版本与命令行。

6. Token layout 是通信与算子的共同契约

专家 GEMM 希望同一专家的 token 连续,以形成较大的矩阵块;网络希望按 destination rank 连续,以形成较少的大消息;原始模型则希望输出回到 token 顺序。一个好的 layout 通常至少维护三组映射:原 token 到发送位置、发送位置到 expert-local 位置、返回位置到原 token。遗漏任一映射都可能造成静默的 token 混淆,而不是显式报错。

量化和多精度会让契约更复杂。FP8 dispatch、BF16 combine 或带 scale 的 payload,都要保证 scale 和数据共享同一索引语义,对齐也不能把无关 token 混进同一块。调试可从小 batch、固定 route 和可打印 token id 开始,确认 round-trip identity 后再接入专家 GEMM。数学正确后才有必要追性能。

7. 通信计算重叠的条件,不是多开一条 stream

设一批 token 被切成若干 chunk。理想流水是:chunk 0 dispatch 后立即计算专家;同时 chunk 1 仍在网络上,chunk -1 的 combine 可与后续计算并行。可是重叠只有在三个条件同时成立时才有效:chunk 足够细以产生并发,chunk 又不能细到每次传输只剩启动开销;GPU 有足够 SM/复制引擎资源;数据依赖与 buffer 回收不会在某个 barrier 汇合。

T_pipelined ≈ warmup + Σchunks max(T_dispatch, T_expert, T_combine) + drain 而非 Σchunks (T_dispatch + T_expert + T_combine)

如果 dispatch 和 grouped GEMM 都需要大量 SM,强行并发会互相降速,最终端到端更慢。若 NIC 与 GPU 的拓扑绕远,网络传输也可能抢占 HBM/NVLink 路径。正确做法是从 trace 中观察重叠区间和资源占用,扫描 chunk size、通信 SM 配额、GEMM tile,而不是只凭“理论可并行”启用重叠。

8. EP 的拓扑要求:对称性、NIC 映射和故障域

EP all-to-all 比 TP all-reduce 更容易暴露网络非对称。一个 rank 到另一个 rank 的路径、GPU 到 NIC 的亲和性、跨 node 是否经过拥塞域,都会改变最慢消息。把所有专家均匀编号然后随意放到 GPU 上,可能让某些 owner 的高频目的地穿越更弱链路;把热专家与冷专家混排,则有机会降低最大链路负载,但必须在真实 router trace 上验证。

部署清单应包括:每个 global rank 对应的 GPU、NUMA、NIC、NVLink clique、EP group;每个方向的有效带宽与 P99;遭遇单卡或单 NIC 故障时哪些 EP group 整体不可服务。故障边界要按执行 mesh 定义,不能只按“一个 GPU pod”口头描述。更完整的硬件视角见 Mainline 通信与拓扑

9. 在线 serving 如何把 EP 纳入调度器

调度器至少知道全局 token budget、KV 可用块和请求 deadline;对于 EP,还应收集每轮 router 输出或其可用预测,记录各 rank 的接收 token 数、dispatch/combine 字节数、等待时间和专家 GEMM 时长。注意这些信息用于排队和容量选择,而不是篡改 route。一个长 prompt 可能在 prefill 时压垮 EP,而 decode 阶段很平稳,因而需要分别设 P/D 的 token 上限。

有前缀缓存时,路由层面的局部性并不等价于 KV 局部性。把请求迁到空闲 replica 能改善队列,却可能失去已有 KV 或需要昂贵迁移;固守 cache-local replica 又会扩大专家热点。该冲突需要由成本模型权衡,不能用“始终最短队列”或“始终本地命中”这种单条规则处理。

10. 必须采集的 profile,而不是只有 GPU 利用率

  • 每层每 EP rank 的 send/recv token 数、字节数和最大/均值比。
  • router、pack、dispatch、expert GEMM、combine、unpack 的 P50/P99 时间线。
  • 同一 stream 与不同 stream 的依赖边、event wait、空洞与 buffer reuse 次数。
  • GPU 到 NIC 的流量方向、链路利用率、重传或拥塞指标,以及对其他 collective 的干扰。
  • 按 prefill/decode、短/长上下文、不同 batch size 分桶后的性能与准确度。
  • 发生 fallback、容量溢出、临时分配、OOM 或超时的完整请求样本。

这些指标应以 trace id 和运行时版本关联。没有版本化的 profile,会让一次 kernel 升级、路由器替换或环境变量变化在后续比较中变成无法解释的噪声。

11. 五种常见失败模式

把 all-to-all 当作固定带宽问题:实际负载是可变、带元数据、带尾部的,不可用平均消息大小代替。
只优化 dispatch:combine、unpack 或最慢专家 GEMM 仍可能位于临界路径,局部加速不等于端到端加速。
chunk 过细:看似增加 overlap,实际增加 kernel launch、计数和同步次数,decode 尤其敏感。
跨拓扑组扩 EP:EP 度变大但 all-to-all 穿越弱链路,吞吐可能下降且 P99 恶化。
忽略输出正确性:索引或 gate 对齐错误能产生数值“正常”的错误文本,必须有 round-trip 与端到端回归。

12. 从零到生产的实施顺序

  1. 在单节点、小 batch 下验证 router 索引、token permutation 与 combine 的数值等价性。
  2. 测量不同 token 数、hidden size、top-k 下的 dispatch/combine 曲线,分别记录单向与双向。
  3. 将专家 GEMM 接入,确认 layout 连续性、group size 和精度路径没有破坏正确性。
  4. 增加 stream/chunk 重叠,用 trace 确认临界路径已经缩短,再调整 SM 资源。
  5. 扩到目标 EP group,验证 GPU-NIC 映射、不同方向、通信竞争和故障边界。
  6. 最后接入在线 scheduler,以真实到达 trace 扫 SLO goodput,而不是仅做饱和离线 batch。

13. 与 Mainline 的连接

EP 是 Transformer 与 MoE 在分布式系统中的落地形态;它的 token 交换由 GPU 算子 的布局和 stream 决定,又受 并行放置通信拓扑 约束。后续阅读 COMET 时,可把它看作在同一 dispatch/combine 临界路径上进一步挖掘细粒度 overlap 的方案。

14. 一手来源与版本边界

来源用途
DeepEP 官方仓库接口、支持平台、benchmark 与版本说明的主入口。
GShard / MoE 系统论文稀疏专家、通信和并行的一手背景资料。
本档案:COMET 与细粒度 overlap本文下一篇独立解释。

本页不把某次仓库 benchmark 当作通用吞吐承诺。GPU、通信库、NIC、消息形状和模型 router 的任一变化都可能改变结果。