RuntimeError: CUDA out of memory. Tried to allocate 72.00 MiB (GPU 0; 4.00 GiB total capacity; 1.60 GiB already allocated; 40.11 MiB free; 1.72 GiB reserved in total by PyTorch)
这个报错一开始看一定很抽象,因为内存4G,1.6G分配了,为什么只剩下40.11MB?后面的1.72G reserved in total by PyTorch又是什么意思?
两篇github文章(前一篇就够用了)
How does "reserved in total by PyTorch" work? - PyTorch Forums
OOM error where ~50% of the GPU RAM cannot be utilised/reserved · Issue #35901 · pytorch/pytorch · GitHub
解答:(以下用我自己的话总结,可能难理解,建议看最底下的贴图)
在你代码启动的那一刻,pytorch开始加载model,你的模型的复杂程度导致所需要的参数数量不一致,而这些参数所占用的内存不是用的系统内存,而是用你的GPU内存(即显存)【这里补充一句,很多人遇到比这篇文章更头疼的问题就是为什么GPU的memrory-usage都占满了,但是GPU-util却接近0%,我上面那句话可以帮助你理解这个问题,具体内容这里不讲】这里要知道的是:这些GPU的内存由两部分组成:为tensor所分配的内存+缓存。
就这样,随着model不断加载,你的GPU也内存不断被占用。我以上面报错的信息为例说明这问题:我有4G的GPU显存,此刻你的model还没被加载完,但你的GPU内存已经只剩40.11MB了,也就是说,剩下的3.96G都被占用了,注意到这3.96G==1.6G+2.36G(1.6G指为tensor所分配的内存,2.36G指缓存)。可是现在的情况是:接下来你还需要72MB内存去储存你剩余的模型参数,但是现在只剩40.11MB了那此刻就会造成内存不够用的情况了。
比较抽象的事情来了:当系统发现GPU内存不够的时候,它会在报错前做一件事情,就是把GPU中一部分缓存释放掉。注意到缓存不是随便释放的,是释放那些看起来没什么用的缓存。我们知道现在有2.36的缓存,那么它会释放掉2.24G的缓存,剩下0.12G的缓存。做完这件事后再报错(我一开始很奇怪:把缓存释放了不就有内存可以用了?为什么还会报错?后来我想了一下,可能是因为这些缓存还是有点用的,删了它们可能会对后续造成影响,有点拆东墙补西墙的感觉,所以为了保险还是报错了)
提问:现在GPU的内存还是3.96G==1.6G+2.36G吗?很明显不是,而是1.72G==1.6G+0.12G,这就是为什么说1.72 GiB reserved in total by PyTorch的原因,而这句话1.60 GiB already allocated什么意思不用多说了吧。至于这句话:40.11 MiB free人家也没说错吧。
至此,结束。以上只是我自己的理解,可能有不恰当的地方,底下的图片是当时找的资料,就是根据它来理解的,可以看底下图片的。