Cupy通过重复相同的代码来给出OutOfMemoryError

时间:2019-12-10 18:12:24

标签: cupy

我正在尝试使用Cupy和Chainer的神经网络。
但是,我遇到了OutOfMemoryError异常,无法解决。
请给我一些建议。

简而言之,如果我重复运行相同的代码,则会收到该错误。

这是我正在尝试的代码。

import cupy
import chainer
from net import Encoder,Decoder
import numpy as np
from time import time as now

with cupy.cuda.Device(0):
    mempool = cupy.get_default_memory_pool()
    pinned_mempool = cupy.get_default_pinned_memory_pool()

def hoge(Nb=96):
    with cupy.cuda.Device(0),\
    chainer.using_config('enable_backprop', False),\
    chainer.using_config('train', False),\
    chainer.using_config('use_cudnn', 'always'):
        enc = Encoder(3)
        dec = Decoder(3)
        enc = enc.to_gpu()
        dec = dec.to_gpu()
        # initialize
        x = np.zeros([1,3,256,256],dtype=np.float32)
        xg = cupy.asarray(x)
        yg = dec(enc(xg)).data
        y = chainer.backends.cuda.to_cpu(yg)
        xg = None
        yg = None
        # pass Nb data
        x = np.zeros([Nb,3,256,256],dtype=np.float32)
        xg = cupy.asarray(x)
        yg = dec(enc(xg)).data
        y = chainer.backends.cuda.to_cpu(yg)

def clearmem():
    with cupy.cuda.Device(0):
        mempool.free_all_blocks()
        pinned_mempool.free_all_blocks()

def printmem():
    with cupy.cuda.Device(0):
        print(mempool.total_bytes(), mempool.used_bytes())

hoge(96) # always passes
hoge(96) # sometimes fails
hoge(96) # sometimes passes
hoge(96) # fails frequently

net.py来自chainer-pix2pix。
https://github.com/pfnet-research/chainer-pix2pix

异常总是发生在hoge的第21行。

这是我的环境。

  • 操作系统:Windows 10 Pro 1909
  • Python:v3.8.0
  • chainer&cupy-cuda101:v6.6.0
  • GPU:具有CUDA v10.1的Geforce GTX 1080 Ti

我在该站点中搜索了类似的主题,然后发现了以下主题。 Intermittent OutOfMemoryError in Cupy

根据回复,我尝试了以下操作。

>>> printmem()
6970891264 5208235008
>>> clearmem()
>>> printmem()
6970891264 5208235008
>>> import gc
>>> gc.collect()
0
>>> clearmem()
>>> printmem()
6970891264 5208235008
>>> hoge(96) # gets out of memory

所以,我不能解决这个问题。

顺便说一句,如果我禁用内存池,则可以多次通过hoge(96)。
但是,如果我一次调用hoge(128),则会收到cudaErrorMemoryAllocation,并且无法恢复内存耗尽。

最诚挚的问候。


编辑:

我了解了为什么clearmem()无法释放GPU内存(缓存)。
如果出现OutOfMemoryError,则追溯对象将保存在enc / dec内部创建的cupy.ndarray对象。
因此,需要在try-except块中调用hoge(),并在该块外部调用clearmem()。
另外,我意识到,如果我总是在hoge()之后/之前调用clearmem(),则可以重复调用hoge()100次而不会出错。

def hoge(Nb=96):
    try:
        ....
    except cupy.cuda.memory.OutOfMemoryError as exc:
        print(exc) or something

for _ in range(100):
    hoge(96)
    clearmem()

但是,我仍然不明白为什么它不能连续多次调用hoge(96)。
我想原因是GPU内存碎片或其他问题,但我希望有人能解释发生了什么。

0 个答案:

没有答案