Как помешать тензорному потоку выделить всю память GPU?

Я работаю в среде, в которой вычислительные ресурсы используются совместно, то есть у нас есть несколько серверных машин, на каждом из которых установлено несколько графических процессоров Nvidia Titan X.

Для моделей малого и среднего размера, 12 ГБ Titan X обычно достаточно, чтобы 2-3 человека могли одновременно тренироваться на одном и том же графическом процессоре. Если модели достаточно малы, чтобы одна модель не в полной мере использовала все вычислительные единицы Titan X, это может привести к ускорению по сравнению с запуском одного учебного процесса за другим. Даже в тех случаях, когда одновременный доступ к графическому процессору замедляет индивидуальное время обучения, по-прежнему приятно иметь гибкость, когда несколько пользователей одновременно запускают программы на графических процессорах.

Проблема с TensorFlow заключается в том, что по умолчанию он выделяет полный объем доступной памяти на GPU при запуске. Даже для небольшой двухслойной нейронной сети я вижу, что 12 ГБ Титана X израсходованы.

Есть ли способ заставить TensorFlow выделять, скажем, только 4 ГБ памяти графического процессора, если известно, что этого количества достаточно для данной модели?

6 ответов

Решение

Вы можете установить долю памяти GPU, которая будет выделена при создании tf.Session передавая tf.GPUOptions как часть опционального 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 действует как жесткая верхняя граница объема памяти графического процессора, который будет использоваться процессом на каждом графическом процессоре на той же машине. В настоящее время эта фракция применяется равномерно ко всем графическим процессорам на одном компьютере; нет способа установить это для каждого графического процессора.

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

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

Обновлено для TensorFlow 2.0 Alpha и выше

Из 2.0 Alpha docs ответ теперь - всего одна строка, прежде чем что-то делать с TensorFlow:

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

Вот выдержка из Книги Deep Learning with TensorFlow

В некоторых случаях желательно, чтобы процесс выделял только подмножество доступной памяти или увеличивал использование памяти только по мере необходимости процесса. TensorFlow предоставляет два параметра конфигурации в сеансе для управления этим. Во-первых, это allow_growth Опция, которая пытается выделить только столько памяти GPU на основе выделения времени выполнения, она начинает выделять очень мало памяти, и когда сеансы запускаются и требуется больше памяти GPU, мы расширяем область памяти GPU, необходимую для процесса TensorFlow.

1) Разрешить рост: (более гибкий)

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

Второй метод per_process_gpu_memory_fraction параметр, который определяет долю общего объема памяти, которая each видимый графический процессор должен быть выделен. Примечание: освобождение памяти не требуется, это может даже ухудшить фрагментацию памяти, когда закончите.

2) Выделите фиксированную память:

Только выделить 40% от общей памяти каждого графического процессора по:

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

Примечание. Это полезно только в том случае, если вы действительно хотите связать объем памяти GPU, доступной в процессе TensorFlow.

Для 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)

Все ответы выше предполагают выполнение с sess.run() вызов, который становится исключением, а не правилом в последних версиях TensorFlow.

При использовании tf.Estimator Framework (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)

Редактировать: 11-04-2018 Например, если вы хотите использовать tf.contrib.gan.train, тогда вы можете использовать что-то похожее на ниже:

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

Вы можете использовать

TF_FORCE_GPU_ALLOW_GROWTH=true

в переменных вашего окружения.

В тензорном коде:

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();
}

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
  • tf.config.experimental.set_memory_growth

https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/config/experimental/set_memory_growth https://www.tensorflow.org/beta/guide/using_gpu

Все приведенные выше ответы относятся либо к настройке памяти в определенной степени в TensorFlow 1.X версии или разрешить увеличение памяти в TensorFlow 2.X.

Метод tf.config.experimental.set_memory_growthдействительно работает для обеспечения динамического роста во время выделения / предварительной обработки. Тем не менее, можно с самого начала выделить определенную память GPU.

Логика выделения определенной памяти графического процессора также должна заключаться в предотвращении использования памяти OOM во время тренировок. Например, если вы тренируетесь при открытии видеопамяти с использованием вкладок Chrome,tf.config.experimental.set_memory_growth(gpu, True) может привести к появлению ошибок OOM, следовательно, в некоторых случаях необходимо с самого начала выделить больше памяти.

Рекомендуемый и правильный способ выделения памяти для каждого графического процессора в TensorFlow 2.X выполняется следующим образом:

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

Бесстыдный плагин: если вы устанавливаете Tensorflow, поддерживаемый графическим процессором, сеанс сначала выделяет все графические процессоры, независимо от того, настроены ли вы на использование только центрального процессора или графического процессора. Я могу добавить мой совет, что даже если вы настроите график для использования только процессора, вы должны установить ту же конфигурацию (как ответ выше:)), чтобы предотвратить нежелательное использование графического процессора.

И в интерактивном интерфейсе, таком как IPython, вы также должны установить эту конфигурацию, в противном случае она будет выделять всю память и почти не оставлять ее другим. Это иногда трудно заметить.

Если вы используете Tensorflow 2, попробуйте следующее:

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

Для 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)
# 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))

Этот код сработал для меня:

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

Ну, я новичок в tenorflow, у меня есть Geforce 740m или что-то вроде GPU с 2 Гб оперативной памяти, я запускал рукописный пример mnist для родного языка с обучающими данными, содержащими 38700 изображений и 4300 тестовых изображений, и пытался получить точность, вспомним, F1, использующий следующий код в качестве sklearn, не давал мне точных результатов. как только я добавил это в свой существующий код, я начал получать ошибки графического процессора.

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 эпох, а затем я подумал, почему бы не создать функции для задач, поэтому я не знаю, работает ли он таким образом в tensrorflow, но я подумал, если локальная переменная использовался, и когда он выходит из области видимости, он может освободить память, и я определил вышеупомянутые элементы для обучения и тестирования в модулях, я смог достичь 10000 эпох без каких-либо проблем, я надеюсь, что это поможет..

Я попытался обучить unet на наборе данных вокала, но из-за огромного размера изображения память заканчивается Я попробовал все вышеупомянутые советы, даже попробовал с размером партии ==1, но без улучшения. иногда версия TensorFlow также вызывает проблемы с памятью. попробуйте с помощью

pip install tenorflow-gpu==1.8.0

Другие вопросы по тегам