DeepEP 通信库使用指南(v2.1)

更新时间:
复制为 MD 格式

1.介绍

PPU DeepEP 是一款专为 PTG PPU 系列产品定制的通信库。它源自开源的 DeepSeek DeepEP,并针对 PPU 硬件架构进行了深度适配与优化。由于该库的 Python 与 C++ 编程接口(API)均有变更,因此上层计算框架需进行相应适配后方可使用。

1.1 适配现状以及使用说明

目前 PPU DeepEP 通信库只适用于 平头哥 PPU 相关产品系列,具体包括:

  • 真武810E

  • 单机内部 PPU 卡间仅支持自研通信协议 ICN Link

  • 多机之间支持业界标准的 Mellanox CX6/CX7 RDMA 网卡

1.1.1 网卡 Affinity 设定

说明

该配置在 DeepEP 版本 1.5.2 之后不需要额外设置,内部会自动检测 affinity 网卡并使用。

由于真武 810E PPU 和 NIC 并不是 1 比 1 配置,导致部分没有 PIX 网卡的 PPU 在使用网卡时会选择其他 NODE 关系的网卡,导致性能不佳, 对此我们调整为基于 nvml 映射关系的设定,目前是通过环境变量固化配置,后续会自动检测并绑定!如果是直接基于 Python buffer.py 开发和使用,可以不用感知此改动,若是适配 C++ 接口则当下需显式设置环境变量以达到理想性能。

if nvml_device_index // 4 == 0:
	os.environ['NVSHMEM_HCA_LIST'] = 'mlx5_bond_4:1'
if nvml_device_index // 4 == 1:
	os.environ['NVSHMEM_HCA_LIST'] = 'mlx5_bond_2:1'
if nvml_device_index // 4 == 2:
	os.environ['NVSHMEM_HCA_LIST'] = 'mlx5_bond_3:1'
if nvml_device_index // 4 == 3:
	os.environ['NVSHMEM_HCA_LIST'] = 'mlx5_bond_1:1'

1.1.2 Native API 修改

原生 DeepEP 固定只支持机内 NUM_MAX_NVL_PEERS 个 Ranks 的通信规模,为了更加灵活的支持不同配置场景,我们在 Native (CPP) 层做了 API 的修改,新增了 local_ranks 的参数,用于表示机内参与通信的 PPU 数量,它可以是最大 16 PPUs 或者 8 PPUs。

Buffer(int rank, int local_ranks, int num_ranks, int64_t num_nvl_bytes, int64_t num_rdma_bytes, bool low_latency_mode, bool use_nvshmem_transport);
说明

Python 文件 buffer.py 里面自动检测机内规模大小,并传递给 Native Buffer 类,所以如果是基于 buffer.py 的使用,就不需要感知此改动。

1.1.3 功能增强以及扩展

功能名称

功能描述

支持版本

Hidden Size 扩展

支持 Hidden Size 2048

1.7

支持 Hidden Size 8192

1.7

Intranode CUDA Graph

支持 CUDA graph 模式下的 intranode kernel

1.7

Load Balance 监控

low latency dispatch 阶段,累计每个 Experts 的 token 总量,用户可以监控 Experts 的负载均衡情况

1.7

诊断功能

支持 low latency dispatch & combine 的等待时间检测,精准定位通信过程中的具体哪些 PPU 卡存在通信性能问题

1.7

UE8M0 数据格式支持

支持 low latency dispatch 阶段的 UE8M0 数据格式

1.7

支持 TopK 10

支持 low latency topk 10 的场景

2.0

支持用户自定义 timeout 时间

支持用户自定义 timeout 时间,防止 GeMM warmup 耗时长导致的超时

2.0

low latency dispatch & combine 量化支持

low latency dispatch 支持 mxfp4 量化,low latency combine 支持 int8/fp8 量化

2.1

intranode & internode dispatch支持uint8类型scale

intranode & internode dispatch 支持 uint8 类型 scale 传输,以支持 mxfp4 量化场景

2.1

internode cuda graph 支持

支持 internode kernel cuda graph 模式

2.1

Hidden Size 扩展

支持 GLM & MiniMax 模型参数配置,hidden 3072 & 6144

2.1

Low Latency Combine SBO 支持

支持 Single Batch Overlap,配合 Gemm 做 Overlap 计算和通信功能

2.1

1.1.4 Python API 扩展

API 名称

API 描述

支持版本

low_latency_dispatch

新增 cumulative_local_expert_recv_stats 参数用于统计每个 Expert 累计的 token 数量,用于 load blance 的监控

1.7

low_latency_dispatch

新增 round_scale 和 use_ue8m0 参数用于支持 dispatch 阶段的 UE8M0 数据格式

1.7

get_comm_stream

获取 deepEP 当前通信的 Stream

1.7

combine

新增 bias Tensor,用于 Combine 阶段的 bias 累计操作

1.7

low_latency_dispatch

新增参数 dispatch_wait_recv_cost_stats 用于统计从每个 Rank wait token 的时间

1.7

low_latency_combine

新增参数 combine_wait_recv_cost_stats 用于统计从每个 Rank wait token 的时间

1.7

set_timeout_seconds

设置 dispatch/combine 的 timeout 时间检查

2.0

low_latency_dispatch

新增参数 use_mxfp4 用于支持 mxfp4 量化

2.1

low_latency_combine

新增 Combine int8/fp8,以及 quant size 量化参数

2.1

internode_dispatch

新增 num_worst_tokens 参数用于支持 cuda graph

2.1

1.1.5 环境变量

环境变量名称

环境变量描述

支持版本

DEEPEP_DISABLE_NETWORK

用于 ICN64 环境下,当网卡环境不 Ready 时,Disable 网络相关的初始化,确保只走 ICN Link 也可以正常工作。

2.1

DEEPEP_TIMEOUT_SECONDS

在端到端场景下,Sglang 推理 warm up 阶段,Gemm 编译耗时很长,导致通信的 kernel wait 时间过长引起 默认 timeout crash,配置该参数可以确保超时时间足够长。

2.1

1.2 Internode Kernel

用户使用时可以用环境变量DEEPEP_INTERNODE_TRANSPORT_MODE 来指定不同的模式。目前支持以下两种模式,默认模式是 1。

  • DeepEP defined ibgda 模式:该模式使用 DeepEP 自定义的 ibgda path,性能更好,但在跑四机/八机的长 sequences 比如 16K 及以上时,压测仍会有 random hang 的问题,尚在定位。

    • 使用方式:在每个node上配置环境变量。export DEEPEP_INTERNODE_TRANSPORT_MODE=0

  • native shmem ibrc 模式:默认模式,全部使用 shmem native api,走 ibrc 分支。两机情况下性能较好。

    • 使用方式:在每个node上配置环境变量。export DEEPEP_INTERNODE_TRANSPORT_MODE=1

1.3 Low Latency Kernel

1.3.1 Int8 量化支持

从 1.6.0 开始 Low Latency Dispatch 支持 Int8 量化,对应的 API 也有所修改, 无论是 Python 还是 C++ 层面都新增了两个参数:

bool use_int8 :表示是否开启使用 Int8 量化。

int quant_size:表示 quant 的范围,目前支持 Group 和 Channel 模式:

  1. Group 模式就是原生自带的 128 大小,以 128 为 Group 进行量化处理,此时 quant_size 等于 128。

  2. Channel 模式就是以 token 为单位进行量化,此时 quant_size 为 hidden_size 大小。

从 2.1 版本开始,APIs 参数进一步扩展,支持 Dispatch mxfp4 量化,以及 Combine int8/fp8 量化。

low_latency_dispatch(const torch::Tensor& x, const torch::Tensor& topk_idx,
                      const std::optional<torch::Tensor>& cumulative_local_expert_recv_stats,
                      const std::optional<torch::Tensor>& dispatch_wait_recv_cost_stats,
                      int num_max_dispatch_tokens_per_rank, int num_experts,
                      bool use_fp8, bool round_scale, bool use_ue8m0, bool use_mxfp4,
                      bool async, bool return_recv_hook, bool use_int8, int quant_size);

low_latency_combine(const torch::Tensor& x, const torch::Tensor& topk_idx, 
                    const torch::Tensor& topk_weights,
                    const torch::Tensor& src_info, const torch::Tensor& layout_range,
                    bool overlap, const std::optional<torch::Tensor>& packed_recv_count,
                    const std::optional<torch::Tensor>& comp_signal, int block_m, int threshold, 
                    int num_sms, const std::optional<torch::Tensor>& combine_wait_recv_cost_stats,
                    int num_max_dispatch_tokens_per_rank, int num_experts,
                    bool zero_copy, bool async, bool return_recv_hook,
                    bool use_fp8, bool round_scale, bool use_int8, int quant_size,
                    const std::optional<torch::Tensor>& out = std::nullopt);
def low_latency_dispatch(self, x: torch.Tensor, topk_idx: torch.Tensor,                                
                         num_max_dispatch_tokens_per_rank: int, num_experts: int,
                         cumulative_local_expert_recv_stats: Optional[torch.Tensor] = None,
                         dispatch_wait_recv_cost_stats: Optional[torch.Tensor] = None,
                         use_fp8: bool = False, round_scale: bool = False, use_ue8m0: bool = False,                               use_mxfp4: bool = False,
                         async_finish: bool = False, return_recv_hook: bool = False,
                         use_int8: bool = False, quant_size: int = 128)

def low_latency_combine(self, x: torch.Tensor, topk_idx: torch.Tensor, topk_weights: torch.Tensor,
                        handle: tuple, overlap: bool = False, packed_recv_count: torch.Tensor = None,
                        comp_signal: torch.Tensor = None, block_m: int = 64, threshold: int = 0,
                        num_sms: int = 3, zero_copy: bool = False, async_finish: bool = False,
                        return_recv_hook: bool = False, out: Optional[torch.Tensor] = None,
                        combine_wait_recv_cost_stats: Optional[torch.Tensor] = None,
                        use_fp8: bool = False, round_scale: bool = False,
                        use_int8: bool = False, quant_size: int = 128)

1.3.2 默认 Enable ICN Link

从 1.6.0 版本开始,deepEP 默认打开 ICN Link,用户可以通过 allow_nvlink_for_low_latency_mode 修改设定。

def __init__(self, group: dist.ProcessGroup,
              num_nvl_bytes: int = 0, num_rdma_bytes: int = 0,
              low_latency_mode: bool = False, num_qps_per_rank: int = 12,
              allow_nvlink_for_low_latency_mode: bool = True,
              explicitly_destroy: bool = False)

1.3.3 MXFP4 量化支持

2.1.0开始,Low Latency Dispatch 支持 MXFP4 量化,对应的 API 也有所修改,无论是 python 还是 C++ 层面都新增了一个参数:

bool use_mxfp4:表示是否开启使用 MXFP4 量化,只支持quant_size32。

1.4 开源框架调用说明

部分开源框架(例如vllm)调用DeepEP对外接口时,每个进程只能访问一张卡(cudaGetDeviceCount结果为1),这种情况下如果通过如下方式

deep_ep::Config::get_nvl_buffer_size_hint 来获取 num_nvl_bytes,以及使用 deep_ep::Config::get_rdma_buffer_size_hint 获取 num_rdma_bytes 作为Buffer的初始化参数,需要额外配置export DEEPEP_NUM_MAX_ICN_PEERS=num_local_ranks(单节点卡数)。

def get_buffer(group: dist.ProcessGroup, hidden_bytes: int) -> Buffer:
    global _buffer

    # NOTES: you may also replace `get_*_config` with your auto-tuned results via all the tests
    num_nvl_bytes, num_rdma_bytes = 0, 0
    for config in (Buffer.get_dispatch_config(group.size()), Buffer.get_combine_config(group.size())):
        num_nvl_bytes = max(config.get_nvl_buffer_size_hint(hidden_bytes, group.size()), num_nvl_bytes)
        num_rdma_bytes = max(config.get_rdma_buffer_size_hint(hidden_bytes, group.size()), num_rdma_bytes)

    # Allocate a buffer if not existed or not enough buffer size
    if _buffer is None or _buffer.group != group or _buffer.num_nvl_bytes < num_nvl_bytes or _buffer.num_rdma_bytes < num_rdma_bytes:
        _buffer = Buffer(group, num_nvl_bytes, num_rdma_bytes)
    return _buffer

2.安装

2.1 whl 包安装

PPU DeepEP 通信库发布形式为 tar 压缩包,里面是 DeepEP whl 包。

参考下面指令便可以快速安装 DeepEP 通信库(以 1.5.2 版本为例,镜像为 pytorch:2.2-ubuntu22.04-cuda12.3-py310)。若需要下载其他版本的 DeepEP,可以提相关需求给到我们。

Note: 从 PPU SDK v1.5.2 release 开始,sailSHMEM 将随 SDK 一起发布,位置在 PPU_SDK/sailSHMEM 下,用户可以不用手动进行下载。

# 该地址为 1v5_release 最新版本的 DeepEP
wget http://ai-artifactory-pub.eng.t-head.cn:9000/artifactory/generic-local/PPU1.0/v1.5.2/Framework/DeepEP/DeepEP.tar.gz  

# 1.5 版本之后,发布路径有变更, 具体如下:
wget https://art-pub.eng.t-head.cn/artifactory/generic-local/SAIL/v2.0.0/Framework/PyTorch/deep_ep-1.0.0-oe-cuda12.9-pytorch2.8.0-ubuntu2404-py312.tar.gzhttps://art-pub.eng.t-head.cn/artifactory/generic-local/SAIL/v2.0.0/Framework/PyTorch/deep_ep-1.0.0-oe-cuda12.9-pytorch2.8.0-ubuntu2404-py312.tar.gz

tar -xvf DeepEP.tar.gz

pip install deep_ep*.whl

# PPU_SDK 路径请根据环境实际情况配置
export LD_LIBRARY_PATH=/usr/local/PPU_SDK/sailSHMEM/lib:$LD_LIBRARY_PATH
export NVSHMEM_DIR=/usr/local/PPU_SDK/sailSHMEM

从 2.1 Release 开始,DeepEP whl 包的发布会自带 sailSHMEM 相关依赖的 libs,所以不再需要单独配置 sailSHMEM 的路径。

2.2 源码安装

如果没有符合要求的 whl 包,DeepEP 也支持直接通过源码安装,具体步骤可以参考如下:

  1. 下载 DeepEP 源码。

    git clone http://gitlab.alibaba-inc.com/ppu_open_source/DeepEP.git -b release
  2. 配置 NVSHMEM_DIR 环境变量为 SDK 下的 sailSHMEM 路径。

    # PPU_SDK 路径请根据环境实际情况配置
    source /usr/local/PPU_SDK/envsetup.sh
    export LD_LIBRARY_PATH=/usr/local/PPU_SDK/sailSHMEM/lib:$LD_LIBRARY_PATH
    export NVSHMEM_DIR=/usr/local/PPU_SDK/sailSHMEM
  3. 进入 DeepEP 源码目录进行编译安装。

    cd DeepEP
    python setup.py build
    python setup.py install
  4. 运行测试用例验证是否安装成功。

    python tests/test_intranode.py
    python tests/test_low_latency.py

2.3 PiP 包编译和安装

1.6.0 之前,DeepEP 的编译和安装方式是以 egg 方式管理的,属于比较老的包安装管理方式,在实际测试中我们发现,容易和系统自带的 pip 安装方式冲突,无法覆盖系统现有版本,导致测试故障。

现在统一升级修改为 whl 包编译和安装方式,具体命令如下:

bash ./install.sh