很多人想象大模型训练,会想到几千张GPU同时开跑。这个画面没错,但少了一个关键细节:这些GPU不是各干各的,而是在同一个训练节拍里一起往前走。
每一步训练,大家都要先算完自己那份,再把结果对齐,然后一起进入下一步。一张卡慢了、断了、通信异常了,受影响的通常不是它自己那一点算力,而是整个训练作业的节奏。
这也是为什么在大模型训练里,掉卡是个很麻烦的词。它不只是少了1/16000的算力,更可能让另外15999张卡一起等。
一、分布式训练不是各跑各的流水线
在同步训练中,每张GPU拿到一小批训练数据,算出一份梯度。梯度可以简单理解为:模型参数下一步应该往哪个方向调整。
问题在于,模型副本分布在很多张卡上,但训练逻辑要求这些副本保持一致。每张卡不能按自己的梯度单独更新,否则很快就会训练出一堆互相不一样的模型。
所以同步数据并行里通常会做这样一件事:每张卡先算出自己的梯度,然后所有卡把梯度汇总、求和或求平均,得到一份全局结果,再一起更新参数。
这个过程很像一桌人AA制。每个人先报自己花了多少钱,等所有人都报完,才能算总账和人均。如果有人迟迟不报、报错了,或者干脆走了,其他人只能等。

大模型训练里的这种等待不是偶发插曲。只要采用同步训练,每一步参数更新都绕不开类似的同步动作。卡越多,整体算力越大,但也越容易遇到某个环节掉队。
二、All-Reduce到底在做什么?
刚才说的“汇总梯度、再让每张卡拿到同一份结果”,在分布式训练里最典型的通信动作叫All-Reduce。
一句话说,All-Reduce就是每个rank都拿出一份数据,系统把这些数据做归约运算,比如求和,然后把结果放回每个rank。训练场景里,这份数据常常就是梯度。

NVIDIA NCCL官方文档对All-Reduce的描述也是这个意思:每个rank提供输入数组,经过归约后,每个rank都收到相同的输出结果。NCCL文档还强调,集合通信操作必须由每个rank用相同的数据量、相同的数据类型调用,否则结果属于未定义行为,可能hang、crash,甚至造成数据损坏。
这里的rank可以先粗略理解成参与训练的一个计算进程,很多场景下一个rank对应一张GPU。严格说,rank和GPU不总是一一对应,但对这篇文章要解释的问题来说,这个简化足够用了。
再看PyTorch的DistributedDataParallel。DDP在反向传播时会把梯度按bucket分组,某个bucket准备好后就触发通信,把不同进程里的梯度同步起来。PyTorch文档也提醒过,如果不同进程之间的collective调用顺序对不上,backward过程可能直接卡住。
所以,All-Reduce的关键不是“通信很慢”这么简单,而是它有一个很强的前提:参与者要按同一套顺序、同一套形状、同一套节拍一起做事。有人掉线,或者有人走到了另一套通信流程里,整个作业就可能卡住。
现代大模型训练当然不只用All-Reduce。FSDP、张量并行、流水线并行里还会大量出现all-gather、reduce-scatter等集合通信。但只要理解All-Reduce,就能理解同步训练为什么怕掉队。
三、掉卡为什么会拖住几千张卡?
理解了前面的同步逻辑,再看掉卡,就不会把它理解成“少一张卡继续跑”。
第一种情况是直接掉卡。GPU报错、显存出现不可纠正错误、NVLink或RoCE网络异常,都可能让某个rank掉出通信队伍。集合通信等不到它,训练就可能停在某一次通信上。后面要做的不是简单跳过这张卡,而是超时检测、故障定位、重建通信组、重新调度,再从checkpoint恢复。
这里有个容易混淆的点:超时不是NCCL自己天然帮你把训练恢复好。NCCL是底层通信库,真正的超时检测和错误处理通常还要依赖上层框架和训练系统。以PyTorch为例,ProcessGroupNCCL有watchdog机制,公开文档里提到NCCL后端默认超时时间是10分钟,其他后端默认是30分钟。也就是说,如果训练系统没有额外的监控和更快的失败处理,一次通信挂住可能会白白占住很多GPU时间。

第二种情况是慢卡,也就是straggler。它比直接掉卡更难排查。卡没有彻底坏,任务还在跑,但它就是比其他卡慢一拍。可能是硬件状态不稳定,可能是链路异常,也可能是某个节点的系统侧问题。
同步训练的麻烦就在这里:下一步要等所有人都到齐。一张慢卡会把所有快卡都拖到自己的节奏上。Meta在Llama 3技术报告里专门提到过这类问题:有些硬件故障会表现成慢节点,表面上像通信问题,但根因可能是某个GPU或主机组件出了问题。
第三种情况是恢复成本。掉卡之后,训练通常不能无损地从故障那一刻继续。系统要判断故障源,决定是否剔除节点,重新拉起作业,再加载最近一次checkpoint。
checkpoint又有自己的两难。存得太少,故障后要回退更远,丢掉更多已经算过的token;存得太频繁,训练又会被保存模型状态这件事打断,还会占用存储和网络带宽。

AWS的checkpoint文章给过一个直观算例:4000张加速卡的集群,如果一次同步checkpoint暂停3分钟,就相当于200个GPU-hours的集群空转。如果每30分钟做一次这样的同步checkpoint,一天会损失9600个GPU-hours。这个数字不是说所有训练都会这样,而是提醒我们:几分钟的停顿,乘上几千张卡之后,就不是小数。
四、Llama 3的数据说明了什么?

Meta训练Llama 3 405B的数据很适合拿来做参照。
按照Meta技术报告,Llama 3 405B预训练最多用到16384张H100。每张H100是80GB HBM3显存、700W TDP。报告还披露,在一个54天的预训练窗口里,训练作业一共发生466次中断,其中47次是计划内中断,419次是非计划中断。
这419次非计划中断里,约78%被归因于确认或疑似硬件问题,包括GPU、主机组件、静默数据损坏,以及非计划的单机维护。GPU相关问题是最大类,占所有非计划问题的58.7%。
换算一下,54天是1296小时,419次非计划中断平均下来大约每3.1小时一次。这个平均数不能理解成故障真的每3小时均匀发生一次,但它足够说明一个事实:到了万卡规模,故障不是极端偶发事件,而是训练系统日常要处理的东西。
Meta同一份报告里还有一句很关键的话:同步训练本身不太容错,一张GPU故障可能要求整个作业重启。即便如此,他们仍然把effective training time做到90%以上,靠的是减少启动和checkpoint时间,自动化诊断和问题处理。
这里值得注意的是,90%以上有效训练时间并不意味着故障少。恰恰相反,它说明在故障很多的情况下,训练系统能不能快速发现、快速恢复,会直接决定最终效率。
五、掉卡真正暴露的是训练系统能力

把这些机制和数据放在一起看,大模型训练最怕掉卡,不是因为硬件不能坏。任何足够大的集群都会遇到硬件故障。
真正的问题是,同步训练把大量GPU绑在同一个节拍上。单卡故障、慢卡、通信错位、checkpoint回退,都会被集群规模放大。单看一张卡,可能只是停几分钟;放到几千张卡上,就是几千张卡一起等。
所以,大模型训练拼的不只是GPU数量。GPU越多,单卡算力越不能解释最终效率。通信、同步、慢节点检测、checkpoint策略、故障恢复和任务调度,都会变成训练成本的一部分。
一张卡掉线本身不可怕。更难的是系统能不能快速判断:它是真坏了,还是只是慢了;是GPU问题,还是网络问题;要不要重启整个作业,还是只需要剔除问题节点。能不能把这套判断和恢复流程做快,决定了大规模训练到底是在有效计算,还是在让昂贵的GPU排队等人。
参考资料:
- Meta,《The Llama 3 Herd of Models》技术报告
- NVIDIA,NCCL Collective Operations官方文档
- PyTorch,DistributedDataParallel官方文档 与 torch.distributed官方文档
- PyTorch Blog,《Flight Recorder: A New Lens for Understanding NCCL Watchdog Timeouts》
- AWS Storage Blog,《Architecting scalable checkpoint storage for large-scale ML training on AWS》