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 拓扑对带宽的影响

不同拓扑结构,带宽表现天差地别。我画了一张图,帮你理解:

GPU拓扑与AllReduce带宽关系 NVLink全互联(8卡) GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 busbw: ~184 GB/s PCIe环形(4卡) GPU0 GPU1 GPU2 GPU3 PCIe Switch busbw: ~30 GB/s 关键对比 • NVLink全互联:GPU之间直连,8卡双向带宽可达600GB/s(理论),实测busbw约184GB/s • PCIe环形:通过PCIe Switch中转,4卡共享带宽,实测busbw约30GB/s • 实际差距:NVLink比PCIe快5-6倍,大模型训练必须用NVLink

你看,NVLink全互联的拓扑,每个GPU都能直接和其他GPU通信,带宽自然高。而PCIe环形,数据要经过Switch中转,带宽就受限了。

4.6 实战建议

最后,我总结几条实战经验:

  1. 先看拓扑,再跑测试:用 nvidia-smi topo -m 确认GPU互联方式,心里有个预期。
  2. 关注大消息的busbw:小消息带宽低是正常的,别慌。重点看1GB以上消息的busbw是否接近理论值。
  3. 对比algbw和busbw:如果两者差距很小,说明通信算法效率高。如果差距很大,可能算法选择有问题。
  4. 多跑几次取平均:单次测试可能有波动,我习惯跑3次取中位数。

一句话总结:单机多卡测试的核心,就是验证GPU之间的通信带宽是否达到硬件预期。algbw是用户看到的,busbw是硬件实际跑的。两者结合,才能全面评估性能。

好了,单机测试就聊到这儿。记住,这一步是后续多机测试的基础。如果单机都跑不满,多机就更别想了。

可可精品资料库