为什么华为云上AI训练必须设置NCCL_IB_TC=128
一、网络组网
云上用于大规模AI训练的GPU服务器,一般会带2种网卡。1种接 VPC 普通网络平面,另1种接主机之间高速通信平面(AI 训练也把这个叫参数交换平面,后面简称「参数面网络」)。如下:
对应GPU服务器内可以看到:(第1个是vpc网卡,第2个是RoCE网卡)
本文只关注「参数面网络」,所以网络简化为:
分布式AI训练需要RDMA,而RDMA需要loseless网络环境。但我们云上使用RoCE(RDMA over Converged Ethernet)协议,走的是ethernet网络环境,无法提供loseless的网络。
为了让RDMA跑在ethernet上,必须想办法为ethernet提供不丢包的网络,来保证网络在因为网络拥塞快发生丢包的时候,及时让发送端降速,来保证网络不丢包。
参考:https://hurray0.com/menu/138/
二、参数面流控
为了实现流控,交换机上选择使用PFC(Priority Flow Control)功能来达成。而pfc又有2种策略,分别为:PCP(Priority Code Point) 和 DSCP(Differentiated Services Code Point)。
其中pcp是基于VLAN实现的,但是云上参数面报文,VLAN-ID已经被用来区分「租户」了,如下:
所以不能采用VLAN头,剩下的只能是DSCP了。DSCP中的(Differentiated Services)是指将网络报文「分类」进行路由,占用6个bit的报文头。不同的DSCP值的报文,具有不同的路由优先级。一般路由优先级有8个 (因为早期IP报文,里面有个TOS字段,用3bit来表示「优先级」,所以大部分路由设备,都认8个级别的优先级。):
所以优先级就有 0-7 总共8个一说。而DSCP有6bit,如下:
6bit总共有64种报文类型(只有部分高级路由设备,才能支持64种报文分类,大部分设备还是认8种优先级分类)。那怎么把 64种类的报文,映射成为8种优先级呢? 其实这里挺巧妙的:直接取前3位来表示优先级就行了。
即DSCP值的前3bit,表示报文优先级。
比如要设置报文优先级4 (4的二进制是: 100)。
DCSP值可以是:100X XXXX 任意值,即:128(1000 0000) - 159(1001 1111),都对应优先级4。
三、华为云优先级队列PFC
因为网络总共有8个优先级队列,华为云设计:队列4用于「AI训练的参数同步」报文,其余报文种类有其他控制逻辑。而PFC设置,是需要服务器+路由设备,同时配置才能生效的。所有参数面的交换机已经设置了队列4开启PFC了,所以必须服务器上,也得设置 开启4队列的优先级pfc功能。如下:
mlnx_qos -i "${if_dev}" --pfc 0,0,0,0,1,0,0,0 --trust dscp
队列4开启pfc功能,并且使用dscp模式。其中 {if_dev} 为网卡名,如enp80s0f0。
RoCE网卡往外发送报文的时候,有8个队列。每个队列对应一个优先级,也是8个。可以通过
mlnx_qos -i网卡名
查询
Priority trust state: dscp
dscp2prio mapping:
prio:0 dscp:07,06,05,04,03,02,01,00,
prio:1 dscp:15,14,13,12,11,10,09,08,
prio:2 dscp:23,22,21,20,19,18,17,16,
prio:3 dscp:31,30,29,28,27,26,25,24,
prio:4 dscp:39,38,37,36,35,34,33,32,
prio:5 dscp:47,46,45,44,43,42,41,40,
prio:6 dscp:55,54,53,52,51,50,49,48,
prio:7 dscp:63,62,61,60,59,58,57,56,
default priority:
Receive buffer size (bytes): 20016,156096,0,0,0,0,0,0,
Cable len: 7
PFC configuration:
priority 0 1 2 3 4 5 6 7
enabled 0 0 0 0 1 0 0 0
buffer 0 0 0 0 1 0 0 0
可以看到:dscp值 =》priority值 的表显示:dscp=32,会映射到优先级4.
而pfc流控配置显示,我们设置为:优先级队列4,开启pfc。
注:TOS位(对应Traffic Class)是8bit,而DSCP位是6bit。所以计算TC值,需要将DSCP值x4(左移2位)。比如:设置DSCP值为32,直接设置TOS值为128(32 x 4 = 128)。
在华为云上做大规模分布式的AI训练(使用参数面网络)时,需要确保网卡开启这个pfc配置。
四、报文优先级设置
网卡上,队列4开启了pfc流控功能。那我们怎么确保我们的报文,都是通过队列4发出去的呢?也就是我们怎么控制报文的DSCP值的?
答:控制某个网卡发出去的报文,都使用某个「流量类型」,即使用特定的DSCP值,可以使用方法:
echo 128 > /sys/class/infiniband/<dev>/tc/<port>/traffic_class
其中<dev>可以使用 ibdev2netdev 查询。
如 mlx5_0 这个网卡,设置发出去的报文都是128的Traffic Class值(注:128的TC值,会使用4号优先级队列。如前文所说 前3bit值为4),可以这么设置:
echo 128 > /sys/class/infiniband/mlx5_0/tc/1/traffic_class
如果网卡级别未设置,想在应用层控制报文的DSCP值,则可以在NCCL中的这个环境变量设置:
NCCL_IB_TC=128
效果是一样的。
参考:
五、网卡设置vs 应用层设置
2种方法,都可以控制报文的「种类」,或者说优先级。那就有一个问题:是否应该在网卡级别设置,使得应用层不用感知这个配置呢?
所以这里,就有一个问题:这2个配置,谁优先级高?即2个都配置时,听谁的?
经过验证:
网卡设置TC值为128(对应队列4), NCCL_IB_TC=127(对应队列3)时。结果发出去的报文是队列4的。
测试前:
/root # ethtool -S enp80s0f0 |grep prio |grep packets
rx_prio3_packets: 24147990
tx_prio3_packets: 12103235
rx_prio4_packets: 24147503
tx_prio4_packets: 48415259
测试后:
/root # ethtool -S enp80s0f0 |grep prio |grep packets
rx_prio3_packets: 36221890
tx_prio3_packets: 12103235
rx_prio4_packets: 24147503
tx_prio4_packets: 60518092
说明底层直接在网卡级别设置其实就足够了。
那为什么华为云还要求用户必须设置 NCCL_IB_TC=128 呢?
因为据测试,OFED 5.5 版本,存在bug:即网卡级别设置TrafficClass值不生效。(注:因为我环境版本是 5.4,所以未验证5.5是否真的存在这种bug)。
/root # ofed_info -s
MLNX_OFED_LINUX-5.4-3.1.0.0:
所以为了统一行为(确保报文使用pfc的优先级4队列),才要求用户在应用层设置:NCCL_IB_TC=128
参考:
https://docs.nvidia.com/networking/pages/viewpage.action?pageId=25134530
https://en.wikipedia.org/wiki/Differentiated_services
六、未设置发送队列影响
如果参数面报文,没有设置优先级队列,也就是没有契合交换机的PFC机制的话,可能触发丢包重传,导致训练速度时快时慢,严重时性能下降80%。
如下一个案例是,未设置pfc优先级队列4,看到性能异常的训练作业所在节点连接的TOR交换机流量明显小且存在中断。
而性能正常作业运行的交换机监控流量应该这样:
查看网卡的报文统计信息:
ethtool -S enp80s0f0 | grep pause
可以看到,有pause报文。
TOR交换机上,也看到入端收到服务器发来的pause帧,说明可能服务器网卡过载,来不及处理TOR交换机向其发送的数据。
正常情况下交换机应暂停向服务器发送数据,直到超时或收到服务器发来新的控制帧。在不正常情况下,例如服务器与交换机采用了不同的流控策略,pause帧没有生效,服务器维持原速度发送数据,最终可能因为服务器网卡buffer空间不足导致服务器端丢包。
所以,服务器与交换机pfc配置对齐还是非常重要的。
七、NCCL_IB_SL又是什么
本文在说NCCL_IB_TC可用于设置报文QOS级别,TC是TrafficClass的缩写。于是肯会顺道提到一个题外话,NCCL_IB_SL又是什么作用呢?SL是ServiceLevel的缩写。毕竟这2个参数都是能设置报文QOS级别的。
SL是L2层的,用于2种pfc方法中的“PCP”。
TC是L3层的,用于2种pfc方法中的“DSCP”。
它们处于IB报文头的不同位置。
总结:
QOS类似分2种:(1)L2的PCP。 (2)L3的DSCP
前面说了PCP是基于VLAN头的,咱们不使用VLAN模式进行QOS流控。所以不需要设置NCCL_IB_SL参数。
参考:https://blog.csdn.net/sunshuying1010/article/details/103661289
八、总结
这些应该明白为什么华为云上面AI训练必须设置NCCL_IB_TC=128了吧?文章有点偏底层,有兴趣的看看。
后面看看其他底层设置DSCP值的方法,尽量将这个用户层的约束(NCCL_IB_TC=128)去掉。如果你知道的话,也恳请留言告知。
注:cma_roce_tos –d <ib_device> -t <tos>
这个命令虽然也可以设置网卡发出去的报文DSCP值,但是它只能设置RDMA-CM的(configure ToS/DSCP for RDMA-CM QPs only),咱们参数通信应该是用的Verbs方法的。
参考:
https://linuxreviews.org/Type_of_Service_(ToS)_and_DSCP_Values
https://enterprise-support.nvidia.com/s/article/howto-set-egress-tos-dscp-on-rdma-cm-qps
- 点赞
- 收藏
- 关注作者
评论(0)