### CANN HCCL-COMM 通信拓扑感知16卡训练时为什么 rank3 总是最慢的那张去年搭了一台 8 卡 Atlas 800 服务器做 LLaMA 预训练一切顺利。后来集群扩到 3 台共 24 卡单卡吞吐从 1.2 tokens/s 掉到 0.7。不是线性下降是断崖式下跌。查了一圈发现不是算力的问题——HCCL 在做跨机 AllReduce 的时候rank3 到 rank8 的 RoCE 链路走的交换机端口被别的业务占了实际带宽只有标称的 30%。HCCL-COMM 是 HCCL 的通信拓扑管理模块。它负责发现 NPU 之间的物理连接关系构建通信拓扑图然后基于这个图选择最优的通信路径。你不用手写拓扑HCCL-COMM 会自动探测。但如果自动探测的结果跟实际物理环境不一致性能就会出问题。HCCL-COMM 怎么发现“谁和谁连着”HCCL-COMM 启动的时候会做一次链路探测每张 NPU 向其他所有 NPU 发探测包。记录每条链路的类型HCCS/RoCE、带宽、延迟。构建一个完整的拓扑图。基于拓扑图选择 AllReduce/AllGather 的最优路径。拓扑探测示例# hccl-comm 的拓扑探测结果fromhccl_commimportTopologyInspector inspectorTopologyInspector()# 查看所有链路linksinspector.get_all_links()forlinkinlinks:print(f{link.src}→{link.dst}: f{link.type},{link.bandwidth}Gbps,{link.latency}us)# 单机8卡输出类似# rank0 → rank1: HCCS, 100Gbps, 0.8us# rank0 → rank2: HCCS, 100Gbps, 0.9us# rank0 → rank3: HCCS, 100Gbps, 0.8us# ...# rank0 → rank8: RoCE, 100Gbps, 5.2us ← 跨机了# rank0 → rank9: RoCE, 100Gbps, 5.1us单机内HCCS 的拓扑不是全互联很多人以为单机 8 卡的 HCCS 是全互联任意两卡直连。实际上不是——达芬奇架构的 HCCS 是一种混合拓扑相邻卡之间有直连链路不相邻的卡需要中转。Atlas 800 的典型 HCCS 拓扑是“环形 对角”rank0 — rank1 — rank2 — rank3 | | | | rank7 — rank6 — rank5 — rank4横向链路是直连的延迟 1μs纵向和对角线需要经过中间卡中转延迟 1.5-2μs。HCCL-COMM 探测到这个拓扑之后在做 Ring AllReduce 时会优先选横向链路构建 Ring避免走中转。Ring 顺序优化示例# 让 hccl-comm 打印它选择的 ring 顺序fromhccl_commimportTopologyInspector inspectorTopologyInspector()ringinspector.get_ring_order(num_cards8)# 理想的 ringrank0→rank1→rank2→rank3→rank4→rank5→rank6→rank7→rank0# 每一步都是横向直连没有中转print(ring)# [0, 1, 2, 3, 4, 5, 6, 7]# 如果 hccl-comm 选错了 ring可能出现中转# 比如选了 0→3→6→1→4→7→2→5→0# rank0 到 rank3 没有直连链路要经过 rank1 或 rank2 中转# 每步多花 1μs8步就多 8μs# allreduce 一次多花 64μs一个 training step 调 20 次 allreduce 1.28ms# 看起来不多但累积下来每个 step 多花 5-8% 的时间跨机RoCE 的拓扑坑更多跨机通信走 RoCERDMA over Converged Ethernet链路情况比 HCCS 复杂得多。交换机型号、网线类型、网卡驱动版本都会影响实际带宽。RoCE 链路质量检测fromhccl_commimportRoCEInspector inspectorRoCEInspector()# 查看 rank0 到所有其他机器上的 rank 的链路质量forrankinrange(8,24):linkinspector.get_link(0,rank)actual_bwinspector.measure_bandwidth(0,rank,size_mb64)utilactual_bw/link.negotiated_bandwidthprint(frank0 → rank{rank:2d}: fnegotiated{link.negotiated_bandwidth}Gbps, factual{actual_bw:.1f}Gbps, futilization{util:.0%})# rank0 → rank 8: negotiated100Gbps, actual97.2Gbps, utilization97%# rank0 → rank 9: negotiated100Gbps, actual95.8Gbps, utilization96%# rank0 → rank10: negotiated100Gbps, actual31.4Gbps, utilization31% ← 异常# rank0 → rank11: negotiated100Gbps, actual98.1Gbps, utilization98%rank10 的利用率只有 31%说明链路有问题。常见原因交换机端口速率协商失败本应跑 100Gbps实际降级到了 25Gbps。网卡 NUMA 绑定错误RoCE 网卡绑到了错误的 CPU NUMA 节点跨 NUMA 访存增加延迟。物理连接问题光模块脏了、光纤弯折角度过大。快速检查命令# 快速检查网卡状态ibstat# 看 rate 一列是不是 Negotiated 100Gbps# 如果是 25Gbps 或 10Gbps说明协商降级了# 检查 NUMA 绑定lscpu|grepNUMA# 确认 NPU 和 RoCE 网卡在同一个 NUMA 节点上# 如果不在用 numactl 重新绑定进程手动指定拓扑自动探测不靠谱的时候有时候自动探测的结果跟你预期的不一样比如它以为两条链路都是 HCCS但实际有一条走了 PCIe 中转。这时候可以手动指定拓扑手动拓扑配置文件hccl_topology.json{version:1.0,devices:[{rank:0,device_id:0,node_id:0},{rank:1,device_id:1,node_id:0},{rank:2,device_id:2,node_id:0},{rank:3,device_id:3,node_id:0},{rank:4,device_id:0,node_id:1},{rank:5,device_id:1,node_id:1},{rank:6,device_id:2,node_id:1},{rank:7,device_id:3,node_id:1}],links:[{src:0,dst:1,type:HCCS,bandwidth_gbps:100},{src:0,dst:2,type:HCCS,bandwidth_gbps:100},{src:0,dst:4,type:RoCE,bandwidth_gbps:100},{src:1,dst:5,type:RoCE,bandwidth_gbps:50}]}启动训练时指定拓扑文件exportHCCL_TOPOLOGY_FILE/path/to/hccl_topology.json手动拓扑在两种场景下特别有用集群网络环境复杂多种交换机混用。物理环境跟默认配置不一致比如某个 HCCS 端口坏了降级走了 PCIe。Hierarchical AllReduce大规模集群必须用的策略当集群规模超过 8 卡2台机器简单的 Ring AllReduce 不再是最优选择。HCCL-COMM 会自动切换到 Hierarchical 策略先做单机内的 AllReduceHCCS再做跨机的 AllReduceRoCE。两层的算法可以分别优化。Hierarchical 策略配置与性能对比fromhccl_commimportHierarchicalConfig# 24卡集群3台机器各8卡configHierarchicalConfig(num_nodes3,cards_per_node8,intra_node_algorithmring,# 机内用 ringHCCS 快inter_node_algorithmring,# 机间也用 ringintra_node_linkHCCS,# 100Gbps延迟 1μsinter_node_linkRoCE,# 100Gbps延迟 ~5μs)# hierarchical allreduce 的执行过程# 第1阶段每台机器内部做 ring allreduce得到局部结果# 8卡 ringHCCS 链路32MB 数据 → 0.82ms# 第2阶段3台机器之间做 allreduce聚合局部结果# 3节点 ringRoCE 链路32MB 数据 → 2.56ms# 第3阶段每台机器内部再广播跨机结果# 8卡 broadcastHCCS 链路32MB 数据 → 0.41ms# 总计3.79ms# 对比 naive ring allreduce24卡一个大环# 24步 ring混合 HCCSRoCE 链路 → 6.2ms# hierarchical 快了 40%调优清单大规模分布式训练遇到通信瓶颈按这个顺序排查# 1. 拓扑是否正确fromhccl_commimportTopologyInspector TopologyInspector().print_topology()# 检查 HCCS/RoCE 分配是否符合物理实际# 2. Ring 顺序是否最优topoTopologyInspector()print(topo.get_ring_order(num_cards24))# 确认跨机跳跃最少# 3. 链路利用率是否正常forrankinrange(24):bwtopo.measure_bandwidth(0,rank,size_mb64)ifbw80:# 低于 80Gbps 就有问题print(f⚠ rank0 → rank{rank}: only{bw}Gbps)# 4. hierarchical 是否启用configtopo.get_hierarchical_config()ifconfig.num_nodes2andnotconfig.enabled:print(⚠ 多机集群没有启用 hierarchical allreduce)HCCL-COMM 是昇腾多卡训练里最容易出问题但最不容易被发现的模块。因为它大部分时候工作正常只有当集群规模扩大或者网络环境变化时才会暴露问题。建议每次扩容集群之后都跑一遍上面的检查。仓库地址https://atomgit.com/cann/hccl
CANN HCCL-COMM 通信拓扑感知:16卡训练时为什么 rank3 总是最慢的那张
发布时间:2026/5/22 23:09:38
### CANN HCCL-COMM 通信拓扑感知16卡训练时为什么 rank3 总是最慢的那张去年搭了一台 8 卡 Atlas 800 服务器做 LLaMA 预训练一切顺利。后来集群扩到 3 台共 24 卡单卡吞吐从 1.2 tokens/s 掉到 0.7。不是线性下降是断崖式下跌。查了一圈发现不是算力的问题——HCCL 在做跨机 AllReduce 的时候rank3 到 rank8 的 RoCE 链路走的交换机端口被别的业务占了实际带宽只有标称的 30%。HCCL-COMM 是 HCCL 的通信拓扑管理模块。它负责发现 NPU 之间的物理连接关系构建通信拓扑图然后基于这个图选择最优的通信路径。你不用手写拓扑HCCL-COMM 会自动探测。但如果自动探测的结果跟实际物理环境不一致性能就会出问题。HCCL-COMM 怎么发现“谁和谁连着”HCCL-COMM 启动的时候会做一次链路探测每张 NPU 向其他所有 NPU 发探测包。记录每条链路的类型HCCS/RoCE、带宽、延迟。构建一个完整的拓扑图。基于拓扑图选择 AllReduce/AllGather 的最优路径。拓扑探测示例# hccl-comm 的拓扑探测结果fromhccl_commimportTopologyInspector inspectorTopologyInspector()# 查看所有链路linksinspector.get_all_links()forlinkinlinks:print(f{link.src}→{link.dst}: f{link.type},{link.bandwidth}Gbps,{link.latency}us)# 单机8卡输出类似# rank0 → rank1: HCCS, 100Gbps, 0.8us# rank0 → rank2: HCCS, 100Gbps, 0.9us# rank0 → rank3: HCCS, 100Gbps, 0.8us# ...# rank0 → rank8: RoCE, 100Gbps, 5.2us ← 跨机了# rank0 → rank9: RoCE, 100Gbps, 5.1us单机内HCCS 的拓扑不是全互联很多人以为单机 8 卡的 HCCS 是全互联任意两卡直连。实际上不是——达芬奇架构的 HCCS 是一种混合拓扑相邻卡之间有直连链路不相邻的卡需要中转。Atlas 800 的典型 HCCS 拓扑是“环形 对角”rank0 — rank1 — rank2 — rank3 | | | | rank7 — rank6 — rank5 — rank4横向链路是直连的延迟 1μs纵向和对角线需要经过中间卡中转延迟 1.5-2μs。HCCL-COMM 探测到这个拓扑之后在做 Ring AllReduce 时会优先选横向链路构建 Ring避免走中转。Ring 顺序优化示例# 让 hccl-comm 打印它选择的 ring 顺序fromhccl_commimportTopologyInspector inspectorTopologyInspector()ringinspector.get_ring_order(num_cards8)# 理想的 ringrank0→rank1→rank2→rank3→rank4→rank5→rank6→rank7→rank0# 每一步都是横向直连没有中转print(ring)# [0, 1, 2, 3, 4, 5, 6, 7]# 如果 hccl-comm 选错了 ring可能出现中转# 比如选了 0→3→6→1→4→7→2→5→0# rank0 到 rank3 没有直连链路要经过 rank1 或 rank2 中转# 每步多花 1μs8步就多 8μs# allreduce 一次多花 64μs一个 training step 调 20 次 allreduce 1.28ms# 看起来不多但累积下来每个 step 多花 5-8% 的时间跨机RoCE 的拓扑坑更多跨机通信走 RoCERDMA over Converged Ethernet链路情况比 HCCS 复杂得多。交换机型号、网线类型、网卡驱动版本都会影响实际带宽。RoCE 链路质量检测fromhccl_commimportRoCEInspector inspectorRoCEInspector()# 查看 rank0 到所有其他机器上的 rank 的链路质量forrankinrange(8,24):linkinspector.get_link(0,rank)actual_bwinspector.measure_bandwidth(0,rank,size_mb64)utilactual_bw/link.negotiated_bandwidthprint(frank0 → rank{rank:2d}: fnegotiated{link.negotiated_bandwidth}Gbps, factual{actual_bw:.1f}Gbps, futilization{util:.0%})# rank0 → rank 8: negotiated100Gbps, actual97.2Gbps, utilization97%# rank0 → rank 9: negotiated100Gbps, actual95.8Gbps, utilization96%# rank0 → rank10: negotiated100Gbps, actual31.4Gbps, utilization31% ← 异常# rank0 → rank11: negotiated100Gbps, actual98.1Gbps, utilization98%rank10 的利用率只有 31%说明链路有问题。常见原因交换机端口速率协商失败本应跑 100Gbps实际降级到了 25Gbps。网卡 NUMA 绑定错误RoCE 网卡绑到了错误的 CPU NUMA 节点跨 NUMA 访存增加延迟。物理连接问题光模块脏了、光纤弯折角度过大。快速检查命令# 快速检查网卡状态ibstat# 看 rate 一列是不是 Negotiated 100Gbps# 如果是 25Gbps 或 10Gbps说明协商降级了# 检查 NUMA 绑定lscpu|grepNUMA# 确认 NPU 和 RoCE 网卡在同一个 NUMA 节点上# 如果不在用 numactl 重新绑定进程手动指定拓扑自动探测不靠谱的时候有时候自动探测的结果跟你预期的不一样比如它以为两条链路都是 HCCS但实际有一条走了 PCIe 中转。这时候可以手动指定拓扑手动拓扑配置文件hccl_topology.json{version:1.0,devices:[{rank:0,device_id:0,node_id:0},{rank:1,device_id:1,node_id:0},{rank:2,device_id:2,node_id:0},{rank:3,device_id:3,node_id:0},{rank:4,device_id:0,node_id:1},{rank:5,device_id:1,node_id:1},{rank:6,device_id:2,node_id:1},{rank:7,device_id:3,node_id:1}],links:[{src:0,dst:1,type:HCCS,bandwidth_gbps:100},{src:0,dst:2,type:HCCS,bandwidth_gbps:100},{src:0,dst:4,type:RoCE,bandwidth_gbps:100},{src:1,dst:5,type:RoCE,bandwidth_gbps:50}]}启动训练时指定拓扑文件exportHCCL_TOPOLOGY_FILE/path/to/hccl_topology.json手动拓扑在两种场景下特别有用集群网络环境复杂多种交换机混用。物理环境跟默认配置不一致比如某个 HCCS 端口坏了降级走了 PCIe。Hierarchical AllReduce大规模集群必须用的策略当集群规模超过 8 卡2台机器简单的 Ring AllReduce 不再是最优选择。HCCL-COMM 会自动切换到 Hierarchical 策略先做单机内的 AllReduceHCCS再做跨机的 AllReduceRoCE。两层的算法可以分别优化。Hierarchical 策略配置与性能对比fromhccl_commimportHierarchicalConfig# 24卡集群3台机器各8卡configHierarchicalConfig(num_nodes3,cards_per_node8,intra_node_algorithmring,# 机内用 ringHCCS 快inter_node_algorithmring,# 机间也用 ringintra_node_linkHCCS,# 100Gbps延迟 1μsinter_node_linkRoCE,# 100Gbps延迟 ~5μs)# hierarchical allreduce 的执行过程# 第1阶段每台机器内部做 ring allreduce得到局部结果# 8卡 ringHCCS 链路32MB 数据 → 0.82ms# 第2阶段3台机器之间做 allreduce聚合局部结果# 3节点 ringRoCE 链路32MB 数据 → 2.56ms# 第3阶段每台机器内部再广播跨机结果# 8卡 broadcastHCCS 链路32MB 数据 → 0.41ms# 总计3.79ms# 对比 naive ring allreduce24卡一个大环# 24步 ring混合 HCCSRoCE 链路 → 6.2ms# hierarchical 快了 40%调优清单大规模分布式训练遇到通信瓶颈按这个顺序排查# 1. 拓扑是否正确fromhccl_commimportTopologyInspector TopologyInspector().print_topology()# 检查 HCCS/RoCE 分配是否符合物理实际# 2. Ring 顺序是否最优topoTopologyInspector()print(topo.get_ring_order(num_cards24))# 确认跨机跳跃最少# 3. 链路利用率是否正常forrankinrange(24):bwtopo.measure_bandwidth(0,rank,size_mb64)ifbw80:# 低于 80Gbps 就有问题print(f⚠ rank0 → rank{rank}: only{bw}Gbps)# 4. hierarchical 是否启用configtopo.get_hierarchical_config()ifconfig.num_nodes2andnotconfig.enabled:print(⚠ 多机集群没有启用 hierarchical allreduce)HCCL-COMM 是昇腾多卡训练里最容易出问题但最不容易被发现的模块。因为它大部分时候工作正常只有当集群规模扩大或者网络环境变化时才会暴露问题。建议每次扩容集群之后都跑一遍上面的检查。仓库地址https://atomgit.com/cann/hccl