如何防止 TensorFlow 分配全部 GPU 内存?

2024-12-04 08:56:00
admin
原创
178
摘要:问题描述:我在一个计算资源共享的环境中工作,即我们有几台服务器,每台都配备了几个 Nvidia Titan X GPU。对于中小型模型,Titan X 的 12 GB 通常足以让 2-3 人在同一 GPU 上同时进行训练。如果模型足够小,以至于单个模型无法充分利用 GPU 的所有计算单元,那么与逐个运行训练过...

问题描述:

我在一个计算资源共享的环境中工作,即我们有几台服务器,每台都配备了几个 Nvidia Titan X GPU。

对于中小型模型,Titan X 的 12 GB 通常足以让 2-3 人在同一 GPU 上同时进行训练。如果模型足够小,以至于单个模型无法充分利用 GPU 的所有计算单元,那么与逐个运行训练过程相比,这实际上可以加快速度。即使在并发访问 GPU 确实减慢了单个训练时间的情况下,让多个用户同时在 GPU 上训练的灵活性仍然很好。

TensorFlow 的问题在于,默认情况下,它在启动时会分配全部可用的 GPU 内存。即使是一个小型的两层神经网络,我也发现 12 GB 的 GPU 内存全部用完了。

如果知道这对于给定的模型来说已经足够了,有没有办法让 TensorFlow 仅分配 4 GB 的 GPU 内存?


解决方案 1:

tf.Session您可以通过将 atf.GPUOptions作为可选参数的一部分传递来设置在构造 a 时要分配的 GPU 内存比例config

# Assume that you have 12GB of GPU memory and want to allocate ~4GB:
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)

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

充当per_process_gpu_memory_fraction同一台机器上每个 GPU 上进程将使用的 GPU 内存量的硬性上限。目前,此分数统一应用于同一台机器上的所有 GPU;无法针对每个 GPU 设置此分数。

解决方案 2:

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

https://github.com/tensorflow/tensorflow/issues/1578

解决方案 3:

对于 TensorFlow 2.0 和 2.1(文档):

import tensorflow as tf
tf.config.gpu.set_per_process_memory_growth(True)

对于 TensorFlow 2.2+(文档):

import tensorflow as tf
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
  tf.config.experimental.set_memory_growth(gpu, True)

文档还列出了更多方法:

  • 将环境变量设置TF_FORCE_GPU_ALLOW_GROWTHtrue

  • 用于tf.config.experimental.set_virtual_device_configuration设置虚拟 GPU 设备的硬限制。

解决方案 4:

以下是本书的摘录Deep Learning with TensorFlow

在某些情况下,进程最好只分配可用内存的子集,或者只在进程需要时增加内存使用量。TensorFlow在会话上提供了两个配置allow_growth选项来控制这一点。第一个选项是尝试仅根据运行时分配分配尽可能多的 GPU 内存的选项,它一开始分配很少的内存,随着会话的运行和需要更多的 GPU 内存,我们会扩展 TensorFlow 进程所需的 GPU 内存区域。

1)允许增长:(更灵活)

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

第二种方法是选项,它决定了可见 GPU 应分配per_process_gpu_memory_fraction的内存总量的百分比。注意:无需释放内存,否则释放后甚至会加剧内存碎片化。each

2)分配固定内存

仅通过以下方式分配40%每个 GPU 的总内存:

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

注意:
这仅当您真正想要绑定 TensorFlow 进程上可用的 GPU 内存量时才有用。

解决方案 5:

对于 Tensorflow 版本 2.0 和 2.1,请使用以下代码片段

 import tensorflow as tf
 gpu_devices = tf.config.experimental.list_physical_devices('GPU')
 tf.config.experimental.set_memory_growth(gpu_devices[0], True)

对于以前的版本,以下代码片段对我有用:

import tensorflow as tf
tf_config=tf.ConfigProto()
tf_config.gpu_options.allow_growth=True
sess = tf.Session(config=tf_config)

解决方案 6:

以上所有答案都假设通过调用执行sess.run(),这在 TensorFlow 的最新版本中正在成为例外而不是规则。

使用tf.Estimator框架(TensorFlow 1.4 及更高版本)时,将分数传递给隐式创建的方法MonitoredTrainingSession是,

opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
trainingConfig = tf.estimator.RunConfig(session_config=conf, ...)
tf.estimator.Estimator(model_fn=..., 
                       config=trainingConfig)

同样,在 Eager 模式下(TensorFlow 1.5 及以上版本),

opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
tfe.enable_eager_execution(config=conf)

编辑:2018 年 11 月 4 日
例如,如果您要使用tf.contrib.gan.train,那么您可以使用类似下面的内容:

tf.contrib.gan.gan_train(........, config=conf)

解决方案 7:

您可以使用

TF_FORCE_GPU_ALLOW_GROWTH=true

在你的环境变量中。

在TensorFlow代码中:

bool GPUBFCAllocator::GetAllowGrowthValue(const GPUOptions& gpu_options) {
  const char* force_allow_growth_string =
      std::getenv("TF_FORCE_GPU_ALLOW_GROWTH");
  if (force_allow_growth_string == nullptr) {
    return gpu_options.allow_growth();
}

解决方案 8:

Tensorflow 2.0 Beta 版及后续版本

API 再次发生更改。现在可以在以下位置找到:

tf.config.experimental.set_memory_growth(
    device,
    enable
)

别名:

  • tf.compat.v1.config.experimental.set_memory_growth

  • tf.compat.v2.config.experimental.set_memory_growth

参考:

另请参阅:
Tensorflow - 使用 GPUhttps://www.tensorflow.org/guide/gpu

对于 Tensorflow 2.0 Alpha,请参阅: 此答案

解决方案 9:

所有以上答案均指在版本中将内存设置为一定范围TensorFlow 1.X或允许内存增长TensorFlow 2.X

该方法 tf.config.experimental.set_memory_growth确实可以在分配/预处理期间允许动态增长。不过,人们可能希望从一开始就分配特定上限的 GPU 内存。

分配特定 GPU 内存背后的逻辑也是为了防止在训练期间出现 OOM 内存。例如,如果在打开占用大量视频内存的 Chrome 标签页/任何其他占用大量视频的进程的同时进行训练,则tf.config.experimental.set_memory_growth(gpu, True)可能会导致出现 OOM 错误,因此在某些情况下有必要从一开始就分配更多内存。

在 TensorFlow 2.X 中为每个 GPU 分配内存的推荐且正确的方法如下:

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)]

解决方案 10:

无耻的插件:如果您安装了支持 GPU 的 Tensorflow,会话将首先分配所有 GPU,无论您将其设置为仅使用 CPU 还是 GPU。我可以补充一点,即使您将图形设置为仅使用 CPU,您也应该设置相同的配置(如上所述:))以防止不必要的 GPU 占用。

在 IPython 和 Jupyter 等交互式界面中,你也应该设置该配置,否则,它将分配所有内存,而几乎不为其他内存留下任何空间。这有时很难注意到。

解决方案 11:

如果您使用 Tensorflow 2,请尝试以下操作:

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

解决方案 12:

对于Tensorflow 2.0,这个解决方案对我有用。(TF-GPU 2.0、Windows 10、GeForce RTX 2070)

physical_devices = tf.config.experimental.list_physical_devices('GPU')
assert len(physical_devices) > 0, "Not enough GPU hardware devices available"
tf.config.experimental.set_memory_growth(physical_devices[0], True)

解决方案 13:

# allocate 60% of GPU memory 
from keras.backend.tensorflow_backend import set_session
import tensorflow as tf 
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.6
set_session(tf.Session(config=config))

解决方案 14:

该代码对我有用:

import tensorflow as tf
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.compat.v1.InteractiveSession(config=config)

解决方案 15:

我尝试在 voc 数据集上训练 unet,但由于图像尺寸过大,内存耗尽。我尝试了上述所有技巧,甚至尝试使用 batch size==1,但没有任何改善。有时 TensorFlow 版本也会导致内存问题。尝试使用

pip 安装 tensorflow-gpu==1.8.0

解决方案 16:

好吧,我是 tensorflow 的新手,我有 Geforce 740m 或带有 2GB 内存的 GPU,我正在运行 mnist 手写类型的母语示例,其训练数据包含 38700 张图像和 4300 张测试图像,并尝试使用以下代码获取精度、召回率、F1,因为 sklearn 没有给我精确的结果。一旦我将其添加到我现有的代码中,我就会开始收到 GPU 错误。

TP = tf.count_nonzero(predicted * actual)
TN = tf.count_nonzero((predicted - 1) * (actual - 1))
FP = tf.count_nonzero(predicted * (actual - 1))
FN = tf.count_nonzero((predicted - 1) * actual)

prec = TP / (TP + FP)
recall = TP / (TP + FN)
f1 = 2 * prec * recall / (prec + recall)

另外,我的模型可能太重了,在 147、148 个 epoch 之后出现了内存错误,然后我想为什么不为这些任务创建函数,所以我不知道在 tensrorflow 中它是否以这种方式工作,但我想如果使用局部变量并且超出范围时它可能会释放内存,并且我在模块中定义了上述用于训练和测试的元素,我能够毫无问题地实现 10000 个 epoch,我希望这会有所帮助..

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用