HCCL 集成 PyTorch 分布式后端:Ascend NPU 上 AllReduce 实战指南
2026/9/18 20:56:45 网站建设 项目流程

HCCL 集成 PyTorch 分布式后端:Ascend NPU 上 AllReduce 实战指南

【免费下载链接】hccl集合通信库(Huawei Collective Communication Library,简称HCCL)是基于昇腾AI处理器的高性能集合通信库,为计算集群提供高性能、高可靠的通信方案项目地址: https://gitcode.com/cann/hccl

本文基于 HCCL 仓库中的 PyTorch AllReduce 示例(examples/03_ai_framework/01_pytorch),讲解如何在单机多卡昇腾 NPU 环境下,通过torch.distributed指定hccl后端完成集合通信。读完本文,你可以完整理解该示例从设备探测、多进程拉起、通信域初始化到dist.all_reduce()下发 AllReduce 算子的全流程,并掌握HCCL_OP_EXPANSION_MODE等关键配置项的使用方法,从而将 HCCL 作为标准分布式后端接入自己的 PyTorch 训练代码。

一、背景:HCCL 如何接入 PyTorch

根据 主流框架集成文档,HCCL(Huawei Collective Communication Library)是面向昇腾 AI 处理器的高性能集合通信库。AI 框架主要有单算子模式、图模式(Ascend IR)和图捕获模式(aclgraph)三种编程执行形态,HCCL 均提供对应工作方式。针对 PyTorch 与 MindSpore,HCCL 的调用已集成到 TorchNPU 插件代码中:开发者只需在框架 API 中指定使用 HCCL 作为分布式后端,直接使用框架原生通信 API(如torch.distributed)即可实现分布式能力,无需手写 HCCL C 接口调用。

这一点在示例代码 hccl_pytorch_allreduce_test.py 中体现得非常直接——全部通信逻辑只有三行框架代码,而通信域初始化、算子编排、结果校验等底层工作均由torch_npu插件桥接到 HCCL 完成。

二、样例能力说明

本样例展示如何使用 PyTorch 接口执行 AllReduce 操作,覆盖以下四个功能点:

步骤使用的接口说明
设备检测torch_npu.npu.device_count()查询当前可用的 NPU 数量,作为进程数与 world_size
多进程拉起torch.multiprocessing.spawn()按卡数启动 N 个进程,每个进程负责一张 NPU
通信域初始化torch.distributed.init_process_group()指定backend="hccl"初始化进程组(通信域)
集合通信torch.distributed.all_reduce()执行 AllReduce 求和归约

三、环境准备

3.1 环境要求

该样例支持以下产品,组网要求为单机 N 卡(N ≥ 2)

  • Ascend 950PR / Ascend 950DT
  • Atlas A3 训练系列产品 / Atlas A3 推理系列产品
  • Atlas A2 训练系列产品
  • Atlas 训练系列产品
  • Atlas 推理系列产品

Python 侧依赖两个包:

  • torch:PyTorch 深度学习框架,提供torch.distributedtorch.multiprocessing等分布式能力;
  • torch_npu:PyTorch 的昇腾 NPU 适配插件,HCCL 通过该插件接入 PyTorch 的分布式后端。

3.2 配置环境变量

运行前需加载 CANN 环境变量(以 root 用户默认安装路径为例):

# 设置 CANN 环境变量 source /usr/local/Ascend/cann/set_env.sh

四、示例代码逐行解析

完整代码见 hccl_pytorch_allreduce_test.py,核心结构如下:

4.1 主进程:设备探测与多进程拉起

def main(): print("Executing AllReduce collective operation via HCCL backend") ip = "127.0.0.1" port = 50001 print("Listening on %s:%d" % (ip, port)) rank_size = torch_npu.npu.device_count() # 查询可用 NPU 数量 print("Available NPU count: %d" % rank_size) # 启动多进程,每个进程绑定一张卡 mp.spawn(run_hccl, args=(rank_size, ip, port), nprocs=rank_size, join=True)

要点说明:

  • torch_npu.npu.device_count()返回本机可用 NPU 数,同时用作nprocs(进程数)和world_size(通信域大小),天然保证“一进程一卡”;
  • mp.spawn(..., join=True)为阻塞调用,主进程会等待所有子进程执行完毕后再返回,这保证了进程退出顺序清晰,便于调试;
  • 127.0.0.1:50001是单机场景下torch.distributed的 rendezvous 地址。扩展到多机训练时,可将ip替换为各节点可达的 master 地址。

4.2 子进程:设备绑定、通信域初始化与 AllReduce

def run_hccl(rank: int, world_size: int, master_ip: str, master_port: int): # 指定当前进程使用的 NPU 设备 torch_npu.npu.set_device(rank) # 初始化进程组,后端使用 HCCL init_method = f"tcp://{master_ip}:{master_port}" dist.init_process_group( backend="hccl", rank=rank, world_size=world_size, init_method=init_method ) # 构造输入数据,1行8列,值为0~7 torch_tensor = torch.arange(world_size, dtype=torch.float32, device="npu") print("[Rank %d] Input: %s" % (rank, torch_tensor)) try: # 调用 HCCL 接口,下发 AllReduce 集合通信算子 dist.all_reduce(torch_tensor, op=dist.ReduceOp.SUM) except Exception as e: print("[Rank %d] Error occurred: %s" % (rank, e)) else: print("[Rank %d] Output: %s" % (rank, torch_tensor))

从框架 API 到 HCCL 接口的映射关系如下,可与 HCCL 原生 C 示例 examples/02_collectives/01_allreduce/main.cc 对照理解:

框架侧调用底层对应的 HCCL 能力说明
torch_npu.npu.set_device(rank)aclrtSetDevice将当前进程绑定到指定 NPU
dist.init_process_group(backend="hccl", ...)HcclGetRootInfo+HcclCommInitRootInfo生成 RootInfo 并初始化通信域(HcclComm),由插件代业务完成
dist.all_reduce(tensor, op=SUM)HcclAllReduce(sendBuf, recvBuf, count, FP32, HCCL_REDUCE_SUM, comm, stream)在任务流上异步下发 AllReduce 算子,并在框架侧同步等待完成
mp.spawn/ 进程退出HcclCommDestroy+aclrtFree通信域与 Device 内存由插件在进程生命周期结束时释放

其中HcclAllReduce的接口签名、缓冲区对齐要求及“注册对称内存后 sendBuf 可能被就地修改”等使用约束,可参见 HcclAllReduce 接口文档。

代码中值得注意的实现细节:

  • 输入张量直接创建在 NPU 上torch.arange(world_size, dtype=torch.float32, device="npu")避免了 Host→Device 拷贝,每个 rank 的输入为[0., 1., 2., ..., 7.](8 个 float32 元素);
  • 异常隔离try/except包裹all_reduce调用,单个 rank 通信失败时打印错误而不影响其他 rank 的日志输出,方便定位问题;
  • world_size 与数据长度一致:这里torch.arange(world_size, ...)使张量长度等于卡数(如 8 卡即 8 个元素),与结果示例中“0~7 初始化、求和后为 0~56”完全对应。

五、运行样例与配置展开模式

5.1 运行

python hccl_pytorch_allreduce_test.py

5.2 可选:配置通信算子展开模式HCCL_OP_EXPANSION_MODE

可通过HCCL_OP_EXPANSION_MODE环境变量配置通信算子的展开模式(即通信算子在哪个执行单元上展开执行),不同产品支持的取值不同。以 HCCL_OP_EXPANSION_MODE 环境变量文档 为准,各产品典型取值如下:

产品默认值支持的主要取值
Ascend 950PR / 950DTAICPU_TSAI_CPU(后续版本废弃,由AICPU_TS替代)、AICPU_TSAICPU_CacheDisableAIVCCU_MSCCU_SCHED
Atlas A3 训练/推理系列AI_CPUAI_CPUAICPU_CacheDisableAIV
Atlas A2 训练/推理系列HOSTHOSTHOST_TSAI_CPU(仅 AllGather/AlltoAll 系算子)、AIV
Atlas 300I Duo 推理卡HOSTHOSTAI_CPU(仅 AllReduce,单机单通信域)

配置示例:

# 设置通信算子的展开模式为AI CPU通信引擎 export HCCL_OP_EXPANSION_MODE=AI_CPU

使用注意(摘自环境变量文档的使用约束):

  • 若通过 HCCL C 接口以HcclCommConfighcclOpExpansionMode参数按通信域粒度配置了展开模式,则通信域粒度配置优先于环境变量
  • 图模式(Ascend IR)或图捕获(aclgraph)场景下,通信算法采用 AI CPU 模式时,单卡上的并发图数量不能超过 6 个,否则可能因 AI CPU 核被占满而导致通信阻塞;
  • AIV模式仅支持对称组网、推理特性,不支持多通信域并行场景,且部分算子在数据量超过一定阈值时系统会自动切换为AI_CPU模式,具体算子与数据类型支持范围请以该环境变量文档为准;
  • AICPU_CacheDisable用于关闭 AI CPU cache(同一通信算子二次执行时复用首次展开结果的特性),适合通信数据量频繁变化的服务场景以降低显存开销。

六、运行结果与验证

每个 rank 的数据初始化为 0~7,经过 AllReduce(求和)操作后,每个 rank 的结果是所有 rank 对应位置数据的和(以 8 卡为例,即 8 份数据相加,第 i 个元素结果为 8i):

[Rank 0] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:0') [Rank 1] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:1') [Rank 2] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:2') [Rank 3] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:3') [Rank 4] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:4') [Rank 5] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:5') [Rank 6] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:6') [Rank 7] Input: tensor([0., 1., 2., 3., 4., 5., 6., 7. ], device='npu:7') [Rank 0] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:0') [Rank 1] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:1') [Rank 2] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:2') [Rank 3] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:3') [Rank 4] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:4') [Rank 5] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:5') [Rank 6] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:6') [Rank 7] Output: tensor([0., 8., 16., 24., 32., 40., 48., 56. ], device='npu:7')

验证方法:若卡数为 N,则每个 rank 的输出张量第 i 个元素应恒等于N × i(0 ≤ i < N),且所有 rank 输出一致。若某个 rank 打印Error occurred,可结合 CANN 日志定位 HCCL 通信域初始化或算子执行阶段的具体报错。

七、延伸阅读与扩展方向

  • C 接口版本对照:不依赖框架、直接调用 HCCL C API 的 AllReduce 单机多卡示例见 examples/02_collectives/01_allreduce(main.cc中展示了aclrtMalloc申请 Device 内存、HcclCommInitRootInfo初始化通信域、HcclAllReduce下发算子、aclrtSynchronizeStream同步等待的完整生命周期),可与本文的 PyTorch 版本逐行对照;
  • TensorFlow 集成:HCCL 通过 TF Adapter 对接 TensorFlow 的调用示例见 examples/03_ai_framework/02_tensorflow;
  • 更多集合通信算子:HCCL 接口文档中还覆盖 Broadcast、AllGather、ReduceScatter、AlltoAll、Scatter、Send/Recv 等算子,见 通信算子接口参考;
  • 环境变量全集:HCCL 各环境变量(如缓冲、超时、确定性计算等)说明见 HCCL 环境变量文档。

将本样例作为最小可运行基线,即可在自有 PyTorch 分布式训练中通过init_process_group(backend="hccl")直接获得 HCCL 的集合通信能力。

【免费下载链接】hccl集合通信库(Huawei Collective Communication Library,简称HCCL)是基于昇腾AI处理器的高性能集合通信库,为计算集群提供高性能、高可靠的通信方案项目地址: https://gitcode.com/cann/hccl

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询