ubuntu 查看GPU使用信息以及用GPU進行TensorFlow計算加速

一、ubuntu 查看GPU的版本信息和使用情況

1.1 使用nvidia自帶的nvidia-smi的命令行工具

1.1.1 查看靜態使用情況(當前GPU使用情況)

nvidia自帶了一個nvidia-smi的命令行工具,會顯示顯存的使用情況

nvidia-smi

在這裏插入圖片描述
解析

  1. 第一欄中:Driver Version :352.63 表示我們使用的驅動是352.63

  2. 第二欄中:

  • 第一行表示GPU序號,名字,Persisitence-M(持續模式狀態)。如該電腦中有一個GPU,序號爲0;名字爲GeForce DTX 970;持續模式的狀態,持續模式雖然耗能大,但是在新的GPU應用啓動時,花費的時間更少,這裏顯示的是off的狀態。
  • 第二行:
    Fan:顯示風扇的轉速,從0到100%之間變動,是計算機的期望轉速,如果計算機不是通過風扇冷卻或者風扇壞了,顯示出來就是N/A。有的nvidia設備如筆記本,tesla系列不是主動散熱的可能顯示不了轉速
    Temp:顯示內部溫度,單位是攝氏度
    Perf:表徵性能狀態,從P0到P12,P0表示最大性能,P12表示最小性能
    Pwr:表示能耗
    Bus-Id:設計GPU總線的相關信息
    Disp.A:DisPlay Active ,表示GPU是否有初始化
    Memory-Usage:表示顯存的使用率
    Volatile GPU-Util:表示浮動的GPU的利用率
    Uncorr.ECC:表示ECC的相關信息,ECC即 Error Correcting Code 錯誤檢查和糾正,在服務器和工作站上的內存中才有的技術
    Compute M:表示計算模式
    Processes:顯示每塊GPU上每個進程所使用的顯存情況。
    圖中紅框標註的參數爲一些重要的參數,主要有溫度、內存使用、GPU利用率

1.2 查看動態使用情況(週期性輸出GPU使用情況)

watch -n * nvidia-smi                  # 每 * 秒更新
watch -n 10 nvidia-smi               # 每10秒更新
watch nvidia-smi                         # 每2 秒更新

在這裏插入圖片描述

1.2 使用nvidia GPU

lspci |grep -i vga
lspci |grep -i nvidia

有GPU的linux的服務器
在這裏插入圖片描述
沒有GPU的linux的服務器
在這裏插入圖片描述

二、用GPU進行TensorFlow計算加速

將深度學習應用到實際問題時,存在的一個非常大的問題是訓練深度學習模型需要的計算量太大。
爲了加速訓練過程,接下來將介紹如何在TensorFlow中使用單個GPU進行計算加速,以及生成TensorFlow會話(tf.Session)時的一些常用參數。通過這些參數可以使調試更加方便而且程序的可擴展性更好。
本文選自**《TensorFlow:實戰Google深度學習框架(第2版)》**。

2.1 tf.device函數

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: (Add): /job:localhost/replica:0/task:0/cpu:0
b: (Const): /job:localhost/replica:0/task:0/cpu:0
a: (Const): /job:localhost/replica:0/task:0/cpu:0
[ 2.  4.  6.]
'''

在配置好GPU環境的TensorFlow中,如果操作沒有明確地指定運行設備,那麼TensorFlow會優先選擇GPU,並且只會將運算優先放到/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: (Add): /job:localhost/replica:0/task:0/gpu:1
b: (Const): /job:localhost/replica:0/task:0/cpu:0
a: (Const): /job:localhost/replica:0/task:0/cpu:0
[ 2.  4.  6.]
'''

在TensorFlow中,不是所有的操作都可以被放在GPU上,如果強行將無法放在GPU上的操作指定到GPU上,那麼程序將會報錯。以下代碼給出了一個報錯的樣例。

import tensorflow as tf

# 在CPU上運行tf.Variable
a_cpu = tf.Variable(0, name="a_cpu")

with tf.device('/gpu:0'):
    # 將tf.Variable強制放在GPU上。
    a_gpu = tf.Variable(0, name="a_gpu")

sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
sess.run(tf.initialize_all_variables())

'''
運行以上程序將會報出以下錯誤:
tensorflow.python.framework.errors.InvalidArgumentError: Cannot assign a device to node 'a_gpu': Could not satisfy explicit device specification '/device:GPU:0' because no supported kernel for GPU devices is available.
Colocation Debug Info:
Colocation group had the following types and devices: 
Identity: CPU 
Assign: CPU 
Variable: CPU 
[[Node: a_gpu = Variable[container="", dtype=DT_INT32, shape=[], shared_ name="", _device="/device:GPU:0"]()]]

'''

不同版本的TensorFlow對GPU的支持不一樣,如果程序中全部使用強制指定設備的方式會降低程序的可移植性。在TensorFlow的kernel中定義了哪些操作可以跑在GPU上。比如可以在variable_ops.cc程序中找到以下定義。

# define REGISTER_GPU_KERNELS(type)                                       \
    REGISTER_KERNEL_BUILDER(                                                 \
      Name("Variable").Device(DEVICE_GPU).TypeConstraint<type>("dtype"),\
      VariableOp);                                                                 \
   …
TF_CALL_GPU_NUMBER_TYPES(REGISTER_GPU_KERNELS);

在這段定義中可以看到GPU只在部分數據類型上支持tf.Variable操作。如果在TensorFlow代碼庫中搜索調用這段代碼的宏TF_CALL_GPU_NUMBER_TYPES,可以發現在GPU上,tf.Variable操作只支持實數型(float16、float32和double)的參數。而在報錯的樣例代碼中給定的參數是整數型的,所以不支持在GPU上運行。

爲避免這個問題,TensorFlow在生成會話時可以指定allow_soft_placement參數。

當allow_soft_placement參數設置爲True時,如果運算無法由GPU執行,那麼TensorFlow會自動將它放到CPU上執行。以下代碼給出了一個使用allow_soft_placement參數的樣例。

import tensorflow as tf
a_cpu = tf.Variable(0, name="a_cpu")
with tf.device('/gpu:0'):
    a_gpu = tf.Variable(0, name="a_gpu")

# 通過allow_soft_placement參數自動將無法放在GPU上的操作放回CPU上。
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_ placement=True))
sess.run(tf.initialize_all_variables())

'''
運行上面這段程序可以得到以下結果:
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
a_gpu: /job:localhost/replica:0/task:0/cpu:0
a_gpu/read: /job:localhost/replica:0/task:0/cpu:0
a_gpu/Assign: /job:localhost/replica:0/task:0/cpu:0
init/NoOp_1: /job:localhost/replica:0/task:0/gpu:0
a_cpu: /job:localhost/replica:0/task:0/cpu:0
a_cpu/read: /job:localhost/replica:0/task:0/cpu:0
a_cpu/Assign: /job:localhost/replica:0/task:0/cpu:0
init/NoOp: /job:localhost/replica:0/task:0/gpu:0
init: /job:localhost/replica:0/task:0/gpu:0
a_gpu/initial_value: /job:localhost/replica:0/task:0/gpu:0
a_cpu/initial_value: /job:localhost/replica:0/task:0/cpu:0
從輸出的日誌中可以看到在生成變量a_gpu時,無法放到GPU上的運算被自動調整到了CPU上(比如a_gpu和a_gpu/read),而可以被GPU執行的命令(比如a_gpu/initial_value)依舊由GPU執行。

'''

2.2 設置CUDA_VISIBLE_DEVICES環境變量

雖然GPU可以加速TensorFlow的計算,但一般來說不會把所有的操作全部放在GPU上。一個比較好的實踐是將計算密集型的運算放在GPU上,而把其他操作放到CPU上。GPU是機器中相對獨立的資源,將計算放入或者轉出GPU都需要額外的時間。而且GPU需要將計算時用到的數據從內存複製到GPU設備上,這也需要額外的時間。TensorFlow可以自動完成這些操作而不需要用戶特別處理,但爲了提高程序運行的速度,用戶也需要儘量將相關的運算放在同一個設備上。

TensorFlow默認會佔用設備上的所有GPU以及每個GPU的所有顯存。如果在一個TensorFlow程序中只需要使用部分GPU,可以通過設置CUDA_VISIBLE_DEVICES環境變量來控制。以下樣例介紹瞭如何在運行時設置這個環境變量。

# 只使用第二塊GPU(GPU編號從0開始)。在demo_code.py中,機器上的第二塊GPU的
# 名稱變成/gpu:0,不過在運行時所有/gpu:0的運算將被放在第二塊GPU上。
CUDA_VISIBLE_DEVICES=1 python demo_code.py
# 只使用第一塊和第二塊GPU。
CUDA_VISIBLE_DEVICES=0,1 python demo_code.py

CUDA_VISIBLE_DEVICES="0,1"       # Same as above, quotation marks are optional
CUDA_VISIBLE_DEVICES=0,2,3       # Devices 0, 2, 3 will be visible; device 1 is maskedCUDA_VISIBLE_DEVICES=""    # No GPU will be visible
————————————————
版權聲明:本文爲CSDN博主「Colie-Li」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/guvcolie/article/details/77164230

TensorFlow也支持在程序中設置環境變量,以下代碼展示瞭如何在程序中設置這些環境變量。

import os
# 只使用第三塊GPU。
os.environ["CUDA_VISIBLE_DEVICES"] = "2"

2.3 TensorFlow動態分配顯存

雖然TensorFlow默認會一次性佔用一個GPU的所有顯存,但是TensorFlow也支持動態分配GPU的顯存,使得一塊GPU上可以同時運行多個任務。下面給出了TensorFlow動態分配顯存的方法。

config = tf.ConfigProto()

# 讓TensorFlow按需分配顯存。
# 方法一:設置最小的GPU使用量
config.gpu_options.allow_growth = True   
# 方法二:設置定量的GPU使用量,以下代碼會佔用所有可使用GPU的90%顯存                  
# config.gpu_options.per_process_gpu_memory_fraction = 0.9  

session = tf.Session(config=config, ...)

原文鏈接:
https://www.cnblogs.com/wj-1314/articles/9947477.html
https://blog.csdn.net/zhang_yang_43/article/details/78357458
https://blog.csdn.net/broadview2006/article/details/79459121
多卡服務器下隱藏部分 GPU 和 TensorFlow 的顯存使用設置
Tensorflow全局設置可見GPU編號
深度學習之卷積神經網絡CNN及tensorflow代碼實現示例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章