我可以使用 TensorFlow 测量单个操作的执行时间吗?
Posted
技术标签:
【中文标题】我可以使用 TensorFlow 测量单个操作的执行时间吗?【英文标题】:Can I measure the execution time of individual operations with TensorFlow? 【发布时间】:2016-03-21 12:12:29 【问题描述】:我知道我可以测量对sess.run()
的调用的执行时间,但是否有可能获得更精细的粒度并测量单个操作的执行时间?
【问题讨论】:
【参考方案1】: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
请注意,子图的任何部分都可以是异步的,您应该非常小心地为计时器操作指定所有输入和输出依赖项。否则,计时器可能会乱序插入到图表中,您可能会得到错误的时间。我发现用于分析 Tensorflow 图的实用程序非常有限的时间线和 time.time() 时间。另请注意,cuda_timer API 将在默认流上同步,这是目前的设计,因为 TF 使用多个流。
话虽如此,我个人还是建议切换到 PyTorch :) 开发迭代更快,代码运行更快,一切都少了很多痛苦。
另一种从 tf.Session 中减去开销(可能是巨大的)的有点老套和神秘的方法是复制图表 N 次并针对变量 N 运行它,求解一个未知的固定开销方程。 IE。你会用 N1=10 和 N2=20 来测量 session.run(),你知道你的时间是 t,开销是 x。所以像
N1*x+t = t1
N2*x+t = t2
求解 x 和 t。缺点是这可能需要大量内存并且不一定准确:) 还要确保您的输入完全不同/随机/独立,否则 TF 将折叠整个子图而不是运行 N 次......玩 TensorFlow 玩得开心: )
【讨论】:
这个例子缺少一套完整的变量或关于如何创建它们的建议。当我点击 Github 中的 sbnet repo 时,它似乎已经过时了 3-4 年。【参考方案2】:2.0兼容答案:您可以在Keras Callback
中使用Profiling
。
代码是:
log_dir="logs/profile/" + datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1, profile_batch = 3)
model.fit(train_data,
steps_per_epoch=20,
epochs=5,
callbacks=[tensorboard_callback])
有关如何进行 Profiling 的更多详细信息,请参阅此Tensorboard Link。
【讨论】:
【参考方案3】:从 Tensorflow 1.8 开始,有一个使用 tf.profile.Profiler
here 的非常好的示例。
【讨论】:
链接失效了,有更新版本吗? (仍然适用于 TF 1.x)【参考方案4】:您可以使用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 中看到它:
此外,单击一个节点将显示确切的总内存, 计算时间和张量输出大小。
【讨论】:
链接(tensorflow.org/programmers_guide/graph_viz#runtime_statistics)已更新。【参考方案5】:由于在谷歌上搜索“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])
【讨论】:
【参考方案6】:对于 Olivier Moindrot 回答下的 fat-lobyte 的 cmets,如果您想收集所有会话的时间线,您可以更改“open('timeline.json', 'w')
”到“open('timeline.json', 'a')
”。
【讨论】:
【参考方案7】:我已经使用Timeline
object 来获取图中每个节点的执行时间:
sess.run()
,但还指定可选参数options
和run_metadata
然后使用run_metadata.step_stats
数据创建一个Timeline
对象
这是一个衡量矩阵乘法性能的示例程序:
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)
然后您可以打开谷歌浏览器,转到页面chrome://tracing
并加载timeline.json
文件。
您应该会看到如下内容:
【讨论】:
嗨!我尝试为我的网络培训创建一个时间线,但不幸的是,如您所展示的那样只为最后一次调用 session.run 生成一个时间线。有没有办法汇总所有会话的时间线? 使用 TensorFlow 0.12.0-rc0,我发现我需要确保 libcupti.so/libcupti.dylib 在库路径中才能正常工作。对我来说(在 Mac 上),我将/usr/local/cuda/extras/CUPTI/lib
添加到 DYLD_LIBRARY_PATH
。
或LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH
在 Ubuntu 上
这里为什么有加法操作符?
因为在调用tf.random_normal
时,TensorFlow首先创建了一个均值为0方差为1的随机张量,然后乘以标准差(这里为1)并加上均值(这里为0)。跨度>
【参考方案8】:
为了更新这个答案,我们确实有一些 CPU 分析功能,专注于推理。如果您查看https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark,您会看到一个程序,您可以在模型上运行以获得每个操作的计时。
【讨论】:
在原始 Tensorflow 操作上获得 GPU 基准测试怎么样?【参考方案9】:在公开版本中还没有办法做到这一点。我们知道这是一个重要的功能,我们正在努力。
【讨论】:
这个答案有可能更新吗?因为github.com/tensorflow/tensorflow/issues/899 似乎可以计算单个操作的 FLOP,从而可以深入了解执行时间。以上是关于我可以使用 TensorFlow 测量单个操作的执行时间吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 TensorFlow 中可靠地测量 sess.run() 的时间?