最大化tensorflow多GPU性能

luk*_*uke 11 c++ performance gpu tensorflow mxnet

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

作为测试,我在32x32输入上创建了两个相同的网络(18个ish层剩余网络,带有小型滤波器组(范围从16-128).批量大小512,每个GPU 128个.).一个在MXNet和一个我已经模仿了初始示例.

我的MXNet网络每秒可以训练大约7k个示例,其中张量流仅能够使用虚拟数据4.2k,而3.7才能使用实际数据.

(在1 GPU上运行时,数字是每秒1.2k的例子,而2.1k)

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

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

  2. 无论如何在一次执行中执行多个列车操作session.run()?还是有异步执行?这将允许在下一批次向前通过的同时进行重量更新?我尝试使用2个线程(系统和使用QueueRunnerss),但这只会导致速度减慢.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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

关闭签名我不确定这些是做什么的.这些有意义吗?

除此之外,分析还报告了低内核并发性,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慢.

zfc*_*zfc 1

在不查看代码的情况下诊断程序的性能问题有点困难。我们是否可以以某种方式读取您的测试代码?

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