tensorflow - GPU 加速


首先檢測是否可用 GPU 

import tensorflow as tf
print('GPU', tf.test.is_gpu_available())        # GPU True

 

tf.device

Tensorflow 通過 tf.device 指定每個操作運行的設備,可以指定本地的 CPU、GPU,還可以指定遠程服務器;

Tensorflow 會給每個本地設備一個名稱,如 /cpu:0,即使電腦有多塊 CPU ,tf 不會做區分,統一叫 /cpu:0,而 如果有多塊 GPU,第 n 塊 GPU 叫 /gpu:n,n 從 0 開始;

with tf.device('/cpu:0'):
    d1 = tf.Variable(1.)
    d2 = tf.Variable(2., name='d2')
with tf.device('/gpu:0'):
    d3 = tf.add(d1, d2)

with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(d3))

 

log_device_placement

tf 提供了 log_device_placement 來查看 計算在 哪個設備上運行;

d1 = tf.constant(1.)
d2 = tf.constant(2., name='d2')
d3 = tf.add(d1, d2)

### log_device_placement 記錄了計算在哪個設備執行
with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
    print(sess.run(d3))

# Device mapping:
# /job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: Quadro P600, pci bus id: 0000:02:00.0, compute capability: 6.1
# Add: (Add): /job:localhost/replica:0/task:0/device:GPU:0
# Const: (Const): /job:localhost/replica:0/task:0/device:GPU:0
# d2: (Const): /job:localhost/replica:0/task:0/device:GPU:0
# 3.0

 

注意

1. 在 配置好 GPU 的 tf 中,計算優先被分配到 GPU 上;

2. 如果有多塊 GPU,tf 也會優先叫計算放到 /gpu:0 上,而其他 GPU 不會被安排任務,如果需要放到其他 GPU,可通過 tf.device 指定

 

allow_soft_placement

不是所有操作都能在 GPU 上運行;

如在 GPU 上用 tf.Variable 創建變量時,只支持實數型(float16、float32、double),不支持整型;

# 在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")
    ##### 上句報錯如下
    # tensorflow.python.framework.errors_impl.InvalidArgumentError: Cannot assign a device for operation a_gpu:
    # Could not satisfy explicit device specification '/device:GPU:0' because no supported kernel for GPU devices is available.
    a_gpu = tf.Variable(0., name="a_gpu")       ### 這樣寫就不報錯

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

 

為了避免某些操作不能放在 GPU 上而報錯,allow_soft_placement 可以將報錯的操作自動放到 CPU 上;

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/device:GPU:0 -> device: 0, name: Quadro P600, pci bus id: 0000:02:00.0, compute capability: 6.1
# a_cpu: (VariableV2): /job:localhost/replica:0/task:0/device:CPU:0
# a_cpu/Assign: (Assign): /job:localhost/replica:0/task:0/device:CPU:0
# a_cpu/read: (Identity): /job:localhost/replica:0/task:0/device:CPU:0
# 
# a_gpu: (VariableV2): /job:localhost/replica:0/task:0/device:CPU:0
# a_gpu/Assign: (Assign): /job:localhost/replica:0/task:0/device:CPU:0
# a_gpu/read: (Identity): /job:localhost/replica:0/task:0/device:CPU:0        ##### 把 GPU 上的操作放到 CPU 上了
# 
# init/NoOp: (NoOp): /job:localhost/replica:0/task:0/device:GPU:0
# init/NoOp_1: (NoOp): /job:localhost/replica:0/task:0/device:GPU:0
# init: (NoOp): /job:localhost/replica:0/task:0/device:GPU:0
# a_cpu/initial_value: (Const): /job:localhost/replica:0/task:0/device:CPU:0
# a_gpu/initial_value: (Const): /job:localhost/replica:0/task:0/device:GPU:0

 

GPU 資源分配

雖然說 GPU 可以加速,但通常不會把所有操作都放在 GPU 上,大致有如下原則:

1. 把計算密集型的操作放到 GPU 上

GPU 是相對獨立的資源,將計算轉入和轉出 GPU 都需要額外的時間,而且 GPU 需要將計算所需的數據 從內存復制到 GPU 設備上,也需要額外的時間,

tensorflow 可自動完成這些操作,但為了提高運算效率,盡量將相關運算放到同一設備上;

2.通過環境變量分配 GPU 和顯存;

################################### 通過環境變量分配 GPU 資源 ###################################
##### tensorflow 默認會占用所有 GPU (多塊GPU) 和 所有顯存,當然我們可以指定 GPU 或者 動態分配顯存


################# 在運行時設置環境變量 #################
##### 只使用第二塊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


################# 在程序中設置環境變量 #################
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '2'        ### 設定只使用 第3塊 GPU


################# 動態分配顯存 #################
##### TF 默認占用 GPU 的所有顯存,我們可以手動分配顯存,使得一塊 GPU 可以同時運行多個任務
config = tf.ConfigProto()

# 讓TensorFlow按需分配顯存
config.gpu_options.allow_growth = True

# 或者直接按固定的比例分配
config.gpu_options.per_process_gpu_memory_fraction = 0.4        ### 占用所有可使用GPU的40%顯存
session = tf.Session(config=config, ...)

 

多 GPU 訓練

見 參考資料1

分布式 Tensorflow 

見 參考資料1

 

 

 

參考資料:

https://blog.csdn.net/weixin_36670529/article/details/87214096  tensorflow的GPU加速計算  【非常全面、深入】

https://www.jianshu.com/p/26ac409dfb38


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM