TensorFlow:多GPU配置(性能)

8

我想了解使用TensorFlow在训练网络时,多GPU系统的最佳实践是什么。

例如,我的一个网络如下所示:

                         input
                           |
                         (...) <-- convolutional layers
                           |
                       _________
    fully-connected    |       |    fully-connected
    output stream 1 -> |       | <- output stream 2

TensorFlow是否能够有效地分配多个GPU?还是我需要自己指定TensorFlow应该为特定操作使用哪个GPU?

我目前还没有进行基准测试,只是今天开始尝试一些GPU实验。然而,目前我还没有在卷积层中指定要使用的设备,但我已经在全连接层中指定了。

# flattened information of the last convolutional layer
h_pooln_flat = tf.reshape(...)

with tf.device("/gpu:0"):
    # stream 1 stuff

with tf.device("/gpu:1"):
    # stream 2 stuff

这是个好主意吗?还是应该让TensorFlow自行分配资源?
我想一条卷积层的“流”不能并行计算,所以哪个设备执行卷积、池化等操作都没有关系,对吧?
有什么技巧可以获得最佳性能吗?
目前我在一个带有2个GPU的Slurm集群节点上进行训练,但潜在地我可以在更多节点上进行训练,比如4、6或者8个GPU。不过,我猜使用超过2个GPU会有很多开销?
编辑(多GPU性能慢):经过一些测试,我感到相当惊讶……如果让TensorFlow决定分配什么资源并删除特定于设备的语句,网络的训练速度会显着提高。这让我真的很惊讶……当总共有两个GPU时,每个输出流都在一个GPU上,还有什么比这更有效的方法呢?此外,根据输出显示,Tensorflow只使用了一个GPU?!
编辑2(NaN值):经过更多的测试,我发现我手动设置的stream 1为gpu:0,stream 2为gpu:1的方案不仅比让TensorFlow自行决定使用什么更慢(而且根据管道脚本的输出,TensorFlow只使用了一个GPU),而且有时候我的解决方案会生成NaN值(我不知道为什么)。就像直接或在初始化后的短时间内。非常奇怪。
TensorFlow是否需要某种线程锁定或多GPU的输入数据的手动复制?

1
我无法回答你的问题,但我可以指出,在Tensorflow的文档中,他们提到在分配用户定义的放置约束后,处理器(GPU和CPU)的分配是采用贪婪方法完成的。这是白皮书:http://download.tensorflow.org/paper/whitepaper2015.pdf。请参见3.2和4.3节。我也很想知道最佳实践的答案。 - nfmcclure
所有的数据传输都已为您完成,您不需要锁定输入数据以防止NaN出现。但是如果您的优化发散,也可能会得到NaN。 - Yaroslav Bulatov
是的,但我在单个GPU上从未遇到过网络中的NaN问题。我的意思是,在5次实验中,它在单个GPU上正常收敛,但在5次多GPU运行中,有3次出现了NaN值。另外:为什么多GPU会更慢?我的意思是由于GPU之间的数据传输,我并没有期望速度翻倍,但会更慢吗? - daniel451
1个回答

6

默认设备放置的逻辑在simple_placer.cc中。

我可能在逻辑上漏掉了一些东西,但是从this line看来,似乎它会将所有GPU操作放在gpu:0上。

从实现结果可以看出,放置策略没有考虑数据传输或计算成本,因此手动放置通常比自动放置更好。例如,如果您正在进行某种输入管道,则默认放置通常会将一些数据处理操作放在GPU上,这会使整体速度变慢。

至于您的实现速度慢...也许在某处发生了gpu0->gpu1的复制?

让多GPU设置正常工作还有很大的空间,让我们知道您的发现!


你好,如果发生了gpu0->gpu1的复制,会有什么影响?并且当我遇到这个问题时需要优化我的代码吗?具体来说,我需要将来自不同GPU的两个流合并到另一个网络中。但是,我发现这个操作会使我的程序慢2倍。是否有任何解决方法?提前感谢。 - xxxzhi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接