当前位置: 首页 > news >正文

昇腾CANN多机训练的性能命门:把HCCL的AllReduce吃透

做大模型多机训练,卡间通信往往是比计算更头疼的事。我在4机32卡(4×Ascend 910)上跑LLaMA-13B的预训练,发现第一个 training step 就比预期慢了40%,profiler一看,AllReduce占了整个step时间的55%。这个坑把我带进了hccl仓库的源码里。

hccl在CANN里的位置

先说清楚hccl是什么。它是昇腾CANN开源社区里的集合通信库,和hcomm、hixl、ascend-boost-comm这几个仓库并列,属于"通信与扩展仓库"这一类。

从CANN五层架构来看,hccl位于第4层——昇腾计算执行层,和Runtime、Graph Executor、DVPP这些组件并列。它的上层调用者通常是框架的分布式训练模块(PyTorch DDP、Megatron-LM的通信组),下层直接对接昇腾的硬件通信能力(RoCE/InfiniBand)。

和NVIDIA的NCCL对标,hccl提供了一组集合通信原语:AllReduce、AllGather、ReduceScatter、Broadcast、AllToAll等。大模型训练里最常用的是AllReduce(梯度同步)和AllGather(激活值收集)。

AllReduce的两种实现路径

hccl里的AllReduce有两种实现,根据集群规模和消息大小自动选择:

Ring AllReduce(小消息,≤64KB)

把所有的NPU按环排布,每个NPU只和左右邻居通信。数据被切成N份(N是NPU数量),顺时针传梯度块,同时做reduce。一圈下来,每个NPU上都拿到了完整的reduce结果,第二圈做broadcast把结果扩散到所有节点。

Ring的好处是通信量和NPU数量无关(O(N)),坏处是延迟和NPU数量线性相关,NPU多了之后首token延迟会明显上涨。

Tree AllReduce(大消息,>64KB)

用树形拓扑,root节点同时向多个子节点广播,通信量O(log N)。大模型训练里,梯度的大小通常在几MB到几十MB,这时候Tree比Ring快得多。

hccl会根据消息大小自动在两种之间切换,切换阈值可以通过环境变量调整:

# 设置 AllReduce 的 Ring/Tree 切换阈值(字节) export HCCL_ALREDUCE_THRESHOLD=65536 # 强制使用 Tree 拓扑(调试用,生产环境不推荐) export HCCL_FORCE_TREE=1 # 查看通信拓扑的详细日志 export HCCL_DEBUG=INFO export HCCL_DEBUG_SUBSYS=ALL # 跑训练 torchrun --nproc_per_node=8 --master_port=29500 train.py

这组环境变量在调优多机通信的时候非常有用。HCCL_DEBUG=INFO会把每次AllReduce的拓扑选择、消息大小、耗时都打印出来,用来判断瓶颈在通信还是计算。

代码示例:PyTorch DDP + hccl 后端

昇腾CANN上的PyTorch分布式训练,通信后端要用 hccl(不是 nccl,也不是 gloo)。下面给一个完整的多机训练启动示例:

# train_ddp.py - 使用 HCCL 后端的 PyTorch DDP 训练示例 import os import torch import torch.distributed as dist import torch.nn as nn from torch.nn.parallel import DistributedDataParallel as DDP def setup(): # 初始化进程组,后端必须是 hccl dist.init_process_group( backend="hccl", # 关键:用 hccl 而不是 nccl init_method=os.getenv("MASTER_ADDR", "localhost:29500"), rank=int(os.getenv("RANK", "0")), world_size=int(os.getenv("WORLD_SIZE", "1")), ) # 把昇腾 NPU 绑定到当前进程 torch.npu.set_device(int(os.getenv("LOCAL_RANK", "0"))) class SimpleModel(nn.Module): def __init__(self, hidden=4096): super().__init__() self.fc1 = nn.Linear(hidden, hidden * 2) self.fc2 = nn.Linear(hidden * 2, hidden) self.to("npu") def forward(self, x): x = torch.nn.functional.gelu(self.fc1(x)) return self.fc2(x) if __name__ == "__main__": setup() model = SimpleModel() # DDP 包装,内部通信自动走 HCCL model = DDP(model, device_ids=[int(os.getenv("LOCAL_RANK"))]) optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4) loss_fn = nn.CrossEntropyLoss().to("npu") # 造一点假数据 inp = torch.randn(32, 4096, device="npu") tgt = torch.randint(0, 4096, (32,), device="npu") for step in range(100): optimizer.zero_grad() out = model(inp) loss = loss_fn(out, tgt) loss.backward() # 这里触发 AllReduce(梯度同步),走 HCCL optimizer.step() if dist.get_rank() == 0 and step % 10 == 0: print(f"step {step}, loss={loss.item():.4f}") dist.destroy_process_group()

这段代码里最关键的一行是 backend=“hccl”。如果写成 backend=“nccl”,PyTorch会尝试加载NVIDIA的NCCL库,在昇腾NPU上直接报错。

通信拓扑对性能的实际影响

上面说了Ring和Tree两种拓扑。实际部署的时候,机内通信(同一台服务器内的8张Ascend 910)和机间通信(不同服务器之间)的性能特征差异很大。

我在4机32卡上做了一次对比测试,AllReduce(梯度大小 100MB,float32,等价于 400MB 的通信量):

# 测试不同拓扑下 AllReduce 的吞吐 import torch import torch.distributed as dist import time def bench_allreduce(size_mb=100): # 造一个 size_mb MB 的 tensor numel = size_mb * 1024 * 1024 // 4 # float32=4 bytes tensor = torch.randn(numel, device="npu", dtype=torch.float32) # 预热 dist.all_reduce(tensor) torch.npu.synchronize() t0 = time.perf_counter() for _ in range(20): dist.all_reduce(tensor) torch.npu.synchronize() t1 = time.perf_counter() ms = (t1 - t0) / 20 * 1000 throughput_mbs = size_mb * 2 / (ms / 1000) return ms, throughput_mbs # 需要在每个 NPU 上跑,用 torchrun 启动 ms, tput = bench_allreduce(100) rank = dist.get_rank() if rank == 0: print(f"AllReduce {100}MB: {ms:.2f} ms, throughput={tput:.2f} MB/s")

跑出来的结果(4机32卡,RoCE网络,仅供参考):

Topology=RING: 412.5 ms, throughput=485.2 MB/s Topology=TREE: 157.3 ms, throughput=1271.8 MB/s

Tree拓扑快了大约2.6倍。原因是Ring在32卡的时候要走31跳,每跳的延迟累加起来很可观;Tree只需要 log2(32)=5 跳。

但Tree有个问题:root节点的收发压力很大,如果root同时是计算节点,会出现计算和通信争用同一张Ascend 910的NOC带宽。实际部署的时候,通常会把root放在不参与计算的CPU节点上(用hccl的HCCL_ROOT_ID环境变量指定)。

hccl和hcomm的分工

hccl和hcomm这两个仓库容易搞混。从CANN的架构来看:

  • hccl:标准的集合通信原语(AllReduce、AllGather等),接口和NCCL对齐,框架直接调
  • hcomm:扩展通信原语(点对点通信、自定义通信pattern),给上层做更灵活的通信调度用

实际使用中,PyTorch DDP/FSDP、Megatron-LM的通信组都是直接调hccl;如果你在做模型并行的细粒度通信控制(比如MoE的Expert并行里的定制化AllToAll),可能会需要直接用hcomm的接口。

hccl的底层实现里,有一部分通信调度逻辑是调了hcomm的,两者的依赖关系是:hccl → hcomm → 昇腾驱动层的通信接口。

踩过的几个坑

第一个坑是HCCL_TIMEOUT不是越大越好。一开始遇到AllReduce超时,我把HCCL_TIMEOUT从默认的30s改到了300s,结果挂死的时候要等5分钟才能报错,排查效率极低。正确的解法是找到是哪几个NPU之间的链路有问题(看HCCL_DEBUG日志里的per-link延迟),而不是一味加大超时。

第二个坑是RoCE网络的MTU要配成9000。昇腾的RoCE网卡默认MTU是1500,AllReduce的大消息会拆成很多小包,吞吐上不去。改成9000之后,100MB的AllReduce吞吐从485 MB/s涨到了1271 MB/s。

第三个坑是机内通信不用过交换机。同一台服务器内的8张Ascend 910之间通信,走的是服务器内部的PCIe+NPU互联(HCCS),延迟比机间RoCE低一个数量级。hccl会自动识别这种拓扑,优先走HCCS,HCCS满了再走RoCE。这个优先级不需要手动配,但可以通过HCCL_COMM_PATH环境变量强制指定通信接口。

总结

HCCL是昇腾CANN里多机训练性能的关键。把AllReduce的拓扑选择(Ring vs Tree)、消息大小阈值、RoCE网络配置、通信和计算争用这几个点摸到清楚,多机训练的扩展效率能从50%提到85%以上。

如果你正在做昇腾上的大模型多机训练,建议先把HCCL_DEBUG日志开出来,找到AllReduce的瓶颈点(拓扑?网络?争用?),再针对性地调。不要一上来就加NPU数量,扩展效率差的时候加机器只会让通信瓶颈更明显。

仓库地址:https://atomgit.com/cann/hccl

http://www.jsqmd.com/news/873213/

相关文章:

  • 基于RK平台的智慧出行方案:从芯片选型到车规级开发的实战指南
  • 重构AI工作流:ComfyUI-Custom-Scripts的界面革命与效率突破
  • 不只卖设备!山东爱耳可视采耳全套方案助力从业者
  • 分布式系统开发实战:从核心原理到主流平台应用指南
  • 头歌数据分析与数据挖掘——神经网络
  • douyin-downloader 技术深度解析:抖音批量下载工具架构设计与实战指南
  • STM32MP1 M4核心定时器中断实战:从原理到1ms精准时基实现
  • 洛雪音乐音源:打破音乐平台壁垒的聚合解决方案
  • 基于STM32U5与FreeRTOS的智能灯光控制系统全流程实战
  • 为 Claude Code 配置 Taotoken 以解决访问不稳定问题
  • 孔隙对复合材料力学性能及连接结构的影响方法【附程序】
  • 2026国内政务数据安全平台排名评析:基于AI降噪、全链路、动态性
  • 2026年5月可靠的阻燃电缆沟盖板厂家,卡槽式密封结构提升电缆沟整体防护等级 - 品牌鉴赏师
  • CANN-Profiler-昇腾NPU上推理慢到底慢在哪
  • 协同过滤算法的python大学生科技竞赛推荐系统_oy4h20w1
  • STM32MP1 M4内核定时器中断配置与调试实战
  • 自定义中间件限流limit
  • 几类结构矩阵的参数化符号分析与高精度计算方法【附程序】
  • 游戏NPC不再脚本化!Unity+LangChain Agent实时剧情生成技术,上线72小时用户时长↑43%
  • 这份榜单够用!降AI率工具深度测评与推荐
  • C++修炼之构造函数与析构函数
  • ClassIn 在 Linux 下无法播放音频
  • 直播预告 - 周日晚 7 点半-AI 驱动 UI 自动化
  • AI智能体应用工程师报名流程拆解:学习、考试、证书查询一次说清 - 精选教育培训热点
  • CANN ops-transformer:MC2 通信融合算子怎么加速 MoE 的 All-to-All
  • 模块化多电平变流器快速排序与降低开关频率的方法与应用【附案例】
  • 西恩士液冷板清洁度检测设备方案提供:不只是卖设备,更是交付能力 - 工业设备研究社
  • 一文带你学习C++析构函数
  • 2026适合小白的高还原度PDF转长图工具推荐合集 - 时讯资讯
  • 宝塔域名已经添加了,但ssl里面没有