que - tensorflow keras tutorial
¿Puedo medir el tiempo de ejecución de operaciones individuales con TensorFlow? (8)
A partir de Tensorflow 1.8, hay un muy buen ejemplo para usar el
tf.profile.Profiler
here
.
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 las operaciones individuales?
Dado que esto está muy arriba cuando buscas en Google "Tensorflow Profiling", ten en cuenta que la forma actual (a finales de 2017, TensorFlow 1.4) de obtener la línea de tiempo está utilizando un ProfilerHook . Esto funciona con MonitoredSessions en tf.Estimator donde tf.RunOptions 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])
He usado el
objeto
Timeline
para obtener el tiempo de ejecución para cada nodo en el gráfico:
-
utiliza un clásico
sess.run()
pero también especifica lasoptions
argumentosoptions
yrun_metadata
-
luego crea un objeto de
Timeline
con los datosrun_metadata.step_stats
Aquí hay un programa de ejemplo que mide el rendimiento de una multiplicación matricial:
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 archivo
timeline.json
.
Deberías ver algo como:
Para actualizar esta respuesta, tenemos algunas funcionalidades para la creación de perfiles de CPU, centradas en la inferencia. Si observa https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark , verá un programa que puede ejecutar en un modelo para obtener tiempos de operación.
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'')
".
Puede extraer esta información utilizando estadísticas de tiempo de ejecución . Deberá 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 solo imprimirlo, puede verlo en el tensorboard:
Además, hacer clic en un nodo mostrará la memoria total exacta, el tiempo de cálculo y los tamaños de salida del tensor.
Recientemente lanzado por la biblioteca de operaciones personalizadas Uber SBNet ( 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 servicio y puede obtener un tiempo erróneo. Encontré tanto la línea de tiempo como el tiempo time.time () de una utilidad muy limitada para perfilar gráficos de Tensorflow. También tenga en cuenta que las API de cuda_timer se sincronizarán en la transmisión predeterminada, que actualmente es por diseño porque TF usa múltiples transmisiones.
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. La sesión (que puede ser enorme) es replicar el gráfico N veces y ejecutarlo para una variable N, resolviendo una ecuación de sobrecarga fija desconocida. Es decir, medirías alrededor de session.run () con N1 = 10 y N2 = 20 y sabes que tu tiempo es ty la sobrecarga es x. Entonces algo como
N1*x+t = t1
N2*x+t = t2
Resuelve para x y t. Lo malo 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 subgráfico y no lo ejecutará N veces ... Diviértase con TensorFlow: )
Todavía no hay una manera de hacer esto en el lanzamiento público. Somos conscientes de que es una característica importante y estamos trabajando en ello.