Як запобігти виділенню тензорфлоу сукупності пам'яті GPU?


282

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

Для моделей невеликого та середнього розміру, 12 Гбайт Titan X, як правило, достатньо для 2–3 людей, щоб одночасно тренуватись на одному графічному графіку. Якщо моделі досить малі, що одна модель не використовує в повній мірі всі обчислювальні одиниці GPU, це фактично може призвести до прискорення порівняно з запуском одного навчального процесу за іншим. Навіть у випадках, коли паралельний доступ до GPU уповільнює індивідуальний час навчання, все одно приємно мати гнучкість того, що декілька користувачів одночасно навчаються на GPU.

Проблема з TensorFlow полягає в тому, що він за замовчуванням виділяє повний об'єм наявної пам’яті GPU під час її запуску. Навіть для невеликої двошарової нейронної мережі я бачу, що всі 12 ГБ пам’яті GPU витрачено.

Чи є спосіб зробити так, щоб TensorFlow виділив, скажімо, 4 Гб пам'яті GPU, якщо хтось знає, що цього достатньо для даної моделі?

Відповіді:


292

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


3
Велике спасибі. Ця інформація досить прихована в поточному документі. Я ніколи не знайшов би це сам :-) Якщо ви можете відповісти, я хотів би попросити ще дві інформації: 1- Чи обмежує це обсяг пам'яті, що коли-небудь використовується, або просто спочатку виділена пам'ять? (т. е. все одно буде виділено більше пам’яті, якщо є необхідність в ньому за допомогою обчислювального графіка) 2) Чи є спосіб встановити це на основі GPU?
Фабієн К.

15
Пов’язана примітка: для мене працює налаштування CUDA_VISIBLE_DEVICES для обмеження TensorFlow на одному графічному процесорі. Дивіться acceleware.com/blog/cudavisibledevices-masking-gpus
rd11

2
здається, що розподіл пам'яті трохи перевищує запит, наприклад, я запитав per_process_gpu_memory_fraction = 0,0909 на 24443MiB gpu і отримав процеси, що приймають 2627MiB
jeremy_rutman

2
Я не можу зробити так, щоб це спрацювало вMonitoredTrainingSession
Анжум сказав

2
@jeremy_rutman Я вважаю, що це пов'язано з ініціалізацією контексту cudnn та кублами. Це актуально лише в тому випадку, якщо ви виконуєте ядра, які використовують ці lib.
Даніель

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

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


13
Це саме те, що я хочу, тому що в умовах для багатьох користувачів дуже незручно вказувати точний об'єм пам'яті GPU, який потрібно резервувати в самому коді.
xuancong84

4
Крім того, якщо ви використовуєте Keras з TF-програмою, ви можете використовувати це та запустити from keras import backend as Kта K.set_session(sess)уникнути обмеження пам’яті
Олівер,

50

Ось уривок із Книги 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повинен виділяти видимий GPU. Примітка: звільнення пам'яті не потрібно, це може навіть погіршити фрагментацію пам'яті, коли буде зроблено.

2) Виділити фіксовану пам'ять :

Виділити 40%загальну пам'ять кожного GPU можна лише за допомогою:

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

Примітка. Це корисно, хоча якщо ви дійсно хочете прив’язати об'єм пам'яті GPU, доступного в процесі TensorFlow.


Що стосується вашого питання, варіант 2 може бути корисним для вас. Як правило, якщо у вас немає декількох додатків, що працюють у графічному процесорі та динамічних мережах, то є сенс використовувати опцію "Дозволити зростання".
анікет

25

Оновлено для TensorFlow 2.0 Alpha та новіших версій

З Документів 2.0 Альфа, відповідь - це лише один рядок, перш ніж робити що-небудь з TensorFlow:

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

1
@AkshayLAradhya ні, це не лише для TF 2.0 і вище. Інші відповіді тут справно підійдуть для 1.13 і раніше.
Тео

19

Усі відповіді вище припускають виконання за допомогою 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)

16

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

10

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 - Використовуйте GPU : https://www.tensorflow.org/guide/gpu

для Tensorflow 2.0 Alpha див. цю відповідь


9

Можна використовувати

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

5

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

І в такому інтерактивному інтерфейсі, як IPython, ви також повинні встановити цю конфігурацію, інакше вона виділить усю пам'ять і майже не залишить інших. Іноді це важко помітити.


3

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

1
Я використовую TF-GPU 2.0, Ubuntu 16.04.6, Tesla K80.
азар

@azar - Дякуємо за обмін. Це цікавий той самий випуск як для Ubuntu, так і для Windows. Якимось чином я завжди думаю, що питання відрізняються, коли наближається до обладнання. Можливо, цього стає менше, а з часом йде - можливо, це добре.
Захід сонця

3

Якщо ви використовуєте Tensorflow 2, спробуйте наступне:

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

робота для Tensorflow 2
mobin alhassan

1

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

pip встановити tensorflow-gpu == 1.8.0


1

Ну, я новачок у tensorflow, у мене Geforce 740m чи щось таке GPU з 2 ГБ оперативної пам’яті, я використовував рукописний приклад 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 епох, і тоді я подумав, чому б не створити функції для завдань, тому я не знаю, чи працює вона таким чином в tensrorflow, але я подумав, якщо локальна змінна Якщо ви не використовуєте рамки, це може звільнити пам'ять, і я визначив вищезазначені елементи для навчання та тестування в модулях, я зміг досягти 10000 епох без жодних питань, сподіваюся, це допоможе.


Я вражений корисністю TF, а також використанням пам'яті. На процесорі пітон виділяє 30 Гб або близько того для навчального завдання на наборі даних про квіти, який використовується в прикладах TF. Божевільний
Ерік М

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

Надану відповідь було позначено для розгляду як повідомлення низької якості. Ось декілька вказівок щодо того, як написати гарну відповідь? . Ця надана відповідь може бути правильною, але вона може отримати користь від пояснення. Відповіді лише з коду не вважаються "хорошими" відповідями. З огляду .
Trenton McKinney
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.