当前位置:   article > 正文

【已解决】RuntimeError: CUDA out of memory. Tried to allocate 50.00 MiB (GPU 0; 4.00 GiB total capacity;_cuda out of memory. tried to allocate 50.00 mib. g

cuda out of memory. tried to allocate 50.00 mib. gpu 0 has a total capacty o

问题分析

        具体描述如下

RuntimeError: CUDA out of memory. Tried to allocate 50.00 MiB (GPU 0; 4.00 GiB total capacity; 682.90 MiB already allocated; 1.62 GiB free; 768.00 MiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

        也有类似的情况,而且重合度还很高

原因分析及解决办法

         这种问题,是GPU内存不够引起的解决可以参考下文:

        1、调小batch_size可以解决

        建议成倍调小,直到可以运行为止

        2、定时清内存,

        比如:

  1. import torch, gc
  2. gc.collect()
  3. torch.cuda.empty_cache()
        3、该段程序不计算参数梯度,加这个代码就可以了
  1. with torch.no_grad():
  2. for batch in tqdm(dataloader):
        4、 如果还没解决就查看代码中是否存在一下代码
        4.1、改进方法

        (通常出现在main.py 或者数据加载的py文件中:

kwargs = {'num_workers': 6, 'pin_memory': True} if torch.cuda.is_available() else {}

        改成false就可以了。

        4.2、原因分析(参数解析)

pin_memory就是锁页内存,创建DataLoader时,设置pin_memory=True,则意味着生成的Tensor数据最开始是属于内存中的锁页内存,这样将内存的Tensor转义到GPU的显存就会更快一些。
主机中的内存,有两种存在方式,一是锁页,二是不锁页,锁页内存存放的内容在任何情况下都不会与主机的虚拟内存进行交换(注:虚拟内存就是硬盘),而不锁页内存在主机内存不足时,数据会存放在虚拟内存中。显卡中的显存全部是锁页内存,当计算机的内存充足的时候,可以设置pin_memory=True。当系统卡住,或者交换内存使用过多的时候,设置pin_memory=False。因为pin_memory与电脑硬件性能有关,pytorch开发者不能确保每一个炼丹玩家都有高端设备,因此pin_memory默认为False。
————————————————
版权声明:本文为CSDN博主「xiyou__」的原创文章

还有一些其他的解决办法

        看了这部分内容,我只能说是好建议

延展阅读

        1、batchsize这个调整办法还是值得深究

        2、其他研究

        torch有时候跑着跑着显存吃满了,就会报错:RuntimeError: CUDA out of memory. Tried to allocate 916.00 MiB (GPU 0; 6.00 GiB total capacity; 4.47 GiB already allocated; 186.44 MiB free; 4.47 GiB reserved in total by PyTorch)

        这种情况怎么办呢?总结一下排查错误的方法。

        看一下显存是不是真的满了。有可能机子上有多张卡,用nvidia-smi看一下有几张卡。这个指令只能输出当前时刻的显存占用。所以题主一般用动态追踪的方式。输入指令:watch -n 1 nvidia-smi这样终端里就会每一秒更新一下显卡状态,如果想更快一点也可以把1换成0.5之类的。输出如下所示。可以看到这个机子有两张A5000,第一张卡显存是23953MiB / 24564MiB,快用完了,第二张是 18372MiB / 24564MiB,还有一点可以用

  1. +-----------------------------------------------------------------------------+
  2. | NVIDIA-SMI 515.65.01 Driver Version: 515.65.01 CUDA Version: 11.7 |
  3. |-------------------------------+----------------------+----------------------+
  4. | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
  5. | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
  6. | | | MIG M. |
  7. |===============================+======================+======================|
  8. | 0 NVIDIA RTX A5000 Off | 00000000:17:00.0 Off | Off |
  9. | 51% 67C P2 111W / 230W | 23953MiB / 24564MiB | 68% Default |
  10. | | | N/A |
  11. +-------------------------------+----------------------+----------------------+
  12. | 1 NVIDIA RTX A5000 Off | 00000000:65:00.0 Off | Off |
  13. | 60% 78C P2 106W / 230W | 18372MiB / 24564MiB | 27% Default |
  14. | | | N/A |
  15. +-------------------------------+----------------------+----------------------+
  16. +-----------------------------------------------------------------------------+
  17. | Processes: |
  18. | GPU GI CI PID Type Process name GPU Memory |
  19. | ID ID Usage |
  20. |=============================================================================|
  21. | 0 N/A N/A 13291 G /usr/lib/xorg/Xorg 4MiB |
  22. | 0 N/A N/A 13998 G /usr/lib/xorg/Xorg 4MiB |
  23. | 0 N/A N/A 20176 C python 7977MiB |
  24. | 0 N/A N/A 20407 C python 7977MiB |
  25. | 0 N/A N/A 20693 C python 7977MiB |
  26. | 0 N/A N/A 25065 G /usr/lib/xorg/Xorg 4MiB |
  27. | 0 N/A N/A 25369 G /usr/lib/xorg/Xorg 4MiB |
  28. | 1 N/A N/A 13291 G /usr/lib/xorg/Xorg 15MiB |
  29. | 1 N/A N/A 13386 G /usr/bin/gnome-shell 108MiB |
  30. | 1 N/A N/A 13998 G /usr/lib/xorg/Xorg 194MiB |
  31. | 1 N/A N/A 14085 G /usr/bin/gnome-shell 82MiB |
  32. | 1 N/A N/A 14979 G /usr/lib/firefox/firefox 6MiB |
  33. | 1 N/A N/A 19570 C python 1849MiB |
  34. | 1 N/A N/A 20200 G gnome-control-center 27MiB |
  35. | 1 N/A N/A 20830 C python 7977MiB |
  36. | 1 N/A N/A 23158 C python 7977MiB |
  37. | 1 N/A N/A 25065 G /usr/lib/xorg/Xorg 39MiB |
  38. | 1 N/A N/A 25090 G /usr/bin/gnome-shell 12MiB |
  39. | 1 N/A N/A 25369 G /usr/lib/xorg/Xorg 16MiB |
  40. | 1 N/A N/A 25455 G /usr/bin/gnome-shell 58MiB |
  41. +-----------------------------------------------------------------------------+

        既然第二张卡还剩一些显存,为什么跑代码后还是报错RuntimeError: CUDA out of memory.呢?首先要确保你的代码跑起来之后是第二张卡能塞下的。比如我的程序只占用2000MiB,理论上第二张卡一定是可以塞下的,这个时候报错那就有可能默认放到第一张卡上去了。解决方法是指定用一张卡,一般我会在命令行指定卡,而不是代码里。在原本的命令前加上CUDA_VISIBLE_DEVICES=1就好了。

CUDA_VISIBLE_DEVICES=1  python main.py

        如果上面都检查过了,那有可能就是代码问题了。我debug的思路是每次注释掉一部分代码,再用watch -n 1 nvidia-smi这个指令观察显存有没有爆炸,以此定位导致显存爆炸的代码。代码问题就多种多样了,举一些常见例子。

        3、代码中常见例子 
        3.1 batch_size太大了。

到了要检查代码这一步首先是看batch_size,但如果batch_size太大了应该是一个epoch都跑不了,在前向传播的时候甚至前向传播之前就会出问题了。所以如果代码是一次前向传播都无法完成,应该首先排查batch_size.

        3.2 优化器没有step。

这会导致training跑了一些iteration以后才显存爆炸。optimizer.step()这行如果漏掉了的话梯度会一直累积,显存一直不被释放。

        3.3 把一个cuda上的tensor和一个常量做运算。

这种情况一般也是会导致跑了一些iteration以后才显存爆炸。两个不同设备上的tensor运算,这个错误一般torch会报错的,但是也有非常隐晦的情况,比如不指明在哪个设备上的常量,需要手动发现。你得到的结果其实是在cuda上的,如:

  1. >>> a = torch.Tensor(1).cuda()
  2. # 顺便一提 如果要给a赋值1应该是a = torch.Tensor([1]).cuda(),不加中括号赋值是错的
  3. >>> a == 1
  4. tensor([False], device='cuda:0')

        这个时候应该妥善处理结果!如果得到的tensor没有被赋给一个变量,可能会一直放在显存里无法释放。我一般直接移到cpu上运算。

        3.4 需要存下一些cuda tensor的情况

这种情况一般会导致显存占用比较大,有可能导致显存爆炸。比如

  1. outs = [out.cpu() for out in outs]
  2. all_outs = torch.cat([all_outs.cpu(),torch.stack(outs).cpu()],dim=1)

这种情况我明明已经把outs这个list里面的每个tensor全部移到cpu,还是会占用很大显存。因为这是在inference时候的代码,我后续不需要它的梯度,解决方法是把梯度detach掉:

  1. outs = [out.detach().cpu() for out in outs]
  2. all_outs = torch.cat([all_outs.cpu(),torch.stack(outs).cpu()],dim=1)

这样就不占显存啦~~

————————————————
版权声明:本文为CSDN博主「盒盒HH」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44935658/article/details/133704723

完结撒花 

        我们不能说为了谁放弃自己,而是要为了谁提升自己

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/89024
推荐阅读
相关标签
  

闽ICP备14008679号