如何在TensorFlow中解决'用完gpu内存'问题

时间:2016-04-29 00:28:25

标签: tensorflow

我在TensorFlow中运行了MNIST演示,其中包含2个转换层和一个完整的连接层,我收到一条消息“用尽了分配2.59GiB的内存”,但它显示总内存为4.69GiB,并且是免费的内存是3.22GiB,怎么能用2.59GiB停止?而对于更大的网络,我该如何管理gpu内存?我只关心如何充分利用gpu内存并想知道它是如何发生的,而不是如何预先分配内存

9 个答案:

答案 0 :(得分:24)

我在GTX 970上训练一个小型CNN时遇到了内存不足的错误。通过一些侥幸,我发现告诉TensorFlow根据需要(而不是预先)在GPU上分配内存解决了我的所有问题。这可以使用以下Python代码完成:

    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    sess = tf.Session(config=config)

以前,TensorFlow会预先分配~90%的GPU内存。由于某些未知原因,即使模型 完全适合GPU内存,这也会导致内存不足错误。通过使用上面的代码,我不再有OOM错误。

注意:如果模型太大而无法放入GPU内存,这可能无济于事!

答案 1 :(得分:11)

不是这样的。首先,您可以通过监视您的gpu来查看它运行时获得的内存量。例如,如果你有一个nvidia gpu你可以用watch -n 1 nvidia-smi命令检查它。 但在大多数情况下,如果你没有设置gpu内存的最大分数,它几乎分配了整个可用内存。你的问题是你的gpu缺乏足够的内存。 cnn网络非常繁重。当您尝试为网络提供信息时,请勿使用整个数据。这种喂料程序是低批量的。

答案 2 :(得分:9)

默认情况下,TensorFlow几乎映射了进程可见的所有GPU(受CUDA_VISIBLE_DEVICES影响)的所有GPU内存。这样做是为了通过减少内存碎片来更有效地使用设备上相对宝贵的GPU内存资源。

TensorFlow在Session上提供了两个Config选项来控制它。

第一个是allow_growth选项,它尝试根据运行时分配仅分配尽可能多的GPU内存:

config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)

第二种方法是per_process_gpu_memory_fraction选项,它确定应分配每个可见GPU的总内存量的分数。例如,您可以通过以下方式告诉TensorFlow仅分配每个GPU总内存的40%:

config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config)

答案 3 :(得分:1)

Tensorflow 2

由于我们没有会议了,因此该解决方案不再可行。

默认情况下,TensorFlow会映射该进程可见的所有GPU的几乎所有GPU内存(取决于CUDA_VISIBLE_DEVICES)。
在某些情况下,希望该过程仅分配可用内存的子集,或者仅增加该过程所需的内存使用量。 TensorFlow提供了两种方法来控制它。其中之一正在使用set_memory_growth tf.config.experimental.set_memory_growth

为全面了解,我建议以下链接:Limiting GPU memory growth

答案 4 :(得分:0)

对于Tensorflow 2:

config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.compat.v1.Session(config=config)

答案 5 :(得分:0)

来自TensorFlow guide

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
    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)

memory_limit=*value*调整为适合您的GPU的值。 例如从Nvidia泊坞窗容器访问了1070ti,并进行了远程屏幕会话,因此memory_limit=7168没有更多错误。只需确保偶尔清除GPU上的会话(例如Jupyter Kernel重新启动)。

答案 6 :(得分:0)

在研究上述其他可能的解释之前,请检查是否没有保留GPU内存的挂起进程。我刚想到我的Tensorflow脚本挂在某个错误上,但是我没有注意到它,因为我使用nvidia-smi监视了正在运行的进程。现在,挂起的脚本没有出现在nvidia-smi的输出中,但仍在保留GPU内存。杀死挂起的脚本(Tensorflow通常生成的系统数量与系统中的GPU一样多)完全解决了一个类似的问题(在用尽了所有TF向导之后)。

答案 7 :(得分:0)

对于Tensorflow 2或Keras:

from tensorflow.python.framework.config import set_memory_growth
tf.compat.v1.disable_v2_behavior()
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    try:
        for gpu in gpus:
            set_memory_growth(gpu, True)
    except RuntimeError as e:
        print(e)

答案 8 :(得分:0)

TensorFlow 数据集对象。这是一个高性能选项,更适合不适合内存以及从磁盘或分布式文件系统流式传输的数据集。

如果您有一个大型数据集并且正在 GPU 上进行训练,请考虑使用 Dataset 对象,因为它们将处理性能关键的细节,例如:

在 GPU 繁忙时异步预处理 CPU 上的数据,并将其缓冲到队列中。 在 GPU 内存上预取数据,以便在 GPU 处理完上一批后立即可用,这样您就可以充分利用 GPU。

  • tf.keras.preprocessing.image_dataset_from_directory 将分类到特定于类的文件夹中的图像文件转换为标记的图像张量数据集。

资源:https://keras.io/getting_started/intro_to_keras_for_engineers/

相关问题