在 MoE(Mixture of Experts)模型规模化部署的背景下,Expert Parallelism(EP)已成为跨 GPU 集群 serving 的核心并行策略。与 Tensor Parallelism 或 Pipeline Parallelism 不同,EP 的通信模式具有显著的动态性:每个 token 应该被路由到哪些 expert,由运行时的 router 根据输入数据实时决定,而非在编译期或初始化阶段固定。这种事件驱动的调度特性,加上大规模集群对通信效率的苛刻要求,催生了 DeepEP 这类高性能通信内核的设计哲学。
事件驱动调度的本质:运行时决策与负载不确定性
传统并行策略的通信模式是静态的 —— 谁发送、谁接收、发送多少,在训练或推理开始前就已确定。EP 则完全不同:router 对每个 token 计算到所有 expert 的 logits,取 top-K 作为路由目标。这意味着在每一层、每一步,token 到 expert 的映射都是全新的、不可预知的。
这种动态性带来了两个核心挑战。第一,接收方在数据到达前无法确定需要分配多少内存。最坏情况下,所有 peer 可能将它们的全部 batch 都路由到同一个 expert,因此最坏情况分配会导致巨大的内存浪费。第二,通信与计算的重叠变得更加复杂 —— 如果没有精确的依赖追踪,GPU 计算单元可能在等待网络传输时空闲,或者网络队列在计算未结束时被阻塞。
事件驱动调度在此体现为:通信内核必须响应 "数据就绪" 事件(路由完成),而非遵循预设的时间表。DeepEP 的解决方案是引入协调阶段(coordination pass):每个 rank 先本地统计要向每个 peer 发送多少 token,然后通过 all-gather 交换这些计数。接收方汇总后,通过前缀和计算每个来源的数据应该写入缓冲区的哪个偏移位置。这一过程模拟了事件驱动系统的典型模式 —— 先收集元数据(事件描述),再调度实际的数据传输(事件处理)。
零拷贝通信:绕过 CPU 的 RDMA 与 NVLink 直传
在 EP 内核中,token 的 hidden state(通常以 BF16/FP8 格式)需要在 GPU 间搬运。传统的拷贝路径涉及 CPU 介入、内存缓冲区的多次复制,这在 HBM 带宽已经捉襟见肘的情况下是不可接受的。
DeepEP 的零拷贝设计依赖两个关键机制。首先是预注册内存(pre-registered memory)。NIC(网络接口卡)只能直接写入提前注册的内存区域,而动态分配的紧凑缓冲区无法满足这一要求。因此,发送方将 token 流式写入接收方预注册的固定大小队列中,接收方则从队列中读取并复制到最终缓冲区。队列的深度决定了发送方可以领先接收方多少步,形成天然的背压机制。
其次是两级跳传输架构。token 从不直接点对点传输到任意远程 GPU,而是先通过 RDMA 发送到目标节点上索引相同的 GPU(home rank),再由该 GPU 通过 NVLink 转发到最终宿主。这种设计将 RDMA 流限制在 "轨道(rail)" 内 —— 每个 NIC 只与对端节点的对应 NIC 通信,避免了连接数的爆炸式增长,同时充分利用了节点内 NVLink 的高带宽。
对于跨节点场景,这一架构意味着每个 token 的传输路径是确定的:源 GPU → RDMA → 目标节点 home GPU → NVLink → 目标 expert GPU。这种确定性路径使得网络拓扑感知的调度成为可能,也为后续的 expert 放置优化(如 EPLB)奠定了基础。
高吞吐量模式:协调阶段与紧凑缓冲区
在 prefill 阶段,batch size 大、计算密集,通信有足够的时间隐藏在计算之后。DeepEP 的高吞吐量模式充分利用这一特点,采用 "先询问,后发送"(ask-then-send)策略。
协调阶段的具体实现是轻量级的:每个 rank 向每个 peer 发送的 token 计数(通常只是一个整数),通过 RDMA 和 NVLink 的两级 all-gather 完成。由于数据量极小(每 peer 仅几个整数),这一阶段的开销可以被后续的 GEMM 计算完全覆盖。在双 batch 重叠的 serving 栈中,一个 microbatch 的通信与另一个 microbatch 的计算并行执行,实现了真正的流水线重叠。
协调完成后,接收方分配ragged buffer—— 大小恰好等于实际接收 token 数的紧凑缓冲区,没有 padding 浪费。发送方通过预注册队列将 token 写入,接收方根据前缀和计算的偏移将数据复制到最终位置。最后一个步骤是本地置换(local permute):由于传输是按来源 rank 分组而非按 expert 分组,需要将数据重新排列为 grouped GEMM 所需的连续 expert 块格式。
这一模式的工程参数包括:预注册队列深度(通常 4-8 个 slot)、协调阶段的同步屏障超时(防止慢节点拖死集群)、以及 ragged buffer 的内存池预分配策略(避免每步的 cudaMalloc 开销)。
低延迟模式:固定缓冲区与信号槽机制
在 decode 阶段,每个 rank 通常只持有少量 token(往往每序列一个),计算负载极轻,协调阶段的往返延迟成为瓶颈。此外,动态形状使得 CUDA graph 的捕获变得困难,进一步增加了 launch overhead。
DeepEP 的低延迟模式采用 "直接发送,无需询问"(send-without-asking)策略,核心思想是用内存换延迟。每个接收方预先为每个(来源 rank, expert)对分配固定大小的私有区域。发送方可以直接计算写入地址:
addr = base + (expert_id * num_ranks + src_rank) * chunk_size + slot
这种静态地址映射消除了协调阶段的往返,数据发送成为 layer 的第一个操作。为了控制内存爆炸,每个区域设置固定的 chunk 上限(如 6 个 token),超出部分需要分 microbatch 处理。
信号槽(count slot)机制解决了 "数据是否已到达" 的同步问题。每个私有区域的末尾预留一个槽位,发送方在完成数据写入后,向该槽位写入实际发送的 token 数。由于槽位初始值为空(可区分于任何有效计数),接收方可以通过轮询或中断感知数据到达。关键的安全保证是:计数写入与数据写入在同一条有序通道(RDMA queue pair 或 NVLink memory fence 后),因此计数可见时数据必然已就位。
低延迟模式的另一个优化是量化传输:dispatch 阶段的数据在传输前量化为 FP8,combine 阶段保持 BF16 以确保精度。这种非对称设计在带宽受限的 decode 场景下显著降低了传输时间。
工程实践:模式选择与监控要点
选择高吞吐量还是低延迟模式,取决于 workload 特征和硬件配置。以下是可落地的决策参数:
选择高吞吐量模式的条件:
- Batch size 较大(prefill 场景,每 rank token 数 > 256)
- 内存敏感(需要最大化 KV cache 可用空间)
- 可以容忍协调阶段的微秒级延迟
选择低延迟模式的条件:
- Batch size 较小(decode 场景,每 rank token 数 < 64)
- 延迟敏感(需要最小化首 token 时间)
- 内存充裕(可以接受 2-4 倍的缓冲区浪费)
关键监控指标:
- 每层的协调阶段耗时(高吞吐量模式)
- 信号槽等待时间分布(低延迟模式,P99 应 < 100μs)
- RDMA 带宽利用率(目标 > 80% 理论峰值)
- NVLink 转发延迟(节点内应 < 5μs)
- 缓冲区利用率(低延迟模式下,实际使用 slot / 总 slot)
回滚策略:在专家负载极度不均衡时(如某个 expert 成为热点),低延迟模式的固定分区可能导致严重的内存浪费和 microbatch 碎片化。此时应动态降级到高吞吐量模式,或触发 EPLB(Expert Parallelism Load Balancing)进行 expert 重分布。
结语
DeepEP 风格的事件驱动 EP 内核展示了高性能并发架构的核心权衡:是通过协调换取内存效率,还是通过预分配换取延迟确定性。零拷贝通信消除了 CPU 在数据路径中的瓶颈,而两级跳传输架构在可扩展性与性能之间找到了平衡点。对于构建大规模 MoE serving 系统的工程师而言,理解这些调度策略的适用边界,并根据实际 workload 特征选择正确的模式,是优化端到端延迟和吞吐量的关键。
资料来源:
- Fergus Finn, "Anatomy of a high-performance EP kernel", 2026
- DeepSeek AI, DeepEP GitHub Repository
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。