我可以使用TensorFlow测量单个操作的执行时间吗?

时间:2015-12-15 15:57:34

标签: tensorflow

我知道我可以测量对sess.run()的调用的执行时间,但是是否可以获得更精细的粒度并测量单个操作的执行时间?

9 个答案:

答案 0 :(得分:97)

我已经使用Timeline object来获取图表中每个节点的执行时间:

  • 您使用经典sess.run(),但也指定了可选参数optionsrun_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)

然后,您可以打开Goog​​le Chrome浏览器,转到页面chrome://tracing并加载timeline.json文件。 你应该看到类似的东西:

timeline

答案 1 :(得分:21)

在公开发布中还没有办法做到这一点。我们知道这是一个重要的功能,我们正在努力。

答案 2 :(得分:18)

由于在搜索“Tensorflow Profiling”时这是高位,请注意当前(2017年末,TensorFlow 1.4)获取时间轴的方式是使用ProfilerHook。这适用于tf.Estimator中的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])

答案 3 :(得分:12)

您可以使用runtime statistics提取此信息。您将需要执行以下操作(请查看上述链接中的完整示例):

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

答案 4 :(得分:10)

为了更新这个答案,我们确实有一些CPU分析功能,专注于推理。如果您查看https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark,您会看到一个程序,您可以在模型上运行以获得每个操作时间。

答案 5 :(得分:2)

对于 Olivier Moindrot 的答案下的 fat-lobyte 的评论,如果你想收集所有会话的时间表,你可以改变“{{1} }“to”open('timeline.json', 'w')“。

答案 6 :(得分:2)

从Tensorflow 1.8开始,使用tf.profile.Profiler here就是一个很好的例子。

答案 7 :(得分:0)

最近由Uber发布的SBNet自定义操作库(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

请注意,子图的任何部分都可以是异步的,您应该非常小心地指定timer ops的所有输入和输出依赖项。否则,计时器可能会无序地插入到图形中,您可能会得到错误的时间。我找到了时间轴和time.time()时间非常有限的实用程序,用于分析Tensorflow图。另请注意,cuda_timer API将在默认流上同步,这是当前设计的,因为TF使用多个流。

话虽如此,我个人建议切换到PyTorch :)开发迭代更快,代码运行速度更快,一切都不那么痛苦。

从tf.Session(可能是巨大的)减去开销的另一种有点hacky和神秘的方法是将图形复制N次并将其运行为变量N,求解未知固定开销的方程式。即你在session.run()周围测量N1 = 10和N2 = 20,你知道你的时间是t,开销是x。像

这样的东西
N1*x+t = t1
N2*x+t = t2

解决x和t问题。缺点是这可能需要大量内存并且不一定准确:)同时确保您的输入完全不同/随机/独立否则TF将折叠整个子图并且不运行N次...享受TensorFlow的乐趣: )

答案 8 :(得分:0)

2.0兼容答案:您可以在 __init__(text) 中使用Profiling

该代码为:

Keras Callback

有关如何进行性能分析的更多详细信息,请参阅此Tensorboard Link