Tensorflow GPU /多GPU如何分配内存?

问题描述:

我有两个问题:Tensorflow GPU /多GPU如何分配内存?

(1)当只使用一个GPU时,Tensorflow如何分配GPU内存?我有这样的(全球使用GPU)卷积2D的实现:

def _conv(self, name, x, filter_size, in_filters, out_filters, strides): 
    with tf.variable_scope(name): 
     n = filter_size * filter_size * out_filters 
     kernel = tf.get_variable(
      '', [filter_size, filter_size, in_filters, out_filters], tf.float32, 
      initializer=tf.random_normal_initializer(stddev=np.sqrt(2.0/n)), 
     ) 
     return tf.nn.conv2d(x, kernel, strides, padding='SAME') 
     # another option 
     # x = tf.nn.conv2d(x, kernel, strides, padding='SAME') 
     # return x 

中注释的另一选项执行相同的操作,但增加了一个新的变量x。在这种情况下,TF会分配更多的GPU内存吗? (2)当使用多个GPU时。我想用list来收集来自多个GPU的结果。执行如下:

def _conv(self, name, input, filter_size, in_filters, out_filters, strides, trainable=True): 
    assert type(input) is list 
    assert len(input) == FLAGS.gpu_num 

    n = filter_size * filter_size * out_filters 
    output = [] 
    for i in range(len(input)): 
     with tf.device('/gpu:%d' % i): 
      with tf.variable_scope(name, reuse=i > 0): 
       kernel = tf.get_variable(
        '', [filter_size, filter_size, in_filters, out_filters], tf.float32, 
        initializer=tf.random_normal_initializer(stddev=np.sqrt(2.0/n)) 
       ) 
       output.append(tf.nn.conv2d(input[i], kernel, strides, padding='SAME')) 

    return output 

由于使用list,TF会分配更多内存吗?是outputlist)连接到某些GPU设备?我有这些问题,因为当我使用两个GPU来训练CNN时,该程序比使用一个GPU时使用更多的GPU内存。我认为这是我错过或误解的东西。

+0

你有没有看过[Tensorflow网站]上的GPU选项页面(https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth)。据我所知,Tensorflow倾向于尽可能多地占用GPU内存,然后自行管理它。当试图用nvidia SMI快速监控时,这可能会有点令人沮丧。但是,您可以允许GPU增长,这意味着它只需要它所需要的并且可以继续获得更多。您可以将TF设置为仅能够占用内存的一小部分。看看这个链接页面是否回答你的任何问题。 – JCooke

+0

感谢您的评论,但该链接没有回答我的问题。在由TF抓取的GPU内存中,有一部分“必要”内存和另一部分用于提高性能。当GPU内存不足时,TF只分配必要的内存(也许后面有更复杂的东西,这就是为什么我们会看到内存不足的警告,但不是故障)。在我的问题中提到的内存意味着这个必要的内存,而不是TF抓住的内存。 – Seven

+0

啊,好吧,我明白了。所以你更关心记忆是如何获得的?恐怕我没有足够的资格给你一个合理的答案。希望别人能帮助你! – JCooke

使用此代码检查每个张量和连接的设备。

for n in tf.get_default_graph().as_graph_def().node: 
    print n.name, n.device 

所以对于这两个问题的答案:

(1)号

(2)如果我想收集整个GPU的直接数据,以及数据被认为计算梯度,会出现问题。因为计算渐变也消耗内存。当跨GPU访问数据时,会分配额外的内存。