2017-06-12 175 views
1

我有兩個問題: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

回答

0

使用此代碼檢查每個張量和連接的設備。

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

所以對於這兩個問題的答案:

(1)號

(2)如果我想收集整個GPU的直接數據,以及數據被認爲計算梯度,會出現問題。因爲計算漸變也消耗內存。當跨GPU訪問數據時,會分配額外的內存。