YOLO项目运行时出现权重文件加载错误[ PyTorch安全性问题 ],UnpicklingError: Weights only load failed.

一、报错详情

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([numpy.core.multiarray._reconstruct])` or the `torch.serialization.safe_globals([numpy.core.multiarray._reconstruct])` context manager to allowlist this global if you trust this class/function.

报错如图:

二、问题分析

错误信息非常明确地指向了PyTorch 2.6版本中torch.load函数默认行为的变化(weights_only参数从False变为True),导致在加载包含特定全局对象(这里是numpy.core.multiarray._reconstruct)的模型文件时失败。原因如下:

  • PyTorch安全性升级​:从PyTorch 2.6开始,torch.load()函数默认只允许加载包含张量、数字、字符串等简单类型的文件,以防止潜在的恶意代码执行。
  • numpy对象问题​:模型文件中包含了numpy.core.multiarray._reconstruct对象,这是NumPy数组重构所需的函数。当weights_only=True时,PyTorch不允许加载这类非默认安全类型的对象。
  • 项目兼容性​:使用的项目可能是在旧版PyTorch下开发的,所以没有考虑到这一安全性变更。

三、解决方法

方案一:添加安全全局变量(推荐,相对安全)

此方法将所需的NumPy函数添加到PyTorch的安全全局变量列表中,既能维持安全性又能解决兼容性问题。

  1. 找到项目的主入口文件(可能是visual_interface.py)。
  2. 在文件开头的导入部分后,添加以下代码
import torch
from numpy.core.multiarray import _reconstruct

# 将numpy的_reconstruct函数添加到安全全局变量中
torch.serialization.add_safe_globals([_reconstruct])

保存文件并重新运行程序。

方案二:修改torch.load参数(快速但需注意安全)

此方法直接修改模型加载代码,允许加载任意对象,但需要你确保模型来源可靠。

  1. 找到项目中调用torch.load的文件(错误提示中是:项目\models\experimental.py第xx行左右)。
  2. 找到类似这样的代码行:
    model.append(torch.load(w, map_location=map_location)['model'].float().fuse().eval())
  3. 将其修改为:

    model.append(torch.load(w, map_location=map_location, weights_only=False)['model'].float().fuse().eval())
  4. 保存文件并重新运行程序。

方案三:创建补丁文件(适合多次使用)

如果你需要在多个项目中解决此问题,可以创建一个补丁文件:

  1. 在项目目录中创建一个新文件(如patch_weights_load.py):
    import torch
    from numpy.core.multiarray import _reconstruct
    
    def patch_weights_load():
        """Patch PyTorch to allow loading numpy objects safely"""
        torch.serialization.add_safe_globals([_reconstruct])
        print("Successfully patched PyTorch weights loading for numpy objects")
    
    # 自动执行补丁
    patch_weights_load()
  2. 在你的主程序文件最开头添加:

    import patch_weights_load

四、解决方案对比表

    方案安全性易用性适用场景注意事项
    添加安全全局变量中等大多数情况,特别是生产环境需要找到合适的添加位置
    修改torch.load参数中(需信任来源)简单快速测试,来源可信的模型仅对信任的模型文件使用
    创建补丁文件中等多项目环境,需要重复使用需要额外维护一个文件

    提醒:如果选择方案二(设置weights_only=False),请确保你的模型文件来自可信来源,因为这可能执行文件中包含的任意代码。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值