[開發技巧]·TensorFlow&Keras GPU使用技巧

[開發技巧]·TensorFlow&Keras GPU使用技巧


1.問題描述

在使用TensorFlow&Keras經過GPU進行加速訓練時,有時在訓練一個任務的時候須要去測試結果,或者是須要並行訓練數據的時候就會顯示OOM顯存容量不足的錯誤。如下簡稱在訓練一個任務的時候須要去測試結果,或者是須要並行訓練數據爲進行新的運算任務。html

首先介紹下TensorFlow&Keras GPU使用的機制:TensorFlow&Keras會在有GPU能夠使用時,自動將數據與運算放到GPU進行訓練(這個不一樣於MXNet與PyTorch處理方式不一樣,MXNet與PyTorch須要手動編程去指定數據與運算的Device,這裏不討論這些方法之間的優劣,選擇適合本身的就行了),默認充滿GPU全部顯存。 python

因此當用戶在運行一個運算任務時會佔據全部顯存,若是再去開啓一個新任務就會內存不足,引發OOM顯存容量不足的錯誤。編程

 

2.問題分析

經過對上述問題解讀,應該能夠經過如下的方法解決:session

  1. 當一個訓練任務默認佔據全部GPU顯存的時候,能夠使用CPU進行新的任務(這顯然不是最優方法,使用CPU進行新的任務速度會很慢)
  2. 當一個訓練任務默認佔據全部GPU顯存的時候,用戶能夠設定此任務佔用的GPU顯存大小,如今再使用GPU進行新的任務時,就能夠並行運行了
  3. 若是有多個GPU能夠默認指定任務在不一樣GPU上。

 

3.使用教程

 

1.解決方法一:使用CPU進行新的任務

這不是最優方法,使用CPU進行新的任務速度會很慢,可是也是一種解決方式app

import os

os.environ['CUDA_VISIBLE_DEVICES'] = '-1'  

# 打印 TF 可用的 GPU
print(os.environ['CUDA_VISIBLE_DEVICES'])

# -1 表示不使用GPU

2.解決方法二:設定任務佔用的GPU顯存大小

這個是筆者比較推薦的方式,因爲TensorFlow&Keras運行一個運算任務時會佔據全部顯存,其實有時並無用到那麼多。性能

這樣作也會有點小問題就是,單個任務會變慢一點,筆者測試結果是在使用上述方法並行運行兩個單個任務速度變爲0.8左右,可是換來了能夠運行兩個任務,仍是很值得的。(推測變慢的緣由是兩個任務並行運算時,對GPU壓力更大,每一個任務上分配的性能就會下降,相似於在電腦上跑多個任務,電腦會卡頓)測試

這樣作要注意一點,在分配顯存空間後,模型訓練佔據的內存要設置好(這個是指實際佔用內存,能夠經過修改batch_size來控制),不要超出你所分配的大小,否則會有不指望的結果出現。spa

import tensorflow as tf

# 在開啓對話session前,先建立一個 tf.ConfigProto() 實例對象

gpuConfig = tf.ConfigProto(allow_soft_placement=True)

# 限制一個進程使用 60% 的顯存
gpuConfig.gpu_options.per_process_gpu_memory_fraction = 0.6

# 把你的配置部署到session  變量名 sess 無所謂
sess1 =tf.Session(config=gpuConfig)


#這樣,若是你指定的卡的顯存是2000M的話,你這個進程只能用1200M。

輸出結果(with 1228 MB memory,表明使用1228 MB,這與設置的0.6 * 2000相符).net

Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1228 MB memory) -> 
physical GPU (device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1)

3.解決方法三:多個GPU指定在不一樣GPU運行

 

若是條件容許,擁有多個,就能夠把不一樣任務放置在不一樣GPU上,要注意若是是和同事共用,要約定好如何分配,省得你們都用了同一個。code

設置方法與方法一相似。-1表明不使用,0表明第一個,1表明第二個

以兩個GPU舉例,第一個任務開頭能夠使用以下,第二個任務就把0改成1,多個GPU方法相似。注意一點要放置在開頭位置。

import os

os.environ['CUDA_VISIBLE_DEVICES'] = '0' 

# 打印 TF 可用的 GPU
print(os.environ['CUDA_VISIBLE_DEVICES'])

# -1 表示不使用GPU 0表明第一個

若是多於兩個GPU,想在某個任務設置多個GPU,能夠使用下述方法

import os

os.environ['CUDA_VISIBLE_DEVICES'] = '0,1' 

# 打印 TF 可用的 GPU
print(os.environ['CUDA_VISIBLE_DEVICES'])

# -1 表示不使用GPU 0表明第一個

最後留個你們一個思考問題,os.environ['CUDA_VISIBLE_DEVICES'] = '-1,0' 時會怎麼樣調用?

歡迎你們在評論區留言發佈本身見解和解讀。。

 

4.參考

1.http://www.javashuo.com/article/p-nyygqlmn-go.html

相關文章
相關標籤/搜索