3. nccl-tests基础:all_reduce_perf工具介绍
好,咱们今天来聊聊nccl-tests这个工具集里最核心的一个——all_reduce_perf。说实话,我刚开始接触NCCL性能测试时,第一反应就是:这玩意儿到底能测出什么?后来踩了不少坑,才慢慢摸清楚它的脾气。
3.1 all_reduce_perf是什么?
简单来说,all_reduce_perf是NCCL官方提供的一个微基准测试工具。它专门用来测量AllReduce操作的带宽和延迟。你想想看,在大规模分布式训练中,AllReduce几乎是每步迭代都要执行的操作——梯度同步嘛。所以它的性能直接决定了你的训练能跑多快。
我个人习惯,拿到一个新集群或者新网卡,第一件事就是跑一遍all_reduce_perf。为什么?因为这是最直观的“体检报告”。
核心价值:all_reduce_perf能告诉你,在给定的GPU数量和消息大小下,你的集群到底能跑出多少带宽,延迟是多少。说白了,就是给你的通信系统打个分。
3.2 命令行参数解析
咱们来看看最常用的几个参数。我当年第一次看这些参数时,说实话有点懵,但用多了就发现其实很直观。
| 参数 | 含义 | 我的经验 |
|---|---|---|
-b |
起始消息大小(bytes) | 通常设成8或16,测小消息延迟 |
-e |
结束消息大小(bytes) | 一般设成128M或256M,看显存 |
-f |
递增因子 | 默认2,也就是每次翻倍 |
-g |
使用的GPU数量 | 单机测就用8,多机测按实际来 |
-w |
预热轮数 | 我一般设5,让GPU先热起来 |
-n |
迭代轮数 | 建议至少100,数据才稳定 |
3.3 参数详解与实战技巧
-b 和 -e:消息大小的范围
这两个参数决定了你的测试覆盖范围。-b 8 -e 128M意味着从8字节一直测到128兆字节。为什么要从这么小开始?因为小消息测的是延迟,大消息测的是带宽。
我曾经遇到过一个案例:某厂商的网卡,大消息带宽表现很好,但小消息延迟高得离谱。如果只测大消息,根本发现不了问题。所以我的建议是:小消息和大消息都要测。
-f:递增因子
默认是2,也就是消息大小每次翻倍:8、16、32、64...一直到128M。我个人觉得这个设置挺合理的。为什么?因为通信性能通常跟消息大小呈对数关系,翻倍采样能覆盖到各个数量级。
但如果你时间紧,也可以设成4甚至10。不过要小心——跳得太快可能会漏掉某些拐点。嗯,这里要注意,有些网络在特定消息大小时会有性能突变。
-g:GPU数量
这个参数很关键。单机8卡就设-g 8,多机的话要配合--nthreads使用。我见过有人单机8卡却只设-g 1,结果测出来的全是单卡性能——这显然不是你想要的结果。
小技巧:如果你想测多机场景,记得在所有节点上同时启动all_reduce_perf,并且保证-g参数一致。我曾经因为一台机器设了8,另一台设了4,结果等了半小时没反应——后来才发现是参数没对齐。
-w 和 -n:预热与迭代
-w是预热轮数,-n是正式测试轮数。为什么要预热?因为GPU和网卡一开始可能处于省电模式,直接测的话性能会偏低。我一般设-w 5 -n 100,预热5轮,正式测100轮取平均。
你可能会问:100轮够吗?说实话,对于大多数场景足够了。但如果你的网络抖动比较大,可以增加到500甚至1000轮。不过要注意测试时间会变长。
3.4 理解带宽与延迟
好,咱们来聊聊这两个核心概念。说白了,带宽是“能跑多快”,延迟是“反应有多慢”。
举个例子:你从北京寄快递到上海。带宽相当于高速公路的宽度——路越宽,同时能跑的车越多。延迟相当于从发货到收货的时间——哪怕路再宽,快递也得花时间在路上跑。
在NCCL测试中,你会看到两个关键指标:
- Algo Busy Bandwidth:算法层面的带宽,反映了实际数据传输速率
- Time:每次操作的平均耗时,也就是延迟
我刚开始看这些数据时,总以为带宽越高越好。后来发现不对——对于小消息,延迟才是关键。比如8字节的消息,带宽再高也没用,因为传输时间主要花在握手和协议开销上。
避坑指南:我曾经在测试时发现带宽数据忽高忽低,排查了半天才发现是其他进程在占用GPU显存。记住:测试前要确保GPU空闲,否则数据会严重失真。
3.5 一个完整的测试示例
咱们来看一个实际命令:
# 单机8卡,从8字节测到128M,翻倍递增,预热5轮,正式测100轮
mpirun -np 8 ./all_reduce_perf -b 8 -e 128M -f 2 -g 8 -w 5 -n 100
输出大概长这样:
# nThreads 1 nGpus 8 minBytes 8 maxBytes 134217728 step: 2(factor)
#
# size time algbw busbw
# (B) (usec) (GB/s) (GB/s)
8 12.3 0.00 0.00
16 12.5 0.00 0.00
32 12.8 0.00 0.00
...
1048576 125.6 8.35 7.31
2097152 210.3 9.97 8.72
4194304 380.1 11.03 9.65
8388608 720.5 11.64 10.19
16777216 1380.2 12.15 10.63
33554432 2680.5 12.52 10.96
67108864 5280.8 12.71 11.12
134217728 10480.2 12.81 11.21
看到没?小消息时(8-32字节),时间基本不变,大约12微秒——这就是延迟。随着消息变大,时间线性增长,带宽逐渐趋于饱和。在这个例子里,最大带宽大约11.21 GB/s。
3.6 知识体系总览
为了让你更直观地理解这一章的内容,我画了一张图:
这张图把咱们这一章的核心内容串起来了。左边是参数配置,中间是工具本身,右边是测试场景,下面是最终目的。你每次跑测试前,可以对照这张图检查一下:参数设对了没?要测什么指标?场景是什么?
好了,关于all_reduce_perf的基础用法就聊到这儿。记住一句话:工具是死的,场景是活的。同样的参数在不同集群上跑出来的结果可能天差地别,关键是要理解每个参数背后的意义。
我的建议:刚开始接触时,先用默认参数跑一遍,看看输出长什么样。然后逐步调整参数,观察变化。这样你就能慢慢建立起直觉——什么样的数据是正常的,什么样的数据说明有问题。
想要更多资料,联系可可