【问题标题】:TensorFlow: critical graph operations assigned to cpu rather than gpuTensorFlow:分配给 cpu 而不是 gpu 的关键图形操作
【发布时间】:2016-02-16 21:12:46
【问题描述】:

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

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

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

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

1) 为什么会这样?我编写了不同的 TF 模型,这些模型由简单的张量乘法和减法组成,只要我使用单精度,它们就可以在 GPU 上完全运行。

那么第二个问题来了,

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

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

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

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

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

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

任何建议都将不胜感激。

【问题讨论】:

  • 看起来对 matmul 中双精度的支持已关闭 here。看起来很奇怪,它调用了支持双精度的 CuBLAS。还有一些操作没有任何数据类型的 GPU 实现
  • 底线——一堆操作没有在 GPU 上实现。一种策略是重组计算以使用更多与 GPU 兼容的操作并为其余的文件提交 github 问题以跟踪社区进度。启用对 matmul 的双重支持似乎很容易实现
  • 尝试将(use_gpu=True, force_gpu=True) 添加到您的会话中,并在构建图表时查看失败的位置。
  • 谢谢雅罗斯拉夫,我在这里提出了一个问题github.com/tensorflow/tensorflow/issues/1140

标签: python tensorflow


【解决方案1】:

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

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

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

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

在 GPU 上回复 float64,有人在三天前打开了一个问题,其中包含 supporting float64 reductions on GPU 的补丁。目前正在审查和测试中。

不,它是否包含在 Python 中并不重要——这实际上只是关于是否定义了一个内核以便它在 GPU 上执行。在许多情况下,“为什么 Y 不支持 GPU 上的 X?”的答案是什么?归结为是否需要 Y 在 GPU 上运行。 float64 的答案更简单:float32 要快得多,因此在大多数情况下,人们会尽可能让他们的模型在 float32 中工作,因为它可以带来全方位的速度优势。

【讨论】:

  • 好的,谢谢。然后我将执行以下操作:1) 使用 GPU 支持的操作尽可能多地重写操作 2) 在 github 上提出问题以将支持扩展到双打。我查看了您指出的reduce_sum 问题,似乎所有工作都完成了在内核中添加REGISTER_GPU_KERNELS(double)。我知道然后必须编写测试,但这真的是所有需要做的吗?
  • 取决于操作。其中一些可能具有特定于类型的优化;我不确定矩阵乘法是什么情况。另一种情况是每个操作都在二进制文件中占用空间,因此有些希望只包含实际用于避免不必要的膨胀的操作。人们要求它是膨胀是值得的证据。 :)
  • 我认为它现在应该基于current tensorflow op code“正常工作”。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 2021-03-23
    • 2019-11-11
    • 2010-11-18
    • 2018-05-18
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多