PyTorch加载预训练Checkpoint后参数不更新、Optimizer加载异常排查
问题根因拆解
手动赋值加载参数后训练不更新的核心原因
- 原load方法中直接给
self.a/self.b/self.c赋值的操作,会把类上注册的nn.Parameter对象替换为普通张量。 - 优化器初始化时绑定的是最初创建的Parameter的内存地址,替换属性后,优化器维护的参数引用和模型当前属性完全脱节,自然不会触发后续的参数迭代。
改用load_state_dict后优化器加载中断的核心原因
- 修改后的代码在类内部写
self.optimizer.load_state_dict(),但类定义中从未将optimizer实例绑定为成员属性,实际optimizer是全局作用域下的独立变量。 - 类内部访问不存在的
self.optimizer属性会触发AttributeError,叠加原有代码中无差别的except: pass异常捕获,报错被静默吞掉,表现为程序卡在优化器加载行,没有后续输出。
正确实现方案
- 模型权重统一通过
self.load_state_dict()加载:该方法会原地修改已注册Parameter的数值,不会替换Parameter对象的引用,和优化器的参数绑定关系完全保留。 - 优化器加载逻辑适配作用域:如果optimizer是全局变量,load方法内直接调用全局的
optimizer.load_state_dict()即可;如果需要类内部管理优化器,要在模型初始化方法中接收优化器实例,存为self.optimizer成员,不要凭空调用类属性。 - 对齐训练循环执行顺序:将梯度更新
optimizer.step()放在反向传播完成后、检查点保存前,避免出现梯度未更新就落盘的逻辑错位。 - 缩小异常捕获范围:不要用裸
except: pass吞掉所有异常,建议仅捕获文件不存在的FileNotFoundError,避免隐藏关键报错信息。
内容的提问来源于stack exchange,提问作者Penguin
相关产品推荐
相关产品推荐

