WeightsUnpickler error: Unsupported global: GLOBAL __main__.Model...以及RuntimeError: ...MKLDNN tensor

目录

问题描述

错误原因

解决方法

方法 1:设置 weights_only=False(不安全)

方法 2:使用  add_safe_globals(安全)

方法3:重新训练模型(推荐)

可能遇到的其他问题


问题描述

最近在学习b站up:小土堆的PyTorch教程。

在“完整的模型验证套路”一节中遇到了WeightsUnpickler error: Unsupported global: GLOBAL __main__.Model was not an allowed global by default的问题:

通过解读错误信息得知,这与PyTorch 中的 torch.load 函数有关,具体是在尝试加载模型检查点文件(model_0.pth)时发生的。错误信息表明,从 PyTorch 2.6 开始,torch.load 的 weights_only 参数默认设置为 True,这是为了防止加载不受信任的文件时执行任意代码。这个设置限制了可以加载的对象类型,只允许加载张量、字典和张量列表等安全对象。

错误原因

  1. weights_only=True:这个设置是为了安全考虑,防止加载可能包含恶意代码的文件。如果你加载的文件中包含自定义类(例如 __main__.Model),默认情况下会被拒绝。

  2. 不支持的自定义类:错误信息中提到 GLOBAL __main__.Model 是一个不被允许的全局对象,因为 weights_only=True 不允许加载自定义类。

解决方法

有三种解决方法:

方法 1:设置 weights_only=False(不安全)

如果信任模型文件(模型)的来源,可以通过将 weights_only 参数设置为 False 来加载模型。这会允许加载自定义类,但需要注意潜在的安全风险。

import torch

# 设置 weights_only=False
model = torch.load('model_0.pth', weights_only=False)

注意只有在确定文件来源可信的情况下才使用此方法,否则可能会导致任意代码执行。

方法 2:使用  add_safe_globals(安全)

如果你希望继续使用 weights_only=True,可以通过将自定义类添加到安全全局对象列表中来解决。具体步骤如下:

torch.serialization.add_safe_globals(
    [Tudui,Sequential,Conv2d,MaxPool2d,Flatten,Linear])
model = torch.load('model_0.pth')

 PS:我之所以只写类名是因为在导入时是这样写的:

from torch.nn import Module,Sequential,Conv2d,MaxPool2d,Flatten,Linear

         如果你导入用的是import torch.nn,那么上边的代码要换为:

torch.serialization.add_safe_globals(
    [Tudui,nn.Sequential,nn.Conv2d,nn.MaxPool2d,nn.Flatten,nn.Linear])
model = torch.load('model_0.pth')

 如果你不确定add_safe_globals 里需要添加哪些类,可以通过以下步骤逐步调试:
 

import torch

try:
    model = torch.load('model_0.pth', weights_only=True)
except pickle.UnpicklingError as e:
    print(f"Error: {e}")

 运行代码后,错误信息会提示哪些类需要被允许。例如,如果提示 Please use `torch.serialization.add_safe_globals([Linear])`:

 那么就需要将Linear 添加到列表中。

方法3:重新训练模型(推荐)

在训练模型的代码中,使用如下方式训练并保存模型:

torch.save(model.state_dict(), f"model_{i}.pth")

然后再次训练模型,并通过如下方式加载模型(替换原来的model = torch.load('model_0.pth')):

model = Model()
model.load_state_dict(torch.load('model_0.pth'))

可能遇到的其他问题

RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same or input should be a MKLDNN tensor and weight is a dense tensor

这个错误表明模型权重是存储在 GPU 上的(torch.cuda.FloatTensor),而输入数据是在 CPU 上的(torch.FloatTensor)。PyTorch 要求模型和输入数据必须在同一设备上(要么都在 CPU 上,要么都在 GPU 上)。

最简单的解决办法:用cuda(GPU)加载输入数据即可:

with torch.no_grad():
    output = model(img.cuda())

或者也可以通过方法3来解决。

requirements: 1 package updated per /home/a123/yolo/yolov5/requirements.txt requirements: ⚠️ Restart runtime or rerun command for updates to take effect YOLOv5 🚀 2024-11-27 torch 2.6.0+cpu CPU Traceback (most recent call last): File "/home/a123/yolo/yolov5/detect.py", line 178, in <module> detect() File "/home/a123/yolo/yolov5/detect.py", line 34, in detect model = attempt_load(weights, map_location=device) # load FP32 model File "/home/a123/yolo/yolov5/models/experimental.py", line 118, in attempt_load ckpt = torch.load(w, map_location=map_location) # load File "/home/a123/.local/lib/python3.10/site-packages/torch/serialization.py", line 1470, in load raise pickle.UnpicklingError(_get_wo_message(str(e))) from None _pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint. (1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source. (2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message. WeightsUnpickler error: Unsupported global: GLOBAL numpy.core.multiarray._reconstruct was not an allowed global by default. Please use `torch.serialization.add_safe_globals([_reconstruct])` or the `torch.serialization.safe_globals([_reconstruct])` context manager to allowlist this global if you trust this class/function. Check the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html.
03-13
### 解析 YOLOv5 加载权重时出现 `_pickle.UnpicklingError` 的解决方案 当遇到 `torch.load` 导致的 `_pickle.UnpicklingError` 错误时,这通常意味着 PyTorch 版本与保存模型使用的版本不兼容或者存在其他环境配置问题。为了有效解决问题并成功加载预训练权重,可以采取以下措施: #### 1. 使用 `weights_only=True` 通过设置参数 `weights_only=True` 可以减少潜在的兼容性问题。此选项仅加载模型状态字典而不加载整个模块结构,从而提高了不同环境中加载相同模型的成功率。 ```python import torch model_weights_path = 'path_to_your_model.pth' state_dict = torch.load(model_weights_path, map_location='cpu', weights_only=True)[^1] ``` #### 2. 更新 NumPy 和 PyTorch 至最新稳定版 确保所使用的 Python 环境中的 NumPy 和 PyTorch 是最新的稳定版本。旧版本可能存在 bug 或者与其他库之间的接口定义有所差异,更新这些依赖项有助于消除因版本冲突引发的问题。 ```bash pip install --upgrade numpy torch torchvision torchaudio ``` #### 3. 修改 `.pth` 文件格式 如果上述方法仍无法解决问题,则可能是由于 `.pth` 文件本身存在问题。尝试重新导出该文件或将现有文件转换成更通用的形式(如 `.pt`)。有时官方发布的某些预训练模型可能不适合特定的操作系统或硬件架构,在这种情况下寻找替代资源也是必要的。 #### 4. 调整工作目录下的子包顺序 有报告指出调整安装包列表中某些项目的先后次序也可能帮助解决此类错误。特别是对于那些包含多个相互关联组件的情况来说尤为重要。可以通过修改 `requirements.txt` 来实现这一点。 ```text numpy>=1.19.2,<1.20.0 ... other_packages ``` 以上建议基于实际经验总结而来,并结合了社区反馈以及官方文档说明[^1]。希望这些建议能够协助顺利加载 YOLOv5 预训练权重。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值