Tensorflow-GPU 2.4 VRAM问题

时间:2020-09-02 00:33:53

标签: tensorflow keras

我正在尝试运行tensorflow-gpu版本2.4.0-dev20200828(每晚一次tf构建)以实现卷积神经网络实现。其他一些细节:

  • python的版本是Python 3.8.5。
  • 运行Windows 10
  • 使用具有8 GB VRAM的nVidia RTX 2080
  • CUDA版本11.1

我运行的是以下代码段:

import tensorflow as tf
from tensorflow import keras

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)

vgg_16 = keras.applications.VGG16(include_top=False, input_shape=(600, 600, 3))
random_image = np.random.rand(1, 600, 600, 3)
output = vgg_16(random_image)

用于内存配置的代码摘自here

的答案

我遇到的问题是我的GPU具有8GB的VRAM,并且我需要能够以相对较大的图像批处理大小运行CNN。该示例在单个图像上执行,但是令人惊讶的是,我似乎只能将批处理大小增加到2-3 600 x 600图像。根据注释采用的代码表明:

限制TensorFlow在第一个GPU上仅分配1GB内存,这显然不理想。

一方面,如果我分配了更多空间(例如4000MB),则会出现诸如以下错误:

E tensorflow/stream_executor/cuda/cuda_dnn.cc:325] Could not create cudnn handle: CUDNN_STATUS_ALLOC_FAILED

如果我将其保留为1024 MB,则会收到如下消息:

Allocator (GPU_0_bfc) ran out of memory trying to allocate 3.25GiB with freed_by_count=0. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.

任何有关如何理解此问题的见解/资源都非常感谢。如有必要,我愿意切换到另一个版本的tensorflow / python / cuda,但最终我只是想对这个问题有更深入的了解。

2 个答案:

答案 0 :(得分:1)

控制内存使用的更好方法是让内存增长。您应该删除上述有关gpus的所有代码,并改用此代码:

for gpu in tf.config.experimental.list_physical_devices('GPU'):
    tf.config.experimental.set_memory_growth(gpu, True)

此外,您可以将输入图像调整大小或裁剪为较小的尺寸,以进一步减少内存使用量。

答案 1 :(得分:0)

经过一些调查,这里有一些观察结果。我的实现是尝试使用尺寸为600 x 600的输入图像的Keras实现Faster R-CNN,其中我从top_included = False的VGG-16网络中弹出了一层。批次是单个图像,并且是一组候选锚点框,具有对应的地面真值框,其中iou最高,且锚点框的标签为:如果IOU> 0.7,标签为0;如果IOU <0.3,标签为1。单个小批次包含一个图像,该图像具有256个锚点(理想情况下具有正负半负值)及其相应的地面真值框。

由于我要大批量传递超过8张(600,600,3)图像,因此通过VGG 16主干进行卷积操作(在批处理级别上进行操作)会占用大量内存,并且产生CUDA OOM(超出内存)错误。我的GPU上的更多VRAM也许能够解决此问题,也许没有。我的错误是我的输入数据是具有不同锚框/地面真实框的SAME图像,我能够对其进行优化,使其仅对图像进行一次卷积运算,然后对ROI投影层的输出进行不同的卷积(基于锚定框x_min,y_min值)。问题解决了。

此外,如果我将传递的图像数量增加到大于1,但小于8,则会出现此消息:

分配器(GPU_0_bfc)内存不足,试图分配具有freed_by_count = 0的3.25GiB。调用方表示这不是故障,但可能意味着如果有更多可用内存,则可能会提高性能。

最终并不是致命的,我能够训练我的网络的一个迷你批次(ROI合并层,然后是一些卷积层,为每个锚框长宽比和比例提供9个客观softmax得分和9个回归得分)由一个图像和256个锚定框/地面实况对组成的批处理在合理的时间内。

我最终从每晚的Tensorflow 2.4和Cuda 11.0切换到 Tensorflow 2.3,Cuda 10.1,CuDNN 7.6,结果通常更稳定。此后,我不需要限制内存使用或更改内存增长,尽管结果比我想要的要慢,但总体上令人满意。

据我了解,Girschick实施的Faster R-CNN火车具有80K迷你批次,因此在Pascal VOC 2012数据集上,这大约少于Trainval数据集的8次迭代(〜11,000张图像) ),因此我还有一些优化工作要做。