Можно ли измерить время выполнения отдельных операций с помощью TensorFlow?


Я знаю, что могу измерить время выполнения вызова sess.run(), но можно ли получить более тонкую детализацию и измерить время выполнения отдельных операций?

9 57

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 и загрузить . Вы должны увидеть что-то вроде:

timeline

вы можете извлечь эту информацию с помощью статистика выполнения. Вам нужно сделать что-то вроде этого (Смотри полный пример в вышеупомянутой ссылке):

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:

кроме того, при нажатии на узел будет отображаться точный общий объем памяти, вычислите время и выходные размеры тензора.

[Example from link

чтобы обновить этот ответ, у нас есть некоторые функции для профилирования ЦП, ориентированные на вывод. Если вы посмотрите на 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:)