本文介绍 PFC、ECN、CNP 与 DCQCN 的工作机制、协作流程,以及训练吞吐下降时的排查方法。
在 AI 集群中,GPU 算力并不总是性能瓶颈。一次 AllReduce、AllGather 或 MoE All-to-All,只要网络中的某个出口发生拥塞,就可能让大量 GPU 等待通信,最终表现为:
-
平均吞吐尚可,但 P99/P999 延迟明显升高;
-
链路没有 Down,光模块也没有误码,作业却像“网络不稳定”;
-
严重时出现 RDMA 重传、QP 超时或训练任务失败。
RoCEv2 使用 UDP/IP 承载 RDMA,可以运行在三层 Leaf-Spine 网络中,但它对拥塞和丢包非常敏感。生产网络通常组合使用三种不同层次的机制:ECN 标记拥塞,DCQCN 调整源端 RNIC 的发送速率,PFC 在队列接近危险水位时逐跳暂停流量。
大模型训练会周期性进入集合通信阶段。多个 GPU 可能在非常接近的时间同时发送数据,流量具有三个典型特征:
-
突发性强:计算阶段结束后,许多 GPU 同时开始通信;
-
大流多:梯度、激活值和专家 Token 会形成持续的高带宽流;
-
同步性强:一个 Rank 变慢,其他 Rank 也可能在同步点等待。
假设 8 台服务器各以 100 Gbit/s 向同一个 100 Gbit/s 出口发送:
8 × 100 Gbit/s 输入
↓
同一个交换机出口
↓
100 Gbit/s
交换机瞬间收到的流量远高于出口能力,多出来的报文只能进入队列。即使平均带宽没有超过网络容量,微秒级的同步突发也可能让缓存快速上涨。
正常水位
↓
达到 ECN 门限:开始标记拥塞
↓
达到 PFC XOFF 门限:暂停直接上游的指定优先级
↓
缓存耗尽:丢包
拥塞控制需要在缓存溢出前抑制队列增长,不要求队列始终保持为空。
RoCEv2 数据报文封装在 UDP/IP 中,标准目标端口通常是 4791。排障时可以在交换机 ACL、流量计数器或镜像抓包中使用 udp dst port 4791 快速定位 RoCEv2 流量。该端口可能因设备或历史配置而不同;RNIC 硬件卸载也可能使主机上的 tcpdump 看不到全部 RDMA 报文,因此不能只凭主机抓包判断流量是否存在。
持续拥塞需要通过 DCQCN 降低源端发送速率。PFC 只能暂时阻止报文继续进入拥塞队列,无法增加出口带宽。
PFC 全称 Priority-based Flow Control,来自数据中心桥接(DCB)体系。它与传统的全链路 Pause 最大的区别是:PFC 可以只暂停一个或若干个 802.1p 优先级,而不暂停整条链路上的所有流量。
当交换机发现某个无损队列达到 XOFF 门限时,会向直接相连的上游设备发送 PFC Pause 帧:
上游收到 Pause 后,暂时停止发送对应优先级的流量。队列下降到 XON 恢复条件后,下游再允许上游继续发送。
-
逐跳:Pause 只作用于直连邻居,不会直接通知最初的发送端;
-
只是兜底:它没有让发送源理解“为什么拥塞”,也没有从根本上降低业务注入速率。
这里的 Buffer(缓存),是交换机 ASIC 临时存放报文的高速存储空间,不是服务器内存,也不是磁盘缓存。当多个入口同时向同一个出口发送,报文到达速度暂时超过出口转发速度时,来不及立即发出的报文会先进入队列 Buffer:
多个入口同时到达
↓
交换机端口 / TC 队列 Buffer 暂存报文
↓
出口按线路速率逐个转发
Buffer 的作用是吸收短时突发和速率差,但容量有限。队列持续增长时,会依次触发 ECN 标记、PFC Pause,最终在缓存耗尽后丢包。交换机可能采用入口缓存、出口缓存、共享缓存和队列专用缓存等不同架构,因此“整机总缓存很大”不等于某个 RoCE 队列可以使用全部容量。
Buffer 可以吸收短时突发,但无法长期承受高于出口转发能力的输入流量。
Headroom 是 Buffer 中专门为 PFC 停止过程预留的安全空间。它不是日常排队容量,而是在队列达到 XOFF、交换机已经发出 Pause 后,用来接住上游尚未来得及停发的在途报文。
交换机发出 Pause 后,上游不会瞬间停止。在 Pause 帧传播、设备处理和发送流水线停止之前,仍有一批在途报文继续到达。
因此,无损队列必须预留 Headroom,用来吸收:
链路越快、线缆越长、设备响应越慢,需要吸收的在途数据通常越多。Headroom 不能照抄另一种交换机或另一种速率的配置,应该使用厂商针对 ASIC、端口速率、MTU 和线缆长度给出的计算或模板。
数量级直觉,不是配置公式:假设从交换机决定发送 Pause,到上游真正停止发送的总延迟预算为 3 μs,那么在 100 Gbit/s 链路上,这段时间仍可能到达:
100 Gbit/s × 3 μs ÷ 8 ≈ 37.5 KB
这只是停止延迟对应的在途数据量。实际 Headroom 还要考虑最大帧、ASIC流水线、缓存 cell 对齐、安全余量和厂商实现,不能直接把 37.5 KB 当作生产配置值。
普通 Buffer:吸收日常排队和微突发
Headroom: 发出 PFC Pause 后,吸收尚未停下的在途报文
Headroom 太小,Pause 已经发出仍可能溢出丢包;预留过大,则会挤占共享 Buffer,降低其他端口或队列吸收突发的能力。
同一优先级内,只要其中一个目的方向拥塞,其他本来不拥塞的流量也可能被一起暂停。
一个下游端口持续发 Pause,上游队列也会积压;上游又可能继续向更上游发 Pause,最终把局部热点扩散到更大范围。
错误的优先级映射、环形依赖、故障网卡持续发送 Pause,可能导致大量端口长期暂停。此时链路仍是 Up,但有效吞吐接近零,排障时很容易误判。
-
启用 PFC watchdog、storm detection 或厂商同类保护;
-
监控 Pause 帧次数之外,还要监控 Pause 持续时间。
ECN 全称 Explicit Congestion Notification。对于 RoCEv2,它使用 IP 头中的两个 ECN 位传递拥塞信息。
发送端发出 ECT 报文。交换机检测到 RoCE 队列超过 ECN 门限后,不必立即丢包,而是把部分或全部经过报文的 ECN 字段改成 CE:
CE 标记不会阻止报文继续转发,而是向端点传递路径拥塞信号。
达到 ECN 门限不等于立即给每个报文标记 CE。一种常见策略是:队列低于 Kmin 不标记;从 Kmin 到 Kmax 按概率标记,并随队列水位升高逐步提高标记概率;超过 Kmax 后高概率或全部标记。具体行为取决于交换机 ASIC、NOS 和配置模式。
只有 ECT(01) 或 ECT(10) 报文能够被改写为 CE(11)。对于 Not-ECT(00) 报文,交换机不能用 CE 表示拥塞,可能按照 WRED 配置执行丢弃。
-
-
-
门限是否与交换机缓存、端口速率和 DCQCN 参数成套设计;
-
ECT 报文是否被正确标记,而不是直接被 WRED 丢弃。
正常情况下,ECN 应早于 PFC 触发。PFC 频繁触发通常表示端到端控速没有及时抑制队列增长。
交换机只负责标记 CE,并不直接控制源端 RNIC 的发送速率。
接收端 RNIC 收到带 CE 标记的 RoCEv2 报文后,会生成 CNP(Congestion Notification Packet,拥塞通知报文),发回发送端:
数据方向:发送端 RNIC ──→ 拥塞交换机 ──→ 接收端 RNIC标记 CE反馈方向:发送端 RNIC ←──────── CNP ────── 接收端 RNIC
-
发送端收到 CNP 后,由拥塞控制算法决定降速幅度和恢复方式。
实际部署中,CNP 常被映射到独立的高优先级队列,以免拥塞反馈本身被数据流堵住。但它不应被错误地塞进一个可能长期被 PFC Pause 的队列,否则会出现“越拥塞,反馈越回不来”的问题。
DCQCN 全称 Data Center Quantized Congestion Notification,是 RoCEv2 中广泛使用的端到端拥塞控制算法。
发送端 RNIC 会根据 CNP 估计拥塞程度,更新目标速率和当前速率。拥塞持续时继续抑制发送;拥塞缓解后,再按照定时器或已发送字节数逐步恢复。
α 是发送端维护的拥塞程度估计值,通常在 0~1 之间。α 越大,降速幅度越大。例如当前速率为 100 Gbit/s、α = 0.4,则新速率约为:
100 × (1 - 0.4 / 2) = 80 Gbit/s
因此,DCQCN 不是每次固定降低某个百分比,而是根据拥塞反馈动态计算降速幅度。不同 RNIC、固件和驱动的实现参数可能有所不同。
参数过于激进,吞吐可能剧烈振荡;参数过于保守,队列降不下来,PFC 会频繁触发。
ECN、CNP 和源端降速形成闭环需要时间。遇到极强微突发时,交换机队列可能在反馈抵达发送端之前就逼近缓存上限。
PFC 的价值是在这段反馈延迟内提供快速的逐跳保护。反过来,只有 PFC 而没有有效的 ECN/DCQCN,持续拥塞就会不断触发 Pause,容易造成拥塞扩散。
1. 多个发送端同时突发
↓
2. 交换机出口队列上涨
↓
3. 达到 ECN 门限,交换机标记 CE
↓
4. 接收端 RNIC 返回 CNP
↓
5. 发送端 DCQCN 降速
↓
6. 拥塞缓解后,发送端逐步恢复速率
若 3~5 的反馈尚未来得及生效,队列继续上涨:
7. 达到 PFC XOFF 门限
↓
8. 交换机逐跳 Pause 指定优先级
↓
9. 队列下降到恢复水位后解除 Pause
ECN 标记门限 < PFC XOFF 门限 < 实际丢包水位
三者之间还要留出足够安全距离:ECN 需要时间完成端到端反馈,PFC XOFF 之后需要 Headroom 吸收在途报文。
这只是设计原则,不是可以直接下发的数值公式。共享缓存架构、端口速率、扇入比、MTU、线缆长度、ASIC 单元大小和厂商实现都会影响最终配置。
服务器与交换机的优先级映射不一致,是 RoCE 故障的常见原因。
应用/NCCL
↓
RNIC 根据 DSCP 或 PCP 标记报文
↓
交换机 Trust DSCP/PCP
↓
映射到 Switch Priority
↓
映射到 Traffic Class / Queue
↓
该队列应用 ECN、PFC 和 Buffer 配置
-
DSCP/PCP → Priority → TC/Queue 映射;
-
主机、Leaf、Spine、边界设备是否保持一致。
只要中间一跳重写 DSCP、Trust 模式错误或队列映射不一致,就可能出现:服务器认为流量属于无损类,交换机却把它放进普通有损队列。
单看端口利用率远远不够。400G 端口的 1 毫秒平均利用率可能并不高,但一个微秒级突发已经足以触发 ECN 或 PFC。
ethtool -S <netdev>
rdma link show
rdma statistic show
perfquery # InfiniBand 场景常用,RoCE 需结合具体驱动
ls /sys/class/infiniband/<device>/ports/1/hw_counters/
# NVIDIA/Mellanox ConnectX(需安装相应驱动工具或 MFT)
mlnx_qos -i <netdev> # 查看 QoS、Trust、PFC 等配置
mst start # 启动 MFT 设备访问服务
mst status -v # 查找 PCI BDF 与 MST 设备名
mlxlink -d <PCI_BDF或MST设备> # 查看链路、FEC、误码等物理层信息
mlxreg 可做寄存器级查询和调试,但也具备修改设备寄存器的能力。生产环境中只应按 NVIDIA 文档或厂商支持人员的明确步骤使用,本文不提供寄存器写入示例。show_gvmid.sh 并非所有 ConnectX 软件栈都提供的标准命令,因此没有把它列为通用排障入口。
-
RoCE 重传、序列错误和 retry exceeded;
-
端口丢包、discard、CRC/FCS、符号错误;
-
NCCL bus bandwidth 和 algorithm bandwidth;
-
Collective 的 P50/P95/P99 延迟;
-
故障是否集中在固定的 Leaf、Spine、Rail 或目的节点。
把作业时间线、RNIC 计数器和交换机队列遥测放到同一个时间轴上,通常比单独看任何一个告警更有效。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pause duration、传播路径、watchdog
|
|
|
|
DSCP/PCP、Trust、Queue counters
|
|
|
局部热点、ECMP 哈希碰撞、链路降速或拓扑不对称
|
|
|
|
|
|
|
|
Headroom 不足、XOFF 太晚或 Pause 未被对端接收
|
Headroom、线缆长度、PFC Rx/Tx、MTU
|
注意:计数器非零不等于故障。ECN 标记本来就是主动拥塞控制的一部分。判断时应该关注速率、持续时间、基线变化以及它与作业长尾的相关性。
检查端口是否降速、FEC 是否异常、CRC/FCS、symbol error、光功率和链路 flap。物理误码与拥塞丢包的处理方向完全不同。
|
|
|
|
|
|
Forward Error Correction,接收端利用冗余编码修复少量比特错误
|
corrected 持续快速增长表示链路质量变差;uncorrectable 表示错误已经无法修复,可能直接丢包
|
|
|
以太网帧完整性校验;接收端计算结果与帧尾校验值不一致时记错
|
报文在物理传输中损坏,常见于模块、光纤、DAC/AOC 或端口异常
|
|
|
|
信号衰减、噪声、线缆质量、模块兼容性或端口硬件存在问题
|
|
|
光模块的发送功率 Tx Power 和接收功率 Rx Power,通常以 dBm 表示
|
Rx 过低常见于光纤衰减、接头脏污或弯折;过高可能使接收器过载,需要与模块规格范围比较
|
|
|
|
模块接触不良、光纤故障、FEC 模式不匹配、端口故障或对端重启
|
其中,少量 FEC corrected 并不必然代表故障,关键是观察增长速率和历史基线;CRC/FCS、FEC uncorrectable、链路 flap 持续增加则应优先处理。不要在物理层错误仍在增长时直接调整 ECN、PFC 或 DCQCN 参数。
FEC / CRC / Symbol Error / 光功率 / Link Flap → 物理链路方向
ECN / CNP / PFC / Queue Occupancy / Buffer Drop → 拥塞控制方向
从 RNIC 到 Leaf、Spine 再到对端,逐跳核对 DSCP/PCP、Trust、Priority、TC 和 Queue。不要只看配置命令成功,要看实际队列计数是否增长。
参照第七节的拥塞控制闭环,依次核对交换机 ECN/CE、接收端 CNP Tx、发送端 CNP Rx、发送速率和队列水位。哪个信号没有按预期变化,就重点检查对应环节。
少量 PFC 不一定异常;持续 Pause、Pause 时长快速增长或多跳扩散才是危险信号。结合队列水位判断 XOFF 是否过早或过晚。
用 NCCL Tests 或业务的 Collective 指标复现,确认问题出现在 AllReduce、All-to-All,还是某个固定源/目的组合。再结合 ECMP、Rail 和交换机遥测定位热点。
先确认物理层、优先级映射和功能闭环正确,再修改 ECN、PFC 或 DCQCN 参数。一次只改一组参数,保留变更前后的队列、CNP、PFC 和作业性能数据。
-
-
接收端 RNIC 通过 CNP 把拥塞反馈给发送端;
-
发送端 DCQCN 降低对应流的发送速率,并在拥塞缓解后逐步恢复;
-
如果端到端反馈尚未生效,PFC 在队列接近危险水位时逐跳暂停,保护缓存不被打爆。