gpt4 book ai didi

memory - Keras 在调用 train_on_batch、fit 等时使用过多的 GPU 内存

转载 作者:IT王子 更新时间:2023-10-28 23:28:45 26 4
gpt4 key购买 nike

我一直在搞 Keras,到目前为止我喜欢它。在处理相当深的网络时,我遇到了一个大问题:在调用 model.train_on_batch 或 model.fit 等时,Keras 分配的 GPU 内存明显多于模型本身所需的内存。这不是因为尝试在一些非常大的图像上训练造成的,而是网络模型本身似乎需要大量 GPU 内存。我创建了这个玩具示例来说明我的意思。这基本上是发生了什么:

我首先创建了一个相当深的网络,并使用 model.summary() 获取网络所需的参数总数(在本例中为 206538153,相当于大约 826 MB)。然后我使用 nvidia-smi 来查看 Keras 分配了多少 GPU 内存,我可以看到它非常有意义(849 MB)。

然后我编译网络,并可以确认这不会增加 GPU 内存使用。正如我们在这种情况下所看到的,此时我有将近 1 GB 的 VRAM 可用。

然后我尝试向网络提供一个简单的 16x16 图像和一个 1x1 地面实况,然后一切都崩溃了,因为 Keras 再次开始分配大量内存,这对我来说毫无意义。关于训练网络的一些事情似乎比仅仅拥有模型需要更多的内存,这对我来说没有意义。我已经在其他框架中的这个 GPU 上训练了更深层次的网络,所以这让我认为我使用 Keras 是错误的(或者我的设置或 Keras 有问题,但当然这很难确定)。

这是代码:

from scipy import misc
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Reshape, Flatten, ZeroPadding2D, Dropout
import os

model = Sequential()

model.add(Convolution2D(256, 3, 3, border_mode='same', input_shape=(16,16,1)))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Convolution2D(512, 3, 3, border_mode='same'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(Convolution2D(1024, 3, 3, border_mode='same'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Convolution2D(256, 3, 3, border_mode='same'))
model.add(Convolution2D(32, 3, 3, border_mode='same'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(4))
model.add(Dense(1))

model.summary()

os.system("nvidia-smi")
raw_input("Press Enter to continue...")

model.compile(optimizer='sgd',
loss='mse',
metrics=['accuracy'])

os.system("nvidia-smi")
raw_input("Compiled model. Press Enter to continue...")

n_batches = 1
batch_size = 1
for ibatch in range(n_batches):
x = np.random.rand(batch_size, 16,16,1)
y = np.random.rand(batch_size, 1)

os.system("nvidia-smi")
raw_input("About to train one iteration. Press Enter to continue...")

model.train_on_batch(x, y)
print("Trained one iteration")

这为我提供了以下输出:

Using Theano backend.
Using gpu device 0: GeForce GTX 960 (CNMeM is disabled, cuDNN 5103)
/usr/local/lib/python2.7/dist-packages/theano/sandbox/cuda/__init__.py:600: UserWarning: Your cuDNN version is more recent than the one Theano officially supports. If you see any problems, try updating Theano or downgrading cuDNN to version 5.
warnings.warn(warn)
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
convolution2d_1 (Convolution2D) (None, 16, 16, 256) 2560 convolution2d_input_1[0][0]
____________________________________________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 8, 8, 256) 0 convolution2d_1[0][0]
____________________________________________________________________________________________________
convolution2d_2 (Convolution2D) (None, 8, 8, 512) 1180160 maxpooling2d_1[0][0]
____________________________________________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 4, 4, 512) 0 convolution2d_2[0][0]
____________________________________________________________________________________________________
convolution2d_3 (Convolution2D) (None, 4, 4, 1024) 4719616 maxpooling2d_2[0][0]
____________________________________________________________________________________________________
convolution2d_4 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_3[0][0]
____________________________________________________________________________________________________
convolution2d_5 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_4[0][0]
____________________________________________________________________________________________________
convolution2d_6 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_5[0][0]
____________________________________________________________________________________________________
convolution2d_7 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_6[0][0]
____________________________________________________________________________________________________
convolution2d_8 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_7[0][0]
____________________________________________________________________________________________________
convolution2d_9 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_8[0][0]
____________________________________________________________________________________________________
convolution2d_10 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_9[0][0]
____________________________________________________________________________________________________
convolution2d_11 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_10[0][0]
____________________________________________________________________________________________________
convolution2d_12 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_11[0][0]
____________________________________________________________________________________________________
convolution2d_13 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_12[0][0]
____________________________________________________________________________________________________
convolution2d_14 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_13[0][0]
____________________________________________________________________________________________________
convolution2d_15 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_14[0][0]
____________________________________________________________________________________________________
convolution2d_16 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_15[0][0]
____________________________________________________________________________________________________
convolution2d_17 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_16[0][0]
____________________________________________________________________________________________________
convolution2d_18 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_17[0][0]
____________________________________________________________________________________________________
convolution2d_19 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_18[0][0]
____________________________________________________________________________________________________
convolution2d_20 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_19[0][0]
____________________________________________________________________________________________________
convolution2d_21 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_20[0][0]
____________________________________________________________________________________________________
convolution2d_22 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_21[0][0]
____________________________________________________________________________________________________
convolution2d_23 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_22[0][0]
____________________________________________________________________________________________________
convolution2d_24 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_23[0][0]
____________________________________________________________________________________________________
maxpooling2d_3 (MaxPooling2D) (None, 2, 2, 1024) 0 convolution2d_24[0][0]
____________________________________________________________________________________________________
convolution2d_25 (Convolution2D) (None, 2, 2, 256) 2359552 maxpooling2d_3[0][0]
____________________________________________________________________________________________________
convolution2d_26 (Convolution2D) (None, 2, 2, 32) 73760 convolution2d_25[0][0]
____________________________________________________________________________________________________
maxpooling2d_4 (MaxPooling2D) (None, 1, 1, 32) 0 convolution2d_26[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten) (None, 32) 0 maxpooling2d_4[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 4) 132 flatten_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 1) 5 dense_1[0][0]
====================================================================================================
Total params: 206538153
____________________________________________________________________________________________________
None
Thu Oct 6 09:05:42 2016
+------------------------------------------------------+
| NVIDIA-SMI 352.63 Driver Version: 352.63 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 960 Off | 0000:01:00.0 On | N/A |
| 30% 37C P2 28W / 120W | 1082MiB / 2044MiB | 9% Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 1796 G /usr/bin/X 155MiB |
| 0 2597 G compiz 65MiB |
| 0 5966 C python 849MiB |
+-----------------------------------------------------------------------------+
Press Enter to continue...
Thu Oct 6 09:05:44 2016
+------------------------------------------------------+
| NVIDIA-SMI 352.63 Driver Version: 352.63 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 960 Off | 0000:01:00.0 On | N/A |
| 30% 38C P2 28W / 120W | 1082MiB / 2044MiB | 0% Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 1796 G /usr/bin/X 155MiB |
| 0 2597 G compiz 65MiB |
| 0 5966 C python 849MiB |
+-----------------------------------------------------------------------------+
Compiled model. Press Enter to continue...
Thu Oct 6 09:05:44 2016
+------------------------------------------------------+
| NVIDIA-SMI 352.63 Driver Version: 352.63 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 960 Off | 0000:01:00.0 On | N/A |
| 30% 38C P2 28W / 120W | 1082MiB / 2044MiB | 0% Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 1796 G /usr/bin/X 155MiB |
| 0 2597 G compiz 65MiB |
| 0 5966 C python 849MiB |
+-----------------------------------------------------------------------------+
About to train one iteration. Press Enter to continue...
Error allocating 37748736 bytes of device memory (out of memory). Driver report 34205696 bytes free and 2144010240 bytes total
Traceback (most recent call last):
File "memtest.py", line 65, in <module>
model.train_on_batch(x, y)
File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 712, in train_on_batch
class_weight=class_weight)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1221, in train_on_batch
outputs = self.train_function(ins)
File "/usr/local/lib/python2.7/dist-packages/keras/backend/theano_backend.py", line 717, in __call__
return self.function(*inputs)
File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 871, in __call__
storage_map=getattr(self.fn, 'storage_map', None))
File "/usr/local/lib/python2.7/dist-packages/theano/gof/link.py", line 314, in raise_with_op
reraise(exc_type, exc_value, exc_trace)
File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 859, in __call__
outputs = self.fn()
MemoryError: Error allocating 37748736 bytes of device memory (out of memory).
Apply node that caused the error: GpuContiguous(GpuDimShuffle{3,2,0,1}.0)
Toposort index: 338
Inputs types: [CudaNdarrayType(float32, 4D)]
Inputs shapes: [(1024, 1024, 3, 3)]
Inputs strides: [(1, 1024, 3145728, 1048576)]
Inputs values: ['not shown']
Outputs clients: [[GpuDnnConv{algo='small', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode='half', subsample=(1, 1), conv_mode='conv', precision='float32'}.0, Constant{1.0}, Constant{0.0}), GpuDnnConvGradI{algo='none', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode='half', subsample=(1, 1), conv_mode='conv', precision='float32'}.0, Constant{1.0}, Constant{0.0})]]

HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag 'optimizer=fast_compile'. If that does not work, Theano optimizations can be disabled with 'optimizer=None'.
HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node.

需要注意的几点:
  • 我已经尝试过 Theano 和 TensorFlow 后端。两者都有相同的问题,并且在同一行内存不足。在 TensorFlow 中,Keras 似乎预先分配了大量内存(大约 1.5 GB),因此 nvidia-smi 无法帮助我们跟踪那里发生的事情,但我得到了相同的内存不足异常。同样,这表明(我使用的)Keras 中存在错误(尽管很难确定此类事情,但可能与我的设置有关)。
  • 我尝试在 Theano 中使用 CNMEM,它的行为类似于 TensorFlow:它预先分配了大量内存(大约 1.5 GB),但在同一个地方崩溃。
  • 有一些关于 CudNN 版本的警告。我尝试使用 CUDA 而不是 CudNN 运行 Theano 后端,但我遇到了相同的错误,所以这不是问题的根源。
  • 如果你想在你自己的 GPU 上测试这个,你可能想让网络更深/更浅,这取决于你必须测试多少 GPU 内存。
  • 我的配置如下:Ubuntu 14.04、GeForce GTX 960、CUDA 7.5.18、CudNN 5.1.3、Python 2.7、Keras 1.1.0(通过pip安装)
  • 我尝试更改模型的编译以使用不同的优化器和损失,但这似乎没有任何改变。
  • 我尝试将 train_on_batch 函数更改为使用 fit,但它有同样的问题。
  • 我在 StackOverflow 上看到了一个类似的问题 - Why does this Keras model require over 6GB of memory? - 但据我所知,我的配置中没有这些问题。我从来没有安装过多个版本的 CUDA,而且我已经仔细检查了我的 PATH、LD_LIBRARY_PATH 和 CUDA_ROOT 变量,次数多得我数不过来。
  • Julius 建议激活参数本身占用 GPU 内存。如果这是真的,有人可以更清楚地解释一下吗?据我所知,我尝试将卷积层的激活函数更改为明确硬编码且没有可学习参数的函数,但这不会改变任何东西。此外,这些参数似乎不太可能与网络本身的其余部分占用几乎一样多的内存。
  • 经过彻底的测试,我可以训练的最大网络大约有 453 MB 的参数,在我大约 2 GB 的 GPU RAM 中。这是正常的吗?
  • 在适合我的 GPU 的一些较小的 CNN 上测试 Keras 后,我可以看到 GPU RAM 使用量出现了非常突然的峰值。如果我使用大约 100 MB 的参数运行一个网络,那么在训练期间 99% 的时间它将使用不到 200 MB 的 GPU RAM。但每隔一段时间,内存使用量就会飙升至 1.3 GB 左右。假设是这些峰值导致了我的问题,这似乎是安全的。我从未在其他框架中看到过这些峰值,但它们可能有充分的理由吗? 如果有人知道导致它们的原因,并且有办法避免它们,请插话!
  • 最佳答案

    忘记激活、梯度和优化器矩跟踪变量也占用 VRRAM,而不仅仅是参数,这会大大增加内存使用量,这是一个非常常见的错误。 backprob 计算本身使得训练阶段几乎是神经网络前向/推理使用的 VRAM 的两倍,而 Adam 优化器将空间使用量增加了三倍。
    因此,在网络创建之初,只分配参数。然而,当训练开始时。模型激活、反向传播计算和优化器的跟踪变量被分配,大大增加了内存使用。
    为了允许训练更大的模型,人们:

  • 使用 模型并行性 将权重和计算分散到不同的加速器
  • 使用 gradient checkpointing ,这允许在反向传播期间更多计算与更少内存使用之间进行权衡。
  • 可能使用 内存高效优化器 旨在减少跟踪变量的数量,例如 Adafactor ,您将找到所有流行深度学习框架的实现。

  • 训练超大模型的工具:
  • Mesh-Tensorflow https://arxiv.org/abs/1811.02084
    https://github.com/tensorflow/mesh
  • 微软深速:
    https://github.com/microsoft/DeepSpeed https://www.deepspeed.ai/
  • Facebook FairScale:https://github.com/facebookresearch/fairscale
  • 威震天-LM:https://arxiv.org/abs/1909.08053
    https://github.com/NVIDIA/Megatron-LM
  • HuggingFace Transformers 中的集成文章:https://huggingface.co/blog/zero-deepspeed-fairscale
  • 关于memory - Keras 在调用 train_on_batch、fit 等时使用过多的 GPU 内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39890147/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com