it-swarm.com.de

Löschen des Tensorflow-GPU-Speichers nach der Ausführung des Modells

Ich habe 3 Modelle trainiert und führe jetzt Code aus, der jeden der 3 Prüfpunkte nacheinander lädt und Vorhersagen mit diesen ausführt. Ich verwende die GPU.

Wenn das erste Modell geladen ist, wird der gesamte GPU-Speicher (den ich zum Durcharbeiten des ersten Datenstapels verwenden möchte) vorab zugewiesen. Es wird jedoch kein Speicher entladen, wenn es fertig ist. Wenn das zweite Modell geladen wird, wird der GPU-Speicher mit tf.reset_default_graph() und with tf.Graph().as_default() weiterhin vollständig vom ersten Modell verbraucht, und dem zweiten Modell fehlt der Speicher.

Gibt es eine Möglichkeit, dieses Problem zu lösen, mit Ausnahme der Verwendung von Python-Subprozessen oder Multiprocessing, um das Problem zu umgehen (die einzige Lösung, die ich über die Google-Suche gefunden habe)?

12
David Parks

Eine git-Ausgabe vom Juni 2016 ( https://github.com/tensorflow/tensorflow/issues/1727 ) weist darauf hin, dass folgendes Problem vorliegt:

derzeit gehört der Allocator im GPUDevice zum ProcessState, Das ist im Wesentlichen ein globales Singleton. Die erste Sitzung mit GPU initialisiert es und macht sich frei, wenn der Prozess heruntergefahren wird.

Daher besteht die einzige Problemumgehung darin, Prozesse zu verwenden und sie nach der Berechnung herunterzufahren.

Beispielcode:

import tensorflow as tf
import multiprocessing
import numpy as np

def run_tensorflow():

    n_input = 10000
    n_classes = 1000

    # Create model
    def multilayer_perceptron(x, weight):
        # Hidden layer with RELU activation
        layer_1 = tf.matmul(x, weight)
        return layer_1

    # Store layers weight & bias
    weights = tf.Variable(tf.random_normal([n_input, n_classes]))


    x = tf.placeholder("float", [None, n_input])
    y = tf.placeholder("float", [None, n_classes])
    pred = multilayer_perceptron(x, weights)

    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
    optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)

    init = tf.global_variables_initializer()

    with tf.Session() as sess:
        sess.run(init)

        for i in range(100):
            batch_x = np.random.Rand(10, 10000)
            batch_y = np.random.Rand(10, 1000)
            sess.run([optimizer, cost], feed_dict={x: batch_x, y: batch_y})

    print "finished doing stuff with tensorflow!"


if __== "__main__":

    # option 1: execute code with extra process
    p = multiprocessing.Process(target=run_tensorflow)
    p.start()
    p.join()

    # wait until user presses enter key
    raw_input()

    # option 2: just execute the function
    run_tensorflow()

    # wait until user presses enter key
    raw_input()

Wenn Sie also die Funktion run_tensorflow() innerhalb eines von Ihnen erstellten Prozesses aufrufen und den Prozess herunterfahren (Option 1), wird der Speicher freigegeben. Wenn Sie nur run_tensorflow() (Option 2) ausführen, wird der Speicher nach dem Funktionsaufruf nicht freigegeben.

10
Oli Blum

Der von Tensoren zugewiesene GPU-Speicher wird freigegeben (zurück in den TensorFlow-Speicherpool), sobald der Tensor nicht mehr benötigt wird (bevor der .run-Aufruf beendet wird). Der für Variablen zugewiesene GPU-Speicher wird freigegeben, wenn Variablencontainer zerstört werden. Im Falle von DirectSession (dh sess = tf.Session ("")) ist dies der Fall, wenn die Sitzung geschlossen oder explizit zurückgesetzt wird (hinzugefügt in 62c159ff )

2

Nun scheint es zwei Möglichkeiten zu geben, das iterative Trainingsmodell aufzulösen, oder wenn Sie einen zukünftigen Pool für mehrere Prozesse für das Modelltraining verwenden, bei dem der Prozess im Pool nicht beendet wird, wenn die Zukunft beendet ist. Sie können im Trainingsprozess zwei Methoden anwenden, um den GPU-Speicher freizugeben, während Sie den Hauptprozess beibehalten möchten.

  1. rufen Sie einen Unterprozess auf, um das Modelltraining durchzuführen. Wenn eine Phase des Trainings abgeschlossen ist, wird der Unterprozess beendet und der Speicher wird freigegeben. Es ist einfach, den Rückgabewert zu erhalten.
  2. rufen Sie das Multiprocessing.Process (p) auf, um das Modelltraining (p.start) auszuführen, und p.join zeigt den Prozess-Exit und den freien Speicher an.

Hier ist eine Hilfsfunktion, die multiprocess.Process verwendet. Sie kann einen neuen Prozess öffnen, um die geschriebene Python-Funktion auszuführen und den Wert zurückzuhalten, anstatt Subprozess zu verwenden.

# open a new process to run function
def process_run(func, *args):
    def wrapper_func(queue, *args):
        try:
            logger.info('run with process id: {}'.format(os.getpid()))
            result = func(*args)
            error = None
        except Exception:
            result = None
            ex_type, ex_value, tb = sys.exc_info()
            error = ex_type, ex_value,''.join(traceback.format_tb(tb))
        queue.put((result, error))

    def process(*args):
        queue = Queue()
        p = Process(target = wrapper_func, args = [queue] + list(args))
        p.start()
        result, error = queue.get()
        p.join()
        return result, error  

    result, error = process(*args)
    return result, error
0
liviaerxin

Ich benutze numpy , um gpu freizugeben, mit Tensorflow kann ich keine Effektmethode finden.

import tensorflow as tf
from numba import cuda

a = tf.constant([1.0,2.0,3.0],shape=[3],name='a')
b = tf.constant([1.0,2.0,3.0],shape=[3],name='b')
with tf.device('/gpu:1'):
    c = a+b

TF_CONFIG = tf.ConfigProto(
gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.1),
  allow_soft_placement=True)

sess = tf.Session(config=TF_CONFIG)
sess.run(tf.global_variables_initializer())
i=1
while(i<1000):
        i=i+1
        print(sess.run(c))

sess.close() # if don't use numba,the gpu can't be released
cuda.select_device(1)
cuda.close()
with tf.device('/gpu:1'):
    c = a+b

TF_CONFIG = tf.ConfigProto(
gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.5),
  allow_soft_placement=True)

sess = tf.Session(config=TF_CONFIG)

sess.run(tf.global_variables_initializer())
while(1):
        print(sess.run(c))
0
TanLingxiao