¿Puedo medir el tiempo de ejecución de operaciones individuales con TensorFlow?


Sé que puedo medir el tiempo de ejecución de una llamada a sess.run(), pero ¿es posible obtener una granularidad más fina y medir el tiempo de ejecución de operaciones individuales?

 57
Author: Martin Thoma, 2015-12-15

9 answers

Todavía no hay una manera de hacer esto en la versión pública. Somos conscientes de que es una característica importante y estamos trabajando en ello.

 21
Author: Ian Goodfellow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 19:41:17

He utilizado el Timeline object para obtener el tiempo de ejecución de cada nodo en el gráfico:

  • se utiliza un clásico sess.run() pero también se especifican los argumentos opcionales options y run_metadata
  • luego crea un objeto Timeline con los datos run_metadata.step_stats

Aquí hay un programa de ejemplo que mide el rendimiento de una multiplicación de matrices:

import tensorflow as tf
from tensorflow.python.client import timeline

x = tf.random_normal([1000, 1000])
y = tf.random_normal([1000, 1000])
res = tf.matmul(x, y)

# Run the graph with full trace option
with tf.Session() as sess:
    run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
    run_metadata = tf.RunMetadata()
    sess.run(res, options=run_options, run_metadata=run_metadata)

    # Create the Timeline object, and write it to a json
    tl = timeline.Timeline(run_metadata.step_stats)
    ctf = tl.generate_chrome_trace_format()
    with open('timeline.json', 'w') as f:
        f.write(ctf)

Luego puede abrir Google Chrome, ir a la página chrome://tracing y cargar el timeline.json file. Deberías ver algo como:

cronología

 84
Author: Olivier Moindrot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-26 17:03:12

Puede extraer esta información usando estadísticas de tiempo de ejecución. Tendrá que hacer algo como esto (consulte el ejemplo completo en el enlace mencionado anteriormente):

run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
run_metadata = tf.RunMetadata()
sess.run(<values_you_want_to_execute>, options=run_options, run_metadata=run_metadata)
your_writer.add_run_metadata(run_metadata, 'step%d' % i)

Mejor que imprimirlo lo puedes ver en tensorboard:

Además, al hacer clic en un nodo se mostrará la memoria total exacta, calcular el tiempo y los tamaños de salida del tensor.

[Ejemplo de link

 10
Author: Salvador Dali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-04 20:24:57

Para actualizar esta respuesta, tenemos alguna funcionalidad para la creación de perfiles de CPU, centrada en la inferencia. Si nos fijamos en https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark verá un programa que puede ejecutar en un modelo para obtener tiempos per-op.

 9
Author: Pete Warden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-07 01:13:40

Dado que esto es alto cuando se busca en Google "Perfiles de Tensorflow", tenga en cuenta que la forma actual (a finales de 2017, TensorFlow 1.4) de obtener la línea de tiempo es utilizando un ProfilerHook. Esto funciona con las sesiones monitoreadas en tf.Estimador donde tf.Las opciones de ejecución no están disponibles.

estimator = tf.estimator.Estimator(model_fn=...)
hook = tf.train.ProfilerHook(save_steps=10, output_dir='.')
estimator.train(input_fn=..., steps=..., hooks=[hook])
 8
Author: Urs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-16 00:18:41

Para los comentarios de fat-lobyte bajo la respuesta de Olivier Moindrot, si desea recopilar la línea de tiempo en todas las sesiones, puede cambiar "open('timeline.json', 'w')" a "open('timeline.json', 'a')".

 2
Author: Cheney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-12 21:42:53

A partir de Tensorflow 1.8, hay un muy buen ejemplo para usar el tf.profile.Profiler aquí.

 2
Author: nitred,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-02 12:26:13

Para perfilar sesiones de TensorFlow automáticamente puede usar el StackImpact profiler. No es necesario instrumentar sesiones o agregar ninguna opción. Solo necesita inicializar el generador de perfiles:

import stackimpact

agent = stackimpact.start(
    agent_key = 'agent key here',
    app_name = 'MyApp')

Tanto el tiempo de ejecución como los perfiles de memoria estarán disponibles en el panel de control.

Información detallada en este artículo: Perfiles de TensorFlow en Entornos de Desarrollo y Producción.

Descargo de responsabilidad: Trabajo para StackImpact.

 0
Author: logix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-17 08:51:37

Recientemente lanzado por Uber SBNet custom op library (http://www.github.com/uber/sbnet ) tiene una implementación de temporizadores basados en eventos cuda, que se pueden usar de la siguiente manera:

with tf.control_dependencies([input1, input2]):
    dt0 = sbnet_module.cuda_timer_start()
with tf.control_dependencies([dt0]):
    input1 = tf.identity(input1)
    input2 = tf.identity(input2)

### portion of subgraph to time goes in here

with tf.control_dependencies([result1, result2, dt0]):
    cuda_time = sbnet_module.cuda_timer_end(dt0)
with tf.control_dependencies([cuda_time]):
    result1 = tf.identity(result1)
    result2 = tf.identity(result2)

py_result1, py_result2, dt = session.run([result1, result2, cuda_time])
print "Milliseconds elapsed=", dt

Tenga en cuenta que cualquier parte del subgrafo puede ser asíncrona debe tener mucho cuidado al especificar todas las dependencias de entrada y salida para las operaciones del temporizador. De lo contrario, el temporizador podría insertarse en el gráfico fuera de orden y puede obtener un tiempo erróneo. Encontré tanto la línea de tiempo y tiempo.time () tiempo de utilidad muy limitada para perfilar gráficos Tensorflow. También tenga en cuenta que las API de cuda_timer se sincronizarán en el flujo predeterminado, que actualmente está diseñado porque TF usa múltiples flujos.

Dicho esto, personalmente recomiendo cambiar a PyTorch :) La iteración de desarrollo es más rápida, el código se ejecuta más rápido y todo es mucho menos doloroso.

Otro enfoque algo hacky y arcano para restar la sobrecarga de tf.Sesión (que puede ser enorme) es replique el gráfico N veces y ejecútelo para una variable N, resolviendo una ecuación de sobrecarga fija desconocida. Es decir, medirías alrededor de la sesión.run () con N1 = 10 y N2 = 20 y sabes que tu tiempo es t y overhead es x. Así que algo como

N1*x+t = t1
N2*x+t = t2

Solucione para x y t. El inconveniente es que esto puede requerir mucha memoria y no es necesariamente preciso:) También asegúrese de que sus entradas sean completamente diferentes/aleatorias/independientes, de lo contrario TF doblará todo el subgrafo y no lo ejecutará N tiempo... Diviértete con TensorFlow:)

 0
Author: Andrei Pokrovsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-25 22:54:33