服务器与大带宽专家 · 持牌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级别策略,可以设为OnFailure或Never。
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后,后续可以用gdb或cuda-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天。

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