ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从PFC到ECN:AI训练无损网络的拥塞控制全解

从PFC到ECN:AI训练无损网络的拥塞控制全解 1. 一次训练中断排查丢包为什么会拖垮整个集群去年秋天我碰到过一次特别棘手的训练中断事故。4千亿参数的多模态模型256张A100跑分布式训练loss曲线在关键的第三个epoch突然拉平然后开始周期性出现NaN。第一反应是代码有bug算法同事排查了两天毫无头绪最后我用ethtool -S检查网卡计数器才发现端口的rx_pause计数在训练峰值时暴涨了几百万次——这根本不是代码问题是网络丢包引发的连锁反应。这里必须先澄清一个容易混淆的点。标题里的PFC在网络领域指的是Priority Flow Control优先级流控IEEE 802.1Qbb标准里定义的东西跟电源圈常说的功率因数校正Power Factor Correction完全是两码事。你在搜索引擎敲PFC出来的往往是图腾柱电路、交错并联、电压电流双环控制这些电源设计的内容跟本文讨论的数据中心无损网络没关系。做网络的人聊PFC一定要带上前缀说网络PFC或者直接说802.1Qbb否则容易跟硬件同事聊岔。回到事故本身。分布式AI训练的流量特征跟传统互联网业务差别太大了。传统Web服务是典型的请求-响应模型一个用户点一下后台返回几百KB的页面流量稀疏、偶发、对延迟不敏感。AI训练完全反过来它跑的是All-to-All通信模式——每个GPU都要把梯度发给另外所有GPU同时从所有GPU接收梯度。Singularity等分布式框架会周期性地进行全局梯度同步每一次同步都意味着几千个GPU同时往交换机的同一个端口方向灌数据形成极其猛烈的incast突发。这种突发流量有多猛我给你一个直观数字。128台GPU服务器做梯度同步每台服务器在几十微秒内喷出1MB数据汇聚到核心交换机时瞬时带宽需求能达到理论线速的5到10倍。交换机内部的缓存通常是8到16MB面对这种突发几百微秒就会填满。缓存一满交换机只能做一件事——把后续到达的数据包丢掉。丢包对传统TCP业务来说很常见重传就行最多慢一点。但在RDMA远程直接内存访问场景下丢包是灾难性的。RDMA的通信语义是要么全部完成要么什么都不算数一个报文丢了整块数据就算失败接收端的网卡直接把整段内存数据丢弃发送端必须从更上层的协议栈重新发起。更麻烦的是RDMA网卡里的重传逻辑非常苛刻一旦重传次数超限QPQueue Pair就直接进入错误状态需要应用层手动重置。一个QP报错往往牵动整个训练通信库的teardown于是几百个GPU全部停下来等网络恢复。这就是那一串NaN的真相。所以AI训练怕丢包怕的不仅仅是重传带来的延迟而是丢包引发的级联故障——包丢失导致QP错误QP错误导致集合通信中断集合通信中断导致整个训练作业挂起。网上搜wifi的丢包率怎么测试那是家用网络测速的思路跟数据中心训练网络的丢包治理完全不是一个量级的问题。为了保住RDMA业界祭出了PFC这把大杀器。2. PFC的工作机制交换机之间互相拉闸的无损方案PFC的初衷非常朴素既然缓存满了会丢包那我就在缓存快满的时候让上游设备暂时停手等等我。它的本质是逐跳流量控制在相邻两台交换机之间建立刹车机制。2.1 队列级别的流控逻辑传统以太网的流控是粗粒度的一停全停802.3x标准里的PAUSE帧就是干这个的。PFC把它精细化到优先级队列层面。802.1Q标准里每个数据帧的VLAN Tag带有3位PCP字段能区分8个优先级。PFC在每台交换机的每个端口上维护8个独立的队列每个队列对应一个优先级。当某个队列的缓存占用超过高门限XOFF阈值交换机就向对端设备发一个PFC Pause帧里面带着一个优先级位图明确说优先级3的流量先停一停。对端收到后只暂停该优先级的发送其他优先级照常跑。当缓存回落到低门限XON阈值以下交换机会再发一个Resume帧Pause帧里时间参数为0对端恢复发送。门限值的设置很有意思。设得太小Pause帧发得频繁链路利用率降低设得太大缓存还没到门限就已经开始排队延迟增大。工业界通常把XOFF设在总缓存的60%到70%XON设在30%到40%留出足够余量让Pause帧在缓存溢出前到达对端。这里必须考虑Pause帧的飞行时间——对端收到Pause后端口上可能还有几十KB的数据已经在链路上了所以门限必须大于链路带宽 × 链路往返时间否则就会出现刹车踩了还追尾的丢包。2.2 PFC依赖的物理条件PFC对链路质量有隐性要求。它对端口的CRC错误、物理误码零容忍。你想如果链路本身存在微小的误码哪怕PFC保证了一个包都不丢坏帧照样会被丢弃RDMA照样报错。所以无损网络机房里光模块的验收标准比普通数据中心严苛得多很多团队要求链路误码率低于10的负15次方并且用perfquery、ibstatus反复巡检光模块的接收功率和误码计数。我还想强调一点PFC是逐跳的不是端到端的。它的控制范围只在相邻两台设备之间数据从服务器A经过三台交换机到服务器B任何一段链路的缓存压力都得靠自己这一段PFC消化它不会跨设备传递拥塞信息。这意味着拥塞点一旦出现在核心交换机上网卡和接入交换机之间的PFC只能兜住自己的这一段核心交换机的缓存仍会被打爆。这也是PFC后期备受诟病的原因之一——它管得了局部管不了整体。3. 无损网络的代价头端阻塞、风向标反转与PFC风暴PFC解决了丢包问题却放出了一堆更阴险的恶魔。很多团队上了无损网络之后业务没变快反而出现各种莫名其妙的时延抖动和吞吐归零。这里的坑之深真的只有趟过的人才知道。3.1 头端阻塞Head-of-Line Blocking先说最经典的头端阻塞。假设一个交换机端口有8个优先级队列其中队列3跑的是RDMA流量队列5跑的是普通TCP存储流量。突然队列3拥塞了PFC把上游的队列3暂停但共享同一个物理端口的其他队列不受影响这是PFC比老PAUSE帧强的地方。然而问题出在交换机内部的转发结构上——很多交换芯片的端口之间共享缓存和仲裁资源队列3把物理链路的传输能力占满队列5的报文即使有自己的队列也需要等待链路空闲才能发出去。更严重的情况是拥塞反向传播。端口A的队列3拥塞它向交换机X发Pause交换机X的队列3暂停发送后X的入端口继续接收来自服务器C的数据X的队列3缓存越积越多于是X又向上游交换机Y发Pause。就这样一层一层反向拉闸拥塞像多米诺骨牌一样从核心交换机一路传到接入交换机最后传导到发出数据的网卡上。整个网络的RDMA流量全被暂停而暂停的原因可能只是某个端口的瞬间拥塞。3.2 PFC风暴与死锁PFC还有一个极其可怕的异常场景——PFC风暴。由于网卡固件bug或者交换机芯片的缓存状态机错乱某个端口可能会疯狂地向对端发送Pause帧即使它根本没有拥塞。对端收到后傻乎乎地把对应优先级全部停掉导致该链路的RDMA流量完全中断。2019年某云厂商就出过这类事故一个交换机端口的异常Pause帧让整个可用区的一半GPU服务器训练中断4个小时。更有意思的是死锁场景。两台交换机互相之间都有流量A向B发PauseB的缓存满了也要向A发Pause如果两个Pause帧在链路上交叉着飞双方都在等对方恢复发送而双方也都在暂停发送——这就是PFC死锁。死锁期间链路完全静止没有任何数据帧通过直到某个超时机制介入强制丢弃Pause帧才恢复。虽然交换芯片厂商做了很多防护比如Pause帧超时自动忽略但这类问题在大型无损网络中依然偶有发生。3.3 PFC是拥塞控制的风向标反转我最想吐槽的是PFC把拥塞信号藏起来了。传统TCP的拥塞信号是丢包丢包意味着网络过载TCP会主动退让。PFC的无损设计把丢包消灭了但它制造了另一个问题——拥塞信号变成了Pause帧而Pause帧在转发路径上是不可见的。运维人员根本不知道流量到底在哪里堵住了只好一台一台交换机登录上去看计数器。网上的下图PFC讨论串里经常能看到运维圈的人互相问哪家的监控能看到逐端口的Pause帧计数这玩意儿直到现在依然是很多团队监控体系的盲区。PFC把拥塞控制的责任从传输层向上推给了链路层但又没有提供端到端的可见性相当于把一个房间里的浓烟藏进了墙里。这也是为什么业界后来一定要引入ECN——我们需要一种能带话给发送端的拥塞信号而不是只在相邻设备之间打手语。4. ECN的设计思路从事后重传到事前报信的关键转向ECNExplicit Congestion Notification显式拥塞通知最早是RFC 3168定义的IP层能力最初给TCP用后来在RoCEv2无损网络里被DCQCN发扬光大。它的核心思想是交换机在缓存将要溢出时不是直接丢包也不是发Pause而是在数据包的IP头里打上一个标记CECongestion Experienced接收端看到标记后通过某种反馈机制告诉发送端该降速了。4.1 ECN标记的报文级逻辑具体实现上发送端发出去的报文IP头的ECTECN-Capable Transport位要置1表示我支持ECN。交换机在转发时如果发现队列长度超过阈值K就把报文的CE位Congestion Experienced置1然后照常转发。接收端的网卡收到CE标记的报文后知道网络某处拥塞了于是根据所使用的协议DCTCP、DCQCN、RoCEv2的CNP机制等向发送端回传反馈发送端据此调整自身的发送速率或拥塞窗口。这里的阈值K是ECN调优的灵魂参数。K设得太小交换机动不动就标记CE发送端频繁降速带宽利用率上不去K设得太大缓存快满了才开始标记报文在交换机里排队时间过长时延飙升。业界有个经验公式K要大于等于带宽时延积BDP的某个比例。比如100Gbps链路RTT按1.5微秒算BDP大约是100Gb/s × 1.5μs ≈ 18.75KB。很多交换机的默认K值远小于这个数需要手动调大。我之前在某个项目里把TOR交换机的ECN阈值从默认的8KB调到32KB训练吞吐直接提升了12%这个优化性价比极高。4.2 DCTCP与DCQCN两个典型的ECN反馈算法ECN标记只是拥塞信号的载体怎么处理这个信号才是区分方案优劣的关键。这里必须提两个经典算法。第一个是DCTCPData Center TCP它在接收端统计每个RTT内被CE标记的报文比例计算一个拥塞程度参数α然后通过标准TCP ACK反馈给发送端。发送端不是一刀切地把窗口减半而是按α的比例做乘法减少α越大降得越狠α小意味着拥塞轻微降速也小。实测下来DCTCP能明显降低流量突发带来的队列堆积。第二个是DCQCNData Center Quantized Congestion Notification它是专门为RoCEv2设计的方案。接收端一旦收到带CE标记的RDMA报文就生成一个CNPCongestion Notification Packet报文回传给发送端。发送端维护一个发送速率变量收到CNP后先做一个大幅降速乘性减少然后进入一个恢复阶段每隔一段时间尝试增加一点速率加性增加如果再次收到CNP就再降。这个先降后慢慢试的过程有点像开车遇到堵车一脚刹车踩到底然后看路况一点点给油。DCQCN的性能很大程度上取决于CNP的发送速率和速率恢复步长这些参数不同场景需要细细调。4.3 ECN相比PFC的本质优势ECN最本质的优势是把拥塞控制拉回了端到端闭环。PFC只在相邻交换机之间传递我满了你停而ECN通过端到端的反馈让真正的流量源头GPU服务器网卡感知拥塞并主动降速。这就好比你做菜糊锅了PFC是邻居闻到焦味跑来拍你窗户让你关火ECN是厨房里的烟雾报警器直接联动燃气阀门自动关掉火源。但ECN也不是完美无缺的。它在无损网络里有个致命短板——它只负责通知不负责兜底。ECN标记的报文从交换机转发到接收端再让接收端回送CNP这个链路本身需要时间。在极端突发下交换机缓存可能在收到CNP之前就满了。所以RoCEv2的实际部署从来不是二选一而是PFC做最后一道防线ECN做主动拥塞避免两者配合才构成完整的无损网络方案。5. 生产环境的组合方案RoCEv2里的PFC兜底与ECN门限调优RoCEv2是目前AI数据中心里绝对的主流网络协议它本质上就是把RDMA报文封装进UDP/IP。RoCEv2在链路层跑在无损网络里下层靠PFC保证零丢包上层靠ECNDCQCN做主动降速。两层机制缺一不可但要命的是它们之间的配合出过无数问题。5.1 优先级划分与流量隔离策略生产环境里网络流量不只有RDMA。存储走iSCSI/NVMe-oF管理面走SSH监控走SNMP这些业务如果用同一个网络必须设置不同的优先级。通常的做法是RDMA流量映射到优先级3其他流量映射到低优先级队列。这个映射关系要在服务器网卡、接入交换机、核心交换机三处保持一致任何一处配错PFC的优先级控制就完全失效。有个典型的坑某团队把RDMA映射到优先级3存储映射到优先级5但接入交换机上忘了启用PFC的优先级5队列导致存储流量拥塞时直接丢包。存储的TCP重传还能扛RDMA流量的缓存池却被存储流量的突发占用最终触发PFC把所有优先级3的流量也暂停了。所以在部署无损网络时一定先想清楚我需要几个无损优先级把PFC使能范围压到最小既能保住RDMA又能减少PFC的副作用面积。5.2 端到端的关键调优参数ECN和PFC的参数调优是整个无损网络上线最磨人的环节。以下是几个我实测过、效果明显的核心参数一是ECN标记阈值K。刚才说了不要用交换机默认值。建议先算出链路BDP把K设成1到2倍BDP然后观察训练作业的流完成时间FCT和吞吐。如果吞吐上不去适当上调K如果时延抖动明显下调K。二是DCQCN的CNP反馈间隔。CNP报文本身会占用网络带宽如果每个CE标记都立刻回CNP拥塞时会形成反馈风暴反而加剧拥塞。通常需要配置一个最小间隔比如每30微秒最多发一个CNP控制反馈频率。三是PFC的XOFF/XON门限。这跟交换机的整体缓存大小相关。有条件的话给不同优先级设置不同的门限值比如RDMA优先级的XOFF设高一些因为ECN已经帮它做过主动降速PFC只是兜底普通流量的XOFF可以设低一些宁可丢包也不影响无损流量。四是网卡侧的PFC队列数。RoCEv2网卡通常支持多个发送队列每个队列可以独立绑定优先级。建议把不同训练作业的大流和小流分开队列避免一个慢启动的连接拖累另一个。还有一个容易忽略的细节PFC和ECN必须同时覆盖同一段链路。如果交换机A上ECN生效但PFC没打开拥塞时ECN标记报文传出去了但交换机B的方向没有PFC兜底一旦突发超过缓存还是会丢包。很多团队在测试环境只开了ECN没开PFC小流量测不出问题一上大规模训练就崩往往就是这个原因。5.3 实测里的观测手段调参的前提是能观测到现象。推荐几个实用的观测手段网卡侧ethtool -S eth0 | grep pause查看rx_pause和tx_pause计数如果rx_pause持续增长说明对端交换机已经在下达暂停指令拥塞正在向源头蔓延。RDMA侧rdma_pma_counters能看到CongestionWindow、CNPSent等DCQCN参数在网卡层面执行情况。如果CNPSent暴涨说明网络经常处于ECN标记状态你的K阈值可能设得太小了。交换机侧查看各端口的ecn_marked和pause_frame_rx计数对比同一时段涨幅能判断拥塞到底被ECN吸收了还是打到了PFC兜底层。有一回我在现场调优发现所有端口的rx_pause都在涨但ecn_marked却没怎么涨。排查一番后确认是网卡的DCQCN参数里反馈系数设置得太保守发送端收到CNP后降速幅度不够导致拥塞持续超过PFC门限。改成更积极的降速参数后rx_pause计数立刻回落了一大截。这类问题不通过计数器对比光凭主观感受很难定位。6. 未来方向与我在这几次实战里沉淀的最后建议无损网络这些年最大的争论点就是我们是不是为了保住RDMA的体面花了太多代价在无损链路上。PFC作为链路层的兜底机制本身不可控、不透明、容易引发连锁故障所以近几年的学术圈和工业界都在探索更激进的方案。6.1 通向可编程数据平面的新思路一方面HPCCHigh Precision Congestion Control这类方案试图利用可编程交换机的带内遥测INT让数据面实时携带链路负载信息发送端基于精确的队列信息做速率控制而不是依赖ECN这种间接标记。另一方面也有像NDPNew Datacenter Protocol这样的方案直接把无损这个目标抛弃掉允许一定的丢包但通过网卡侧的快速重传和调度算法把丢包代价降到最低——毕竟今天的高速网卡已经有足够能力在几微秒内完成重传。这些方向现在还各有各的问题。HPCC要求全网交换机支持INT升级成本高NDP对网卡硬件的要求也不低。短时间内PFCECNDCQCN依然是AI训练网络的主流组合。但有一点已经明确网络团队不能再把无损网络视为一个配置完就完事的静态方案它更像一个需要持续调参、持续监控、甚至需要根据训练作业特征动态调整的活系统。6.2 我的几点亲身经验结合这几次实战最后分享几条实在的建议第一上线无损网络前先把监控补齐。Pause计数、ECN标记计数、CNP计数这三类指标必须纳入告警体系。我见过太多团队网络一抖动只能靠应用层loss曲线反推浪费大量排查时间。第二不要迷信厂家默认参数。不同交换机型号、不同网卡型号的缓存能力和反馈机制差异很大一定要做一次小规模负载测试把K值和DCQCN参数放到实际流量里去验证。第三优先保大流别让老鼠流骚扰大象流。AI训练里集合通信的大流量是核心心跳、日志这类小流虽然占带宽小但突发时一样会触发PFC。设置优先级时给不同训练作业的流量做好VLAN和优先级规划让长寿大流和短小流尽量分开队列能显著减少大象流被PFC误伤的概率。第四保留一个逃生通道。就算做成了无损网络也不能把普通TCP流量完全牺牲掉。给存储和管理面留一个非无损的普通优先级万一PFC风暴或者死锁真的出现了你还有一条路能登录设备做排查和恢复。说到底从PFC到ECN的演进本质上是网络拥塞控制从被动刹车走向主动报信的过程。PFC解决的是别丢包的问题ECN解决的是别拥塞的问题但两者都只是手段。对AI训练来说核心永远是别让丢包打断训练。理解了这一层再看各种新协议和新算法思路就清晰了——大家都在往同一个方向使劲让GPU在通信的时候少一点等待多一点算力。
返回列表