训练任务容错及故障处理
本文介绍了智算云平台任务功能的容错日志、故障排查思路及解决方案。
平台的容错日志
当训练任务开始时,会自动生成容错日志,记录了开机检测结果、异常定位、重启操作等记录。点击任务详情中的容错日志,可查看每一轮运行任务时输出的容错日志。
任务启动、重启时均会执行开机检测(Bootcheck)。开机检测(Bootcheck)一切正常时的容错日志输出示例:
2024-08-05 18:11:14 Start to run Bootchecking...
2024-08-05 18:11:18 DiskTest /mnt/wangruisong/.gpfs_test: Succeed
2024-08-05 18:11:18 /mnt/wangruisong RW TEST: 5.9 GB/s 663 MB/s
2024-08-05 18:11:18 DiskTest /mnt/public/.gpfs_test: Succeed
2024-08-05 18:11:18 /mnt/public RW TEST: 5.3 GB/s 674 MB/s
2024-08-05 18:11:27 GPU Number: 1
2024-08-05 18:11:27 CUDA Version: 12.3
2024-08-05 18:11:27 PyTorch Version: v2.2.0a0+6a974be
2024-08-05 18:11:27 CUDA: Available
2024-08-05 18:11:27 NCCL Version: (2, 19, 3)
2024-08-05 18:11:27 GPU Type: NVIDIA A100-SXM4-40GB
2024-08-05 18:11:51 AllReduce Check: Succeed
2024-08-05 18:11:51 Check Finished.
训练失败后平台自动执行异常定位(Troubleshooting),示例输出如下:
2024-08-05 18:28:32 Start to run Troubleshooting...
2024-08-05 18:28:37 DiskTest /mnt/public/.gpfs_test: Succeed
2024-08-05 18:28:37 /mnt/public RW TEST: 5.5 GB/s 630 MB/s
2024-08-05 18:28:37 DiskTest /mnt/wangruisong/.gpfs_test: Succeed
2024-08-05 18:28:37 /mnt/wangruisong RW TEST: 4.5 GB/s 726 MB/s
2024-08-05 18:28:45 GPU Number: 1
2024-08-05 18:28:45 CUDA: Available
2024-08-05 18:28:45 PyTorch Version: v2.2.0a0+6a974be
2024-08-05 18:28:45 CUDA Version: 12.3
2024-08-05 18:28:45 GPU Type: NVIDIA A100-SXM4-40GB
2024-08-05 18:28:45 NCCL Version: (2, 19, 3)
2024-08-05 18:29:15 NCCL Performance Check: Bus Bandwidth Average: 4.0184 GB/s
2024-08-05 18:29:15 Check Finished, task will be restarted.
WARNING
- 硬件错误(如掉卡)将阻断任务继续执行,平台将自动帮您进行重调度至健康节点。
- 其他异常问题(如慢节点)不会阻断任务继续执行,平台将继续执行用户代码。
任务与 Worker 日志
如果训练代码存在问题,导致任务失败,您可以在任务详情中查看任务日志和 Worker 日志。
- 当发生错误时,可以从任务列表中点击日志,查看所有的错误日志记录,找到第一个异常日志记录及其对应的 Pod 信息。
- 根据第一条错误日志的记录信息,查找相应的代码位置,分析可能的原因,例如通信超时退出、计算错误退出、硬件错误退出、Pod 或进程失去连接退出等。
现场测试
如果有现场保留,您也可以自行运行基准测试以检查 Pod 和硬件是否存在问题。如果这些测试都通过,那么很可能是代码出现了问题。
- 计算基准测试,如 gpu-burn
- 通信基准测试,如 nccl-test
- 训练基准测试等
关于如何保留现场,可参见下方优化训练任务的启动命令。
登录任务的 worker
在任务详情页查看到任务 worker 的状态,可点击刷新获取当前最新状态。必要时可以登录 worker 进行错误排查或查询进程信息。
Worker 的登录入口在任务详情页 Worker 信息中。
NOTE
仅在任务运行中时可登录 Worker。
调试 NCCL
在调试和排障时,使用以下 NCCL 环境变量有助于排查问题。
设置 NCCL 在运行时打印丰富的日志信息,帮助调试和分析 NCCL 相关的性能问题和错误。
# 调试时打印日志使用
export NCCL_DEBUG=INFO
NOTE
打印大量调试信息可能会影响 NCCL 的性能,因此建议只在调试需要时启用此设置。
暂时绕过自动选择接口的机制,指定 NCCL 通信使用的网络接口。
# 设置socket建环使用eth0的通道
export NCCL_SOCKET_IFNAME=eth0
如果您的镜像是用的 NGC 镜像,或者加载了 NCCL 的 sharp 等插件的话,有可能会出错。可临时添加如下环境变量,帮助诊断问题或验证网络配置。
# 指示 NCCL 不使用任何网络通信插件
export NCCL_NET_PLUGIN=none
优化训练任务的启动命令
在 AIStudio 中进行模型训练时,我们希望能够提供较好的排障体验。我们将诊断一个训练任务启动命令的问题,并演示如何改进。
原始命令
该训练任务的启动命令存在以下问题:
- 缺乏日志记录,无法跟踪每个阶段的开始和结束时间以及执行状态。
- 使用
tee
命令重定向输出,即使训练任务失败也无法识别错误。 - 缺少错误处理机制,无法在训练任务失败时采取措施。
wget https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-vocab.json
wget https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-merges.txt
mkdir -p checkpoints/gpt2_345m
cd checkpoints/gpt2_345m
wget --content-disposition https://api.ngc.nvidia.com/v2/models/nvidia/megatron_l
m_345m/versions/v0.0/zip -O megatron_lm_345m_v0.0.zip
unzip megatron_lm_345m_v0.0.zip
rm megatron_lm_345m_v0.0.zip
cd ../..
git clone https://github.com/EastInsure/Megatron-DeepSpeed.git
cd Megatron-DeepSpeed
bash train/7B1_test.sh $MASTER_ADDR $MASTER_PORT $WORLD_SIZE $RANK | tee $(pwd)/M
egatron-DeepSpeed.log
改进方案
为了提高训练任务的易用性和鲁棒性,建议按照以下步骤进行改进:
添加日志记录:在每个关键操作前后添加日志记录,记录时间、Pod 名称和操作状态(例如是否已开始或结束)。这一改动将使我们能更好地跟踪脚本的执行进度。在容器内部获取
$HOSTNAME
环境变量可得到 Pod 名称。例如:
shellecho "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME starts to download gpt2-vocab.json and gpt2-merges.txt" wget https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-vocab.json wget https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-merges.txt echo "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME has completed the vocab download and starts to download the checkpoints."
使用
tee
命令并启用set -o pipefail
。原始命令最后一个操作将输出结果通过管道形式重定向到了日志文件中,因为tee
的命令总是会成功的,导致这种方式即使任务出错了也无法正确识别到。例如使用
set -o pipefail
确保管道中的任何错误都会导致脚本退出。shellset -o pipefail bash train/7B1_test.sh $MASTER_ADDR $MASTER_PORT $WORLD_SIZE $RANK | tee $(pwd)/Megatron-DeepSpeed.log
同理,如果重定向操作在脚本内部完成,也可以这样改造,从而可以把出错信息完整的保留。
shellbash train/7B1_test.sh $MASTER_ADDR $MASTER_PORT $WORLD_SIZE $RANK > >(tee -i $(pwd)/logs/$$HOSTNAME.log) 2>&1
添加错误处理机制,保留现场。在训练任务完成后,检查其返回值。如果返回值非零,则表示训练任务失败,需要采取措施,例如记录错误信息并保留容器。
例如,在
bash train/7B1_test.sh
命令之后使用ret=$?
捕获退出代码。如果退出代码非零,则意味着训练失败,打印错误消息并保留 10000 秒。使用exit $?
将bash train/7B1_test.sh
执行结果状态返回给容器。shellret=$? if [[ ${ret} -ne 0 ]]; then echo "[$(date +"%Y-%m-%d %H:%M:%S")] $HOSTNAME has crashed! The onsite reservation time is 10000s" sleep 10000 fi exit $?
以下是改造后的完整脚本:
set -o pipefail
# 下载 gpt2-vocab.json 和 gpt2-merges.txt
echo "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME 开始下载 gpt2-vocab.json 和 gpt2-merges.txt"
wget https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-vocab.json
wget https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-merges.txt
echo "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME 已完成 vocab 下载,开始下载检查点"
# 创建检查点目录并下载检查点
mkdir -p checkpoints/gpt2_345m
cd checkpoints/gpt2_345m
wget --content-disposition https://api.ngc.nvidia.com/v2/models/nvidia/megatron_lm_345m/versions/v0.0/zip -O megatron_lm_345m_v0.0.zip
unzip megatron_lm_345m_v0.0.zip
rm megatron_lm_345m_v0.0.zip
cd ../..
# 克隆训练代码
echo "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME 已完成检查点下载,开始拉取训练代码"
git clone https://github.com/EastInsure/Megatron-DeepSpeed.git
cd Megatron-DeepSpeed
# 运行训练脚本
echo "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME 已完成代码拉取,开始运行训练脚本"
bash train/7B1_test.sh $MASTER_ADDR $MASTER_PORT $WORLD_SIZE $RANK | tee $(pwd)/Megatron-DeepSpeed.log
# 检查训练结果
ret=$?
if [[ ${ret} -ne 0 ]]; then
echo "[$(date +"%Y-%m-%d %H:%M:%S")] \$HOSTNAME 训练失败!现场保留时间为 10000s"
sleep 10000
fi
exit $?