前阵子帮朋友排查一个万卡训练集群的异常,现象很典型:GPU利用率掉到60%以下,NCCL的AllReduce时延飙到正常值的两倍,甚至出现周期性的“掉卡”报错。折腾一圈下来,问题出在RoCEv2网络的PFC死锁和ECN水线配置上。说实话,这类故障在现在的AI Infra团队里太常见了——大模型训练网络已经把RoCEv2逼到了极限,而很多人对它背后的运行机制还停留在“无损以太网”这个模糊概念上。
如果你也在做大模型训练相关的工作,无论是网络工程师、AI平台运维,还是算法工程师想搞明白自己训练作业为什么变慢,这篇文章都值得看完。我会从RoCEv2为什么能扛起大模型训练网络讲起,拆解它的核心技术原理,再落到实际部署中的拓扑设计、参数配置和故障排查。全是实际集群里验证过的东西,不是网上抄来的概念。
1. 大模型训练把网络逼到了什么地步
1.1 从数据并行到MoE:通信模式的质变
大模型训练的网络负载,跟传统云计算的“南北向流量”完全不同。传统业务大多是客户端到服务器的小流量、高并发,而训练集群里是GPU卡之间的“东西向流量”,而且是动辄几十GB的集体搬运。
拿经典的AllReduce来举例。数据并行场景下,每张卡算完自己的梯度,需要把梯度Reduce一下再广播回去。几万张卡同时做这个操作,通信量不是简单相加,是成倍放大。这里有一个大家常用的估算公式:一次AllReduce的数据量约等于模型参数量的2倍,时间步数一叠加,单位时间内要搬的字节数非常惊人。到了千亿参数模型,单次AllReduce就要搬运200GB以上的梯度数据,而一个训练iteration往往只有几秒,留给通信的时间窗口极其苛刻。
真正让网络压力陡增的,是MoE(混合专家)模型的普及。MoE模型里每个token只会经过部分专家,这就导致序列在不同的专家之间反复分发和聚合,形成了大量的All-to-All通信。这种通信模式下,每张卡都可能和集群里的任意一张卡交换数据,流量模式不再是规律的环形或树形,而是变成了一张无形的“全网乱序蜘蛛网”。
再加上张量并行和流水线并行,不同并行维度之间还有各自的通信需求。一个典型的千亿参数训练作业,往往同时存在:
- 数据并行的AllReduce(全卡参与,大数据量)
- 张量并行的AllReduce(节点内,小数据量高频率)
- 流水线并行的点对点通信(前后层之间,中等数据量)
- MoE场景的All-to-All(全网卡间随机通信,突发性强)
这四种通信流量叠加在一起,网络里的流量模型已经不是“潮汐式”的,而是随时可能瞬间打满任何一个端口。传统TCP的拥塞控制在这种场景下根本来不及反应,一旦出现微小的拥塞,丢包重传就会让通信时延成倍放大,训练迭代速度直接崩盘。
1.2 训练网络真正的三条硬指标
我们评估一张训练网络到底行不行,核心看三个数字:有效带宽、尾延迟、丢包率。
有效带宽好理解,就是训练通信能实际用到的带宽,而不是网卡的标称速率。很多情况下明明都是400G网卡,实际NCCL跑出来的带宽只有300G甚至更低。差距就出在网络协议的效率上。
尾延迟是很多算法工程师容易忽略的指标。大模型训练是典型的同步并行模式——每一轮迭代都要等所有GPU都算完、通信完成才能进入下一轮。哪怕9999张卡都完成了,只剩下1张卡因为网络重传慢了100毫秒,整个集群都得等它。所以训练网络对延迟的要求不是“平均延迟低”,而是“最差延迟也不能高”。RoCEv2的PFC机制也好,拥塞控制也好,本质上都是在努力压住那个尾延迟。
丢包率就更致命了。对普通Web服务来说,0.1%的丢包可能只是让页面加载慢了一点,用户感知不强。但到了RDMA网络里,RoCEv2的硬件卸载机制对丢包极其敏感,一个报文丢了,整个发送队列可能都要停下来等重传,实际的通信效率会断崖式下跌。这也是为什么RoCEv2要依赖PFC这类流控手段来保证“无损”——它不是洁癖,是没办法。
2. RoCEv2的技术底座:无损以太网是怎么炼成的
2.1 为什么传统以太网在RDMA面前不够用
先简单回顾一下RDMA的演进。RDMA(Remote Direct Memory Access)本来是InfiniBand(IB网络)的看家本领,它允许网卡直接读写对端主机内存,绕过CPU和内核协议栈,把延迟做到微秒级别。但IB网络的问题是贵,而且需要专用的交换机、专用线缆,生态封闭。
于是就有了RoCE(RDMA over Converged Ethernet)方案。第一代RoCEv1直接MDA在以太网二层上,不能跨VLAN路由,只能在同一个二层域里玩,无法应对大规模集群组网。到了RoCEv2,把RDMA报文封装进了UDP/IP里,这样就能依赖标准的三层路由跨子网传输,从根本上解决了规模扩展的问题。RoCEv2也因此成了目前绝大多数AI训练集群的默认选择。
为什么传统TCP以太网干不了这个活?本质原因是TCP为“尽力而为”的互联网设计,重传机制健壮但开销太大。TCP的发送窗口和ACK机制在长肥管道里需要很长的建立时间,而且CPU需要处理大量中断和协议栈逻辑,根本无法支撑上万张卡同时以接近线速的速率通信。RDMA则把整个数据传输路径卸载到网卡的硬件里,从内存到内存,核心CPU完全不参与用户态数据拷贝。一台机器上的两张400G RDMA网卡,CPU占用率能控制在个位数以内,换成传统网卡打满就得烧掉好几个核。
2.2 PFC机制:为无损付出的“刹车”代价
要实现无损以太网,关键在流控。RoCEv2依赖的核心机制是802.1Qbb,也就是PFC(Priority Flow Control,优先级流控)。
PFC的思路很朴素:交换机上每个端口有多个队列,按优先级区分。当某个高优先级队列的缓冲占用超过阈值时,交换机就会向对端发送一个PAUSE暂停帧,让对方在指定时间内暂停发送这一优先级的流量。等到缓冲区降下来,再发一个恢复信号。这就像高速公路上前方车流拥堵,交警大哥用对讲机喊话:“后边的车先停一停,别往前挤了。”
PFC看起来是个好方案,但在大规模训练集群中暗藏杀机。最典型的问题就是PFC死锁——也叫PFC风暴。当网络拓扑中存在环路(包括逻辑环路)时,A交换机发PFC暂停B,B暂停C,C又暂停A,形成一个环形等待,队列头部阻塞,整个网络的吞吐量瞬间归零。就算没有物理环路,优先级设计不合理造成的拥塞树也能导致类似问题。
我调研过不少大型训练集群,很多团队对PFC是又爱又恨。有经验的网络团队会把PFC的buffer阈值调得异常保守,宁可让队列多留些余量,也不轻易触发流控。另外还要给PFC预留独立的优先级队列,不像普通业务流量那样混在一起。这里先留个悬念,具体怎么配,我在后面章节会有完整的实操说明。
2.3 ECN和DCQCN:避免“刹过头”的关键
PFC是粗粒度的链路层流控,只有“停”和“走”两个状态,很容易刹过头。真正让RoCEv2在拥塞控制上具备“细颗粒度”的,是ECN(显式拥塞通知)配合DCQCN拥塞控制算法。
ECN的原理是:交换机检测到队列长度超过阈值后,不再发送暂停帧,而是在IP包的ECN字段上打个标记。接收端看到这个标记,就生成一个CNP拥塞通知报文,反向发给发送端。发送端收到CNP后按比例降低发送速率,同时周期性探测是否恢复,如果一段时间没有新的CNP,就逐渐提升速率。这个机制类似聪明的高速公路管理:不是直接封路,而是通过广播告诉所有司机“前方拥堵,请减速慢行”,让车流平滑地调整速度。
DCQCN算法里有两个参数很有意思:一个是注水速率,恢复到原速的速度;一个是降速比例,收到CNP后砍掉多少速率。如果降速太激进,会浪费带宽;如果太温和,拥塞又控制不住。实际调优时,这两个参数往往要结合具体的流量模型反复测试。我在3.2节会有具体的配置参考值。
有了PFC + ECN + DCQCN三件套,RoCEv2才能实现在普通以太网硬件上跑出接近InfiniBand的效果。但要注意,“无损”只是优先队列层面的无损,不是真正意义上所有流量都不丢包。理解了这个底层逻辑,后面很多故障排查就有头绪了。
2.4 RoCEv2和InfiniBand:绕不开的选型命题
聊RoCEv2就绕不开和InfiniBand的对比。头部互联网公司的超大集群,以及很多云计算大厂,旗舰训练集群往往选择IB网络,理由很简单:IB设计之初就是给HPC的RDMA用的,天生的无损架构,有自研拥塞控机制(比如NPB、自适应路由),稳定性更可控。但IB的问题也摆在明面上——贵、专有、绑定厂商。
InfiniBand实现同等规模组网的成本通常比RoCEv2高出50%甚至更多。而且IB交换机的开放性和可编程性不如白盒以太网,运维团队想做深度调优和监控时受约束更多。不可否认IB依然是性能天花板,但RoCEv2在成本和通用性上的优势,让它在绝大多数企业级大模型训练场景里成了务实之选。
我的观点是:如果团队预算充裕、有专职高性能网络工程师长期维护,选IB省心。如果预算有限、更追求灵活性和生态兼容,RoCEv2是个够用的方案,前提是你得愿意花时间在它的PFC、ECN调优上。据我了解,国内许多训练集群走的都是“RoCE为主、IB为辅”的路线,实际跑出来的吞吐量差距已经很小了。
3. 训练集群中的RoCEv2拓扑设计与配置实操
3.1 两层还是三层:Spine-Leaf拓扑的取舍
RoCEv2网络设计的第一步,是确定拓扑。目前主流的训练集群是Spine-Leaf(叶脊)架构,这也是为了支撑大模型的All-to-All流量而做的必选项。
两层Spine-Leaf是常见的配置:所有Leaf接入交换机和所有Spine核心交换机之间做ECMP等价多路径,GPU服务器挂在Leaf下,全网任意两台服务器之间的路径数等于Spine的数量。以大热的400G RoCE网络为例,假设有64个Spine端口、128个Leaf,理论上有64条等价路径。流量进入网络后,哈希算法会把这些流量尽量均衡地分散到64条链路上。
但两层架构在巨型集群面前会有瓶颈。一个万卡集群,单机8卡,就需要1250台GPU服务器,按照一台服务器2个400G端口接入来算,至少需要2500个Leaf接入端口。如果Spine层要提供足够的带宽收敛比,就需要成倍的Spine交换机,机架空间、功耗、光纤数量都是巨大的负担。所以很多超大规模集群会选择三层设计,在Spine之上再加Core层,好处是扩展性好,坏处是路径变长、延迟增加,而且PFC死锁的风险范围更大。
从实际经验看,千卡以下集群用两层完全够,万卡级建议直接上三层,中间不要再抠收敛比——训练网络的收敛比必须做到1:1,任何收敛都意味着流量无路可走,拥塞概率急剧上升。
3.2 交换机选型与buffer预算的硬道理
RoCEv2最吃交换机的地方在于buffer,也就是端口缓冲区。为什么buffer这么关键?因为RoCEv2的“无损”依赖PFC和ECN来吸收瞬时突发流量。当多个GPU同时向一个端口灌流量,瞬间的burst可能超过链路带宽,队列来不及排队就必须有buffer来缓冲。Buffer不够,交换机只能丢包,丢包对RoCEv2的伤害远大于对TCP的伤害。
在选型上,我建议明确区分“深buffer”和“浅buffer”交换机:
- 深buffer交换机,典型单端口共享buffer在几十MB以上,适合核心层和汇聚层。
- 浅buffer交换机,典型共享buffer只有几MB到十几MB,适合接入层且流量相对规律的场景,但如果在接入层承担过多突发流量,很快就会成为瓶颈。
厂商的具体数值差异很大,但都要围绕一个公式来算:总buffer除以活跃端口数,得到单端口有效buffer。比如一台交换机共享内存32MB、有128个端口,单端口能拿到的buffer只有256KB。在400G端口上,256KB只够缓存约0.005毫秒的流量,一个微小的转瞬即逝的脉冲就能打穿。所以大型训练集群的交换机选型,预算再紧,核心层的buffer口碑也不能含糊,否则后续排查PFC风暴时你就知道了,光看计数器都会怀疑人生。
3.3 部署配置的完整命令与参数备忘
下面给出一套经过实测的RoCEv2部署配置模板,适用于主流的Cumulus Linux或SONiC系交换机。这里以MLNX_OFED驱动环境下的Linux主机侧和交换机侧为例,代码片段可以直接参考,具体参数请根据自己的网络规模和流量模型调整。
交换机侧核心配置(SONiC风格示意):
# 启用PFC,为RoCEv2流量预留优先级队列(此处以优先级3为例) # 400G需要精确计算阈值,此时假设交换机共享buffer为32MB # 开启该优先级队列的PFC能力 config qos pfc enable 3 # 设置ECN水线,阈值可以先用保守值 # 低阈值为共享buffer 40%,高阈值60% config qos ecn 3 low-watermark 40000 high-watermark 60000 # 配置无损队列的调度权重,让RoCEv2流量相对其他业务获得高优先级 config qos scheduling-priority 3 weight 8主机侧配置(Mellanox网卡推荐参数):
# 查看当前网卡的RoCE模式,确保是RoCEv2 sudo mlxconfig -d mlx5_0 query | grep ROCE # 开启自适应速率和ECN支持 sudo mlxconfig -d mlx5_0 set ROCE_MODE=2 # 1=RoCEv1, 2=RoCEv2 sudo mlxconfig -d mlx5_0 set ECN_ENABLE=1 # QP拥塞控制参数(DCQCN相关,数值为建议起点) sudo mlxconfig -d mlx5_0 set CC_ACTIVE=1 sudo mlxconfig -d mlx5_0 set CC_QOS_LINK_BW=1000很多团队刚上手时把ECN水线设得很激进(低阈值设得很小),结果交换机动不动就打上ECN标记,DCQCN频繁降速,带宽反而跑不满。我的建议是初期把ECN水线调得保守一些(阈值高一些),让PFC兜底,先确保无丢包,再逐步调低水线寻找带宽和时延之间的平衡点。
3.4 多租户场景下的QoS与隔离设计
训练集群往往不是单一团队独占,多个训练任务、推理服务共存,这时候QoS设计的价值就体现出来了。很多集群出问题,不是RoCEv2本身不行,而是不同业务的流量互相干扰。
方案一是按物理隔离,比如按GPU分区划分独立的网络平面,每个租户独享一套RoCEv2网络平面。好处是隔离彻底、故障边界清晰,坏处是可扩展性差、成本高。方案二是通道隔离,在共享物理网络的基础上,用VLAN + PFC优先级队列区分业务。RoCEv2流量的优先级队列固定在一个PFC class上,其他流量走普通队列,互不干扰。
实际运维中,我强烈建议至少在服务器侧给RoCEv2流量和存储流量分配不同的优先级队列。我们遇到过的最典型的故障场景是:存储集群在做数据备份时,突发流量占满了整条链路,直接把正在训练的任务挤成了乌龟爬。后来通过在交换机侧将存储流量压入低优先级队列、训练流量保留在高优先级队列,这个问题才彻底解决。
4. 训练集群中那些磨人的RoCEv2故障与排查实录
4.1 PFC风暴:一条命令定位问题的完整链路
先讲一个我实际处理过的案例。客户反馈2000卡训练集群的吞吐量从日均85%突然跌到30%,NCCL测试跑出来的AllReduce带宽不到正常值的一半。第一反应是排查链路,光看端口流量全部正常,没有任何链路错误。然后看GPU,也没有异常。最后把目光落到交换机PFC计数器上。
# 在交换机上查看PFC控制帧计数(SONiC) show pfc counters # 输出留意每个端口高优先级队列的PFC Tx/Rx计数和Duration不问不知道,一问吓一跳:所有Leaf上联Spine的端口,PFC Tx计数都在疯狂上涨,说明Leaf一直在被Spine“喊停”。这就是典型的PFC风暴前兆。接下来做的是逐段定位哪个端口在持续发送PFC暂停帧,以及哪个前置节点在持续接收PFC。用如下命令逐级排查:
# 查看具体端口的PFC暂停帧计数及持续时间 show queue pfc counters <interface> # 查看Ingress/egress队列的Byte计数,找出异常增长队列 show queue counters <interface>通过对比发现,故障源不是服务器,而是某几台Spine上联Core的端口。这些端口的PFC暂停帧持续较长,并且这些暂停帧引起了上层交换机的队列堆积,最终蔓延到全网。问题本质是:连接多个Leaf的某台Spine交换机buffer已经耗尽,因为某个训练任务突然产生了全网All-to-All通信,链路过载,PFC在整个网络上“连锁踩刹车”。
根因确认后,我们做的不是加buffer,而是针对这个大流量任务单独调控优先级,并重新分配ECN水线,让拥塞反馈更快、更早到达发送端,而不是等到buffer耗尽才开始PFC。从那以后,这个集群的PFC风暴再没有发生。
4.2 ECN参数调优:为什么水线调低反而变好了
另一个常见现象是带宽跑不满。刚接入RoCEv2时,如果按厂商默认参数跑,很多集群达到预期的八成性能就不错了。问题往往出在ECN水线上。
举一组实测数据。某集群跑GPT-3级别模型,默认配置下ECN标记率大概在0.1%到0.2%,但带宽只能到260G/400G。后来把ECN低水线从40000(KB)下调到30000,高水线从60000下调到50000,重点是把DCQCN的降速比例从默认值调得更平滑,带宽反而提升到340G/400G,同时尾部时延还下降了5%。原因很简单:默认水线太高,交换机要等到队列堆积很严重才打ECN标,这时候拥塞已经扩散了,速度已经刹不住了。而水线调低之后,拥塞能在早期被发现,发送端及时微调,反而避免了大幅降速。
不过ECN水线不是越低越好。有次我们把低水线从30000压到20000,结果出现了TCP-like的锯齿波,流量忽高忽低,有效带宽反而下降。ECN标记率超过了3%,DCQCN在“快速降速、缓慢恢复”之间反复横跳。所以调参要有耐心,每次只动一个变量,标记率、带宽、时延三个指标一起记录。
4.3 一条CC消息引发的“血案”:拥塞通知报文的影响
RoCEv2的拥塞通知报文CNP虽然不是什么庞然大物,但它在高拥塞时的行为极其重要。CNP是接收端发给发送端的,告诉对方自己收到了带ECN标记的包,请降速。问题在于CNP本身也消耗网络资源,而且它是高优先级,如果交换机的CNP处理路径和RoCEv2普通数据报文出现在同一个队列,会加剧拥塞。
很多厂商默认把CNP放在最高优先级队列,这本身没问题,但如果同时存在大量CNP,它占了无谓的带宽,实际数据带宽就会下降。排查时可以看CNP计数器:
# 网卡侧查看CNP计数 ethtool -S <interface> | grep -i cnp # 交换机侧查看PFC和ECN相关计数器 show pfc counters我见过一个极端案例:某厂商网卡在特定固件版本下,CNP生成频率异常高,导致全网吞吐下降20%,最后通过升级网卡固件、调整ECN阈值才解决。这种问题最难就是因为单看数据面一切“正常”,只能靠CNP计数器对比各个节点的数据来定位。
4.4 NCCL测试与日常监控:给RoCEv2做体检的正确姿势
排查完后,日常监控不能掉链子。我固定每个季度会对训练集群做一次RoCEv2专项体检,工具和命令如下:
perftest套件(ib_write_bw、ib_read_lat):直接测RDMA收发带宽和时延,判断网卡和链路健康度。nvidia-smi dmon:配合监控GPU利用率、显存读写和NCCL通信占比。ethtool -S:观察网卡侧丢包、CRC错误、CNP、PFC暂停帧。- 交换机侧:持续采集PFC计数、ECN标记计数、buffer占用率、端口瞬时流量。
体检结果要画成趋势图,重点看三个指标的周环比:PFC暂停帧计数、ECN标记率、CNP计数。任何一个出现持续上升,都说明拥塞在积累,有演变成大故障的苗头。正常的集群这三类计数应该是低而平稳的。
5. 从运维视角看RoCEv2的底线与未来
做运维越久越明白,RoCEv2不是万能的,但它确实是大模型训练网络当下最务实的一种解法。相比InfiniBand的封闭和昂贵,RoCEv2给了我们一个“基于标准以太网”的持久化方案。哪怕是新建网络,未来从RoCEv2迁移到更新的无损方案,风险也可控。
我的核心体会是:RoCEv2的好坏很大程度上取决于运维团队对它的理解深度——PFC、ECN、DCQCN这三套机制像三根绳子,系紧了会勒死性能,放松了又会丢包。你必须建立一整套监控、告警和快速定位能力,才能真正“扛起”大规模训练网络。很多人选RoCEv2是为了省钱,结果省下来的硬件成本,最后都变成了人力排查成本,这一点大家要有心理准备。
最后分享一个小技巧:在集群环境里做RoCEv2变更,一定记得先在单台机器上验证,再批量下发。我们曾经因为在交换机上统一调整ECN阈值,结果不同厂商、不同型号的交换机对阈值的单位理解不一样,导致全网流量雪崩,训练中断了两个小时。从那以后,我养成了每次只动一小批端口、观察半小时再继续的习惯。这个习惯,建议你也养成。