摘要:本文将针对 DeepEP 项目进行深入浅出的功能解析与设计分析,并在此基础上提出一些潜在的优化思路。本报告分为三个主要部分:功能解析、创新设计点、可能的优化方案。为了便于理解,文中会适度引用部分代码片段或函数接口说明。
一、功能解析
DeepEP 旨在为 MoE(Mixture of Experts)及其专家并行(Expert-Parallel)场景提供高效的通信库,核心功能包括:
- 分发(Dispatch):将一定数量的 token(通常是深度学习中自注意力机制或 MoE 中的输入数据)按专家、节点或其他策略进行划分,并分发到指定的目标 GPU/节点。
- 聚合(Combine):在计算完成后,将分发到多个专家或节点的中间结果按原顺序或策略合并回源节点,以继续后续的计算流程。
- 低时延模式(Low-Latency Mode):该模式主要面向推理阶段或需要极低延迟的场景,通过 RDMA、IBGDA 等技术减少通信开销,并提供了一种 Hook 机制,可以在发起发送请求后延迟真正的接收过程,以与其他计算进行流水线重叠。
1. 整体结构概览
从代码组织来看,DeepEP 的核心由 C++/CUDA 层和 Python 层组成:
-
C++/CUDA 层(见
csrc/deep_ep.cpp
,csrc/deep_ep.hpp
等)- 通过 pybind11 将核心通信操作和内存管理封装为 Python 可调用接口。
- 借助 NVSHMEM 以及 cudaIpc 等机制,实现了在 GPU 间共享或跨节点的高带宽/低延迟数据交换。
- 引入了
Buffer
类(deep_ep::Buffer
)来统一管理通信流、FIFO 任务队列、本地和 RDMA 缓冲区,以及 CPU 端用作监控的计数器等。
-
Python 层(见
deep_ep/buffer.py
、deep_ep/utils.py
等)- 提供了易于集成的高级接口,包括常见的
dispatch
、combine
函数,屏蔽了底层通信细节。 - 定义了
Buffer
(Python 版本)的封装类,在初始化时,根据用户参数分配 NVLink 或 RDMA 等所需的通信内存,并与底层 C++/CUDA 组件完成同步。 - 提供了
set_num_sms
等配置接口,让使用者可根据集群的 SM 资源进行性能调优。
- 提供了易于集成的高级接口,包括常见的
整体而言,DeepEP 代码的核心流程是:
- 在 Python 层初始化
Buffer
对象,并根据需求传入num_nvl_bytes
,num_rdma_bytes
等参数。 - 在 C++ 层的
Buffer
构造函数中,申请 GPU 上/跨节点的通信内存(比如通过cudaMalloc
或 NVSHMEM)。 - 使用
sync
等接口,完成进程间、设备间的句柄交换与通信初始化。 - 在分发/聚合等函数(例如
intranode_dispatch
,internode_dispatch
)中,启动对应的 kernel 执行,将数据在不同 GPU 或节点之间搬运。 - 在低时延场景下,通过
low_latency_dispatch
与low_latency_combine
走一条更轻量的 RDMA 通道,牺牲一定带宽以换取显著的端到端延迟优势。
2. 核心类与重要函数
下面以 deep_ep::Buffer
类中的部分函数为例,简要概括其功能。
(1)构造与销毁:Buffer::Buffer(...)
与 Buffer::~Buffer()
Buffer::Buffer