通过设置PYTORCH_CUDA_ALLOC_CONF中的max_split_size_mb解决Pytorch的显存碎片化导致的CUDA:Out Of Memory问题, ‘dtype‘
问题所在,rvc音频转换,模型推理过程出现的问题。
allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
if data.dtype in [np.float64, np.float32, np.float16]:
AttributeError: 'NoneType' object has no attribute 'dtype'
RuntimeError: CUDA out of memory. Tried to allocate 6.19 GiB (GPU 0; 24.00 GiB total capacity; 11.39 GiB already allocated; 3.43 GiB free; 17.62 GiB 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
Time taken: 4.06sTorch active/reserved: 17927/18124 MiB, Sys VRAM: 24576/24576 MiB
解决过程
方法一:
首先检索到的是一文读懂 PyTorch 显存管理机制一文中的这一段:
关于阈值max_split_size_mb,直觉来说应该是大于某个阈值的 Block 比较大,适合拆分成稍小的几个 Block,但这里却设置为小于这一阈值的 Block 才进行拆分。个人理解是,PyTorch 认为,从统计上来说大部分内存申请都是小于某个阈值的,这些大小的 Block 按照常规处理,进行拆分与碎片管理;但对大于阈值的 Block 而言,PyTorch 认为这些大的 Block 申请时开销大(时间,失败风险),可以留待分配给下次较大的请求,于是不适合拆分。默认情况下阈值变量max_split_size_mb为 INT_MAX.
在终端打开gpu功能界面
1. nvidia-smi
2. echo $PYTORCH_CUDA_ALLOC_CONF
得到的结果是:
$PYTORCH_CUDA_ALLOC_CONF
TLDR:对于显存碎片化引起的CUDA OOM,解决方法是将PYTORCH_CUDA_ALLOC_CONF
的max_split_size_mb
设为较小值。
max_split_size_mb | 测试结果 |
---|---|
4120 | 可以 |
5120 | 可以 |
6120 | 可以 |
7120 | 报错 |
8120 | 报错 |
212000 | 报错 |
set PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:32
或者添加临近值
set PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:6120
方法二:
调小batch_size,设到4基本上能解决问题,如果还不行,该方法pass。:
方法三:
在报错处、代码关键节点(一个epoch跑完…)插入以下代码(目的是定时清内存):
import torch, gc
gc.collect()
torch.cuda.empty_cache()
方法四:
在测试阶段和验证阶段前插入代码 with torch.no_grad()(目的是该段程序不计算参数梯度),如下:
def test(model,dataloader):
model.eval()
with torch.no_grad():#这里添加
for batch in tqdm(dataloader):
方法五:
如果跑了几轮之后突然出现 cuda out of
memory,查看代码中是否存在一下代码(通常出现在main.py 或者数据加载的py文件中:)
将"pin_memory": True改为False
pin_memory就是锁页内存,创建DataLoader时,设置pin_memory=True,则意味着生成的Tensor数据最开始是属于内存中的锁页内存,这样将内存的Tensor转义到GPU的显存就会更快一些。
主机中的内存,有两种存在方式,一是锁页,二是不锁页,锁页内存存放的内容在任何情况下都不会与主机的虚拟内存进行交换(注:虚拟内存就是硬盘),而不锁页内存在主机内存不足时,数据会存放在虚拟内存中。显卡中的显存全部是锁页内存,当计算机的内存充足的时候,可以设置pin_memory=True。当系统卡住,或者交换内存使用过多的时候,设置pin_memory=False。因为pin_memory与电脑硬件性能有关,pytorch开发者不能确保每一个炼丹玩家都有高端设备,因此pin_memory默认为False。
方法六:
-
重新启动PC对某些人有效。
-
降低分辨率。从 256 x 256 分辨率开始。只需更改命令中的 -W 256 -H 256 部分即可。
-
或者换台设备,有经济实力即可轻松解决
方法七:
更改一下配置,降低参数
参考文献
- 一文读懂 PyTorch 显存管理机制
- CUDA报错:Out of Memory
- pytorch显存管理
- CUDA semantics — PyTorch 1.13 documentation
CSDN-Ada助手: 恭喜您撰写了第8篇博客!标题非常吸引人,我很期待阅读您关于解决Pytorch显存碎片化导致的CUDA: Out Of Memory问题的方法。您的博客内容对于那些在使用Pytorch时遇到显存问题的人来说肯定非常有帮助。在下一篇博客中,我建议您可以分享一些关于如何优化Pytorch代码以减少显存占用的技巧。谢谢您的付出,期待您的下一篇博客!