正文
因此百度百舸对GPU机器交付前及交付后的稳定性质量进行了系统性管理:
4.任务容错的准召率保障
任务层面稳定性最核心的就是做好容错,能够让业务在无论遇到何种故障时都能快速恢复。
那么,首要的工作就是我们能够准确的识别出异常,然后对故障进行诊断定位,最后能够自动化的从异常中恢复。
因此,任务容错需要能够从端侧(即每个训练worker)探测到进程与环境的各类异常,同时有个中心服务(Master)从任务全局的视角去诊断、定位异常,最终做出相应的决策来使任务能够快速从异常中恢复。
任务容错最重要的就是提升故障的召回率与准确率,即如何能够尽可能的准确识别、定位所有故障。我们将故障分类两类:
显式故障和隐式故障
。
下面我们就以最典型的隐式故障场景——训练进程hang死为例,来看下如何
能够做好hang自动感知、诊断。
4.1.训练hang的自动感知
训练任务发生hang之后,绝大多数情况都会以timeout的方式报错并退出进程,最常见的就是在通信过程中如果发生hang,NCCL的watchdog会中断通信,并有报如下timeout报错,然后再由pytorch的torchrun进程感知并中断训练过程。
[E ProcessGroupNCCL.cpp:828] [Rank 1] Watchdog caught collective operation timeout: WorkNCCL(SeqNum=15173, OpType=ALLREDUCE, Timeout(ms)=1800000) ran for 1802710 milliseconds before timing out.
[E ProcessGroupNCCL.cpp:828] [Rank 0] Watchdog caught collective operation timeout: WorkNCCL(SeqNum=15173, OpType=ALLREDUCE, Timeout(ms)=1800000) ran for 1802713 milliseconds before timing out.
Pytorch默认为10分钟NCCL通信超时,而Megatron-LM为30分钟。在万卡规模训练场景中,意味着一万张卡要至少浪费30分钟才能被发现。这个时效性是不可接受的。而且当30分钟超时后程序会立马退出,很难有机会
进行下一步定位,需要一些时效性更高的感知机制,并且在程序退出前获取一些有效信息供后续诊断分析。
很多公司、实验室在面对hang的问题时,会在采用框架层插桩的方式来trace训练进程,这种方式通常是比较直接且准确的,但是有比较强的侵入性,而且可能还会有一些性能开销。
对于云厂商来说,需要寻找对用户更透明、更无损的方式来感知、定位hang异常。
如何感知训练hang,以百度百舸的产品设计思路为例,我们可以从以下几个方向
去思考:
-
训练进程hang的最直观表现是什么?
人工判断一个任务是否hang了,最直接的方式就是看是否所有worker的任务日志一段时间内都不输出日志了,所以hang自动感知的第一种方法就是采集所有worker的日志,并判断所有worker日志中最后一行日志是否为x分钟前的(x小于Pytorch的通信超时时间,例如8分钟),如果是则基本可以判定为hang。
-
任务hang时,可能进程的调用栈都不在发生变化,进程的调用栈可以通过py-spy/pystack等工具进行探测,所以我们可以用此类工具对所有训练任务进行一个定时采样,当采集n个样本所有进程栈都没有变化时,可以判定一次hang,这种方式通常可以将hang感知缩小至3~5分钟。
-
训练进程中的CUDA算子计算、集合通信操作通常都是在毫秒,甚至微秒、纳秒内完成的,当任务在正常迭代过程中发生了hang,我们常遇到的情况是所有rank的RDMA流量会降到0,而GPU的利用率为100%、SM利用率则在很低的水位。如果持续几分钟都是这种状态时,意味着训练进程已经计算完成,在等着集合通信完成,这种情况下基本可以判定为hang。