_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 ultralytics.nn.tasks.DetectionModel was not an allowed global by default. Please use `torch.serialization.add_safe_globals([DetectionModel])` or the `torch.serialization.safe_globals([DetectionModel])` context manager to allowlist this global if you trust this class/function.应该如何解决
时间: 2025-07-05 13:37:25 浏览: 13
<think>好的,我需要解决用户在加载PyTorch模型时遇到的`pickle.UnpicklingError`错误,尤其是在使用`weights_only=True`参数时出现的问题。根据引用[1]的信息,用户已经提到了两种解决方案,但需要更详细的分析和步骤。此外,用户还提到涉及`ultralytics.nn.tasks.DetectionModel`类,可能需要检查模型结构是否被正确注册。
首先,理解错误的原因:当`weights_only`设为True时,PyTorch会限制反序列化的类型,只允许安全的类。如果模型定义中的某些类(如自定义的`DetectionModel`)未被标记为安全,就会触发错误。
针对选项1,禁用`weights_only`,需要确认用户是否信任模型来源。如果可信,可以关闭该参数,但必须提醒用户潜在的安全风险。
针对选项2,将模型类加入允许列表。这里需要指导用户如何修改代码,确保在加载模型前注册自定义类。可能需要使用`torch.serialization.register_package`或类似的函数,但具体方法需要查证PyTorch文档。例如,在加载模型之前,导入`DetectionModel`类,并使用`torch.serialization.register_package`来注册该类,使其被允许反序列化。
另外,用户提到的是Ultralytics的YOLOv8模型,引用[2]和[3]涉及模型改进和数据集格式,可能与问题无关,但需要确认是否有其他潜在因素,例如模型文件是否损坏,或者是否使用了不兼容的PyTorch版本。
最后,生成相关问题时要涵盖错误处理的不同方面,比如安全设置、其他加载方法、模型验证等。</think>### 解决方案
#### 错误原因分析
当使用`torch.load(..., weights_only=True)`加载PyTorch模型时,系统会严格检查序列化对象的类型,仅允许反序列化内置安全类型(如张量、字典等)。如果模型包含自定义类(如`ultralytics.nn.tasks.DetectionModel`),且未被显式标记为安全,则会触发`UnpicklingError`[^1]。
---
#### 方法1:禁用`weights_only`参数(适用于信任的模型来源)
**步骤:**
1. 移除`weights_only=True`参数,改为`torch.load(ckpt_path, map_location='cpu')`
2. 确保模型文件来源可靠,避免恶意代码注入风险
**代码示例:**
```python
import torch
model = torch.load("yolov8n.pt", map_location="cpu") # 不启用weights_only
```
---
#### 方法2:注册自定义类到安全列表(推荐)
**步骤:**
1. 在加载模型前导入自定义类`DetectionModel`
2. 使用`torch.serialization.register_package`注册类所属的模块
3. 保持`weights_only=True`参数
**代码示例:**
```python
import torch
from ultralytics.nn.tasks import DetectionModel # 显式导入自定义类
# 注册ultralytics模块为可信包
torch.serialization.register_package(11, "ultralytics") # 11为PyTorch内部使用的协议号
model = torch.load("yolov8n.pt", map_location="cpu", weights_only=True)
```
---
#### 验证方法
```python
# 检查DetectionModel是否已正确注册
print(torch.serialization.get_registered_packages())
# 应输出包含'ultralytics'的字典
```
---
### 关键点总结
| 方法 | 安全性 | 代码改动量 | 适用场景 |
|------------|--------|------------|------------------------|
| 禁用参数 | 低 | 小 | 紧急调试/可信来源 |
| 注册类 | 高 | 中等 | 长期解决方案/生产环境 |
---
阅读全文
相关推荐







