YOLO26训练中断怎么办?resume参数使用实战解析
你是否在训练YOLO26模型时,突然遇到断电、显存溢出、误关终端,或者服务器资源被抢占导致训练被迫中止?眼看着跑了127个epoch却无法继续,只能从头再来?别急——YOLO26(基于Ultralytics v8.4.2)原生支持断点续训,关键就在一个常被忽略的参数:resume。
本文不讲抽象原理,不堆技术术语,只聚焦一件事:当你按下Ctrl+C、遭遇OOM崩溃、或意外退出后,如何用一行代码真正把训练接上,且保证权重、优化器状态、学习率调度、甚至进度条都严丝合缝地延续下去。所有操作均基于你正在使用的「YOLO26官方版训练与推理镜像」实测验证,步骤清晰、命令可复制、效果可复现。
1. 为什么resume不是“重启训练”,而是“接着跑”?
很多新手误以为resume=True只是重新加载最后保存的权重再训,其实完全不是。真正的断点续训,是完整恢复以下5个关键状态:
- 模型参数(weights)
- 优化器状态(optimizer state,含动量、二阶矩等)
- 学习率调度器(lr scheduler step 和当前lr值)
- 已完成的epoch计数和迭代步数(避免重复计算)
- 训练日志文件(results.csv、events.out.tfevents)的追加写入
这意味着:如果你在第138个epoch中途中断,启用resume后,它会从第139个epoch的第一步开始,学习率按原调度策略继续衰减,优化器记忆着前138轮的梯度历史——和没中断过一模一样。
注意:
resume功能依赖训练过程中自动保存的last.pt文件。该文件默认位于project/name/weights/last.pt,包含全部上述状态。只要这个文件存在,续训就可靠。
2. resume参数的三种使用方式(附真实命令)
2.1 方式一:命令行直接启用(最简单,推荐新手)
无需修改任何Python脚本,直接在终端运行带--resume标志的命令:
python train.py --data data.yaml --cfg ultralytics/cfg/models/26/yolo26.yaml --weights yolo26n.pt --epochs 200 --batch 128 --imgsz 640 --project runs/train --name exp --resume优势:零代码改动,适合快速验证;
❌ 注意:必须确保runs/train/exp/weights/last.pt存在,且路径与--project和--name严格匹配。
2.2 方式二:在train.py中显式设置(最可控,推荐工程化)
回到你已有的train.py文件,找到model.train(...)调用处,将resume=False改为resume=True:
model.train( data=r'data.yaml', imgsz=640, epochs=200, batch=128, workers=8, device='0', optimizer='SGD', close_mosaic=10, resume=True, # ← 关键修改:由False改为True project='runs/train', name='exp', single_cls=False, cache=False, )然后像往常一样运行:
python train.py优势:逻辑内聚,便于版本管理;可配合条件判断(如if os.path.exists('runs/train/exp/weights/last.pt'): resume=True);
注意:若之前训练未生成last.pt(比如手动删了、或首次运行),程序会报错提示“no last.pt found”,此时需确认路径或改回resume=False重训。
2.3 方式三:指定任意权重文件续训(高级用法,用于迁移调试)
有时你想从某个特定检查点(比如best.pt或某次手动保存的epoch150.pt)开始续训,而非默认的last.pt。这时不能用resume=True,而要组合使用weights=和resume=False,并确保该权重文件本身包含优化器状态。
例如,你想从runs/train/exp/weights/epoch150.pt继续:
model.train( data=r'data.yaml', imgsz=640, epochs=200, # 注意:这里仍填总epochs数,不是剩余数 batch=128, workers=8, device='0', weights=r'runs/train/exp/weights/epoch150.pt', # ← 指向含optimizer状态的权重 resume=False, # ← 必须为False,否则会去找last.pt project='runs/train', name='exp_resume150', )关键提醒:只有通过YOLOv8+原生model.train()保存的权重(.pt格式)才包含优化器状态。用torch.save(model.state_dict())保存的.pth文件不支持续训。
3. 实战排错:resume不生效的5个高频原因与解法
即使代码写对了,resume也可能“看似没反应”。以下是镜像环境中实测最常见的5类问题及解决方案:
3.1 问题:终端报错FileNotFoundError: No last.pt found in ...
- 原因:
last.pt被删除、路径错误、或训练从未成功保存过(如首次运行就崩溃)。 - 解法:
- 进入项目目录检查:
ls -l runs/train/exp/weights/ - 若无
last.pt,但有best.pt,可临时复制:cp runs/train/exp/weights/best.pt runs/train/exp/weights/last.pt - 确保
project和name参数与原训练完全一致(大小写、下划线、空格均敏感)。
- 进入项目目录检查:
3.2 问题:续训后epoch从0开始,或learning rate重置为初始值
- 原因:使用的权重文件(
weights=参数指向的)不含优化器状态,或resume=True未生效(被其他参数覆盖)。 - 解法:
- 用
torch.load()检查权重内容:import torch ckpt = torch.load('runs/train/exp/weights/last.pt') print('optimizer' in ckpt) # 应输出True print(ckpt['epoch']) # 应显示上一次的epoch数 - 确认
train.py中resume=True未被注释,且没有拼写错误(如resum=True)。
- 用
3.3 问题:续训时显存爆满(OOM),比首次训练还容易崩
- 原因:
resume会加载last.pt中的完整优化器状态(含动量缓存),额外增加约15%显存占用。 - 解法:
- 临时降低
batch:batch=96→batch=64; - 或添加
cache=False(禁用内存缓存); - 终极方案:在
train.py中加入torch.cuda.empty_cache()调用。
- 临时降低
3.4 问题:续训后mAP不升反降,loss曲线突跳
- 原因:数据增强随机种子未固定,导致续训时
mosaic、mixup等增强策略与之前不一致。 - 解法:在
model.train()前强制设置种子:import random import numpy as np import torch SEED = 42 random.seed(SEED) np.random.seed(SEED) torch.manual_seed(SEED) torch.cuda.manual_seed(SEED)
3.5 问题:Xftp下载last.pt后,在本地重新resume失败
- 原因:镜像中训练使用的是绝对路径(如
/root/workspace/ultralytics-8.4.2/...),而本地路径不同,导致data.yaml中路径解析失败。 - 解法:
- 下载后,先用文本编辑器打开
last.pt(实际是zip格式),解压查看args.yaml; - 修改其中
data字段为本地data.yaml的绝对路径; - 重新打包为
.pt(或更简单:直接在本地重新运行train.py,仅修改data=参数指向本地路径)。
- 下载后,先用文本编辑器打开
4. resume进阶技巧:让续训更稳、更快、更智能
4.1 技巧一:自动检测并启用resume(防手误)
在train.py开头加入以下逻辑,让脚本自己判断是否该续训:
import os from ultralytics import YOLO PROJECT = 'runs/train' NAME = 'exp' RESUME_PATH = f'{PROJECT}/{NAME}/weights/last.pt' resume = os.path.exists(RESUME_PATH) print(f"→ 自动检测到续训文件: {RESUME_PATH} → {'启用' if resume else '禁用'}") model = YOLO(model='/root/workspace/ultralytics-8.4.2/ultralytics/cfg/models/26/yolo26.yaml') model.train( data=r'data.yaml', imgsz=640, epochs=200, batch=128, resume=resume, # ← 动态赋值 project=PROJECT, name=NAME, )4.2 技巧二:限制续训最大epoch,避免超训
若原计划200 epoch,但你发现180 epoch时val_loss已收敛,想续训到190就停:
# 在train.py中,动态计算剩余epochs import torch if os.path.exists(RESUME_PATH): ckpt = torch.load(RESUME_PATH) current_epoch = ckpt['epoch'] remaining_epochs = min(190, 200) - current_epoch # 最多跑到190 print(f"→ 当前epoch: {current_epoch}, 剩余训练: {remaining_epochs} epochs") model.train(epochs=remaining_epochs, ...) # ← 传入剩余数,非总数4.3 技巧三:续训时更换学习率策略(微调场景)
续训不等于“原样接着跑”。比如你想在150 epoch后切换成更小的学习率:
from ultralytics.utils.torch_utils import smart_inference_mode if resume: # 加载后立即修改学习率 for param_group in model.trainer.optimizer.param_groups: param_group['lr'] = 0.001 # 设为新lr print("→ 续训中:学习率已更新为0.001")5. 总结:掌握resume,就是掌握YOLO26训练的主动权
resume=True不是“重启”,而是全状态无缝衔接,它让你告别“139/200 —— 断了,重来”的焦虑;- 三种启用方式中,命令行
--resume最轻量,train.py内设resume=True最稳健,指定权重续训最灵活; - 遇到不生效?先查
last.pt是否存在、是否含optimizer、路径是否匹配——90%的问题源于此; - 进阶技巧的本质,是把
resume从“开关”变成“工具”:自动判断、动态控制、策略调整。
记住:在深度学习训练中,时间是最昂贵的成本。而resume,正是你对抗意外、节省时间、提升效率最朴实也最有力的武器。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。