HcclReduce 完整指南:多设备数据归约一次讲透
【免费下载链接】runner-imagesGitHub Actions runner images项目地址: https://gitcode.com/GitHub_Trending/ru/runner-images
HcclReduce 是 HCCL(CANN 集合通信库)提供的集合通信算子接口:它把通信域内所有 rank 的数据做归约(相加、相乘、取最大/最小值),归约完成后,结果只送到 root 节点准备好的那块 buffer 里。如果你的任务是在多设备之间做梯度汇总或结果聚合,这就是标准的 Reduce 入口。
它解决什么:多设备数据汇总
分布式训练里,每个 rank(通信域中每个设备进程的唯一编号)手里都持有一份本地数据。但很多步骤要求"所有设备的数据合起来再算",比如把各 rank 的梯度相加,只保留在某个指定设备上继续训练。
如果手写多轮点对点发送、再逐次累加,代码繁琐,通信次数也多。HcclReduce 把这件事压缩成一次集合通信调用:每个 rank 交出 sendBuf,库在设备侧完成数据交换与归约,root(接收结果的那个 rank)的 recvBuf 里拿到最终值。
📌 顺带解释三个高频概念:
- rank:参与通信的设备进程编号,root 就是结果要送往的那个 rank。
- 通信域(HcclComm):一组约定好一起执行集合通信操作的 rank。
- 任务流(stream):本 rank 上执行这条集合通信指令的执行流。
快速上手:HcclReduce 最小调用流程
一次完整的调用分四步:分配 buffer → 初始化通信域与任务流 → 发起调用 → 释放资源。
// 函数原型: // HcclResult HcclReduce(void *sendBuf, void *recvBuf, uint64_t count, // HcclDataType dataType, HcclReduceOp op, // uint32_t root, HcclComm comm, aclrtStream stream); // 1) 分配 Device 侧 buffer:float32,8 个元素 void *sendBuf = nullptr, *recvBuf = nullptr; uint64_t count = 8; size_t bytes = count * sizeof(float); aclrtMalloc(&sendBuf, bytes, ACL_MEM_MALLOC_HUGE_ONLY); aclrtMalloc(&recvBuf, bytes, ACL_MEM_MALLOC_HUGE_ONLY); // 2) 初始化通信域(rankSize 为通信域内 rank 总数),创建任务流 HcclComm hcclComm; HcclCommInitRootInfo(rankSize, &rootInfo, deviceId, &hcclComm); aclrtStream stream; aclrtCreateStream(&stream); // 3) 发起 Reduce:所有 rank 的 sendBuf 相加,结果写入 root 的 recvBuf HcclReduce(sendBuf, recvBuf, count, HCCL_DATA_TYPE_FP32, HCCL_REDUCE_SUM, rootRank, hcclComm, stream); aclrtSynchronizeStream(stream); // 阻塞,等待集合通信执行完成 // 4) 释放资源 aclrtFree(sendBuf); aclrtFree(recvBuf); aclrtDestroyStream(stream); HcclCommDestroy(hcclComm);调用返回HcclResult:成功时是HCCL_SUCCESS,其他值表示失败。集合通信是异步提交到任务流上的,aclrtSynchronizeStream返回之前不能假设结果已就绪。
参数逐个拆解:从 sendBuf 到 stream
- sendBuf(输入):存放本 rank 源数据的 buffer 地址,即参与归约的那块 Device 内存。
- recvBuf(输出):归约结果最终写入的 buffer。root rank 拿到的结果就在其中,其余 rank 无需关注该 buffer 的内容。
- count(输入):参与归约的元素个数,按元素计、不是字节数。只有一个 int32 参与时,count 就是 1。
- dataType(输入):
HcclDataType类型,指定数据的数据类型。各硬件支持哪些类型并不相同,见文末一览表。 - op(输入):
HcclReduceOp类型,归约方式,目前支持 sum、prod、max、min 四种。 - root(输入):结果要送往的 rank id。
- comm(输入):参与本次集合通信的通信域(
HcclComm)。 - stream(输入):本 rank 执行该调用的任务流(
aclrtStream)。
调用前的约束检查清单
⚠️ 这些约束不满足时,这次 Reduce 就很难正常出结果,提交任务前逐项对照:
- 参数全体一致:同一通信域内,所有 rank 传入的 count、dataType、op 三个值必须完全相同。
- 地址对齐:sendBuf 与 recvBuf 都要按 dataType 满足对齐要求——
- int8:1 Byte
- int16、float16、bfp16:2 Byte
- int32、float32:4 Byte
- int64、uint64、float64:8 Byte
- op 与硬件的兼容:Ascend 950PR/950DT 支持的操作类型只有 sum、max、min;Atlas A3 与 Atlas A2 系列当前版本的 prod 不支持 int16、bfp16。
- A2 上慎用 int64:功能可用,但性能会有一定劣化。
- 950PR/950DT 上 int64、uint64、float64 仅支持节点内通信,跨节点场景别用这三种类型。
硬件与版本支持一览
✅ 各硬件对 HcclReduce 集合通信的支持情况:
| 硬件 | 支持情况 | 支持的数据类型 | 限制与备注 |
|---|---|---|---|
| Ascend 950PR / 950DT | 支持 | int8、int16、int32、int64、uint64、float16、float32、float64、bfp16 | int64/uint64/float64 仅节点内通信;操作类型支持 sum、max、min |
| Atlas A3 训练系列/推理系列 | 支持 | int8、int16、int32、int64、float16、float32、bfp16 | 当前版本 prod 不支持 int16、bfp16 |
| Atlas A2 训练系列/推理系列 | 支持 | int8、int16、int32、int64、float16、float32、bfp16 | 仅支持 Atlas 800T A2 训练服务器、Atlas 900 A2 PoD 集群基础单元、Atlas 200T A2 Box16 异构子框;int64 有性能劣化;当前版本 prod 不支持 int16、bfp16 |
| Atlas 训练系列 | 支持 | int8、int32、int64、float16、float32 | — |
| Atlas 推理系列 | 不支持 | — | — |
小结
需要把散落在多个设备上的数据(求和、连乘、取最大/最小)汇聚到某个指定 rank 继续计算时,HcclReduce 就是对应的集合通信入口:确认硬件支持列表、对齐好 buffer、保证各 rank 参数一致,就可以接进你的训练或推理流程。
【免费下载链接】runner-imagesGitHub Actions runner images项目地址: https://gitcode.com/GitHub_Trending/ru/runner-images
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考