- 高性能计算
- 通信
- 深度学习
- 分布式训练
【免费下载链接】nccl
Optimized primitives for collective multi-GPU communication
本篇技术文章基于 NCCL 仓库中的contrib/nccl_ep/RELEASE.md发布说明展开,系统解读 NCCL EP(Expert Parallelism,专家并行)v0.1 实验性发布的定位:它是在 NCCL Device API 的 LSA(Load-Store Accessible)与 GIN(GPU-Initiated Networking)操作之上构建的 MoE dispatch/combine 通信原语集合。读完后,你将清楚该版本"支持什么、不支持什么"——包括节点/卡数上限、max_tokens_per_rank必填约束、MAX_SUPPORTED_TOKENS_PER_RANK编译期上限、无 FP8 支持等边界——并能结合源码定位这些限制的具体落点,以及用ep_test/ep_bench/ 单元测试进行验证的方法。
NCCL EP 是什么:发布背景与版本定位
NCCL EP 是 NCCL 的高性能 API 扩展,面向 Mixture-of-Experts(MoE)通信场景,提供跨分布式 GPU 系统的专家并行(EP)优化原语,核心是统一的ncclEpDispatch与ncclEpCombine两个操作。它构建在 NCCL Device API 之上:用 GIN 的put/signal操作承载 RDMA 路径、用 LSA load/store 操作承载 NVLink 路径,使关键路径上不依赖 CPU 参与。
从 include/nccl_ep.h 中的版本宏可以确认,当前发布对应v0.1(NCCL_EP_MAJOR 0 / NCCL_EP_MINOR 1 / NCCL_EP_PATCH 0,打包版本码NCCL_EP_VERSION_CODE = MAJOR*10000 + MINOR*100 + PATCH),API 特性版本为NCCL_EP_API_VERSION = 1。该构建体系由 Makefile 直接解析这三个宏来生成libnccl_ep.so.MAJOR.MINOR.PATCH,因此版本号与发布说明所述 release 严格对应。
v0.1 提供两种面向不同负载特征的通信算法(见 README):
- Low-Latency(LL)模式:面向小批量、延迟敏感的推理负载,采用到专家的点对点 all-to-all 通信;
- High-Throughput(HT)模式:面向训练与大批量 prefill,采用分层通信——节点内聚合走 NVLink、节点间走 RDMA,并利用 Hopper 架构特性(warp-specialized 流水线、TMA 操作)。
RELEASE.md 的定性非常明确:这是一个实验性(experimental)发布,QA 覆盖有限。以下各节逐条解析发布说明中的"Known Limitations"表,并给出源码中的对应证据。
已知限制(Known Limitations)逐条解析
发布说明以表格形式列出了 v0.1 的全部已知限制。下表完整继承原文档内容,并补充每条限制在仓库中的落点:
| 限制 | 说明 | 仓库中的对应证据 |
|---|---|---|
| Limited QA coverage | 该发布被视为实验性版本,QA 测试有限 | tests/ 目录的覆盖面(见下文) |
| No FP8 support | 当前不支持 FP8 数据类型 | ep_enums.h 等公开头文件仅面向 BF16 等工作负载说明;内部 FP8 原语未对 API 开放(见下文分析) |
| Fabric selection | 当前 API 版本不提供强制走 RDMA-only 通信的方式 | 无对应配置项(见 nccl_ep.h 中ncclEpGroupConfig_t字段清单) |
| Up to 8 nodes | 最多支持 64 GPU(8 节点 × 8 GPU) | nccl_ep.cc 中基于rdma_team_size/lsa_team_size的团队语义与内部缓冲按节点数伸缩 |
| Up to 8 ranks per node | 每节点最多 8 GPU | 同上,gpus_per_node = nRanks / nNodes推导逻辑 |
| max_tokens_per_rank required | NCCL_EP_AUTO尚不支持;max_tokens_per_rank必须设置为单 rank 的批大小(任何单个 rank 将 dispatch 的最大 token 数) | nccl_ep.cc 中的断言 |
| Max Num Tokens Support | HT 内核当前使用common.h中定义的MAX_SUPPORTED_TOKENS_PER_RANK宏 | include/common.hpp,当前值为 8192 |
| HT mode performance | HT 模式正在调优,本版本可能表现出次优结果 | 定性说明,无源码落点 |
下面对其中与开发者最相关的几条展开。
限制一:HT 模式必须显式设置 token 上限(NCCL_EP_AUTO尚不可用)
发布说明指出:NCCL_EP_AUTO尚未支持,max_tokens_per_rank必须设置为"该 rank 将 dispatch 的最大 token 数"(即 per-rank 批大小的上界)。
源码可以直接印证这一约束。在 nccl_ep.cc 的ncclEpCreateGroup()参数校验中:
- LL 模式要求
max_dispatch_tokens_per_rank > 0(断言信息:"max_dispatch_tokens_per_rank must be greater than 0 for low latency mode"); - HT 模式同样要求该字段非零("must be set for HT backend"),且不得超过编译期上限(见下节);
- HT 模式还额外要求
max_recv_tokens_per_rank > 0且>= max_dispatch_tokens_per_rank(nccl_ep.cc#L1331-L1336)。
README 中对 HTNCCL_EP_LAYOUT_FLAT布局的说明也印证了这一点:v0.1 只支持"静态分配"(N(r) = num_ranks * max_dispatch_tokens_per_rank),而"先查询再分配"的动态模式(依赖max_dispatch_tokens_per_rank = NCCL_EP_AUTO与recv_total_counter)被明确标注为PLANNED, NOT YET SUPPORTED IN v0.1。
实践含义:HT 模式下你无法把 buffer 尺寸完全交给库自动推导,必须按最坏路由情况预置 slot 预算;LL 模式下max_recv_tokens_per_rank可留 0(NCCL_EP_AUTO),库会自动按nRanks * max_dispatch_tokens_per_rank推导(见 nccl_ep.h 的字段注释)。
限制二:MAX_SUPPORTED_TOKENS_PER_RANK是 HT 模式的编译期硬上限
发布说明特别指出:HT 内核当前使用配置在common.h中的宏MAX_SUPPORTED_TOKENS_PER_RANK来决定"最多支持多少 token"。该宏实际定义在 include/common.hpp:
#define MAX_SUPPORTED_TOKENS_PER_RANK 8192 // Must match kernel template in hybridep_adapter.cu #define FINISHED_SUM_TAG (MAX_SUPPORTED_TOKENS_PER_RANK * 2) #define HT_OF_NUM_TOKENS_PER_CHUNK 64从源码结构看,这个常量深度参与了 HT 模式的内存布局与内核行为:
- 组创建期校验:nccl_ep.cc#L1253-L1255 断言 HT 模式下
max_dispatch_tokens_per_rank不得超过MAX_SUPPORTED_TOKENS_PER_RANK,越界即触发 "HT max_dispatch_tokens_per_rank exceeds build-time MAX_SUPPORTED_TOKENS_PER_RANK"; - RDMA 缓冲以该常量定容:nccl_ep.cc#L953-L961 中,节点间聚合缓冲按
MAX_SUPPORTED_TOKENS_PER_RANK * (rdma_team_size - 1)的 stride 分配(内核侧用rdma_remote_node_id * MAX_SUPPORTED_TOKENS_PER_RANK + token_offset寻址),分块调度也按MAX_SUPPORTED_TOKENS_PER_RANK / HT_OF_NUM_TOKENS_PER_CHUNK计算每 rank 的最大 chunk 数; - 内核模板参数:该常量被原样传给 device/hybridep_adapter.cu 中
d_model.max_num_of_tokens_per_rank,并通过 JIT 模板 device/jit/dispatch_jit.cuh / device/jit/combine_jit.cuh 注入到 JIT 编译的 dispatch/combine 内核中; - 位宽约束:device/hybrid_ep.cuh#L168-L170 用
static_assert保证该常量能塞进em_s2d槽位域,且不与-1哨兵值冲突。
实践含义:如果你的 per-rank 批大小超过 8192 token,HT 模式在当前发布中无法直接承载,只能走 LL 模式或减小每 rank token 数;该值属于"构建期常量"(注释要求与hybridep_adapter.cu的内核模板保持一致),不是运行时可调参数。
限制三:FP8 不在本版本的 API 支持范围内
发布说明声明"FP8 data types are not currently supported"。从源码结构看,这一限制需要加一个注脚:库内部已经存在 FP8 相关基础设施——device/device_primitives.cuh#L122-L136 提供了 E4M3 格式的 FP8 scale 计算(kFinfoAmaxE4M3 = 448.0f、calculate_fp8_scales),device/low_latency.cu#L105-L153 中 LL 内核通过kUseFP8模板参数支持"BF16 在发送侧量化为 FP8"的路径,device/hybridep_adapter.cu 也保留了use_fp8参数。但对外 API 层面,公开头文件的张量描述以 BF16 类工作负载(max_token_bytes按 bf16 最坏情况定容)为基准,且 device/hybridep_adapter.cuh#L337 有明确注释"HT combine doesn't support FP8, only BF16"。因此发布说明的结论成立:当前版本用户不应指望通过ncclEpDispatch/ncclEpCombine直接获得 FP8 张量端到端支持,内部的 FP8 路径更多是后续扩展的地基。
限制四:拓扑上限——8 节点、每节点 8 GPU
发布说明将规模上限锁定为8 节点 × 8 GPU = 64 GPU。实现侧的证据:
- nccl_ep.cc#L1318-L1327 通过 allgather 主机名去重统计
nNodes,再计算gpus_per_node = nRanks / nNodes(L1410),HT 模式要求rdma_team_size * lsa_team_size == nRanks(L1429),即"节点间 rail 团队 × 节点内 LSA 团队"的双层结构; - include/common.hpp#L18 定义了
NUM_MAX_RDMA_PEERS 20,从源码结构看,这是内部对 RDMA peer 数量的容量预留,与发布说明"最多 8 节点"的对外边界共同构成该版本的规模约束(对外文档以 8 节点/64 GPU 为准)。
实践含义:跨 9 个节点以上的 EP 部署在当前版本不受支持;单节点超过 8 卡的机型(如单机 16 GPU)同样超出边界。
限制五:API 无法强制 RDMA-only 通信
发布说明指出当前 API 版本不提供强制 RDMA-only 通信的方式,即没有"fabric selection"开关。核对 nccl_ep.h 中ncclEpGroupConfig_t的全部字段(algorithm、num_experts、max_dispatch_tokens_per_rank、max_recv_tokens_per_rank、max_token_bytes、rdma_buffer_size、num_qp_per_rank、num_channels、max_num_sms、alloc、enable_mask、timeout_ns),确实不存在网络介质选择项。HT 模式的"节点内 NVLink + 节点间 RDMA"分层由库根据拓扑(ncclTeamLsa/ncclTeamRail)内部决定;LL 模式的多机路径则依赖 GIN。对于有严格网络介质要求的场景(例如必须全 RDMA),当前版本只能接受库的默认行为。
限制六:HT 模式性能仍在调优
发布说明坦承 HT 模式"正在为性能调优,本版本可能表现出次优结果"。这与 HT 实现的技术复杂度一致:它涉及节点内 mega-buffer 统一分配(nccl_ep.cc#L687)、RDMA 节点间分组标志位、以及按 device/jit/ 目录做运行时 JIT 编译的内核体系。因此在做性能评估时,应把 HT 模式的数字视为"参考基线"而非"承诺值";需要微基准时可以使用随构建产出的ep_bench工具(下文"验证与复现"节)。
关于实验性定性的旁证:QA 覆盖现状
发布说明称该版本"QA 测试有限"。仓库中 contrib/nccl_ep/tests/ 目录反映了当前的自动化测试面:
- test_lifecycle.cu——组/句柄生命周期;
- test_output_layout.cu——输出布局;
- test_ht_bwd.cu——HT 反向路径;
- test_ht_stale_routing_map.cu——HT 陈旧路由表场景;
- test_handle_maps.cu、test_tensor_create.cu——句柄映射与张量创建。
测试通过 run_tests.sh 驱动。这套用例覆盖了核心正确性路径,但相对一个生产级通信库而言覆盖面有限,与"experimental"定位相符——在生产环境启用前,建议在自己的负载特征(top-k、expert 数、批大小、节点数)上自行回归。
该版本的构建、运行与验证方式
虽然 RELEASE.md 本身不展开构建细节,但理解"哪些东西可以验证"依赖构建产物。以下流程来自 README 与 Makefile,供复现发布说明中的行为边界使用。
依赖与前置条件
| 组件 | 版本 | 说明 |
|---|---|---|
| CUDA | 13+ | 必需(Makefile 对 CUDA 11.8+/12.8+/13 分别配置不同NVCC_GENCODE,最低要求 sm_90) |
| NCCL | 2.29+ | 需带 Device API 与 GIN 支持 |
| MPI | 任意(OpenMPI/MPICH 等) | 多进程启动必需 |
| GPU | Hopper(H100)或 Blackwell | 已测试配置 |
先用nvidia-smi --query-gpu=compute_cap --format=csv探测算力(Hopper 为9.0),然后设置环境:
export COMPUTE_CAP=<discovered compute_cap> export CUDA_HOME=/path/to/cuda export MPI_HOME=/path/to/openmpi export NCCL_HOME=/path/to/nccl/build # 期望的 NCCL 构建目录 export LD_LIBRARY_PATH="${CUDA_HOME}/lib:${CUDA_HOME}/lib64:${CUDA_HOME}/extras/CUPTI/lib64:${NCCL_HOME}/lib:$LD_LIBRARY_PATH" export PATH="${CUDA_HOME}/bin:${NCCL_HOME}/bin:${MPI_HOME}/bin:$PATH"两步构建
# Step 1: 构建带 Device API 支持的 NCCL cd /path/to/nccl-source make -j src.build BUILDDIR=${NCCL_HOME} # Step 2: 构建 NCCL EP 库与测试程序 make -C contrib/nccl_ep MPI=1 BUILDDIR=${NCCL_HOME} \ NVCC_GENCODE="-gencode=arch=compute_${COMPUTE_CAP},code=sm_${COMPUTE_CAP}"构建成功后产出(相对BUILDDIR):lib/libnccl_ep.a、lib/libnccl_ep.so、include/nccl_ep.h、test/nccl_ep/ep_test(覆盖 LL 与 HT 两种模式的测试应用)、test/nccl_ep/ep_bench(两种模式的微基准)。Makefile 中MPI=1才会链接 MPI 构建ep_test/ep_bench;不传MPI=1时目标会被跳过并打印提示。
运行与调试
多机 RDMA 场景推荐设置 GIN 类型:
export NCCL_GIN_TYPE=3 # GDAKI - GPU Direct Async Kernel-Initiated # 调试输出 export NCCL_DEBUG=INFO export NCCL_DEBUG_SUBSYS=ALL验证发布说明中各条限制时,可以按这样的思路:
- token 上限:用
ep_test把max_dispatch_tokens_per_rank调到 8192 以上,预期在ncclEpCreateGroup处触发 HT 断言(nccl_ep.cc#L1253-L1255); NCCL_EP_AUTO不可用:HT 模式下把max_dispatch_tokens_per_rank置 0,预期触发 "must be set for HT backend" 断言;- 节点/卡数边界:在超过 8 节点或单机超过 8 卡的拓扑上启动
ep_test,确认当前版本不予支持; - 性能基线:用
ep_bench采集 LL 模式带宽(README 中给出 H100 平台上 BF16 dispatch/combine 的参考数字,作为对比锚点)。
完整的 LL/HT API 调用示例可参考 ep_test.cu 与 README 中的 "Usage Examples" 章节(HT 前向/反向、LL expert-major/rank-major 两套完整 C 代码)。
v0.1 发布边界速查
把发布说明的已知限制整理为"该版本能做什么 / 不能做什么"的速查清单:
能做的:
- LL 模式(推理)与 HT 模式(训练/prefill)的 dispatch/combine,LL 支持
send_only分阶段执行(配合ncclEpComplete)实现计算-通信重叠; - LL 布局支持
NCCL_EP_LAYOUT_EXPERT_MAJOR/NCCL_EP_LAYOUT_RANK_MAJOR;HT 布局支持NCCL_EP_LAYOUT_FLAT/NCCL_EP_LAYOUT_EXPERT_MAJOR(定义见 include/ep_enums.h); - 自定义设备内存分配器(
ncclEpAllocConfig_t)、LL 模式 RDMA buffer 懒分配/集体扩容(NCCL_EP_AUTO,注意其三个约束见 README 的 "rdma_buffer_size and lazy allocation" 一节); - 最多 8 节点 × 8 GPU(64 GPU)规模。
不能做的(v0.1 边界):
- FP8 数据类型的 API 级支持;
- 强制 RDMA-only 的 fabric 选择;
- HT 模式下
max_dispatch_tokens_per_rank = NCCL_EP_AUTO(动态 token 上限,规划中); - 超过
MAX_SUPPORTED_TOKENS_PER_RANK(当前 8192)的单 rank dispatch 上限(HT 模式); - 9 节点以上规模、单节点 9 卡以上拓扑。
使用时应留意的:
- 实验性定位:自动化测试面(tests/)有限,生产引入前需自行回归;
- HT 模式性能仍在调优,本版本数字可能次优。
参考
- NCCL EP 发布说明
- NCCL EP 完整文档(API Reference / Execution Modes / Usage Examples)
- C API 头文件
- 枚举与布局定义
- 构建配置常量(含 MAX_SUPPORTED_TOKENS_PER_RANK)
- 实现主体
- 单元测试
- 构建系统
- 许可证
- 高性能计算
- 通信
- 深度学习
- 分布式训练
【免费下载链接】nccl
Optimized primitives for collective multi-GPU communication
相关推荐
CANN ops-transformer 算子解析:aclnnMoeDistributeDispatchV2 的 MoE 专家分发、量化与 EP 域 AllToAllV 通信实战
CANN ops transformer 算子解析:aclnnMoeDistributeDispatchV2 的 MoE 专家分发、量化与 EP 域 AllTo
算子库人工智能大模型深度学习CANNAscendCANN ops-transformer 算子详解:aclnnMoeDistributeCombineSetup 专家并行(EP)Combine 侧通信算子
CANN ops transformer 算子详解:aclnnMoeDistributeCombineSetup 专家并行(EP)Combine 侧通信算子 导
算子库人工智能大模型深度学习CANNAscendCollectiveX使用指南:InferenceX如何统一评测DeepEP、MoRI、NCCL EP的MoE通信性能
CollectiveX使用指南:InferenceX如何统一评测DeepEP、MoRI、NCCL EP的MoE通信性能 InferenceX 是开源 AI 推理
人工智能大模型模型评测Agent 评测
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考