Buscar..


Use Graph.finalize () para capturar los nodos que se agregan al gráfico

El modo más común de usar TensorFlow implica primero construir un gráfico de flujo de datos de operadores TensorFlow (como tf.constant() y tf.matmul() , luego ejecutar pasos llamando al método tf.Session.run() en un bucle (por ejemplo, un bucle de entrenamiento).

Una fuente común de fugas de memoria es donde el ciclo de entrenamiento contiene llamadas que agregan nodos al gráfico, y se ejecutan en cada iteración, lo que hace que el gráfico crezca. Esto puede ser obvio (por ejemplo, una llamada a un operador TensorFlow como tf.square() ), implícito (por ejemplo, una llamada a una función de biblioteca TensorFlow que crea operadores como tf.train.Saver() ), o sutil (por ejemplo, una llamada a un operador sobrecargado en un tf.Tensor y una matriz NumPy, que implícitamente llama tf.convert_to_tensor() y agrega un nuevo tf.constant() al gráfico).

El método tf.Graph.finalize() puede ayudar a detectar fugas de esta manera: marca un gráfico como de solo lectura y genera una excepción si se agrega algo al gráfico. Por ejemplo:

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)

En este caso, el operador sobrecargado * intenta agregar nuevos nodos al gráfico:

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.

Utilice el asignador tcmalloc

Para mejorar el rendimiento de la asignación de memoria, muchos usuarios de TensorFlow a menudo usan tcmalloc lugar de la implementación malloc() predeterminada, ya que tcmalloc sufre menos fragmentación al asignar y desasignar objetos grandes (como muchos tensores). Se sabe que algunos programas TensorFlow que utilizan mucha memoria pierden espacio de direcciones del montón (mientras liberan todos los objetos individuales que usan) con el malloc() predeterminado, pero se ejecutaron bien después de cambiar a tcmalloc . Además, tcmalloc incluye un generador de perfiles de pila , lo que hace posible rastrear dónde podrían haber ocurrido las fugas restantes.

La instalación de tcmalloc dependerá de su sistema operativo, pero lo siguiente funciona en Ubuntu 14.04 (trusty) (donde script.py es el nombre de su programa Python de TensorFlow):

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

Como se mencionó anteriormente, simplemente cambiar a tcmalloc puede arreglar muchas fugas aparentes. Sin embargo, si el uso de la memoria sigue creciendo, puede usar el generador de perfiles de la siguiente manera:

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

Después de ejecutar el comando anterior, el programa escribirá periódicamente perfiles en el sistema de archivos. La secuencia de perfiles se denominará:

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

Puede leer los perfiles utilizando la herramienta google-pprof , que (por ejemplo, en Ubuntu 14.04) puede instalarse como parte del paquete google-perftools . Por ejemplo, para ver la tercera instantánea recopilada arriba:

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

Al ejecutar el comando anterior se abrirá una ventana de GraphViz, que muestra la información del perfil como un gráfico dirigido.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow