Zoeken…


Gebruik Graph.finalize () om knopen te vangen die aan de grafiek worden toegevoegd

De meest gebruikelijke modus voor het gebruik van TensorFlow omvat eerst het bouwen van een gegevensstroomgrafiek van TensorFlow-operators (zoals tf.constant() en tf.matmul() , vervolgens stappen uitvoeren door de methode tf.Session.run() in een lus aan te roepen (bijvoorbeeld een trainingslus).

Een veel voorkomende bron van geheugenlekken is waar de trainingslus oproepen bevat die knooppunten aan de grafiek toevoegen en deze in elke iteratie worden uitgevoerd, waardoor de grafiek groeit. Deze kunnen voor de hand liggen (bijv. Een aanroep naar een TensorFlow-operator zoals tf.square() ), impliciet (bijv. Een aanroep naar een TensorFlow-bibliotheekfunctie die operators creëert zoals tf.train.Saver() ), of subtiel (bijv. Een aanroep naar een overbelaste operator op een tf.Tensor en een NumPy-array, die impliciet tf.convert_to_tensor() en een nieuwe tf.constant() toevoegt aan de grafiek).

De methode tf.Graph.finalize() kan helpen om dergelijke lekken op te vangen: het markeert een grafiek als alleen-lezen en roept een uitzondering op als er iets aan de grafiek wordt toegevoegd. Bijvoorbeeld:

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 dit geval probeert de overbelaste * operator nieuwe knooppunten aan de grafiek toe te voegen:

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.

Gebruik de tcmalloc-allocator

Om de prestaties van geheugentoewijzing te verbeteren, gebruiken veel TensorFlow-gebruikers vaak tcmalloc plaats van de standaard malloc() -implementatie, omdat tcmalloc minder last heeft van fragmentatie bij het toewijzen en dealloceren van grote objecten (zoals veel tensoren). Van sommige geheugenintensieve TensorFlow-programma's is bekend dat ze heap-adresruimte lekken (terwijl ze alle individuele objecten vrijmaken die ze gebruiken) met de standaard malloc() , maar ze tcmalloc prima na het overschakelen naar tcmalloc . Bovendien bevat tcmalloc een heap-profiler , waarmee het mogelijk is om te achterhalen waar eventuele resterende lekken zijn opgetreden.

De installatie voor tcmalloc is afhankelijk van uw besturingssysteem, maar het volgende werkt op Ubuntu 14.04 (vertrouwd) (waarbij script.py de naam is van uw TensorFlow Python-programma):

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

Zoals hierboven opgemerkt, kan eenvoudig overschakelen naar tcmalloc veel zichtbare lekken verhelpen. Als het geheugengebruik echter nog steeds groeit, kunt u de heap-profiler als volgt gebruiken:

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

Nadat u de bovenstaande opdracht hebt uitgevoerd, schrijft het programma periodiek profielen naar het bestandssysteem. De reeks profielen krijgt de volgende naam:

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

U kunt de profielen lezen met behulp van de tool google-pprof , die (bijvoorbeeld op Ubuntu 14.04) kan worden geïnstalleerd als onderdeel van het pakket google-perftools . Om bijvoorbeeld de derde momentopname te bekijken die hierboven is verzameld:

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

Als u de bovenstaande opdracht uitvoert, verschijnt er een GraphViz-venster met de profielinformatie als een gerichte grafiek.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow