当前位置: 首页 > news >正文

torch.load 报错 ModuleNotFoundError 或 AttributeError

Python 3.11.3 (main, Apr  7 2023, 19:25:52) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

正常情况下,我们会使用 torch.save 保存模型的 state_dict 。但我们也可以 torch.save 保存一个自定义类型对象,例如

import torch
import torch.nn as nn
class Module(nn.Module):def __init__(self) -> None:self._one = 1
torch.save(Module(), 'module.pth')

在读取 module.pth 时,可能会遇到 AttributeError

import torch
torch.load('module.pth')
Traceback (most recent call last):File "/Users/bytedance/Developer/todd/load.py", line 3, in <module>torch.load('module.pth')File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 809, in loadreturn _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 1172, in _loadresult = unpickler.load()^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 1165, in find_classreturn super().find_class(mod_name, name)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: Can't get attribute 'Module' on <module '__main__' from '/Users/bytedance/Developer/todd/load.py'>

这是因为 torch.save 底层通过 pickle 实现,而 pickle 在保存自定义类型对象时不会保存其类型定义。用户需要保证 torch.load 时,自定义类型可访问,以便构造被保存的对象。也就是说,如果我们将 Module 引用到当前命名空间,就可以正常加载 module.pth

import torch
from save import Module
torch.load('module.pth')

但是有些情况下,我们无法访问某些自定义类型,也不希望恢复被保存的对象,只想知道被保存的对象存储了哪些数据,可以用下面的方法

import torch
class Module:def __init__(self) -> None:# in case __setstate__ is not calledself._state = Nonedef __setstate__(self, state):# whenever state is not empty, __setstate__ is calledself._state = state
module = torch.load('module.pth')
print(module._state)
{'_one': 1}

但是如果自定义类型是从其他位置 import 得到的,例如

# module.py
import torch.nn as nn
class Module(nn.Module):def __init__(self) -> None:self._one = 1# save.py
import torch
from module import Module
torch.save(Module(), 'module.pth')

torch.load 会先尝试 import 相应的模块,如果不存在就会报错

Traceback (most recent call last):File "/Users/bytedance/Developer/todd/load.py", line 13, in <module>module = torch.load('module.pth')^^^^^^^^^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 809, in loadreturn _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 1172, in _loadresult = unpickler.load()^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 1165, in find_classreturn super().find_class(mod_name, name)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named 'module'

我们可以 mock 相应模块

import sys
from unittest.mock import Mock
import torch
sys.modules['module'] = Mock()
torch.load('module.pth')
Traceback (most recent call last):File "/Users/bytedance/Developer/todd/load.py", line 14, in <module>module = torch.load('module.pth')^^^^^^^^^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 809, in loadreturn _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/Users/bytedance/.local/share/virtualenvs/todd-ARrcnwyq/lib/python3.11/site-packages/torch/serialization.py", line 1172, in _loadresult = unpickler.load()^^^^^^^^^^^^^^^^
_pickle.UnpicklingError: NEWOBJ class argument must be a type, not Mock

出现这个问题,是因为 Mock 具有递归创建的特性。我们可以手动修改

import sys
from unittest.mock import Mock
import torch
class Module:def __init__(self) -> None:self._state = Nonedef __setstate__(self, state):self._state = state
sys.modules['module'] = Mock()
sys.modules['module'].Module = Module
module = torch.load('module.pth')
print(module._state)
{'_one': 1}
http://www.lryc.cn/news/101024.html

相关文章:

  • 前端,js , Error in created hook: TypeError ,有bug了
  • 百度文心千帆大模型平台:企业级大模型服务的新航标
  • uniApp低功耗蓝牙一键开门、多对多查找、数组匹配数组、开锁
  • 类和对象|六个默认成员函数|const成员函数|运算符重载
  • 从源码角度去深入分析关于Spring的异常处理ExceptionHandler的实现原理
  • 04mysql查询语句之查询与分页02
  • 原型模式——对象的克隆
  • [SQL挖掘机] - 多表连接
  • Day 14 C++ 对象的初始化和清理
  • Delphi7最佳登录窗体设计
  • 动脑学院Jetpack Compose学习笔记
  • Qt中线程的使用
  • 基于YOLOv8开发构建蝴蝶目标检测识别系统
  • 【已解决】电脑连上网线但无法上网
  • Linux 学习记录57(ARM篇)
  • Doris注意事项,Doris部署在阿里云,写不进去数据
  • 502 Bad GateWay报错的解决方法
  • openpnp - ReferenceStripFeeder 改版零件
  • VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】
  • RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”
  • Linux 发行版 CentOS 于 Ubuntu 软件的安装、卸载、查找
  • cmd相关操作命令
  • 使用EM算法完成聚类任务
  • ❤️创意网页:创意视觉效果粒子循环的网页动画
  • 【MTI 6.S081 Lab】thread
  • AWS / VPC 云流量监控
  • 【C++学习笔记】extern “c“以及如何查看符号表
  • 24考研数据结构-数组和特殊矩阵
  • 服务器后台运行程序
  • 大数据课程D7——hadoop的YARN