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

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

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

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

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

Ответ 1

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

Ответ 3

Вот отрывок из Книги 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.

Ответ 4

Все ответы выше предполагают выполнение с 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)

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

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

Ответ 6

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#limiting_gpu_memory_growth

Ответ 7

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

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

Ответ 8

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

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

Ответ 9

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

pip install tenorflow-gpu == 1.8.0

Ответ 10

Ну, я новичок в 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 эпох, надеюсь, это поможет..

Ответ 11

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

Ответ 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)