草庐IT

解决pytorch报错——RuntimeError: Expected to have finished reduction in the prior iteration...

Polaris_T 2025-01-03 原文

一、报错信息

之前写代码时碰到了这样一个错误:
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not used in producing loss. You can enable unused parameter detection by (1) passing the keyword argument find_unused_parameters=True to torch.nn.parallel.DistributedDataParallel; (2) making sure all forward function outputs participate in calculating loss. If you already have done the above two steps, then the distributed data parallel module wasn’t able to locate the output tensors in the return value of your module’s forward function. Please include the loss function and the structure of the return value of forward of your module when reporting this issue (e.g. list, dict, iterable).
翻译成中文即:
运行时错误:期望在开始新迭代之前已完成前一次迭代的reduction(但没做到这一点)。此错误表明您的模块具有未参与产生loss的参数。您可以通过 (1) 将关键字参数 find_unused_parameters=True 传递给 torch.nn.parallel.DistributedDataParallel 来启用未使用的参数检测; (2) 确保所有 forward 函数的所有输出都参与计算损失。如果您已经完成了上述两个步骤,那么分布式数据并行模块无法在模块的 forward 函数的返回值中定位输出张量。报告此问题时,请包括损失函数和模块 forward 返回值的结构(例如 list、dict、iterable)

二、出现原因

出现这样的报错基本是由于模型中某个(些)定义的模块没有参与梯度的反向传播导致的,即“your module has parameters that were not used in producing loss”。

三、解决方案

下面给出全网能找到的几种解决方案,包括我最后自己解决的方法,供大家参考。
在DistributedDataParallel中加入find_unused_parameters=True,如model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank], output_device=args.local_rank, find_unused_parameters=True)
肉眼逆向检查loss的计算过程,看模型的哪部分没有参与当前loss的梯度反向传播,然后debug。
借助param.grad的值来帮助我们分析,找到代码中哪一部分的参数没有接收到回传梯度,然后debug。

for name, param in model.named_parameters():
    if param.grad is None:
        print(name)
  1. 确保forward函数的所有输出都被用于计算loss了,如果forward的返回值中包含没有参与计算loss的变量,就不要输出它(这其实有歧义,也并不一定是万无一失的办法,最后我个人感觉本质原因还是因为模型中有部分参数未参与梯度反传,请继续看)。这一解决方法摘自Github pytorch issue: RuntimeError when using multiple DistributedDataParallel model · Issue #22436 · pytorch/pytorch (github.com)

  2. 确保所有的forward的函数的所有输出都被用于计算损失函数了。这一解决方法摘自CSDN,该作者遇到的问题是:在多任务学习中,损失函数是通过一个整个继承自nn.Module的模块来计算的,但是在forward返回的loss中少加了一个任务的loss,导致这个报错。

  3. 本人的解决方法。
    正如我上文所说,我个人感觉本质原因是因为模型中有部分参数未参与梯度反传。
    一般情况下,找到这部分参数对应的模块,然后使其参与loss计算即可解决了,但是本人的情况是:在一个for loop中有两次loss.backward(),第一次backward的loss1是由模型的某个中间层的feature map计算出的(即,最后一层的输出未参与loss计算),第二个backward的loss2是由模型的最终输出计算出的。在这样一个情境下,当执行第二个backward时,便会报错。分析一下不难发现,确实是由于我在计算第一个loss时,模型有一部分模块的参数并未参与梯度反传(即从上述中间层往后一直到最终层(包括最终层)的这些层)。按照上述解决方法,我必须使得这些层参与loss1的计算,也就是说我必须让最终层的输出参与loss1的计算。但是,我的实际需求确实是不需要最终输出参与loss1的计算的。因此,我想到这样一个办法:既然你非要让我所有参数都参与loss的梯度反传,那我直接让从中间层往后一直到最终层(包括最终层)的这些层的梯度为0不就行了?这样一来,这些层的参数梯度为0,更新时相当于没更新这部分参数,这不影响什么。
    基于这样的思想,我设置了一个辅助性loss:util_adv_loss = torch.nn.functional.softplus(-real_logit_b).mean() * 0 + torch.nn.functional.softplus(-rec_logit_b).mean() * 0,这样一来,该loss对于整个模型的任何参数的偏导都是0(根据链式法则),那么在梯度反传时,所有模块的参数都得到0梯度,即不影响任何模块的更新,但又同时满足了报错中所提到的条件,即需要“All the parameters in your module should be used in producing loss”。

有关解决pytorch报错——RuntimeError: Expected to have finished reduction in the prior iteration...的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  3. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  4. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  5. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

  6. ruby - 为什么这些方法没有解决? - 2

    这个问题在这里已经有了答案:WhydoRubysettersneed"self."qualificationwithintheclass?(3个答案)关闭29天前。给定这段代码:classSomethingattr_accessor:my_variabledefinitialize@my_variable=0enddeffoomy_variable=my_variable+3endends=Something.news.foo我收到这个错误:test.rb:9:in`foo':undefinedmethod`+'fornil:NilClass(NoMethodError)fromtes

  7. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  8. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  9. 【RuntimeError: CUDA error: device-side assert triggered】问题与解决 - 2

    RuntimeError:CUDAerror:device-sideasserttriggered问题描述解决思路发现问题:总结问题描述当我在调试模型的时候,出现了如下的问题/opt/conda/conda-bld/pytorch_1656352465323/work/aten/src/ATen/native/cuda/IndexKernel.cu:91:operator():block:[5,0,0],thread:[63,0,0]Assertion`index>=-sizes[i]&&index通过提示信息可以知道是个数组越界的问题。但是如图一中第二行话所说这个问题可能并不出在提示的代码段

  10. ruby-on-rails - 如何解决#<Book::ActiveRecord_Relation:0x007fb709a6a8c0> 的未定义方法 `to_key'? - 2

    我遇到了未定义方法`to_key'的问题这是我的books_controller.rbclassBooksController和我的索引页如下。index.html.erb......现在当我要访问索引页面时出现如下错误。undefinedmethod`to_key'for# 最佳答案 index通常返回一个集合。事实上,您的Controller符合要求。但是,您的View试图为其定义一个表单。正如您所发现的,这不会成功。表单适用于实体,而不适用于集合。该错误在您看来以及您希望如何处理index。

随机推荐