3. 模型加载报错:.pt文件损坏、权重路径错误、模型架构不匹配

模型加载报错,可以说是YOLO调试里最让人头疼的问题之一。明明训练了好几天,结果加载时报错,心态直接崩了。我刚开始接触YOLO时,就因为这个折腾了一整个下午。后来踩的坑多了,慢慢总结出一些规律。

说白了,这类报错就三种情况:文件坏了、路径错了、架构对不上。咱们一个一个说。

3.1 .pt文件损坏——最隐蔽的坑

.pt文件损坏,通常不是人为操作失误,而是传输或存储过程中出了问题。我遇到过最典型的一次:用网盘下载预训练权重,下载到一半网络断了,续传后文件大小看起来正常,但加载时就报 EOFError。

⚠️ 注意: 文件大小正常 ≠ 文件完整。PyTorch的序列化格式对完整性要求很高,哪怕少一个字节都可能加载失败。

怎么判断文件是否损坏?我一般用两个方法:

  1. 检查文件头——用 torch.load 的 weights_only=True 参数做快速验证
  2. 对比MD5值——官方发布的权重通常有MD5校验码
import torch

# 方法1:快速验证文件完整性
try:
    ckpt = torch.load('yolov8n.pt', map_location='cpu', weights_only=True)
    print("✅ 文件加载成功")
except Exception as e:
    print(f"❌ 文件损坏: {e}")

# 方法2:检查MD5(以官方值为准)
import hashlib
with open('yolov8n.pt', 'rb') as f:
    md5 = hashlib.md5(f.read()).hexdigest()
print(f"MD5: {md5}")
💡 我的习惯: 每次下载完权重,第一件事就是跑MD5校验。别嫌麻烦,这能省下后面排查的几小时。

3.2 权重路径错误——90%的新手都犯过

路径错误其实是最容易解决的,但也是最容易忽略的。我见过有人把路径写成了 ./weights/yolov8n.pt,但实际文件在 ./models/weights/yolov8n.pt,结果报 FileNotFoundError。

常见的路径问题就这几类:

错误类型 典型报错信息 原因
文件不存在 FileNotFoundError: [Errno 2] No such file or directory 路径写错了,或者文件没下载
相对路径混乱 FileNotFoundError(无具体路径提示) 工作目录和脚本目录不一致
扩展名遗漏 RuntimeError: Unknown format 没写 .pt 或 .pth
路径含中文/空格 UnicodeDecodeError 或加载失败 PyTorch对非ASCII路径支持不好

我的建议是:永远用路径,或者用 os.path 拼接路径。别手写字符串拼接,容易出错。

import os
from pathlib import Path

# 推荐做法:用Path对象
weights_dir = Path(__file__).parent / 'weights'
model_path = weights_dir / 'yolov8n.pt'

if not model_path.exists():
    raise FileNotFoundError(f"权重文件不存在: {model_path}")

model = torch.hub.load('ultralytics/yolov8', 'custom', path=str(model_path))
🔑 关键点: 路径问题排查时,先 print(os.getcwd()) 看看当前工作目录,再确认文件实际位置。很多时候问题就出在这里。

3.3 模型架构不匹配——最隐蔽的坑

这个坑我踩得最深。有一次我用YOLOv8n训练了一个模型,然后想用YOLOv8s的配置文件去加载,结果报 RuntimeError: Error(s) in loading state_dict。当时我还纳闷:不都是YOLOv8吗?

其实,权重文件里保存的是模型参数,不是模型结构。你用哪个架构训练的,就必须用完全一样的架构去加载。哪怕只是改了 depth_multiple 或 width_multiple,参数数量对不上,就会报错。

常见的架构不匹配场景:

  • 模型大小不一致:用nano的权重加载small模型
  • 类别数不同:训练时10类,加载时用默认80类
  • 自定义修改了网络层:加了注意力机制或改了head结构
  • YOLO版本混用:v5的权重加载到v8上
# 错误示范:架构不匹配
model = YOLO('yolov8n.pt')  # 训练时是nano
model.load('yolov8s.pt')    # 加载small权重 → 报错

# 正确做法:保持架构一致
model = YOLO('yolov8n.yaml')  # 先定义架构
model.load('yolov8n.pt')      # 再加载对应权重
⚠️ 避坑指南: 我曾经在自定义数据集上训练了50个epoch,结果因为改了模型配置文件里的 ch(输入通道数),加载时报错。排查了半小时才发现是通道数不匹配。所以,训练和推理用同一个yaml文件,别手改。

3.4 排查流程总结

遇到模型加载报错,别慌。按这个流程走,基本能定位问题:

模型加载报错排查流程 模型加载报错 步骤1:检查文件路径是否存在 os.path.exists() / Path.exists() 步骤2:检查文件是否损坏 torch.load(weights_only=True) / MD5 步骤3:检查模型架构是否匹配 yaml文件 / 类别数 / 版本号 步骤4:检查设备与内存 GPU显存 / CPU内存 / CUDA版本 定位并修复问题 💡 排查顺序 先易后难 路径 → 完整性 → 架构 → 设备环境 🔧 常用工具 torch.load hashlib.md5 os.path / Path
💡 我的经验: 按这个流程走,90%的模型加载问题能在5分钟内定位。剩下10%是环境问题,比如PyTorch版本不兼容,或者CUDA版本对不上。那个就属于另一个话题了。

3.5 终极方案:重新下载

如果以上方法都试过了还是不行,别死磕。直接重新下载权重文件,或者重新导出模型。我见过有人花了两小时排查一个损坏的.pt文件,最后发现是硬盘坏道导致的。重新下载到另一个盘,问题就解决了。

嗯,模型加载报错其实不可怕。只要掌握了排查思路,大部分问题都能快速解决。关键是别慌,按步骤来。