大型深度学习模型往往需要几十台甚至数百台GPU服务器协同训练。当其中一台服务器突然掉电、GPU故障、网络中断或者训练进程崩溃时,影响并不局限于这台机器。对于采用数据并行、张量并行或流水线并行的训练任务,一个节点退出可能导致通信组失效、当前迭代无法完成,严重时整个训练作业都会停止。
因此,分布式训练的容错重点并不是简单地“把坏机器换掉”,而是判断故障发生在哪里、当前训练状态保存到了什么位置,以及剩余资源能否按照原有并行方式继续运行。真正决定训练损失多少的,往往是故障检测、检查点设计、训练状态保存以及作业重新启动机制。
故障检测首先要解决的是“谁已经失效”。分布式训练系统通常会通过进程健康检查、节点管理系统、通信超时以及 GPU 和网络监控发现异常。具体机制并不一定都是传统意义上的固定间隔“心跳加ACK”。例如训练进程可能因为 GPU kernel 卡死而无法正常通信,也可能是节点本身仍然在线,但高速网络接口已经失效。因此,系统需要结合训练进程状态、通信超时、GPU错误和节点管理信息判断故障,而不能只依赖一个心跳信号。
一旦确认节点失效,系统还必须处理通信组。以AllReduce为例,每个参与者通常都需要按照相同的通信顺序参与 collective operation。如果其中一个rank消失,其他rank可能无法完成当前的AllReduce,最终造成整个训练作业卡住或异常退出。因此,故障处理往往需要终止受影响的通信上下文,并由作业管理系统重新建立训练进程组,而不是简单把故障GPU从原来的通信拓扑中删除以后继续执行。
训练状态恢复则是整个容错体系的核心。现代训练任务保存的通常不仅是模型参数,还包括优化器状态、当前训练步数、学习率调度器状态以及与数据读取有关的状态等。以Adam一类优化器为例,优化器本身维护额外的动量和二阶统计量。如果恢复时只有模型权重而没有恢复这些状态,后续训练的计算轨迹就可能发生变化。因此,一个真正可用的checkpoint需要根据训练框架保存足够完整的训练状态,而不能只保存模型文件。
Checkpoint的作用,是把训练过程划分成一系列可以恢复的状态点。假设训练已经进行到第100万步,最近一次成功保存的checkpoint位于第999000步,而第100万步附近发生服务器故障,那么重新启动以后通常只能可靠地从最近的有效checkpoint继续。已经完成但没有成功持久化的计算可能需要重新执行。这就是所谓的恢复点目标,也就是Recovery Point Objective,RPO。checkpoint越频繁,理论上可能丢失的训练进度越少,但保存checkpoint本身也会占用GPU训练时间、CPU资源、网络带宽和存储I/O。
恢复速度则涉及Recovery Time Objective,RTO。checkpoint文件可能达到数百GB甚至TB级别,如果每次故障都从远程存储完整读取,重新启动时间可能非常长。因此大型训练系统通常会考虑并行写入、分层存储、异步checkpoint、节点本地缓存以及增量或差异化保存等方法。不过这些机制并不意味着任何系统都可以把“故障节点的计算进度”和checkpoint简单合并。能否增量恢复取决于具体框架和checkpoint格式。
不同并行方式对故障的敏感程度也不同。数据并行通常让多个worker处理不同的数据分片,再通过AllReduce同步梯度。一个worker失效后,当前同步步骤往往无法正常完成,训练作业可能需要重新启动,并重新建立world size和通信组。某些支持弹性训练的系统能够在worker数量变化后继续运行,但这需要框架本身支持动态成员管理,而且训练语义、有效batch size、学习率策略等也可能随之发生变化。
张量并行和流水线并行则更加复杂。模型的一部分可能分布在多个GPU之间,一个节点的GPU失效可能意味着整个并行组无法继续执行。此时不是把任务随便迁移到另一张空闲GPU就能解决,因为新的GPU必须具备相应的模型状态,并重新建立并行拓扑。对于大模型训练来说,GPU之间的高速互联,例如NVLink、InfiniBand或RoCE网络,也会直接影响恢复和重新初始化的成本。
数据状态同样容易被忽略。假设checkpoint记录的是模型第50000步,但数据加载器实际上已经预取了一部分后续数据,那么恢复以后如何保证数据顺序、数据分片和随机状态符合训练设计,就需要框架专门处理。对于使用随机数据增强、shuffle以及分布式sampler的训练任务,随机数状态和数据读取位置也可能影响恢复后的训练轨迹。
故障节点恢复以后,并不一定意味着它必须马上重新加入原来的训练任务。如果硬件故障尚未排除,让同一台服务器重新加入可能再次导致任务中断。更常见的做法是由集群调度系统将故障节点标记为不可用,然后寻找新的GPU资源重新启动训练worker。新节点需要重新加载checkpoint、初始化通信环境并加入训练进程。对于大规模集群,还需要考虑新节点的GPU型号、显存容量、网络拓扑以及驱动和CUDA环境是否与原训练环境兼容。
这里还存在一个经常被忽视的问题:GPU故障并不一定意味着GPU本身坏了。训练日志中的CUDA错误、ECC错误、Xid错误、PCIe异常、GPU掉线以及网络通信错误可能来自不同层级。实际运维通常需要结合GPU监控、系统日志、NCCL日志、PCIe状态、网络交换机信息以及节点硬件健康数据进行定位。如果只是把服务器重新加入集群而没有找到根因,同一故障可能再次发生。
因此,成熟的分布式训练容错体系通常包含多个层次:集群调度器负责发现和隔离异常节点,训练框架负责处理进程失败和重新启动,通信库负责处理collective通信异常,checkpoint系统负责保存和恢复训练状态,而监控系统负责记录GPU、CPU、内存、网络和存储的异常情况。不同层次并不是互相替代,而是共同完成故障恢复。
对于大型训练任务,最重要的指标也不是简单追求“永不停止”。更实际的目标是降低单次故障造成的训练进度损失,并控制恢复时间和额外开销。checkpoint太少,故障后需要重跑大量计算;checkpoint太频繁,又可能让训练本身受到存储和I/O影响。因此,checkpoint周期需要根据模型规模、训练速度、存储吞吐量以及节点故障概率综合设计。
当训练恢复以后,还需要验证恢复是否真正成功。除了确认训练进程重新运行,还应检查global step、模型参数、optimizer state、学习率状态、数据读取状态以及loss曲线是否符合预期。如果恢复后loss突然出现异常变化,也不能简单认为“模型已经恢复”,而需要检查checkpoint完整性、数据状态以及并行配置是否发生变化。
分布式训练的容错,本质上是在计算效率和恢复可靠性之间寻找工程上的平衡。单台GPU服务器发生故障并不可怕,真正困难的是如何让数十乃至数百台GPU组成的计算系统,在部分硬件失效以后仍然能够准确判断故障、停止错误状态、保存可靠的训练进度,并从最近的有效状态重新建立计算环境。对于大模型训练,checkpoint、通信、调度和监控并不是几个独立的辅助功能,而是决定整个训练系统能否长期稳定运行的重要基础设施。
分布式训练任务中一台 GPU 服务器故障会发生什么,系统如何恢复训练进度
图片说明:示意图 图片来源:Public Domain(公有领域)
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP