Tensorflow "know" 什么时候不把数据放到GPU?
Does Tensorflow "know" when not to put data in GPU?
我正在尝试将 tensorboard 与 tensorflow 一起使用,我将其设置为:
rand = tf.placeholder(dtype=tf.float32) # this will be visualised in tensorboard later on
tf.summary.image('random_noise_visualisation', rand,max_outputs=5)
merged_summary_op = tf.summary.merge_all() # to me this seems like a helper to
# merge all tensorboard related operations
然后我评估我的 merged_summary_op
并为它提供一个非常大的数组,大小约为 1 GB。
它似乎没有从已经使用的内存中使用任何额外的 GPU 内存。
我也刚刚尝试评估我的 rand
占位符,我想也许摘要操作有特殊处理以防止数据进入 GPU。我做到了:
random_value = np.random.randn(3000,224,224,1)
sess.run(rand,feed_dict={rand:random_value})
又一次,没有额外的 GPU 使用率。
然而,当我这样做时
sess.run(rand + 2 ,feed_dict={rand:random_value}) # forced to do some calculation
有额外的 GPU 利用率,增加了大约 1 GB。
对于上述所有实验,我将会话用作:
sess = tf.InteractiveSession(graph=tf.Graph())
我的问题是:
- Tensorflow 知道什么时候不发送 Tensor 到 GPU 吗?
- 从交互式会话更改为普通会话会影响此行为吗?
- 是否有任何特定的文档?
Does Tensorflow know when to not bother to send a Tensor to the GPU ?
是的。
事实上,在您的第一个 rand
实验中,tensorflow 发现不打扰 任何设备,因为提供的提取 rand
已经在 feed_dict
。这个相当简单的优化可以在 session.py
:
中看到
self._final_fetches = [x for x in self._fetches if x not in feeds]
... 和 later on in the same file:
# We only want to really perform the run if fetches or targets are provided,
# or if the call is a partial run that specifies feeds.
if final_fetches or final_targets or (handle and feed_dict_tensor):
results = self._do_run(handle, final_targets, final_fetches,
feed_dict_tensor, options, run_metadata)
else:
results = []
第二个实验不属于这个优化,所以这个图是真实评估的。 Tensorflow 将占位符固定到可用的 GPU,因此也添加了,这解释了 GPU 利用率。
如果运行与log_device_placement=True
的会话,这可以生动地看出:
with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
random_value = np.random.randn(300,224,224,1)
print(sess.run(rand + 2, feed_dict={rand: random_value}).shape)
就image summary op而言,确实比较特殊:ImageSummary
op 没有GPU实现。这是源代码 (core/kernels/summary_image_op.cc
):
REGISTER_KERNEL_BUILDER(Name("ImageSummary").Device(DEVICE_CPU),
SummaryImageOp);
因此,如果您尝试手动将其放置到 CPU,session.run()
将抛出错误:
# THIS FAILS!
with tf.device('/gpu:0'):
tf.summary.image('random_noise_visualisation', rand,max_outputs=5)
merged_summary_op = tf.summary.merge_all() # to me this seems like a helper to
# merge all tensorboard related operations
这似乎是合理的,因为摘要操作不执行任何复杂的计算并且主要处理磁盘 I/O。
ImageSummary
不是唯一的 CPU 操作,例如,所有摘要操作都是。有一个 related GitHub issue,但目前没有更好的方法来检查 GPU 是否支持特定的操作,其他检查源代码。
一般来说,tensorflow 会尝试利用尽可能多的可用资源,因此当 GPU 放置可行且没有其他限制时,引擎倾向于选择 GPU 而不是 CPU。
Will changing from Interactive session to a normal session affect this behaviour ?
没有。 InteractiveSession
不影响设备放置逻辑。唯一的大区别是 InteractiveSession
在创建时将自己设为默认会话,而 Session
仅在 with
块内默认。
Is there any particular documentation for this ?
恐怕我在这里是错的,但很可能不是。对我来说,最好的真相来源是源代码。
我正在尝试将 tensorboard 与 tensorflow 一起使用,我将其设置为:
rand = tf.placeholder(dtype=tf.float32) # this will be visualised in tensorboard later on
tf.summary.image('random_noise_visualisation', rand,max_outputs=5)
merged_summary_op = tf.summary.merge_all() # to me this seems like a helper to
# merge all tensorboard related operations
然后我评估我的 merged_summary_op
并为它提供一个非常大的数组,大小约为 1 GB。
它似乎没有从已经使用的内存中使用任何额外的 GPU 内存。
我也刚刚尝试评估我的 rand
占位符,我想也许摘要操作有特殊处理以防止数据进入 GPU。我做到了:
random_value = np.random.randn(3000,224,224,1)
sess.run(rand,feed_dict={rand:random_value})
又一次,没有额外的 GPU 使用率。
然而,当我这样做时
sess.run(rand + 2 ,feed_dict={rand:random_value}) # forced to do some calculation
有额外的 GPU 利用率,增加了大约 1 GB。
对于上述所有实验,我将会话用作:
sess = tf.InteractiveSession(graph=tf.Graph())
我的问题是:
- Tensorflow 知道什么时候不发送 Tensor 到 GPU 吗?
- 从交互式会话更改为普通会话会影响此行为吗?
- 是否有任何特定的文档?
Does Tensorflow know when to not bother to send a Tensor to the GPU ?
是的。
事实上,在您的第一个 rand
实验中,tensorflow 发现不打扰 任何设备,因为提供的提取 rand
已经在 feed_dict
。这个相当简单的优化可以在 session.py
:
self._final_fetches = [x for x in self._fetches if x not in feeds]
... 和 later on in the same file:
# We only want to really perform the run if fetches or targets are provided,
# or if the call is a partial run that specifies feeds.
if final_fetches or final_targets or (handle and feed_dict_tensor):
results = self._do_run(handle, final_targets, final_fetches,
feed_dict_tensor, options, run_metadata)
else:
results = []
第二个实验不属于这个优化,所以这个图是真实评估的。 Tensorflow 将占位符固定到可用的 GPU,因此也添加了,这解释了 GPU 利用率。
如果运行与log_device_placement=True
的会话,这可以生动地看出:
with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
random_value = np.random.randn(300,224,224,1)
print(sess.run(rand + 2, feed_dict={rand: random_value}).shape)
就image summary op而言,确实比较特殊:ImageSummary
op 没有GPU实现。这是源代码 (core/kernels/summary_image_op.cc
):
REGISTER_KERNEL_BUILDER(Name("ImageSummary").Device(DEVICE_CPU),
SummaryImageOp);
因此,如果您尝试手动将其放置到 CPU,session.run()
将抛出错误:
# THIS FAILS!
with tf.device('/gpu:0'):
tf.summary.image('random_noise_visualisation', rand,max_outputs=5)
merged_summary_op = tf.summary.merge_all() # to me this seems like a helper to
# merge all tensorboard related operations
这似乎是合理的,因为摘要操作不执行任何复杂的计算并且主要处理磁盘 I/O。
ImageSummary
不是唯一的 CPU 操作,例如,所有摘要操作都是。有一个 related GitHub issue,但目前没有更好的方法来检查 GPU 是否支持特定的操作,其他检查源代码。
一般来说,tensorflow 会尝试利用尽可能多的可用资源,因此当 GPU 放置可行且没有其他限制时,引擎倾向于选择 GPU 而不是 CPU。
Will changing from Interactive session to a normal session affect this behaviour ?
没有。 InteractiveSession
不影响设备放置逻辑。唯一的大区别是 InteractiveSession
在创建时将自己设为默认会话,而 Session
仅在 with
块内默认。
Is there any particular documentation for this ?
恐怕我在这里是错的,但很可能不是。对我来说,最好的真相来源是源代码。