Можно ли измерить время выполнения отдельных операций с помощью TensorFlow?
Я знаю, что могу измерить время выполнения вызова sess.run()
, но можно ли получить более тонкую детализацию и измерить время выполнения отдельных операций?
9 ответов:
пока нет способа сделать это в публичном релизе. Мы знаем, что это важная особенность, и мы работаем над этим.
я использовал
Timeline
объект чтобы получить время выполнения для каждого узла в графе:
- вы используете классический
sess.run()
но также укажите необязательные аргументыoptions
иrun_metadata
- затем вы создаете
Timeline
объектrun_metadata.step_stats
сведения
вот пример программы, которая измеряет производительность умножения матриц:
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)
вы можете затем откройте Google Chrome, перейдите на страницу
chrome://tracing
и загрузить . Вы должны увидеть что-то вроде:
вы можете извлечь эту информацию с помощью статистика выполнения. Вам нужно сделать что-то вроде этого (Смотри полный пример в вышеупомянутой ссылке):
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)
лучше, чем просто печатать его вы можете увидеть его в tensorboard:
кроме того, при нажатии на узел будет отображаться точный общий объем памяти, вычислите время и выходные размеры тензора.
чтобы обновить этот ответ, у нас есть некоторые функции для профилирования ЦП, ориентированные на вывод. Если вы посмотрите на https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark вы увидите программу, которую вы можете запустить на модели, чтобы получить за-op тайминги.
поскольку это высоко при поиске в Google для "профилирования Tensorflow", обратите внимание, что текущий (конец 2017 года, TensorFlow 1.4) способ получения временной шкалы использует ProfilerHook. Это работает с MonitoredSessions в tf.Оценщик где ТФ.RunOptions не доступны.
estimator = tf.estimator.Estimator(model_fn=...) hook = tf.train.ProfilerHook(save_steps=10, output_dir='.') estimator.train(input_fn=..., steps=..., hooks=[hook])
комментарии сало-lobyte под Moindrot Оливьеответ, если вы хотите собрать временную шкалу по всем сеансам, вы можете изменить "
open('timeline.json', 'w')
" на "open('timeline.json', 'a')
".
начиная с Tensorflow 1.8, есть действительно хороший пример для использования
tf.profile.Profiler
здесь.
для автоматического профилирования сеансов TensorFlow вы можете использовать профайлер StackImpact. Нет необходимости в инструментальных сеансах или добавлять какие-либо параметры. Вам просто нужно инициализировать профилировщик:
import stackimpact agent = stackimpact.start( agent_key = 'agent key here', app_name = 'MyApp')
на панели мониторинга будут доступны профили времени выполнения и памяти.
вся информация в этой статье: профилирование тензорного потока в средах разработки и производства.
отказ от ответственности: я работаю на StackImpact.
недавно выпущенный Uber SBNet custom op library (http://www.github.com/uber/sbnet) имеет реализацию таймеров на основе событий cuda, которые могут быть использованы следующим образом:
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
обратите внимание, что любая часть подграфа может быть асинхронной, вы должны быть очень осторожны с указанием всех входных и выходных зависимостей для ОПС таймера. В противном случае таймер может быть вставлен в график не по порядку, и вы можете получить ошибочное время. Я нашел оба график и время.время () очень ограниченная утилита для профилирования тензорных графов. Также обратите внимание, что API cuda_timer будут синхронизироваться по умолчанию stream, который в настоящее время по дизайну, потому что TF использует несколько потоков.
сказав это, я лично рекомендую переключиться на PyTorch :) итерация разработки быстрее, код работает быстрее, и все намного менее болезненно.
еще один несколько хакерский и тайный подход к вычитанию накладных расходов из tf.Сессия (который может быть огромным) состоит в том, чтобы повторить график N раз и запустить его для переменной N, решая для уравнения неизвестных фиксированных накладных расходов. То есть вы бы мерили вокруг сессии.запустите () с N1=10 и N2=20, и вы знаете, что ваше время-t, а накладные расходы-x. так что что-то вроде
N1*x+t = t1 N2*x+t = t2
решить для x и т. недостатком является то, что это может потребовать много памяти и не обязательно точно :) также убедитесь, что ваши входы совершенно разные / случайные / независимые в противном случае TF будет складываться весь подграф и не запускать его N раз... Удачи с TensorFlow:)