GPU 软件
在多 GPU 服务器上运行 NCCL 测试:all_reduce_perf 分步指南
在开始长时间训练之前,请先确认全部 8 张 GPU 之间能以全速通信。这些检查耗时很短,能及早发现大多数互联问题。
本页内容
检查 GPU 拓扑
nvidia-smi topo -m
nvidia-smi nvlink --status
systemctl status nvidia-fabricmanager
在 topo 矩阵中,NV# 表示两张 GPU 通过 NVLink 相连,其中 # 为链路数量。PIX、PXB、PHB、NODE 和 SYS 都是 PCIe 路径,按距离由近到远排列。该矩阵还会显示每张 GPU 的 CPU 亲和性和 NUMA 亲和性。
在 HGX 服务器(H100、H200、B200、B300)上,每一对 GPU 之间都应显示 NV 条目,并且 Fabric Manager 应处于 active (running) 状态。RTX PRO 6000 服务器没有 NVLink:其 GPU 之间通过 PCIe 通信,因此在这台服务器上出现 PCIe 条目属于正常现象。背景知识请参阅 NVLink 与 PCIe 对比。
编译 nccl-tests
- 安装编译工具,并检查是否存在 NCCL 开发头文件:
sudo apt install -y git build-essential ls /usr/include/nccl.h - 如果缺少
nccl.h,请从 NVIDIA 的 CUDA 软件源安装 NCCL,该软件源的配置方法见驱动与 CUDA 版本。先列出可用版本,然后选择 CUDA 后缀(例如+cuda12.8)不高于 nvidia-smi 所显示“CUDA Version”的最新版本:apt-cache madison libnccl2 | head sudo apt install -y libnccl2=VERSION libnccl-dev=VERSION - 编译测试程序:
生成的二进制文件位于git clone https://github.com/NVIDIA/nccl-tests.git cd nccl-tests make -j"$(nproc)" CUDA_HOME=/usr/local/cuda./build/中。
如果不想改动主机环境,可以在 NGC PyTorch 容器内用同样的方法编译,该容器已包含 CUDA 和 NCCL。
在 8 张 GPU 上运行 all_reduce_perf
./build/all_reduce_perf -b 8 -e 8G -f 2 -g 8
由一个进程驱动 8 张 GPU(),数据量从 8 字节()增加到 8 GB(),每一步翻倍(algbw 和 busbw 两个带宽数值。请确认:
- 每一行的
#wrong列都为 0,说明结果正确; - busbw 随消息大小增加而上升,并在最大的几档消息大小处趋于平稳;
- 最后的“Avg bus bandwidth”一行在多次运行之间保持稳定。
其他集合通信操作的测试用法相同:all_gather_perf、reduce_scatter_perf 和 sendrecv_perf。
busbw 的含义
algbw 是数据量除以耗时。它会随 GPU 数量变化,因此很难在不同配置之间比较。busbw
厂商标称的链路速度是测试达不到的峰值,因此应以结果的一致性作为判断依据:比较多次运行的结果;如果您有一台配置相同的服务器,也与它比较。大消息时带宽骤降、结果远低于同型号的另一台服务器,或者测试卡住不动,通常说明拓扑、Fabric Manager 或硬件存在问题。请通过控制台中的工单,把完整输出和拓扑矩阵发给我们。
用 NCCL_DEBUG=INFO 调试
NCCL_DEBUG=INFO ./build/all_reduce_perf -b 1G -e 1G -g 8 2>&1 \
| tee nccl-debug.log
日志会显示 NCCL 版本、GPU 之间选用的传输方式(经 NVLink 的 P2P 或 NVLS、经主机内存的 SHM、经网络的 NET),以及 NCCL 构建的环(ring)和树(tree)。在 HGX 服务器上,您应该看到 NVLink 传输方式。如果看到的是 SHM,请检查拓扑和 Fabric Manager。在基于 PCIe 的 RTX PRO 6000 服务器上,如果测试卡住或报错,请加上 NCCL_P2P_DISABLE=1 重新运行。如果这次运行正常,问题就出在点对点(P2P)通信上:请在控制台提交工单,我们可以协助排查。
用 torchrun 启动 DDP 或 FSDP 任务
torchrun 会为每张 GPU 启动一个进程,并设置 PyTorch 分布式包所需的环境变量。在装有 PyTorch 的环境中,将以下检查脚本保存为 allreduce_check.py:
import os
import torch
import torch.distributed as dist
dist.init_process_group("nccl")
rank = int(os.environ["LOCAL_RANK"])
torch.cuda.set_device(rank)
x = torch.ones(1024, device="cuda") * (rank + 1)
dist.all_reduce(x)
print(f"rank {rank}: {x[0].item()}")
dist.destroy_process_group()
在全部 8 张 GPU 上运行它:
torchrun --standalone --nproc_per_node=8 allreduce_check.py
每个 rank 都应输出 36.0,即 1 到 8 之和。您的 DDP 或 FSDP 训练脚本也以同样的方式启动。DDP 在每张 GPU 上保留一份完整的模型副本,并对梯度求平均。FSDP 将参数、梯度和优化器状态分片到各张 GPU 上,因此可以训练单张 GPU 显存装不下的模型。任务卡住时,在命令前加上 NCCL_DEBUG=INFO。
多节点注意事项
- 网络。申请在您的服务器之间开通私有网络(在部署服务器时写在订单备注中,或在控制台提交工单),并让 rendezvous 和 NCCL 流量使用私有地址。
- 网络接口。用
ip找到私有网络接口,并在每个节点上将-br addr NCCL_SOCKET_IFNAME设置为该接口的名称,以免 NCCL 选中公网接口。 - 启动。在每个节点上运行同一条命令,只修改 rank。此处的
10.0.0.1代表第一个节点的私有地址:
在第二个节点上使用torchrun --nnodes=2 --nproc_per_node=8 --node_rank=0 \ --master_addr=10.0.0.1 --master_port=29500 train.py;如果启用了防火墙,请在节点之间放行该端口。--node_rank=1 - 高速互联。节点之间要以全速传输 GPU 流量,需要在您的服务器之间布线并配置 RDMA 网络(InfiniBand 或 RoCE),而私有网络并不提供这一能力。如果单个任务需要超过 8 张 GPU 以 NVLink 速度交换数据,GB300 NVL72 机架可以把全部 72 张 GPU 置于同一个 NVLink 域中。
问题仍未解决?
请在控制台提交工单,写明服务器、您运行了什么以及错误输出(如有)。工程师 7×24 小时答复。