4、单机多卡测试:单节点内GPU拓扑与all_reduce_perf实战
好,咱们进入实操环节。单机多卡测试,说白了就是看看你手头这台机器里,GPU之间到底能跑多快。我个人习惯,拿到一台新机器,第一件事就是跑这个测试。为什么?因为很多性能问题,根源都在卡间通信上。
4.1 先搞清楚你的GPU拓扑
动手之前,我建议你先用 nvidia-smi topo -m 看一眼拓扑。这步很关键,能帮你预判结果。
# 查看GPU拓扑
nvidia-smi topo -m
输出大概长这样:
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 mlx5_0
GPU0 X NV2 NV2 NV2 NV2 NV2 NV2 NV2 PIX
GPU1 NV2 X NV2 NV2 NV2 NV2 NV2 NV2 PIX
GPU2 NV2 NV2 X NV2 NV2 NV2 NV2 NV2 PIX
GPU3 NV2 NV2 NV2 X NV2 NV2 NV2 NV2 PIX
GPU4 NV2 NV2 NV2 NV2 X NV2 NV2 NV2 PIX
GPU5 NV2 NV2 NV2 NV2 NV2 X NV2 NV2 PIX
GPU6 NV2 NV2 NV2 NV2 NV2 NV2 X NV2 PIX
GPU7 NV2 NV2 NV2 NV2 NV2 NV2 NV2 X PIX
看到 NV2 了吗?这代表NVLink 2.0。如果是 PIX 或者 PHB,那就是走PCIe了。嗯,这里要注意:NVLink的带宽通常是PCIe的5-10倍,差距非常大。
核心概念:NVLink是NVIDIA自家的高速互联技术,GPU之间直连,延迟低、带宽高。PCIe则是通过CPU和芯片组中转,路径长、带宽受限。
4.2 运行all_reduce_perf
拓扑看完了,咱们直接上 all_reduce_perf。这是NCCL官方提供的带宽测试工具,非常直观。
# 单机8卡测试,消息大小从256字节到8GB
./build/all_reduce_perf -b 256 -e 8G -f 2 -g 8
参数说明:
-b 256:起始消息大小,256字节-e 8G:结束消息大小,8GB-f 2:每次翻倍,即256、512、1K、2K...这样递增-g 8:使用8张GPU
跑起来之后,你会看到类似这样的输出:
#
# out-of-place in-place
# size count type redop root time algbw busbw #wrong time algbw busbw #wrong
# (B) (elements) (us) (GB/s) (GB/s) (us) (GB/s) (GB/s)
262144 65536 float sum -1 30.24 8.67 15.17 0 30.18 8.69 15.20 0
524288 131072 float sum -1 33.12 15.83 27.70 0 33.08 15.85 27.73 0
1048576 262144 float sum -1 38.45 27.27 47.72 0 38.40 27.30 47.78 0
2097152 524288 float sum -1 48.21 43.50 76.13 0 48.18 43.53 76.18 0
4194304 1048576 float sum -1 67.89 61.78 108.12 0 67.85 61.82 108.19 0
8388608 2097152 float sum -1 106.72 78.62 137.59 0 106.68 78.66 137.66 0
16777216 4194304 float sum -1 184.35 91.01 159.27 0 184.30 91.04 159.32 0
33554432 8388608 float sum -1 340.12 98.66 172.66 0 340.08 98.68 172.70 0
67108864 16777216 float sum -1 656.78 102.18 178.82 0 656.72 102.20 178.86 0
134217728 33554432 float sum -1 1289.4 104.10 182.18 0 1289.3 104.12 182.21 0
268435456 67108864 float sum -1 2556.7 104.98 183.72 0 2556.5 105.00 183.75 0
536870912 134217728 float sum -1 5098.2 105.30 184.28 0 5097.9 105.32 184.31 0
1073741824 268435456 float sum -1 10182 105.46 184.56 0 10181 105.48 184.59 0
2147483648 536870912 float sum -1 20349 105.54 184.70 0 20347 105.56 184.73 0
4294967296 1073741824 float sum -1 40682 105.58 184.77 0 40679 105.60 184.80 0
4.3 解读两个关键指标:algbw 和 busbw
输出里最重要的两列,就是 algbw 和 busbw。很多新手只看 algbw,其实 busbw 才是真正的硬件能力体现。
| 指标 | 全称 | 含义 | 典型值(8卡NVLink) |
|---|---|---|---|
| algbw | Algorithm Bandwidth | 算法带宽,即用户视角的通信速率 | ~105 GB/s |
| busbw | Bus Bandwidth | 总线带宽,即硬件实际传输速率 | ~184 GB/s |
为什么会有两个值?我解释一下。AllReduce操作,数据量是 N 个元素,但实际在总线上传输的数据量是 2 * (N - 1/N) * N 个元素(取决于算法)。busbw 把这个系数考虑进去了,所以它更能反映硬件的真实能力。
我的经验:判断NVLink是否正常工作,就看大消息下的 busbw 是否接近理论峰值。比如A100 8卡NVLink的理论双向带宽是 600GB/s(8卡 * 12条链路 * 50GB/s / 2),实际跑到 180-190 GB/s 就算正常。如果只有几十GB/s,那肯定有问题。
4.4 不同消息大小的表现差异
你仔细看上面的输出,会发现一个规律:小消息带宽低,大消息带宽高。为什么会这样?
- 小消息(< 1MB):通信延迟占主导,带宽利用率低。比如256字节的消息,algbw只有8.67 GB/s,远低于峰值。
- 中等消息(1MB - 100MB):带宽逐渐爬升,延迟影响减弱。
- 大消息(> 100MB):带宽趋于饱和,接近硬件极限。比如8GB消息,algbw稳定在105 GB/s左右。
我曾经遇到过一个案例:某用户说他的NCCL带宽只有理论值的60%。我一看测试结果,小消息带宽正常,大消息上不去。最后发现是PCIe Gen4降级到了Gen3,一根命令修复了。
注意:如果大消息的 busbw 远低于理论值,先检查PCIe链路状态:nvidia-smi -q -d PCI。常见问题包括:PCIe降速、NUMA不亲和、CPU频率限制等。
4.5 拓扑对带宽的影响
不同拓扑结构,带宽表现天差地别。我画了一张图,帮你理解:
你看,NVLink全互联的拓扑,每个GPU都能直接和其他GPU通信,带宽自然高。而PCIe环形,数据要经过Switch中转,带宽就受限了。
4.6 实战建议
最后,我总结几条实战经验:
- 先看拓扑,再跑测试:用
nvidia-smi topo -m确认GPU互联方式,心里有个预期。 - 关注大消息的busbw:小消息带宽低是正常的,别慌。重点看1GB以上消息的busbw是否接近理论值。
- 对比algbw和busbw:如果两者差距很小,说明通信算法效率高。如果差距很大,可能算法选择有问题。
- 多跑几次取平均:单次测试可能有波动,我习惯跑3次取中位数。
一句话总结:单机多卡测试的核心,就是验证GPU之间的通信带宽是否达到硬件预期。algbw是用户看到的,busbw是硬件实际跑的。两者结合,才能全面评估性能。
好了,单机测试就聊到这儿。记住,这一步是后续多机测试的基础。如果单机都跑不满,多机就更别想了。