11

我想知道是否有人可以建议如何在 4 GPU 设置中从 tensorflow 中获得最佳性能。

作为测试,我在 32x32 输入上创建了两个相同的网络(18 层残差网络,带有小型滤波器组(范围从 16-128)。批量大小 512,每个 GPU 128。)。一个在 MXNet 中,一个是我根据 inception 示例建模的。

我的 MXNet 网络每秒可以训练大约 7k 个示例,其中 tensorflow 只能处理 4.2k 的虚拟数据和 3.7 的真实数据。

(在 1 个 GPU 上运行时,数字是每秒 1.2k 示例 vs 2.1k)

在我的实验中,我有几个问题希望能加快速度。

  1. 训练时 GPU 利用率似乎很低。我注意到在 tensorflow 白皮书中支持在同一个 GPU 上运行多个流。这在公开发布中可能吗?

  2. 无论如何要在一次执行中执行多个火车操作session.run()吗?或者有异步执行?这将允许在下一批前向传递的同时完成权重更新?我曾尝试使用 2 个线程(包括 system 和 with QueueRunners),但这只会导致速度变慢。MXNet 能够通过在 CPU 上运行权重更新来提高速度,以便 gpu 可以用于下一批。

  3. 新的分布式运行时是否会通过让我在一台机器上运行多个工作人员来解决其中一些问题?

  4. 还有什么可以做的吗?

我知道这里有很多关于堆栈溢出的类似问题,但是虽然我的搜索我找不到我尚未尝试过的问题的解决方案。

编辑:

我做了一点 CUDA 分析来看看昂贵的内核是什么。根据我的运行,21.4% 的时间花在里面:

void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>,
Eigen::TensorPaddingOp<Eigen::array<std::pair<int, int>,
unsigned long=4> const, Eigen::TensorMap<Eigen::Tensor<float const,
int=4, int=1, long>, int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4)

20.0% 的时间花在

void Eigen::internal::EigenMetaKernel_NonVectorizable<Eigen::TensorEvaluator
<Eigen::TensorAssignOp<Eigen::TensorMap<Eigen::Tensor<float, int=4, int=1, long>, int=16>,
Eigen::TensorBroadcastingOp<Eigen::array<int, unsigned long=4>
const, Eigen::TensorMap<Eigen::Tensor<float const, int=4, int=1, long>,
int=16> const > const > const, Eigen::GpuDevice>, long>(float, int=4)

关闭签名我不确定这些在做什么。这些有意义吗?

除此之外,分析报告了低内核并发性,如预期的那样为 0%。并且计算利用率低 34.9%(假设这包括启动时间和训练循环中的一点 python。总共大约 32 秒,总共 91 秒。这意味着 tensorflow 内的利用率约为 50%。)

编辑2:

我附上了一份精简后的源代码。总的来说,虽然我更关心问题 1-3,并且不想花费太多时间。

此外,我在 tensorflow 上运行:f07234db2f7b316b08f7df25417245274b63342a

编辑3:

更新到最新的 tensorflow (63409bd23facad471973b110df998782c0e19c06) 相同的代码,默认数据格式 (NHWC),这似乎加快了很多。在假数据 6.7k-6.8k(我认为是热依赖性?)示例上是第二个 4gpu。1gpu -- 每秒 2.0k 个示例。对于 4gpu,实际数据性能约为每秒 4.9k 个示例。1gpu -- 每秒 1.7k 个示例。

编辑4:

此外,我尝试将数据格式切换为 BCHW。我根据Soumith 的基准进行了转换。卷积部分确实更快,但批处理规范似乎把一切都搞砸了。使用简单的实现(固定轴,并制作权重 [1,C,1,1] 而不是 [C,])我只能在 4 gpu(假数据)上每秒获得 1.2k 个示例。与批量规范操作之前和之后的转置一样,我每秒可以获得 6.2k 个示例(假数据)。仍然比 NHWC data_format 慢。

4

1 回答 1

1

不看代码就很难诊断程序的性能问题。我们有可能以某种方式阅读您的测试代码吗?

顶部显示的 TensorPadding 有点奇怪。我希望 cudnn 调用应该在配置文件的顶部。无论如何,向我们展示测试代码会很有帮助。

于 2016-03-18T06:08:14.610 回答