非常游戏网
如何在Python中解析PyTorch的pth模型文件_使用torch.load读取参数字典

如何在Python中解析PyTorch的pth模型文件_使用torch.load读取参数字典

2026-05-26日常编程195519

应显式指定 map_location='cpu' 并启用 weights_only=True(PyTorch ≥2.0),区分保存的是完整模型还是 state_dict,加载后校验类型、key 结构及数值合法性。

torch.load 读取 .pth 文件时抛出 PickleError 或 RuntimeError 怎么办

直接用 torch.load 加载非安全来源的 .pth 文件,极大概率触发 RuntimeError: Attempting to deserialize object on a CUDA device 或更危险的 pickle.UnpicklingError —— 因为 .pth 本质是 Python 的 pickle 序列化文件,可能含任意代码执行逻辑。

安全做法是强制指定 map_location 并禁用自动反序列化代码对象:

  • 始终显式传入 map_location='cpu',避免设备不匹配错误
  • 若模型保存时用了 torch.save(model.state_dict(), ...),则加载后得到的是 dict,不是完整模型对象;别试图直接 model.load_state_dict(...) 前不做初始化
  • 对不可信文件,加 weights_only=True(PyTorch ≥2.0),它会跳过所有自定义类/函数反序列化,只允许基础类型和 torch.Tensor

示例:

import torch
state_dict = torch.load('model.pth', map_location='cpu', weights_only=True)

加载后得到的字典 key 长得不像层名?检查是否保存了整个模型还是仅 state_dict

两种常见保存方式导致字典结构完全不同:

  • torch.save(model, 'full_model.pth') → 加载结果是完整 nn.Module 实例,带 forward__dict__、甚至自定义属性
  • torch.save(model.state_dict(), 'weights.pth') → 加载结果是纯 dict,key 形如 'conv1.weight''bn2.running_mean',无模块嵌套逻辑

type(...)list(...keys())[:3] 快速判断:

Python 3.14.3

微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。

ckpt = torch.load('model.pth', map_location='cpu')
print(type(ckpt))  #  还是 ?
print(list(ckpt.keys())[:3])  # 若报 AttributeError,则不是 dict

想查看某层权重形状但 key 名不确定?用字典遍历 + 字符串匹配

state_dict 的 key 是字符串,没有层级结构,但习惯上用点号分隔模块名。别硬记全路径,用 instartswith 快速过滤:

  • [k for k in state_dict if 'layer4' in k] 找所有 layer4 相关参数
  • [k for k in state_dict if k.endswith('.bias')] 找全部偏置项
  • state_dict['backbone.conv1.weight'].shape 直接取张量看 torch.Size([64, 3, 7, 7])

注意:key 区分大小写,且不含 .module. 前缀——除非模型曾用 nn.DataParallel 保存,此时所有 key 会多一层前缀,需用 {k.replace('module.', ''): v for k, v in state_dict.items()} 清洗

加载后权重数值全是 nan 或 inf?检查保存时是否启用了梯度计算

如果训练中误将 requires_grad=True 的中间变量(比如 loss、optimizer.state)存进 state_dict,或保存了未 detach 的计算图节点,torch.load 可能还原出非法浮点值。

  • 加载后立刻检查:torch.isnan(next(iter(state_dict.values()))).any()
  • 正常权重应全为 finite 值:torch.isfinite(weight).all().item() == True
  • 根本解法:保存前确保只存 .state_dict(),而非 model.__dict__ 或手动构造的 dict

这种问题在调试自定义训练循环时特别容易被忽略——因为模型跑着不报错,但保存下来的文件已损坏。