如何在 TensorFlow 中可靠地测量 sess.run() 的时间?

Posted

技术标签:

【中文标题】如何在 TensorFlow 中可靠地测量 sess.run() 的时间?【英文标题】:How to reliably measure time of sess.run() in TensorFlow? 【发布时间】:2017-04-11 09:51:28 【问题描述】:

我的问题是,如果一个操作的参数是常量,TF会缓存结果:

a = tf.constant(np.random.randn(*(100, 101)))
b = tf.constant(np.random.randn(*(100, 102)))
c = tf.constant(np.random.randn(*(101, 102)))
# Some expensive operation.
res = tf.einsum('si,sj,ij->s', a, b, c)
%timeit sess.run(res)

最慢的运行时间是最快的运行时间的 577.76 倍。这可能意味着正在缓存中间结果。 10000 次循环,3 次中的最佳:每个循环 137 µs

如果我在每次运行时从头开始生成张量,那么我也会计算张量生成的开销:

a = tf.random_normal((100, 101))
b = tf.random_normal((100, 102))
c = tf.random_normal((101, 102))
res = tf.einsum('si,sj,ij->s', a, b, c)
%timeit sess.run(res)

最慢的运行时间是最快的运行时间的 4.07 倍。这可能意味着正在缓存中间结果。 10 个循环,3 个循环中的最佳值:每个循环 28 毫秒

也许在这个特定的例子中,开销并不大,但对于更便宜的操作来说,它可能很重要。

有什么方法可以冻结参数,这样它们就不会在每个 sess.run() 上重新计算,而是抑制所有其他缓存?

【问题讨论】:

【参考方案1】:

在每次运行(跨会话)时,将评估您传递给 sess.run() 的任何张量对象。来自文档:

Session 对象封装了 Operation 对象所在的环境 执行,并对张量对象进行评估。

不可能忽略跨会话评估(计算)张量的值,只要它是要评估的表达式的一部分。

在您的示例中,张量对象 a, b, c 始终在每个会话中进行评估,因为需要它们的值来计算 einsum。但是,在一个会话中,它们只计算一次并在运行中缓存。

但是,在一个会话中,您可以让它只被评估一次并在其他地方使用它。但同样,这仅在会话中有效。

【讨论】:

所以您是说我们无法可靠地测量诸如 einsum 之类的操作的执行时间?如果作为一个肮脏的黑客我修复了参数,但将它们乘以一个随机数怎么办?它将强制 TF 重新计算所有内容,同时不会增加大量开销... const = tf.random_normal((1,))[0] res = tf.einsum('si,sj,ij->s', const * a , 常量 * b, 常量 * c) 在会话中,您测量的实际上是操作所花费的时间,即einsum 但似乎中间计算在运行中被缓存,请参阅原始问题中的第一个示例。运行时间为 137 µs,这比这个特定的 einsum 对随机输入的速度要快得多(即使不包括生成此输入的时间)。 这可能有帮助吗? tensorflow.org/api_docs/python/tf/… 也许使用占位符和提要字典?

以上是关于如何在 TensorFlow 中可靠地测量 sess.run() 的时间?的主要内容,如果未能解决你的问题,请参考以下文章

使用 TensorFlow 在 GPU 上计算梯度时系统挂起

如何以可靠的方式测量执行一段代码所花费的时间?

在多线程 C++ 应用程序中测量时间

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

不可靠的 Android Jetpack 基准测试库测量结果?

在 C# 中,如何可靠地杀死进程树 [重复]