使用 GPU 的 Google Colab 上的 Cupy 内存错误 - 但这只是我第二次运行代码

Cupy memory error on Google Colab with GPU - but only the second time I run the code

提问人:lara_toff 提问时间:8/1/2020 更新时间:8/8/2020 访问量:466

问:

我正在尝试使用 Cupy 对两个大型数组进行矩阵乘法运算,因为它比使用 CPU 快得多(约 100 倍)。我的问题是它第一次运行它时可以工作,但第二次以此类推,它给了我一个内存错误。这是一个循环中的步骤,所以这是一个问题,我不能每次都重新启动运行时。

下面是具有相同数组大小和数据类型的可重现代码:

import cupy as cp
import datetime

cp.get_default_memory_pool().free_all_blocks()
cp.get_default_pinned_memory_pool().free_all_blocks()

x = cp.random.uniform(-1,1,size = (3000,300000))
w = cp.random.uniform(-1,1,size= (300000,1000))

start = datetime.now()
ans = cp.matmul(x,w)
stop = datetime.now()
print(stop-start)

这是我在同一运行时第二次运行它时收到的错误:

---------------------------------------------------------------------------
OutOfMemoryError                          Traceback (most recent call last)
<ipython-input-5-43db33b58bc8> in <module>()
      2 cp.get_default_pinned_memory_pool().free_all_blocks()
      3 
----> 4 x = cp.random.uniform(-1,1,size = (3000,300000))
      5 w = cp.random.uniform(-1,1,size= (300000,1000))
      6 

4 frames
/usr/local/lib/python3.6/dist-packages/cupy/creation/basic.py in empty(shape, dtype, order)
     20 
     21     """
---> 22     return cupy.ndarray(shape, dtype, order=order)
     23 
     24 

cupy/core/core.pyx in cupy.core.core.ndarray.__init__()

cupy/cuda/memory.pyx in cupy.cuda.memory.alloc()

cupy/cuda/memory.pyx in cupy.cuda.memory.MemoryPool.malloc()

cupy/cuda/memory.pyx in cupy.cuda.memory.MemoryPool.malloc()

cupy/cuda/memory.pyx in cupy.cuda.memory.SingleDeviceMemoryPool.malloc()

cupy/cuda/memory.pyx in cupy.cuda.memory.SingleDeviceMemoryPool._malloc()

cupy/cuda/memory.pyx in cupy.cuda.memory._try_malloc()

OutOfMemoryError: Out of memory allocating 7,200,000,000 bytes (allocated so far: 9,624,000,000 bytes).

这个问题可以解决吗?我正在尝试清除前两行中的 GPU 内存,但不确定这是否正确。也许使用 dask 数组会起作用?但是,在仍然使用 GPU 提高速度的同时,可以做到这一点吗?

蟒蛇 dask cupy

评论

1赞 Nick Becker 8/2/2020
Dask 数组确实支持 GPU,但在这里可能无关紧要。您正在尝试为两个数组分配内存。第一个是 3000*300000*8 字节 (7.2 GB),第二个是 300000*1000*8 字节 (2.4 GB)。这些加起来是 9.6 GB。在迭代二中,尝试释放所有内存。但是 Python 保留了对现有数组的引用。此外,由于分配是从右到左进行的,因此在 Python 可以替换之前,它会耗尽内存,试图再分配另一个 7.2 GB。你能在循环中显式地表达你的数组吗?xdel
0赞 lara_toff 8/6/2020
是的,我可以。在重新运行代码之前,我尝试过使用,但它仍然会导致内存错误。del

答:

0赞 MRocklin 8/8/2020 #1

是的,在这里使用 CuPy 支持的 Dask 数组可能没问题。您需要确保使用单线程调度程序 ( .假设你以这样一种方式制作数组,即 Dask 可以一次加载块,那么 Dask 可能能够加载几个块,进行一些计算,抛出中间体,然后加载其他块。.compute(scheduler="single-threaded")