HCCL 集合通信:昇腾集群的参数同步引擎
大模型训练的本质是将一个超大矩阵乘法拆到多张 NPU 上并行计算每张卡算完自己的分片后把梯度合并。合并操作就是集合通信。HCCLHuawei Collective Communication Library是 CANN 的集合通信库对应 NVIDIA NCCL。它不参与模型计算不管理训练循环只做一件事——在多卡之间高效搬运数据。为什么大模型训练离不开通信以 LLaMA-70B 为例。单张 Ascend 910 显存 32GB模型参数 140GBFP16放不下。必须把模型切到 8 张卡上每张卡负责八分之一的参数。前向计算时每张卡算出自己那部分的梯度然后需要把所有卡的梯度加起来每张卡才能更新自己的参数。这个加起来就是 AllReduce 操作。没有通信库的帮助AllReduce 需要手动写一个算法——每张卡把自己的梯度发给某个收集者收集者相加完后广播回去。通信量O(N²)N 为卡数卡越多通信效率越低。HCCL 用 Ring AllReduce 把通信量降到O(N)。Ring 通信为什么常见Ring AllReduce 是所有集合通信库的标配算法。以 4 张卡为例卡 0 → 卡 1 → 卡 2 → 卡 3 → 卡 0逻辑 Ring每张卡只跟前后邻居通信。梯度被切成 N 块N卡数每张卡持有不同块的数据。Reduce-Scatter 阶段4 步Step 1: 卡0把块0发给卡1卡1把块1发给卡2卡2把块2发给卡3卡3把块3发给卡0 Step 2: 每张卡收到后做元素求和再把结果传给下一张 Step 3: 继续传递和累加 Step 4: 每张卡持有某个块的完整和AllGather 阶段3 步每张卡把自己持有的完整块广播给所有卡所有卡最终持有全部块的完整和总通信量 2 × (N-1) × (gradient_size / N)跟卡数 N 无关。N 越大每张卡承担的通信量反而越小。这就是 Ring 算法扩展性的来源。HCCL 与 NCCL 的区别拓扑感知不同。NCCL 为 NVIDIA 的 NVLink 和 InfiniBand 拓扑做了深度优化——知道 GPU 之间是 NVLink 直连还是走 PCIe 交换机通信路径选择不同。HCCL 针对的是昇腾集群的 HCCSHuawei Cache Coherence System互联和 RoCE 网络拓扑结构自然不同。HCCL 也会自动检测卡间拓扑但检测方式和通信路径算法跟 NCCL 不一样。通信原语实现不同。NCCL 有 150 种算法变体Ring、Tree、NVLink Direct 等HCCL 的算法数量少一些但覆盖了核心场景AllReduce、AllGather、ReduceScatter、Broadcast、AllToAll。集成方式不同。NCCL 通过 PyTorch 的 DistributedDataParallel 和 DeepSpeed 集成。HCCL 同样集成进了 PyTorch通过torch_npu训练脚本里的torch.distributed.all_reduce在昇腾上走的就是 HCCL。应用层代码完全一致——换卡不换代码。昇腾集群如何同步参数一条典型的分布式训练命令torchrun--nproc_per_node8train.pyPyTorch 内部为每张卡创建独立的进程每个进程绑定一张 NPU。DDP 初始化时调用torch.distributed.init_process_group(backendhccl)HCCL 在背后做的事情通信域初始化。8 个进程互相发现建立通信拓扑。HCCL 自动检测 NPU 之间的物理拓扑HCCS 直连、PCIe 交换机、RoCE 网络为每对卡选择最短通信路径。Buffer 注册。每张卡在显存中分配通信 BufferHCCL 把 Buffer 地址注册到 DMA 引擎。注册完成后通信走硬件 DMA不经过 CPU 拷贝。通信就绪。所有卡之间建立好通信链路后DDP 开始训练循环。训练每步的反向传播结束后PyTorch 调用all_reduce(gradients)HCCL 执行 Ring AllReduce所有卡的梯度同步同值。HCCL 在 CANN 中的位置CANN 跟通信相关有三个仓库hccl — 集合通信库AllReduce、AllGather 等 hcom — 通信算子库更底层的通信原语 hixl — 单边通信库零拷贝场景hccl 在最高层直接对接 PyTorch DDP 和 DeepSpeed。hcom 是 hccl 的下层——hccl 的 AllReduce 调用 hcom 的发送和接收算子。hixl 是另一条路径用于推理场景的 PD 分离通信。大模型训练中的通信优化实际分布式训练中通信开销不只是一个算法问题还涉及工程层面的各种权衡。计算通信重叠。Ring AllReduce 的 Reduce-Scatter 阶段可以在反向传播的同时异步启动——模型最后一层的梯度刚算出来通信就开始了不用等到所有层都算完。这种重叠可以让通信开销消失在计算的时间里。HCCL 支持通过hccl_stream让通信和计算使用不同的 Stream实现异步重叠。梯度压缩。通信的数据量跟模型大小成正比。LLaMA-70B 每步更新要同步约 140GB 的梯度。FP16 下即便用 Ring 拆分每张卡每步仍要传输约 35GB。常见压缩手段FP16 → FP32 混精度梯度用 FP16 通信通信量减半梯度裁剪只同步大于阈值的梯度元素TopK 稀疏化只同步梯度值最大的 K% 元素前两种 HCCL 原生支持。TopK 稀疏化需要训练框架配合——DeepSpeed 和 Megatron-LM 有自己的稀疏通信实现。性能参考在 8×Ascend 910 集群上HCCL AllReduce 的实测带宽数据量NCCL (A100×8 NVLink)HCCL (Ascend 910×8 HCCS)1MB12 GB/s9 GB/s16MB58 GB/s42 GB/s128MB92 GB/s78 GB/s512MB108 GB/s95 GB/sHCCL 在大数据量下的带宽能达到对标硬件的 88%95/108。小数据量差距大一些75%主要原因是 HCCL 的 Ring 算法在小 Buffer 场景的初始化开销偏高。HCCL 仓库hcom 通信算子库通信拓扑与带宽利用率HCCL 的另一个关键优化是拓扑感知的通信路径选择。在一个 8 卡节点上实际的物理拓扑可能是NPU 0 ── HCCS ── NPU 1 NPU 4 ── HCCS ── NPU 5 │ │ │ │ PCIe PCIe PCIe PCIe │ │ │ │ NPU 2 ── HCCS ── NPU 3 NPU 6 ── HCCS ── NPU 7NPU 0 和 NPU 1 之间是 HCCS 直连带宽 100GB/s。NPU 0 和 NPU 2 之间走 PCIe 交换机带宽只有 32GB/s。HCCL 在通信域初始化阶段通过探测每对卡之间的延迟和带宽构建一张拓扑权重图。AllReduce 的 Ring 算法在切分数据块时会优先让数据沿高带宽路径流动尽量避免通过低带宽路径传输大量数据。跨节点场景16 卡中节点间的网络通信带宽RoCE 200GbE远低于节点内的 HCCS 带宽HCCL 会减少跨节点通信的频次——每轮 AllReduce 只做一次跨节点数据交换。HCCL 在 PyTorch 训练中的实际调用实际开发中你大概率不会直接调用 HCCL 的 API。PyTorch 的torch.distributed封装了 HCCL你只需要在初始化时指定 backendimporttorch.distributedasdist dist.init_process_group(backendhccl)# 后端换成 hccl后面的dist.all_reduce(tensor)、dist.broadcast(tensor, src0)都走 HCCL。从应用代码的视角看NCCL 和 HCCL 的切换就是改一个 backend 名字。HCCL 也提供 C API 供自定义通信场景使用——比如在 GNN 训练中手动控制通信粒度。C API 的接口跟 NCCL 的 nccl.h 非常相似方便从 GPU 迁移过来的用户快速上手。参考仓库HCCL 集合通信库hcom 通信算子库
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2630806.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!