
凌晨两点半手机连震三下值班群里有人发了一条告警截图一个万卡集群上的训练任务吞吐掉了三成loss曲线已经横盘快两个小时了。第二天早会上算法团队和平台团队互相看了一眼谁都知道这不是一个简单的“重启一下”能解决的事。万卡集群性能变慢是AI基础设施运维里最磨人、最考验功力的场景之一——一万张卡同时在工作但训练进度就像堵在早高峰环路上的车哪儿都动了哪儿都没动。这篇东西我按实际排查经验整理成一套可复用的思路从现象分类、通信层诊断、慢卡定位到网络拓扑和存储瓶颈最后聊一聊日常怎么防患于未然。无论你手上是几千卡还是刚起步搭集群这套方法都适用而且能帮你少走不少弯路。1. 万卡集群性能变慢先搞清楚慢在哪一级1.1 别急着看卡先看现象属于哪一类万卡集群的“慢”不是一种慢至少可以分为三种全局吞吐下降但每张卡利用率看着还行。这种情况大概率不是算力问题而是通信、同步或数据供给跟不上GPU在空转等待。单卡或少数卡利用率掉坑整体被拖累。这是典型的木桶效应——同步训练中最慢的那张卡决定整个step的节奏。任务抖动每隔一段时间就卡一下。这种多为存储延迟、checkpoint写盘、网络闪断或后台任务干扰。我在处理问题时会先打开两个维度训练框架的step耗时分布和集群的节点监控。如果每张卡的平均利用率都正常但step时间在拉长那通信和同步就是第一嫌疑如果只有少数节点利用率低那就直奔节点和单卡健康检查。这个分类原则非常重要。有一次我们花了大半天查集合通信参数结果最后发现是某个节点的电源管理策略导致GPU降频纯算力问题和网络一根毛的关系都没有。先分类再动手能省掉一大半无效排查时间。1.2 建立性能基线和“慢”的量化标准没有对比就没有“慢”。万卡集群规模大每张卡的型号、驱动、固件版本可能有差异甚至不同批次机器的散热条件都不一样。所以第一步一定是先建立性能基线记录集群满负荷运行时的标准吞吐samples/s 或 tokens/s。记录每个step的标准耗时和P99耗时。记录通信占step总时长的比例常规情况下这个值应该在个位数百分比。保存历史监控数据至少保留30天方便回溯。我见过不少团队连基线都没有告警阈值全靠拍脑袋。等真正出现问题了连“慢了多少”都说不清楚只能凭感觉猜。建议用你用的监控平台Prometheus Grafana、云厂商监控等把这三个指标固定成dashboard再挂上告警。有了历史曲线很多问题根本不需要猜往前翻一天看曲线什么时候开始掉再去那个时间点附近找变更记录定位速度快得多。2. 集合通信是万卡集群最脆弱的环节2.1 为什么通信会成为瓶颈万卡规模的训练几乎都是数据并行或混合并行每个step都需要做梯度同步这依赖集合通信库NCCL、RCCL等在成千上万张卡之间做AllReduce。你可以把集合通信想成一次全公司同时参加的晨会每个人都要发言也要听完所有人的发言最后达成一致的结论。只要有一个人连不上或者说话慢所有人都得等。在通信层面影响性能的核心因素是这两类单条链路质量差某个IB链路降速、丢包重传、误码率上升都会让通信延迟放大。流量负载不均:网络拓扑设计不合理或路由策略不佳导致部分链路拥塞其他链路闲置。在万卡规模下这两种问题都会被放大。一张卡的通信故障会拖慢整个训练任务一次网络微突发拥塞就可能让几千张卡同时陷入等待。2.2 NCCL日志和超时参数是突破口当怀疑通信层有问题时我建议先用NCCL的debug日志做第一轮扫描。把NCCL_DEBUG设为INFO或VERSION重新跑一个短任务然后看日志里有没有明显的报错或异常。重点看这些信息哪个rank报错对应哪台机器、哪张卡。有没有IB超时记录超时参数是NCCL_IB_TIMEOUT和NCCL_IB_RETRY_CNT。有没有连接建立失败的记录这通常指向网络连通性或防火墙问题。各个rank的初始化耗时是否一致某个rank明显偏慢说明它所在的节点有问题。补充一个经验不要一上来就调大NCCL_IB_TIMEOUT。超时时间是保护机制调大了问题不会消失只会隐藏更久。正确做法是先定位到是哪个链路或哪张卡在超时再做针对性的硬件检查而不是在参数上打补丁。如果想快速量化通信性能可以在集群里跑一下NCCL官方的all_reduce_perf测试分别在单机8卡、单机间、整个集群三个层级跑一遍对比带宽是否符合预期。这个测试跑出来的数据会很直观地告诉你性能瓶颈是在节点内、节点间还是全网。3. 慢节点与故障GPU的定位技巧3.1 训练日志里的痕迹会告诉你答案通信层排查没发现问题接下来就要把目光放到节点和单卡上。第一步是看训练日志——别小看这一步日志里的step耗时分布比什么监控都直接。具体做法是把每个step的耗时、每张卡的利用率按时间打出来画成曲线。看三种典型形态所有step均匀变慢整集群算力集体下降通常是散热、功耗策略变化或驱动问题。个别step偶发巨大延迟可能有慢卡、网络抖动或存储毛刺需要进日志看是那几个rank拖慢了整体。某张卡利用率长期偏低直奔单卡健康状态。我在实际战斗中最喜欢用的还是框架自带的profile工具比如PyTorch的torch.profiler或TensorFlow的profile。它可以按kernel级别告诉你每个算子在卡上花了多少时间通信算子又花了多少时间。如果通信算子耗时占比明显偏高问题又回到了通信层如果某个算子在不同卡上耗时差异巨大那就是该卡算力受损。3.2 一张卡是不是“坏”了看这几个指标GPU或加速卡包括NPU的健康状态不能只看“能不能用”要看性能是不是衰减了。我通常重点检查这几个指标ECC错误次数内存纠错可以正常工作但错误次数持续增长说明显存颗粒正在老化或松动。温度与功耗温度过高会触发降频功耗上不去说明供电或散热有问题。时钟频率对比实际频率和标称频率长期低于标称值就要警惕。物理链路状态用ibstat查看链路是否正常Lane状态是否降级。remapped rowsnvidia-smi可以看到如果这个数值持续增长说明显存存在悄悄失效的行卡的性能会越来越差。在国产NPU集群上对应的工具是npu-smi info同样关注芯片温度和健康状态。无论是哪种卡一旦确认是坏卡直接隔离并走替换流程不要指望它自己恢复。我踩过很多次坑每次心软想着“再跑跑看”最后都是拖累全集群。3.3 用最小复现实验来圈定问题范围当你怀疑某几个节点有问题但证据还不够明确时可以做一个最小复现实验只在这些节点上跑一个8卡或16卡的小任务看性能是否异常。如果小任务正常说明问题在更大范围的网络或调度层面如果小任务也慢那就可以确定问题在节点内部。这个方法和程序员做bug二分定位是一个逻辑。先把问题范围缩小到可以控制的最小单元再逐步扩大复现规模。直接在一万卡上做实验成本高、变量多、结果还不一定干净。4. 网络拓扑与消息路由隐性瓶颈的聚集地4.1 万卡集群的拓扑长什么样性能瓶颈就长在哪万卡集群的网络拓扑通常是两层或三层结构GPU服务器接入leaf交换机leaf交换机再通过spine交换机互联。不同厂商的机型布线方式不同但核心原则一致——任何一条链路的带宽不足都会成为全集群的木桶。我处理过的最隐蔽的一个问题就是某个leaf交换机和spine之间的链路因为光模块老化实际协商速率掉了一半。从监控看所有链路都显示Up但性能就是上不去。后来在交换机上查端口计数值发现CRC错误包在持续增长最终换了光模块才解决。所以网络排查不要只看连通性还要看链路质量。重要的检查项包括设备端口是否出现CRC错误包、丢包和重传。光模块的光功率是否在正常范围内。链路是否协商到了正确的速率。拥塞控制相关的统计指标是否异常。4.2 用流量监控和拥塞指标定位网络热点万卡集群上网卡数量动辄上万想定位是哪条链路拥塞光靠人工翻交换机配置是行不通的。建议这样操作打开交换机或云网络监控平台批量导出端口流量数据。按利用率排序找出流量超过80%的端口。观察这些端口集中在哪些交换机、哪些机柜看是否形成了局部热点。结合训练任务的消息通信模式哪些节点之间通信最密集判断是任务设计问题还是网络结构问题。我遇到过一种情况框架默认的网卡分配策略和任务本身的拓扑不匹配导致一堆本应走无阻塞链路的通信流量全挤到了某一条链路上局部拥塞严重整体吞吐直线下降。修复方式很简单调整rank到网卡的映射关系性能立刻回来。这类问题不靠流量监控根本发现不了。4.3 拥塞控制参数动了就是双刃剑当确认存在网络拥塞很多人的第一反应是调整拥塞控制算法或队列参数。这个方向没错但必须非常谨慎。万卡集群的网络是高度耦合的系统一个参数在局部生效可能在全局引发新的不公平和更多拥塞。举个简单的例子把某个队列的优先级调高短期内该队列的流量是顺畅了但高优先级流量可能持续挤占低优先级流量的带宽其他任务的通信性能反而更差。更麻烦的是这类问题在监控上往往没有明显的报错只会表现为“某个任务忽快忽慢”。所以调拥塞参数之前先记录基线一次性只改一个变量改完立刻跑小规模测试验证再逐步扩大验证范围。5. 数据供给和存储容易被忽略的隐形瓶颈5.1 数据加载慢GPU就会“等米下锅”万卡集群跑训练不仅卡要够快数据也要能“喂饱”这些卡。如果数据加载跟不上GPU利用率再高也会出现周期性空转表现就是训练吞吐上不去。数据供给主要看这两点存储吞吐能力底层文件系统能提供的每秒读写吞吐必须大于所有训练任务峰值需求的总和。单次读取延迟特别是有大量小文件读取的场景文件元数据操作的延迟会成为很大的瓶颈。我碰过一次典型的案例训练任务用的数据集是几百万张小图片存储在并行文件系统上。平时跑小规模任务还好扩到几千卡并发读之后元数据服务器直接被打爆每个step的等待时间从几秒涨到几十秒训练几乎停滞。5.2 IO对齐和预取花小钱办大事数据供给优化有几个性价比很高的手段把小文件提前打包成大文件如TFRecord、WebDataset、或自定义二进制格式减少元数据开销。使用数据预取让数据加载和计算重叠起来。在计算节点本地配置NVMe缓存把热数据提前缓存到本地。检查存储网络和计算网络是否分离避免数据流量挤占通信带宽。还有一个小细节检查数据加载的batch size和GPU数量是否匹配。假设每张卡一个step要读2MB数据一万张卡一个step就是20GB。如果存储系统带宽不够就自然会拖慢整个训练。这类问题从根上说不是“网络慢”也不是“卡慢”而是数据管道的口径不够粗。5.3 Checkpoint写入定时引爆的隐形炸弹比数据加载更隐蔽的是checkpoint写入。训练任务通常会定期保存模型权重这个操作需要把几十GB甚至几百GB的数据写到持久化存储。在保存期间存储带宽被大量占用正常数据读取就会变慢进而导致整个训练任务出现周期性卡顿。怎么解决业内常见的做法是把checkpoint先写到节点本地NVMe盘再异步往远端存储同步或者把checkpoint数据切成多个分片写到不同存储节点。这些方案都需要在训练框架层面改代码看起来麻烦但能避免训练进程被写盘IO卡死。6. 从救火到防火万卡集群的长期运维建议6.1 建立健康巡检制度坏东西早发现早处理万卡集群的故障是常态关键不是杜绝故障而是缩短故障从发生到被发现的时间。我的建议是至少建立以下巡检项每天自动跑一遍所有节点的健康检查GPU ECC、温度、链路状态。每周跑一次小规模的集合通信性能测试对比基线。每周检查存储系统的读写延迟和吞吐趋势。每次硬件变更后立刻做性能验证不要等到训练任务挂了再处理。很多团队不做这些事情等到训练任务变慢才去翻监控最后发现问题已经存在好几天了。如果有一张健康巡检报表昨天和今天的性能对比一目了然问题就不会拖过夜。6.2 变更管理是万卡集群的生命线作为一个管过多套集群的人我越来越觉得大多数“玄学性能问题”背后都藏着一个变更。可能是某台机器的驱动升级了可能是某个交换机刷了固件可能是存储上多了一个新任务在抢带宽也可能是有人改了一行网络配置。所以我强烈建议严格执行变更记录和变更窗口制度所有变更必须记录时间和操作内容。变更前先拍快照或备份配置。大的变更先在小范围验证再推全集群。每次变更后自动对比性能基线。这套制度看起来“增加流程负担”但关键时刻能救命。上次任务性能下降我翻变更记录发现三天前有人给某批机器更新了网卡驱动回滚之后问题直接消失。没有变更记录这种问题可能要排查一周。6.3 告警阈值不是越敏感越好最后说一个比较反直觉的经验告警阈值不要设置得太敏感。如果每个小波动都告警值班人员很快会对告警麻木真正的大故障反而没人及时响应。正确的做法是针对step耗时、通信占比、节点温度这类关键指标设置多级阈值。第一级只记录不打扰第二级发通知第三级才真正告警。运维平台的告警规则可以灵活配置但规则的设计思路一定要想清楚宁可少而精不要多而滥。我个人在实际操作中的一个体会是万卡集群的性能优化本质上是在查“最慢的那个点”。不管是慢卡、慢链路还是慢存储只要找到了那个点问题往往迎刃而解。真正难的不是技术而是建立一套系统性的排查和预防机制让问题在影响训练之前就被发现。最后再分享一个小技巧处理这类问题先别急着动参数先把当前状态完整记录下来包括日志、监控、配置然后再开始动任何东西。“先存档再操作”这套思路不管是在软件系统还是硬件集群上都适用。有了完整的现场就算自己一时没查出原因也能让后面接手的人快速进入状态。