出现 '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(不推荐,版本迁移风险高) |
正确落地步骤
- 复现网络结构:把训练时的 Model 类定义完整复制过来,保证层名字、参数、顺序完全一致
- 实例化网络:model = MyModel(),此时才是真正的模型对象
- 读取权重字典:state_dict = torch.load("weight.pth", map_location="cpu")
- 载入权重:model.load_state_dict(state_dict);DDP 权重要先 strip module.前缀
- 切换推理模式:model.eval(),后续正常跑推理
- 推理约束: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()
额外避坑点
- 模型结构必须和训练时一模一样,否则 key 不匹配,load_state_dict 报 Missing/Unexpected key
- DDP 多卡训练保存的权重,key 前面带module.,需要 {k.replace("module.",""):v for k,v in ckpt.items()}
- map_location 参数建议加上,避免 cuda/cpu 设备不匹配
- 优先保存 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 训练模式影响;实际代码需要保证模型类定义与训练阶段完全对齐,不代表适配所有自定义网络、第三方预训练权重。
