轉自:https://blog.csdn.net/lemon_tree1994/article/details/79206790
TensorFlow程序可以通過tf.device函數來指定運行每一個操作的設備,這個設備可以是本地的CPU或者GPU,也可以是某一台遠程的服務器。TensorFlow會給每一個可用的設備一個名稱,tf.device函數可以通過設備的名稱來指定執行運算的設備。比如CPU在TensorFlow中的名稱為/cpu:0。
在默認情況下,即使機器有多個CPU,TensorFlow也不會區分它們,所有的CPU都使用/cpu:0作為名稱。而一台機器上不同GPU的名稱是不同的,第n個GPU在TensorFlow中的名稱為/gpu:n。比如第一個GPU的名稱為/gpu:0,第二個GPU名稱為/gpu:1,以此類推。
TensorFlow提供了一個快捷的方式來查看運行每一個運算的設備。在生成會話時,可以通過設置log_device_placement參數來打印運行每一個運算的設備。下面的程序展示了如何使用log_device_placement這個參數。
import tensorflow as tf a = tf.constant([1.0, 2.0, 3.0], shape=[3], name='a') b = tf.constant([1.0, 2.0, 3.0], shape=[3], name='b') c = a + b # 通過log_device_placement參數來輸出運行每一個運算的設備。 sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) print sess.run(c) ''' 在沒有GPU的機器上運行以上代碼可以得到以下輸出: Device mapping: no known devices. add: /job:localhost/replica:0/task:0/cpu:0 b: /job:localhost/replica:0/task:0/cpu:0 a: /job:localhost/replica:0/task:0/cpu:0 [ 2. 4. 6.] '''
在以上代碼中,TensorFlow程序生成會話時加入了參數log_device_placement=True,所以程序會將運行每一個操作的設備輸出到屏幕。於是除了可以看到最后的計算結果之外,還可以看到類似“add:/job:localhost/replica:0/task:0/cpu:0”這樣的輸出。這些輸出顯示了執行每一個運算的設備。比如加法操作add是通過CPU來運行的,因為它的設備名稱中包含了/cpu:0。
在配置好GPU環境的TensorFlow中,如果操作沒有明確地指定運行設備,那么TensorFlow會優先選擇GPU。比如將以上代碼在亞馬遜(Amazon Web Services, AWS)的 g2.8xlarge實例上運行時,會得到以下運行結果。
Device mapping: /job:localhost/replica:0/task:0/gpu:0 -> device: 0, name: GRID K520, pci bus id: 0000:00:03.0 /job:localhost/replica:0/task:0/gpu:1 -> device: 1, name: GRID K520, pci bus id: 0000:00:04.0 /job:localhost/replica:0/task:0/gpu:2 -> device: 2, name: GRID K520, pci bus id: 0000:00:05.0 /job:localhost/replica:0/task:0/gpu:3 -> device: 3, name: GRID K520, pci bus id: 0000:00:06.0 add: /job:localhost/replica:0/task:0/gpu:0 b: /job:localhost/replica:0/task:0/gpu:0 a: /job:localhost/replica:0/task:0/gpu:0 [ 2. 4. 6.]
從上面的輸出可以看到在配置好GPU環境的TensorFlow中,TensorFlow會自動優先將運算放置在GPU上。不過,盡管g2.8xlarge實例有4個GPU,在默認情況下,TensorFlow只會將運算優先放到/gpu:0上。於是可以看見在上面的程序中,所有的運算都被放在了/gpu:0上。如果需要將某些運算放到不同的GPU或者CPU上,就需要通過tf.device來手工指定。下面的程序給出了一個通過tf.device手工指定運行設備的樣例。
import tensorflow as tf # 通過tf.device將運算指定到特定的設備上。 with tf.device('/cpu:0'): a = tf.constant([1.0, 2.0, 3.0], shape=[3], name='a') b = tf.constant([1.0, 2.0, 3.0], shape=[3], name='b') with tf.device('/gpu:1'): c = a + b sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) print sess.run(c) ''' 在AWS g2.8xlarge實例上運行上述代碼可以得到一下結果: Device mapping: /job:localhost/replica:0/task:0/gpu:0 -> device: 0, name: GRID K520, pci bus id: 0000:00:03.0 /job:localhost/replica:0/task:0/gpu:1 -> device: 1, name: GRID K520, pci bus id: 0000:00:04.0 /job:localhost/replica:0/task:0/gpu:2 -> device: 2, name: GRID K520, pci bus id: 0000:00:05.0 /job:localhost/replica:0/task:0/gpu:3 -> device: 3, name: GRID K520, pci bus id: 0000:00:06.0 add: /job:localhost/replica:0/task:0/gpu:1 b: /job:localhost/replica:0/task:0/cpu:0 a: /job:localhost/replica:0/task:0/cpu:0 [ 2. 4. 6.] '''
在以上代碼中可以看到生成常量a和b的操作被加載到了CPU上,而加法操作被放到了第二個GPU“/gpu:1”上。在TensorFlow中,不是所有的操作都可以被放在GPU上,如果強行將無法放在GPU上的操作指定到GPU上,那么程序將會報錯。
地址:http://www.infoq.com/cn/articles/introduction-of-tensorflow-part07?utm_source=articles_about_TensorFlow&utm_medium=link&utm_campaign=TensorFlow
通常,如果你的TensorFlow版本是GPU版本的,而且你的電腦上配置有符合條件的顯卡,那么在不做任何配置的情況下,模型是默認運行在顯卡下的。
在一些情況下,我們即使是在GPU下跑模型,也會將部分Tensor儲存在內存里,因為這個Tensor可能太大了,顯存不夠放,相比於顯存,內存一般大多了,於是這個時候就常常人為指定為CPU設備。
需要注意的是,這個方法會減少顯存的負擔,但是從內存把數據傳輸到顯存中是非常慢的,這樣做常常會減慢速度。(轉自:https://blog.csdn.net/LoseInVain/article/details/78814091)