为什么华为云上AI训练必须设置NCCL_IB_TC=128

举报
tsjsdbd 发表于 2023/05/30 16:27:06 2023/05/30
【摘要】 了解报文DSCP值与Traffic Class关系,明白为什么华为云上面AI训练必须设置NCCL_IB_TC=128。

 

一、网络组网

云上用于大规模AI训练的GPU服务器,一般会带2种网卡。1种接 VPC 普通网络平面,另1种接主机之间高速通信平面(AI 训练也把这个叫参数交换平面,后面简称「参数面网络」)。如下:

 

对应GPU服务器内可以看到:(第1个是vpc网卡,第2个是RoCE网卡)


本文只关注「参数面网络」,所以网络简化为:


分布式AI训练需要RDMA,而RDMA需要loseless网络环境。但我们云上使用RoCERDMA over Converged Ethernet)协议,走的是ethernet网络环境,无法提供loseless的网络。

为了让RDMA跑在ethernet上,必须想办法为ethernet提供不丢包的网络,来保证网络在因为网络拥塞快发生丢包的时候,及时让发送端降速,来保证网络不丢包。

                   参考:https://hurray0.com/menu/138/

 

二、参数面流控

                   为了实现流控,交换机上选择使用PFCPriority Flow Control)功能来达成。而pfc又有2种策略,分别为:PCPPriority Code Point) 和 DSCPDifferentiated Services Code Point)。

其中pcp是基于VLAN实现的,但是云上参数面报文,VLAN-ID已经被用来区分「租户」了,如下:


所以不能采用VLAN头,剩下的只能是DSCP了。DSCP中的(Differentiated Services)是指将网络报文「分类」进行路由,占用6bit的报文头。不同的DSCP值的报文,具有不同的路由优先级。一般路由优先级有8个 (因为早期IP报文,里面有个TOS字段,用3bit来表示「优先级」,所以大部分路由设备,都认8个级别的优先级。):


所以优先级就有 0-7 总共8个一说。而DSCP6bit,如下:


6bit总共有64种报文类型(只有部分高级路由设备,才能支持64种报文分类,大部分设备还是认8种优先级分类)。那怎么把 64种类的报文,映射成为8种优先级呢? 其实这里挺巧妙的:直接取前3位来表示优先级就行了。


DSCP值的前3bit,表示报文优先级。

 

比如要设置报文优先级4 4的二进制是: 100)。

DCSP值可以是:100X XXXX 任意值,即:1281000 0000- 1591001 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值,需要将DSCPx4(左移2位)。比如:设置DSCP值为32,直接设置TOS值为12832 x 4 = 128)。

 

在华为云上做大规模分布式的AI训练(使用参数面网络)时,需要确保网卡开启这个pfc配置。

四、报文优先级设置

网卡上,队列4开启了pfc流控功能。那我们怎么确保我们的报文,都是通过队列4发出去的呢?也就是我们怎么控制报文的DSCP值的?

 

答:控制某个网卡发出去的报文,都使用某个「流量类型」,即使用特定的DSCP值,可以使用方法:

echo 128 > /sys/class/infiniband/<dev>/tc/<port>/traffic_class

其中<dev>可以使用 ibdev2netdev 查询。

 

mlx5_0 这个网卡,设置发出去的报文都是128Traffic Class值(注:128TC值,会使用4号优先级队列。如前文所说 前3bit值为4),可以这么设置:

echo 128 > /sys/class/infiniband/mlx5_0/tc/1/traffic_class

如果网卡级别未设置,想在应用层控制报文的DSCP值,则可以在NCCL中的这个环境变量设置:

NCCL_IB_TC=128

效果是一样的。

 

参考:

https://docs.nvidia.com/networking/pages/viewpage.action?pageId=19798092#RDMAoverConvergedEthernet(RoCE)-DefiningEthernetPriority(PCPin802.1qHeaders)

 

五、网卡设置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级别,TCTrafficClass的缩写。于是肯会顺道提到一个题外话,NCCL_IB_SL又是什么作用呢?SLServiceLevel的缩写。毕竟这2个参数都是能设置报文QOS级别的。

SLL2层的,用于2pfc方法中的“PCP”。

TCL3层的,用于2pfc方法中的“DSCP”。


它们处于IB报文头的不同位置。

总结:

QOS类似分2种:(1L2PCP。 (2L3DSCP


前面说了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://edc.intel.com/content/www/us/en/design/products/ethernet/800-series-linux-flow-control-configuration-guide-for-rdma-use-c/determining-pfc-priority-mode-pcp-vs-dscp/

https://enterprise-support.nvidia.com/s/article/howto-set-egress-tos-dscp-on-rdma-cm-qps

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。