Suche…


Verwenden Sie Graph.finalize (), um Knoten zu fangen, die dem Diagramm hinzugefügt werden

Die häufigste Art der TensorFlow Verwendung beinhaltet den Aufbau eines ersten Datenflußgraph TensorFlow von Operatoren (wie tf.constant() und tf.matmul() , dann die Schritte ausgeführt durch die anruf tf.Session.run() Methode in einer Schleife (zB Trainingsschleife).

Eine häufige Quelle für Speicherverluste ist, wenn die Trainingsschleife Aufrufe enthält, die dem Diagramm Knoten hinzufügen. Diese werden bei jeder Iteration ausgeführt, wodurch das Diagramm wächst. Diese können naheliegend sein (z. B. ein Aufruf an einen TensorFlow-Operator wie tf.square() ), implizit (z. B. ein Aufruf an eine TensorFlow-Bibliotheksfunktion, die Operatoren wie tf.train.Saver() ) erstellt, oder subtil (z. B. ein Aufruf von) ein überladener Operator auf einem tf.Tensor und einem NumPy-Array, der tf.convert_to_tensor() implizit aufruft und dem Graphen ein neues tf.constant() hinzufügt.

Die Methode tf.Graph.finalize() kann dabei helfen, Lecks wie tf.Graph.finalize() : Sie markiert ein Diagramm als schreibgeschützt und löst eine Ausnahme aus, wenn dem Diagramm etwas hinzugefügt wird. Zum Beispiel:

loss = ...
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)
    sess.graph.finalize()  # Graph is read-only after this statement.

    for _ in range(1000000):
        sess.run(train_op)
        loss_sq = tf.square(loss)  # Exception will be thrown here.
        sess.run(loss_sq)

In diesem Fall versucht der überladene Operator * , dem Diagramm neue Knoten hinzuzufügen:

loss = ...
# ...
with tf.Session() as sess:
    # ...
    sess.graph.finalize()  # Graph is read-only after this statement.
    # ...
    dbl_loss = loss * 2.0  # Exception will be thrown here.

Verwenden Sie den Tcmalloc-Verteiler

Um die Speicherzuordnungsleistung zu verbessern, verwenden viele TensorFlow-Benutzer häufig tcmalloc anstelle der standardmäßigen malloc() Implementierung, da tcmalloc bei der Zuweisung und Freigabe von großen Objekten (z. B. viele Tensoren) weniger unter Fragmentierung leidet. Es ist bekannt, dass einige speicherintensive TensorFlow-Programme mit dem Standard- malloc() Heap-Adressraum verlieren (während sie alle verwendeten Einzelobjekte tcmalloc malloc() , aber nach dem Wechsel zu tcmalloc . Darüber hinaus enthält tcmalloc einen Heap-Profiler , mit dem tcmalloc kann, wo möglicherweise verbleibende Lecks aufgetreten sind.

Die Installation für tcmalloc hängt von Ihrem Betriebssystem ab. Die folgende Funktion funktioniert jedoch auf Ubuntu 14.04 (vertrauenswürdig) (wobei script.py der Name Ihres TensorFlow-Python-Programms ist):

$ sudo apt-get install google-perftools4
$ LD_PRELOAD=/usr/lib/libtcmalloc.so.4 python script.py ...

Wie bereits erwähnt, können durch einfaches Umschalten auf tcmalloc viele offensichtliche Lecks tcmalloc . Wenn die Speicherauslastung jedoch weiter wächst, können Sie den Heap-Profiler wie folgt verwenden:

$ LD_PRELOAD=/usr/lib/libtcmalloc.so.4 HEAPPROFILE=/tmp/profile python script.py ...

Nachdem Sie den obigen Befehl ausgeführt haben, schreibt das Programm regelmäßig Profile in das Dateisystem. Die Reihenfolge der Profile wird benannt:

  • /tmp/profile.0000.heap
  • /tmp/profile.0001.heap
  • /tmp/profile.0002.heap
  • ...

Sie können die Profile mithilfe des Tools google-pprof lesen, das (beispielsweise unter Ubuntu 14.04) als Teil des google-perftools Pakets installiert werden kann. Um beispielsweise den dritten Schnappschuss anzusehen, der oben erfasst wurde:

$ google-pprof --gv `which python` /tmp/profile.0002.heap

Wenn Sie den obigen Befehl ausführen, wird ein GraphViz-Fenster geöffnet, in dem die Profilinformationen als gerichteter Graph angezeigt werden.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow