TensorFlow:分配给 cpu 而不是 gpu 的关键图形操作

TensorFlow: critical graph operations assigned to cpu rather than gpu

我已经将 TensorFlow DNN 模型(2 个隐藏层,带有在 MNIST 上训练的 elu 激活函数)实现为 Python class,以便使用自己的优化例程将 TF 调用包装在另一个库中和工具。

当 运行在 TeslaK20 上进行一些测试时,我注意到 GPU 的使用率为总容量的 4%。因此,我更仔细地查看了日志设备放置,发现所有关键操作,如 MatMulSumAddMean 等都被分配给了CPU。

首先想到的是因为我用的是dtype=float64,所以我换成了dtype=float32。虽然更多的操作分配给了 GPU,但仍然有很多操作分配给了 CPU,例如 Meangradient/Mean_grad/Prodgradient/Mean

所以我的第一个问题来了(我在最后链接了一个工作代码示例),

1) 为什么会这样?我编写了不同的 TF 模型,其中包含简单的张量乘法和缩减,只要我使用单精度,它们 运行 完全在 GPU 上运行。

那么第二个问题来了,

2) 为什么TF会根据数据类型将图分配给不同的设备?我知道并非所有内核都是为 GPU 实现的,但我认为 MatMul 之类的东西可以在 GPU 上 运行 实现单精度和双精度。

3) 模型被包裹在 Python class 中这一事实会产生影响吗?我不认为是这种情况,因为正如我所说,其他类似包裹但更简单的模型并没有发生这种情况。

4) 要在 GPU 上完全 运行 模型,我可以采取哪些步骤?

这是我从我的库中分离出来的代码的完整工作示例

https://gist.github.com/smcantab/8ecb679150a327738102

如果您 运行 它并查看输出,您将看到图表的不同部分是如何分配给不同设备的。要查看示例末尾的 main() 中的 dtypedevice 随类型和设备的变化情况。请注意,如果我设置 allow_soft_placement=False 图形将无法初始化。

如有任何建议,我们将不胜感激。

正如 Yaroslav 指出的:Mean, in particular, was not yet implemented for GPU,但它现在可用,因此这些操作应该 运行 在具有最新 TensorFlow 的 GPU 上。 (根据当时 link 的 DEVICE_GPU 注册)

在均值可用之前,此状态为:

(a) 您可以手动实现均值,因为 reduce_sum is available on GPU.

(b) 我已重新联系某人以查看是否有添加 GPU 支持的简单方法,但我们会看到。

关于 GPU 的 float64,三天前有人用 supporting float64 reductions on GPU 的补丁打开了一个问题。目前正在审查和测试。

不,它是否包含在 Python 中并不重要 - 这实际上只是关于是否已定义内核以使其在 GPU 上执行。在许多情况下,"why is X supported on GPU by Y not?" 的答案归结为 GPU 上是否存在对 运行 Y 的需求。 float64 的答案更简单:float32 快得多,因此在大多数情况下,人们努力让他们的模型尽可能在 float32 中运行,因为它提供了全面的速度优势。

大多数显卡,如 GTX 980、1080 等,都去除了双精度浮点硬件单元。由于这些比较新的 Tesla 单位(具有 FP64 双精度硬件)便宜得多,因此更普遍,因此与单精度相比,在图形卡上进行双精度计算非常慢。 GPU 上的 FP64 计算似乎比没有 FP64 硬件的 GPU 上的 FP32 慢 32 倍。我相信这就是为什么倾向于为 GPU 设置 FP32 计算而为 CPU 设置 FP64(这在大多数系统中更快。)希望在未来,框架将在运行时测试 GPU 功能来决定在哪里分配 FP64 计算。