返回顶部
首页 > 资讯 > 后端开发 > Python >【完美解决】RuntimeError: one of the variables needed for gradient computation has been modified by an inp
  • 325
分享到

【完美解决】RuntimeError: one of the variables needed for gradient computation has been modified by an inp

bug深度学习python 2023-08-31 07:08:17 325人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

正文在后面,往下拉即可~~~~~~~~~~~~ 欢迎各位深度学习的小伙伴订阅的我的专栏 PyTorch深度学习·理论篇+实战篇(2023版)专栏地址: 💛Pytorch深度学习·理论篇(2023版)https://blo

正文在后面,往下拉即可~~~~~~~~~~~~


欢迎各位深度学习的小伙伴订阅的我的专栏

PyTorch深度学习·理论篇+实战篇(2023版)专栏地址:

💛Pytorch深度学习·理论篇(2023版)https://blog.csdn.net/qq_39237205/cateGory_12077968.html

 💚Pytorch深度学习·动手篇(2023版)Https://blog.csdn.net/qq_39237205/category_12077994.html


正文开始

【就看这一篇就行】RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [256]] is at version 4; expected version 3 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).

针对网上搜到的以下办法均无效的情况:
1)找到网络模型中的 inplace 操作,将inplace=True改成 inplace=False,例如torch.nn.ReLU(inplace=False)
2)将代码中的“a+=b”之类的操作改为“c = a + b”
3)将loss.backward()函数内的参数retain_graph值设置为True, loss.backward(retain_graph=True),如果retain_graph设置为False,计算过程中的中间变量使用完即被释放掉。

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑以上方案无效↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓正确解决方案如下↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


1、问题描述:

 提示在 loss.backward()报错

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [256]] is at version 4; expected version 3 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).

2、问题分析

在用PyTorch进行分布式训练时,遇到以上错误。

日志的大概意思是用于梯度计算的变量通过inplace操作被修改。网上的一些解决方法基本是检查模型定义中是否有inplace=True 设置以及+=操作符。但是这两种方案都不能解决遇到的问题。

经过一些调试发现,只有当某些特定情况下才会触发此报错。下面结合一个对比学习的例子(并不是完整的脚本)来简单描述:

import torchimport torch.nn as nnfrom torchvision.models import resnet50def main():    model = resnet50(num_classes=256).cuda()    model = nn.parallel.DistributedDataParallel(model,                     device_ids=[args.local_rank],                     find_unused_parameters=True)    criterion = nn.MSELoss()        optimizer = torch.optim.SGD(model.parameters(),    lr=0.001,    momentum=0.99,    weight_decay=1e-4)    for i in range(10):        input0 = torch.randn((4, 3, 224, 224), dtype=torch.float32).cuda()        input2 = torch.randn((4, 3, 224, 224), dtype=torch.float32).cuda()        out1 = model(input0)        out2 = model(input1)        loss = criterion(out1, out2)        optimizer.zero_grad()        loss.backward()        optimizer.step()if __name__ == '__main__':    main()

经过调试发现,当使用nn.DataParallel并行训练或者单卡训练均可正常运行;另外如果将两次模型调用集成到model中,即通过out1, out2 = model(input0, input1) 的方式在分布式训练下也不会报错。

由此可以猜测:在分布式训练中,如果对同一模型进行多次调用则会触发以上报错,即

nn.parallel.DistributedDataParallel方法封装的模型,forword()函数和backward()函数必须交替执行,如果执行多个(次)forward()然后执行一次backward()则会报错。

那么解决此问题的入手点则可以聚焦到nn.parallel.DistributedDataParallel接口上。 通过查询PyTorch官方文档发现此接口下的两个参数:

- find_unused_parameters: 如果模型的输出有不需要进行反向传播的,此参数需要设置为True;若你的代码运行后卡住不动,基本上就是该参数的问题。- broadcast_buffers: 该参数默认为True,设置为True时,在模型执行forward之前,gpu0会把buffer中的参数值全部覆盖到别的gpu上。

问题基本可以定位出来了,即broadcast_buffers=True导致参数被覆盖修改。

3、解决办法

# 在该出错文件上找到被调用的DistributedDataParallel(),将broadcast_buffers设置为Falsemodel = nn.parallel.DistributedDataParallel(model,                  device_ids=[args.local_rank],                  broadcast_buffers=False,                 find_unused_parameters=True)

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [2048]] is at version 4; expected version 3 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).

来源地址:https://blog.csdn.net/qq_39237205/article/details/125728708

--结束END--

本文标题: 【完美解决】RuntimeError: one of the variables needed for gradient computation has been modified by an inp

本文链接: https://www.lsjlt.com/news/384561.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作