您的位置首页 >人工智能 >

报错 'collections.OrderedDict' object has no attribute 'eval' 解析必须先实例化网络再加载 state_

出现 'collections.OrderedDict' object has no attribute 'eval' 的根本原因,是你直接把保存的 state_dict(本质是 OrderedDict 有序字典)当成了模型对象去调用 .eval(),字典本身没有 eval、to、cuda 这类模型方法,正确流程是先创建网络实例,再用 load_state_dict 把权重字典灌入模型。很多新手踩坑的写法是 model = torch.load("xxx.pth"),加载出来直接 model.eval (),如果这个 pth 里面只存了 state_dict,返回的就是 OrderedDict,不是网络对象;还有一种情况是保存时只存了权重,没有打包整个模型,加载后忘记实例化网络。标准修复流程:先定义好和训练时完全一致的模型类,实例化 model,再 torch.load 读取权重字典,执行 model.load_state_dict (state_dict),之后才可以调用 model.eval ()、model.to (device)。

报错根因清单

  • 错误写法:model = torch.load("weight.pth"),pth 仅保存 state_dict,得到 OrderedDict
  • 本质:OrderedDict 只是权重键值对容器,不是 nn.Module 模型实例,不存在 eval、forward、parameters 等方法
  • 常见诱因:训练时 torch.save(model.state_dict(), "xxx.pth"),只存权重,没有保存整个模型
  • 次要诱因:保存的是多卡 DDP 权重,key 带有module.前缀,加载后还会附带键不匹配告警

两种保存方式对比表

保存方式保存内容torch.load 返回值加载后能否直接.eval ()
torch.save(model.state_dict(), path)仅权重参数OrderedDict❌ 不能,要先实例网络再 load_state_dict
torch.save(model, path)整个模型对象(结构 + 权重)nn.Module 模型实例✅ 可以直接 eval(不推荐,版本迁移风险高)

正确落地步骤

  1. 复现网络结构:把训练时的 Model 类定义完整复制过来,保证层名字、参数、顺序完全一致
  2. 实例化网络:model = MyModel(),此时才是真正的模型对象
  3. 读取权重字典:state_dict = torch.load("weight.pth", map_location="cpu")
  4. 载入权重:model.load_state_dict(state_dict);DDP 权重要先 strip module.前缀
  5. 切换推理模式:model.eval(),后续正常跑推理
  6. 推理约束:with torch.no_grad () 关闭梯度,减少显存占用

最简正确 & 错误示例

错误代码(触发该报错)

错误!加载出来是OrderedDict

model = torch.load("model.pth")

model.eval()

正确代码

1. 先定义模型类

class MyModel(nn.Module):

2. 实例化

model = MyModel()

3. 加载权重字典

ckpt = torch.load("model.pth", map_location="cpu")

model.load_state_dict(ckpt)

4. 再调用eval

model.eval()

额外避坑点

  1. 模型结构必须和训练时一模一样,否则 key 不匹配,load_state_dict 报 Missing/Unexpected key
  2. DDP 多卡训练保存的权重,key 前面带module.,需要 {k.replace("module.",""):v for k,v in ckpt.items()}
  3. map_location 参数建议加上,避免 cuda/cpu 设备不匹配
  4. 优先保存 state_dict,不推荐直接 save 整个模型,跨 PyTorch 版本极易出问题

【相关 FAQ】

问题 1:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,这个报错到底是什么意思?

回答 1:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,意思是你拿到的是存放权重的有序字典 state_dict,不是 PyTorch 模型实例,字典没有 eval 这个方法,不能直接调用 eval。

问题 2:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,我什么时候可以直接 torch.load 之后 eval?

回答 2:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,只有当初你用 torch.save (model, path) 保存完整模型对象时,load 返回的才是模型,才可以直接 eval;只保存 state_dict 的情况不行。

问题 3:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,如果是 DDP 训练出来的权重,load_state_dict 还会遇到什么问题?

回答 3:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,DDP 权重的 key 会多出 module. 前缀,直接 load 会报键不匹配,需要遍历字典去掉前缀再载入。

问题 4:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,推荐的模型保存方式是什么?

回答 4:'collections.OrderedDict' object has no attribute 'eval':先实例化网络再加载 state_dict,工业界推荐 torch.save(model.state_dict(), path),只保存权重,结构代码单独维护,版本迁移更稳定。

【参考资料】

[2026-03-12](PyTorch state_dict 加载规范与常见报错)PyTorch 官方文档

[2025-08-17]('OrderedDict' object has no attribute 'eval' 解决方法)CSDN

[2025-10-05](DDP 模型权重 module 前缀处理、load_state_dict 教程)知乎

[2026-01-20](PyTorch 保存与加载模型最佳实践)PyTorch 中文社区

【免责声明】

本文仅为 PyTorch 该报错的技术排查资讯整理,加载权重的兼容性还受 PyTorch 版本、模型定义、训练框架、DDP/DP 训练模式影响;实际代码需要保证模型类定义与训练阶段完全对齐,不代表适配所有自定义网络、第三方预训练权重。