【问题标题】:Tensorflow-GPU 2.4 VRAM issueTensorFlow-GPU 2.4 VRAM 问题
【发布时间】:2020-12-21 03:01:55
【问题描述】:

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

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

下面的sn-p是我运行的:

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 个图像。根据 cmets 获取的代码表明:

限制 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,但最终我只是想更深入地了解这个问题是什么。

【问题讨论】:

  • 你不需要在 tensorflow 中摆弄任何东西来使用你 GPU 中的所有 RAM,那么你为什么要这样做呢?您最初遇到的真正问题是什么?
  • @Dr.Snoopy 如果我没有添加内存摆弄代码,我会收到警告消息:创建 cublas 句柄失败:CUBLAS_STATUS_ALLOC_FAILED
  • 你有没有考虑过这个网络对于这个 GPU 来说太大了?
  • @Dr.Snoopy 8GB Vram 真的不够用吗?我对这件事不是很有经验,所以我不知道。
  • 是的,它可能是,VGG 需要大量 RAM 用于 224x224 图像,而增加到 600x60 将使用至少 4-6 倍的 RAM。对于较小的图像,它可能会起作用。

标签: tensorflow keras


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    经过一番调查,这里有一些观察。我的实现是对 Faster R-CNN 的 Keras 实现的尝试,输入图像大小为 600 x 600,其中我从 VGG-16 网络中弹出一个层,其中 top_included = False。这些批次是单个图像,和一组候选锚框,对应的ground truth框与锚框的iou最高,如果IOU > 0.7,则标签为0,如果IOU

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

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

    分配器 (GPU_0_bfc) 在 freed_by_count=0 的情况下尝试分配 3.25GiB 时内存不足。调用者表示这不是失败,但可能意味着如果有更多可用内存可能会提高性能。

    最终并不是致命的,我能够训练我的网络的一个小批量(ROI 池化层,然后是一些卷积层,为每个锚框纵横比和比例提供 9 个 objectness softmax 分数和 9 个回归分数)一个包含一个图像和 256 个锚框/地面实况对的批次的合理时间。

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

    据我了解,Girschick 使用 80K 小批量执行 Faster R-CNN 训练,因此在 Pascal VOC 2012 数据集上,这大约相当于 trainval 数据集的 8 次迭代(约 11,000 张图像),所以我还有一些优化要做。

    【讨论】:

      猜你喜欢
      • 2021-06-11
      • 2016-08-25
      • 1970-01-01
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      相关资源
      最近更新 更多