服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-09-15 更新于 2026-09-15 简米科技 5,373 字 13 分钟阅读

训练任务失败后平台如何自动重试并保留现场日志,怎么配置?

导读训练任务失败后,平台自动重试并保留现场日志的核心做法是:在任务编排层配置失败识别与退避重试,同时用独立日志通道和快照机制把崩溃现场固定下来,避免容器一删,证据全没,训练任务失败自动重试机制怎么设计训练任务挂了,平台的第一反应不应该是无脑拉起,而是先看一眼退出码,再决定要不要重试,如果代码本身有语法错误,拉起来十……

训练任务失败后,平台自动重试并保留现场日志的核心做法是:在任务编排层配置失败识别与退避重试,同时用独立日志通道和快照机制把崩溃现场固定下来,避免容器一删,证据全没。

训练任务失败自动重试机制怎么设计

训练任务挂了,平台的第一反应不应该是无脑拉起,而是先看一眼退出码,再决定要不要重试,如果代码本身有语法错误,拉起来十次还是失败,还白白烧GPU卡时。

先给失败分类,再决定重试策略

多数训练平台的失败可以分成两类:

  • 可重试失败:节点资源不足、网络抖动、GPU驱动临时异常、数据加载超时、节点漂移。
  • 不可重试失败:训练代码报错、配置文件写错、数据路径不存在、精度不收敛。

区分这两类失败,通常靠容器退出码,例如Kubernetes环境下,退出码137多半是OOM或被信号杀掉,退出码1一般是程序自身抛异常,平台会根据退出码判断是否需要自动重试。

Kubernetes Job的重试参数怎么配

在Kubernetes里,一个训练任务通常用Job或自定义资源承载,自动重试依赖两个字段:

restartPolicy:Pod级别策略,可以设为OnFailureNever
backoffLimit:Job级别重试次数上限。

一个最小配置长这样:

apiVersion: batch/v1
kind: Job
metadata:
  name: train-retry-demo
spec:
  backoffLimit: 3
  template:
    spec:
      restartPolicy: OnFailure
      containers:
      - name: trainer
        image: pytorch/pytorch:2.0.0-cuda11.7-cudnn8-runtime
        command: ["python", "train.py"]
        volumeMounts:
        - name: logs
          mountPath: /workspace/logs
      volumes:
      - name: logs
        persistentVolumeClaim:
          claimName: train-logs-pvc

backoffLimit: 3表示整个Job最多额外重试3次。restartPolicy: OnFailure表示Pod内容器失败后原地重启,这里有一个容易踩的坑:Pod内重启不消耗backoffLimit次数,它只针对Pod级失败,比如节点被驱逐、Pod被删。

退避间隔不要照搬Web服务

Web服务常用的指数退避,对GPU训练任务未必合适,训练任务通常需要先找回checkpoint,再重新申请资源,如果退避太短,任务会在资源未释放时反复撞墙;如果退避太长,又会放大排队等待成本。

业内专家指出,重试策略必须与断点续训配合,否则只是重复烧钱,多数情况下,训练重试采用固定短间隔加人工熔断,比长尾指数退避更稳。

训练平台故障现场日志保留方法

很多团队以为stdout就是日志,容器退出后还能用

训练任务失败后平台如何自动重试并保留现场日志,怎么配置?

kubectl logs看到,容器一旦被驱逐,或者Pod被控制器清理,标准输出会跟着容器生命周期一起消失,真正能用于事后排查的,是写到持久卷或对象存储的那份落盘日志。

日志不要只写容器标准输出

训练脚本里建议同时输出到两个地方:

  • stdout:方便实时查看和平台采集。
  • /workspace/logs/train.log:落到PVC或对象存储,容器重建后依然存在。

Python训练脚本里可以这样写:

import logging
logging.basicConfig(
    level=logging.INFO,
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler("/workspace/logs/train.log")
    ]
)

容器编排侧再用一个日志采集sidecar,比如Vector、Fluentd或Filebeat,去tail这个目录,把日志推到对象存储,sidecar和训练容器共享同一个日志卷,训练容器写,sidecar实时上传,训练容器崩了也不影响上传进程。

现场快照比日志更“现场”

日志只能说明程序走到哪一步,看不出当时的环境状态,现场快照才是完整证据。

训练平台保留现场日志时,至少要做三件事:

  • 保留训练容器退出前的最后一段日志,可以用kubectl logs train-xxx -c trainer --previous取到上一次崩溃记录。
  • 保留/workspace/checkpoints下的最新checkpoint文件,这是重试能从断点继续的前提。
  • 保留环境变量和GPU拓扑信息,例如nvidia-smi输出、env输出、/proc/driver/nvidia/version

对于偶发性CUDA错误,现场快照尤其重要,可以配合容器提交命令把崩溃现场保存成镜像:

docker commit train-container train-crash-snapshot:20260101

这样即使原始节点被回收,也能在本地重新拉起容器做复现。

core dump不能丢

如果训练进程崩在底层CUDA或NCCL,文本日志往往只有一行Segmentation fault,真正有用的是core dump。

在容器里提前放开core dump,并指定输出到共享卷:

ulimit -c unlimited
echo "/workspace/coredumps/core.%e.%p" > /proc/sys/kernel/core_pattern

需要注意,改core_pattern需要容器具备较高权限,生产环境通常由平台统一配置,保留core dump后,后续可以用gdbcuda-gdb还原崩溃栈。

深度学习训练中断自动重试怎么设置

不同平台的配置入口不一样,但思路一致:把失败识别、重试次数、checkpoint恢复串起来。

Kubeflow PyTorchJob的自动重试

Kubeflow上跑分布式训练,PyTorchJob的自定义资源里直接配置

训练任务失败后平台如何自动重试并保留现场日志,怎么配置?

restartPolicy

apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
  name: training-retry
spec:
  pytorchReplicaSpecs:
    Master:
      replicas: 1
      restartPolicy: OnFailure
      template:
        spec:
          containers:
          - name: pytorch
            image: pytorch/pytorch:2.0.0-cuda11.7-cudnn8-runtime

这里Master和Worker最好使用不同策略,Master失败一般要重试,因为它负责聚合梯度;Worker失败如果框架支持弹性训练,可以降级继续,也可以按OnFailure策略重建,多数情况下,Master和Worker都设成OnFailure,但要在代码里接住NCCL超时,避免一个Worker卡住拖垮整个Job。

SLURM集群的中断重试

SLURM上跑训练任务,如果节点故障,任务会直接终止,可以在提交脚本里加--requeue参数:

srun --requeue --job-name=train-gpu --gres=gpu:8 python train.py

--requeue的作用是任务被节点故障打断后,自动回到队列等待可用资源,如果训练框架支持checkpoint,作业重新调度后会自动从最近一次保存点继续。

需要注意,--requeue对用户主动取消的任务不生效,只对系统原因导致的失败负责,这个机制适合长时间训练的GPU任务。

PyTorch Lightning的代码级重试

不想依赖平台,也可以在训练框架里做重试,PyTorch Lightning的Trainer直接支持:

from pytorch_lightning import Trainer
trainer = Trainer(
    max_retries=3,
    retry_strategy="exponential_backoff",
    default_root_dir="/workspace/checkpoints"
)

它会在训练异常退出后自动从最新checkpoint恢复,这个方案的好处是平台无关,坏处是重试过程仍然受当前进程和节点限制,节点整个挂掉时,代码级重试也无能为力。

GPU训练任务失败自动重试方案对比

不是所有重试方案都适合GPU训练,下面把常见方案按重试粒度、日志保留能力和适用场景做个对比。

方案 重试粒度 现场日志保留 适用场景 配置复杂度
Kubernetes Job Pod级 依赖PVC或外部采集 单机单卡训练
Kubeflow PyTorchJob 角色级 依赖持久卷和sidecar 分布式多卡训练
SLURM requeue 作业级 依赖集群共享存储 超算中心、高校集群
PyTorch Lightning 进程级 依赖本地目录,节点丢失会丢

训练任务失败后平台如何自动重试并保留现场日志,怎么配置?

中小规模、快速实验

云平台托管训练 任务级 一般自带日志服务 企业生产环境

从保留现场日志的角度看,云平台托管训练通常最省心,因为它把日志、指标、checkpoint都接到对象存储,但从可控性和成本看,Kubernetes自建方案更灵活,也更容易按北京地区GPU训练平台的需求做定制。

训练任务失败日志排查:从现场日志到根因

现场日志保留下来,不是为了“有日志”,而是为了能快速定位,训练任务失败后的日志排查,一般沿着这条路径走:

kubectl get events --sort-by=.lastTimestamp | grep train-xxx
kubectl logs train-xxx -c trainer --previous --tail=200
kubectl describe pod train-xxx | grep -A10 "Events"

三条命令分别看调度事件、上一次崩溃日志、Pod状态变化,多数训练失败都能在这一轮里找到方向。

常见失败模式和检索关键词:

  • CUDA out of memory:日志里直接出现,属于显存不足。
  • NCCL timeout:分布式通信超时,检查网络和GPU拓扑。
  • DataLoader worker exit:数据加载进程异常,减少num_workers或检查存储IO。
  • Checkpoint corrupted:checkpoint文件损坏,需要回到更早的保存点。

日志路径最好固定成约定,例如/workspace/logs/train-{job_id}.log,这样平台侧可以用同一套采集和清理策略管理,不会出现每个任务日志散落各处的情况。

训练任务失败后平台如何自动重试并保留现场日志:Q&A

训练任务失败后平台如何自动重试并保留现场日志?

平台通过任务控制器监听失败事件,先判断退出码是否属于可重试类型,再按照配置的重试次数和退避策略拉起新容器,日志保留依靠两个通道:训练容器把文本日志写入持久卷,sidecar实时上传对象存储;同时平台保留最新checkpoint和可选core dump作为现场快照。

GPU训练任务失败自动重试方案里,重试次数设多少合适?

行业共识认为,日志保留周期至少要覆盖一个完整训练周期加两次重试窗口,重试次数多数建议控制在3次以内,GPU任务的成本按卡时计费,超过3次仍失败,基本可以判断为代码或数据问题,需要人工介入。

北京地区训练平台日志保留多久?

主流云平台在北京地区与其它地域的默认日志服务保留周期多数为7天,部分服务支持延长到30天,自建平台一般将PVC回收策略设为Retain,日志对象存储生命周期按项目要求配置,训练任务日志通常不建议短于7天。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱