最常见的几个原因其实并不复杂——路径写错了、文件损坏了、键名对不上,或者设备映射没处理好。每个问题都有对应的排查思路,下面逐一拆解。

torch.load 读取 .pth 文件时路径不对或报错 OSError: No such file or directory
路径问题大概是最常见的翻车现场。尤其是在 Jupyter 或不同工作目录下运行代码时,torch.load 并不会自动去项目根目录或模型目录里翻找——它只认当前 os.getcwd() 的相对路径或者你给它的绝对路径。
- 推荐的做法:用
os.path.abspath("model.pth")或者Path(__file__).parent / "model.pth"显式构造路径,别靠“应该就在旁边”这种直觉。 - 加载之前先跑一下
os.path.exists("model.pth"),确认文件确实在那里,这比报错后回头翻路径快得多。 - 如果文件藏在子目录里,比如
weights/ckpt.pth,记得把斜杠写全——"weightsckpt.pth"这种手误并不少见。
加载时报 RuntimeError: unexpected EOF 或 pickle.UnpicklingError
这通常意味着文件本身坏了、不完整,或者压根就不是 PyTorch 保存的 .pth 格式——比如实际是 ONNX、TensorFlow checkpoint,或者下载中途断了。
- 在 Linux/macOS 上用
file model.pth看一眼文件类型,在 Windows 上用 PowerShell 执行Get-ChildItem model.pth | Select Length检查大小——空文件或者只有几 KB 的基本可以扔了。 torch.load默认走pickle反序列化,极少数情况下会碰到用旧方式(torch.sa ve(..., _use_new_zipfile_serialization=False))保存的文件,但更多时候就是文件本身不合法。- 千万别用文本编辑器强行打开或“修复”
.pth文件——它是二进制 ZIP 格式,改一个字节整个文件就废了。
加载后 state_dict 键名对不上,模型 load_state_dict 失败
权重文件里的键(比如 "backbone.conv1.weight")跟模型实际参数名不一致,这种冲突通常来自:模型定义改过、用了不同训练脚本,或者权重是从 Hugging Face 这类第三方库拿过来的。
- 先打印看看:
print(torch.load("model.pth").keys())确认存的是不是直接state_dict,再用print(list(model.named_parameters()))对比一下。 - 如果只是键名前缀不同,比如多了一层
module.,可以用state_dict = {k.replace("module.", ""): v for k, v in state_dict.items()}清洗——这是多卡训练保存后的常见问题。 - 如果键名顺序或结构完全不搭,别硬做映射映射——先确认你加载的权重真的是给这个模型用的,而不是同名但不同架构的文件。
用 map_location 避免 GPU 加载失败或显存泄漏
在 CPU 上加载本应放在 GPU 上的 .pth 文件,或者反过来,如果不指定 map_location,很容易直接 OOM 或者报 Invalid device。
- CPU 加载时务必写
torch.load("model.pth", map_location="cpu"),否则默认会尝试加载到原设备(比如cuda:0)。 - 如果想加载到指定的 GPU 卡,用
map_location="cuda:1",别靠后面补model.cuda()——后者不改变state_dict里张量的设备,load_state_dict会失败。 - 更稳妥的写法:
map_location=torch.device("cpu"),比字符串更明确,也能兼容 PyTorch 的未来版本。
说到底,PyTorch 的 torch.load 行为高度依赖文件来源和保存时的上下文。同一个 .pth 文件,换个环境可能因为设备、路径、模型定义的微小差异就加载失败——别想当然地以为“能跑通一次就永远没问题”。