我想了解使用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的输入数据的手动复制?