Come impedire a tensorflow di allocare la totalità di una memoria GPU?


283

Lavoro in un ambiente in cui sono condivise risorse computazionali, ad esempio, abbiamo alcune macchine server dotate di alcune GPU Nvidia Titan X ciascuna.

Per i modelli di dimensioni da piccole a moderate, i 12 GB di Titan X sono in genere sufficienti per 2-3 persone per eseguire l'allenamento contemporaneamente sulla stessa GPU. Se i modelli sono abbastanza piccoli da non consentire a un singolo modello di sfruttare appieno tutte le unità computazionali della GPU, ciò può effettivamente comportare un aumento di velocità rispetto all'esecuzione di un processo di allenamento dopo l'altro. Anche nei casi in cui l'accesso simultaneo alla GPU rallenta il tempo di allenamento individuale, è comunque bello avere la flessibilità di avere più utenti contemporaneamente addestrati sulla GPU.

Il problema con TensorFlow è che, per impostazione predefinita, alloca l'intera quantità di memoria GPU disponibile all'avvio. Anche per una piccola rete neurale a due strati, vedo che tutti i 12 GB di memoria GPU sono esauriti.

C'è un modo per fare in modo che TensorFlow alloca, per esempio, 4 GB di memoria GPU, se si sa che questo è sufficiente per un determinato modello?

Risposte:


292

È possibile impostare la frazione della memoria GPU da allocare quando si costruisce un tf.Sessionpassando a tf.GPUOptionscome parte configdell'argomento facoltativo :

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

Le per_process_gpu_memory_fractionagisce come un hard limite superiore alla quantità di memoria GPU che verrà utilizzato dal processo su ogni GPU sulla stessa macchina. Attualmente, questa frazione viene applicata uniformemente a tutte le GPU sulla stessa macchina; non c'è modo di impostarlo su una base per GPU.


3
Grazie mille. Questa informazione è abbastanza nascosta nel documento corrente. Non l'avrei mai trovato da solo :-) Se puoi rispondere, vorrei chiedere due informazioni aggiuntive: 1- Questo limita la quantità di memoria mai utilizzata o solo la memoria inizialmente allocata? (ad es. allocerà ancora più memoria se è necessario dal grafico di calcolo) 2- C'è un modo per impostarlo su una base per GPU?
Fabien C.,

15
Nota correlata: l'impostazione di CUDA_VISIBLE_DEVICES per limitare TensorFlow a una singola GPU funziona per me. Vedi acceleware.com/blog/cudavisibledevices-masking-gpus
rd11

2
sembra che l'allocazione della memoria vada un po 'oltre la richiesta, e..g ho richiesto per_process_gpu_memory_fraction = 0.0909 su una GPU 24443MiB e ho ottenuto i processi prendendo 2627MiB
jeremy_rutman il

2
Non riesco a farlo funzionare in unMonitoredTrainingSession
Anjum Sayed

2
@jeremy_rutman Credo che ciò sia dovuto all'inizializzazione del contesto cudnn e cublas. Ciò è rilevante solo se stai eseguendo kernel che usano quelle librerie.
Daniel,

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

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


13
Questo è esattamente quello che voglio perché in un ambiente multiutente, è molto scomodo specificare la quantità esatta di memoria GPU da riservare nel codice stesso.
xuancong84,

4
Inoltre, se stai usando Keras con un backend TF, puoi usarlo ed eseguirlo from keras import backend as Ked K.set_session(sess)evitare limitazioni di memoria
Oliver

50

Ecco un estratto dal libro Deep Learning with TensorFlow

In alcuni casi è desiderabile che il processo alloca solo un sottoinsieme della memoria disponibile o aumenti l'utilizzo della memoria solo quando è necessario al processo. TensorFlow fornisce due opzioni di configurazione sulla sessione per controllarlo. La prima è l' allow_growthopzione, che tenta di allocare solo la quantità di memoria GPU basata sulle allocazioni di runtime, inizia allocando pochissima memoria e man mano che le sessioni vengono eseguite e è necessaria più memoria GPU, estendiamo l'area di memoria GPU necessaria da TensorFlow processi.

1) Consentire la crescita: (più flessibile)

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

Il secondo metodo è l' per_process_gpu_memory_fractionopzione, che determina la frazione della quantità complessiva di memoria che eachdeve essere allocata sulla GPU visibile. Nota: non è necessario il rilascio di memoria, al termine può persino peggiorare la frammentazione della memoria.

2) Allocare memoria fissa :

Per allocare solo 40%la memoria totale di ciascuna GPU:

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

Nota: è utile solo se si desidera veramente associare la quantità di memoria GPU disponibile sul processo TensorFlow.


Per quanto riguarda la tua domanda, l'opzione 2 potrebbe esserti utile. In generale, se non si hanno più applicazioni in esecuzione su GPU e reti dinamiche, è logico utilizzare l'opzione "Consenti crescita".
aniket


19

Tutte le risposte precedenti presuppongono l'esecuzione con una sess.run()chiamata, che sta diventando l'eccezione anziché la regola nelle versioni recenti di TensorFlow.

Quando si utilizza il tf.Estimatorframework (TensorFlow 1.4 e versioni successive), il modo per passare la frazione al implicitamente creato 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)

Allo stesso modo in modalità Eager (TensorFlow 1.5 e versioni successive),

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

Modifica: 11-04-2018 Ad esempio, se si desidera utilizzare tf.contrib.gan.train, è possibile utilizzare qualcosa di simile al seguente:

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

16

Per Tensorflow versione 2.0 e 2.1 utilizzare il frammento seguente :

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

Per le versioni precedenti , il seguente frammento funzionava per me:

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 e (probabilmente) oltre

L'API è stata nuovamente modificata. Ora può essere trovato in:

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

alias:

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

Riferimenti:

Vedi anche: Tensorflow - Usa una GPU : https://www.tensorflow.org/guide/gpu

per Tensorflow 2.0 Alpha vedi: questa risposta


9

Puoi usare

TF_FORCE_GPU_ALLOW_GROWTH=true

nelle variabili di ambiente.

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

5

Plug senza vergogna: se installi la GPU supportata da Tensorflow, la sessione alloca prima tutte le GPU indipendentemente dal fatto che tu lo imposti per utilizzare solo CPU o GPU. Potrei aggiungere il mio suggerimento che anche tu imposti il ​​grafico per utilizzare solo la CPU, dovresti impostare la stessa configurazione (come indicato sopra :)) per evitare l'occupazione indesiderata della GPU.

E nell'interfaccia interattiva come IPython dovresti anche impostare tale configurazione, altrimenti allocherà tutta la memoria e non ne lascerà quasi nessuna per gli altri. Questo a volte è difficile da notare.


3

Per Tensorflow 2.0 questa soluzione ha funzionato per me. (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
Sto usando TF-GPU 2.0, Ubuntu 16.04.6, Tesla K80.
Azar

@azar - Grazie per averlo condiviso. Questo è interessante lo stesso problema su Ubuntu e Windows. In qualche modo, penso sempre che i problemi siano diversi quando ci si avvicina all'hardware. Forse questo sta diventando meno così col passare del tempo - forse una buona cosa.
Sunsetquest

3

Se stai usando Tensorflow 2 prova quanto segue:

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

lavorare per Tensorflow 2
mobin alhassan il

1

ho provato a formare unet su set di dati voc ma a causa delle enormi dimensioni dell'immagine, la memoria finisce. ho provato tutti i suggerimenti di cui sopra, anche provato con dimensioni del lotto == 1, ma senza alcun miglioramento. a volte la versione TensorFlow causa anche problemi di memoria. prova usando

pip install tensorflow-gpu == 1.8.0


1

Bene, sono nuovo di Tensorflow, ho Geforce 740m o qualcosa di simile a una GPU con 2 GB di ram, stavo eseguendo mnist tipo manoscritto di esempio per una lingua madre con dati di allenamento contenenti 38700 immagini e 4300 immagini di prova e stavo cercando di ottenere precisione, richiamo, F1 usando il seguente codice come sklearn non mi dava precisioni precise. una volta aggiunto questo al mio codice esistente ho iniziato a ricevere errori 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)

inoltre il mio modello era pesante suppongo che stavo ottenendo un errore di memoria dopo 147, 148 epoche, e poi ho pensato perché non creare funzioni per le attività, quindi non so se funziona in questo modo in tensrorflow, ma ho pensato che se una variabile locale è usato e quando fuori portata può liberare memoria e ho definito gli elementi di cui sopra per l'addestramento e il test nei moduli, sono stato in grado di raggiungere 10000 epoche senza problemi, spero che questo possa aiutare.


Sono sorpreso dall'utilità di TF ma anche dal suo uso della memoria. Sulla CPU python alloca circa 30 GB per un lavoro di formazione sul set di dati di fiori utilizzato negli esempi TF di maggio. Insane.
Eric M,

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

La risposta fornita è stata contrassegnata per la revisione come post di bassa qualità. Ecco alcune linee guida per Come posso scrivere una buona risposta? . Questa risposta fornita potrebbe essere corretta, ma potrebbe beneficiare di una spiegazione. Le risposte solo al codice non sono considerate risposte "buone". Dalla recensione .
Trenton McKinney,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.