GPU版選擇說明
TensorFlow不僅提供了CPU版資源調度工具包,而且提供了GPU版資源調度工具包。該工具包在計算中,同時利用CPU和GPU進行數據計算,當處理圖像任務時,優勢較僅使用CPU處理十分明顯,處理速度比單純使用CPU提高10倍甚至百倍到千倍,極大地提高了開發效率。
GPU版TensorFlow安裝后還不能換立即使用,因為需要調用GPU資源,所以需要安裝GPU驅動。因為我用的N卡,因此還需要安裝NVIDIA驅動CUDA和神經網絡加速計算單元cuDNN。
驅動可以直接搜索並到NVIDIA官網進行下載安裝,我的電腦配置CPU是i7 9700,顯卡是GeForce RTX 2060 SUPER,內存是16G*2,因此這里我都下了最新版CUDA 11.1.0和cuDNN 8.2.0。
CUDA簡介
CUDA(Compute Unified Device Architecture,統一計算架構),是顯卡廠商NVIDIA推出的運算平台。 CUDA™是一種由NVIDIA推出的通用並行計算架構,該架構使GPU能夠解決復雜的計算問題。 它包含了CUDA指令集架構(ISA)以及GPU內部的並行計算引擎。
cuDNN簡介
NVIDIA cuDNN是用於深度神經網絡的GPU加速庫。它強調性能、易用性和低內存開銷,可以集成到更高級別的機器學習框架中。簡單的插入式設計可以讓開發人員專注於設計和實現神經網絡模型,而不是簡單調整性能,同時還可以在GPU上實現高性能現代並行計算。
CUDA與cuDNN的關系
CUDA看作是一個工作台,上面配有很多工具,如錘子、螺絲刀等。cuDNN是基於CUDA的深度學習GPU加速庫,有了它才能在GPU上完成深度學習的計算。它就相當於工作的工具,比如它就是個扳手。但是CUDA這個工作台買來的時候,並沒有送扳手。想要在CUDA上運行深度神經網絡,就要安裝cuDNN,就像你想要擰個螺帽就要把扳手買回來。這樣才能使GPU進行深度神經網絡的工作,工作速度相較CPU快很多。
檢查CUDA與cuDNN是否安裝成功
- 可以通過在cmd中輸入
nvcc -V
查看CUDA版本來確認是否安裝成功,或者輸入nvidia-smi
查看顯卡驅動版本、cuda版本、顯卡使用情況。 - 到CUDA目錄(如C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\demo_suite)下執行bandwidthTest.exe和deviceQuery.exe兩個程序,可以打開cmd再將程序拖進去執行,結果都出現
Result = PASS
即可。
安裝CUDA與cuDNN遇到的問題及解決
- CUDA安裝過程中出現的第一個選擇路徑是臨時安裝文件,默認安裝在了C盤,安裝完畢后會自動刪除。
- cuDNN下載下來是個壓縮包,需要將文件全放到CUDA(NVIDIA GPU Computing Toolkit)目錄下。而安裝完CUDA后打開的文件夾CUDA Samples所在上上級目錄下的NVIDIA GPU Computing Toolkit這個文件夾下並沒有CUDA文件夾,而在C盤Program Files下找到了正確的文件夾,並將壓縮包里的東西全部復制到CUDA\v11.1\路徑下。
C:\ProgramData\NVIDIA GPU Computing Toolkit(✖)
C:\Program Files\NVIDIA GPU Computing Toolkit(✔)
完成后添加環境變量path:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\lib\x64
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\CUPTI\lib64
PyCharm中安裝TensorFlow-GPU
安裝命令:pip install tensorflow-gpu
。自動安裝的最新版2.4.0。
安裝完進行測試,運行如下代碼:
import tensorflow as tf
import timeit # 性能分析模塊
# 查看版本
print(tf.__version__)
# CUDA是否可用
print(tf.test.is_built_with_cuda())
# GPU是否可用
print(tf.test.is_gpu_available())
# 創建在cpu環境上運算的兩個矩陣
# tf.device:指定模型運行的具體設備
with tf.device('/cpu:0'):
# 用於從“服從指定正態分布的序列”中隨機取出指定個數的值
# shape:輸出張量的形狀,必選
# mean:正態分布的均值,默認為0
# stddev:正態分布的標准差,默認為1.0
# dtype:輸出的類型,默認為tf.float32
# seed:隨機數種子,是一個整數,當設置之后,每次生成的隨機數都一樣
# name:操作的名稱
cpu_a = tf.random.normal(shape=[10000, 1000])
cpu_b = tf.random.normal([1000, 2000])
print(cpu_a.device, cpu_b.device)
# 創建在gpu環境上運算的兩個矩陣
with tf.device('/gpu:0'):
gpu_a = tf.random.normal([10000, 1000])
gpu_b = tf.random.normal([1000, 2000])
print(gpu_a.device, gpu_b.device)
# cpu矩陣相乘
def cpu_run():
with tf.device('/cpu:0'):
# 將矩陣a乘以矩陣b,生成a*b
c = tf.matmul(cpu_a, cpu_b)
return c
# gpu矩陣相乘
def gpu_run():
with tf.device('/gpu:0'):
c = tf.matmul(gpu_a, gpu_b)
return c
# 正式計算前需要熱身,避免將初始化時間結算在內
cpu_time = timeit.timeit(cpu_run, number=10)
gpu_time = timeit.timeit(gpu_run, number=10)
print('warm up:', cpu_time, gpu_time)
# 正式計算
cpu_time = timeit.timeit(cpu_run, number=10)
gpu_time = timeit.timeit(gpu_run, number=10)
print('run time:', cpu_time, gpu_time)
timeit的使用可以參考我的另一篇博文:
【timeit】Python小段代碼性能測試模塊
正確的運行結果如下
2.4.1
True
True
/job:localhost/replica:0/task:0/device:CPU:0 /job:localhost/replica:0/task:0/device:CPU:0
/job:localhost/replica:0/task:0/device:GPU:0 /job:localhost/replica:0/task:0/device:GPU:0
warm up: 0.6571273 1.2346933
run time: 0.6092833999999998 0.001225699999999108
可見GPU運算速度要比CPU快得多。
OK,到此環境部署完成!
安裝TensorFlow-GPU遇到的問題及解決
- 剛開始用清華源直接安裝GPU版本時總是失敗,報SSLError,取消使用清華源后安裝成功(有文章提到是因為清華源無對應GPU版本),雖然有時候會超時失敗。
- 運行程序時控制台輸出大片紅色文字是正常,但也可能隱藏着報錯,如:
Could not load dynamic library 'cusolver64_10.dll'; dlerror: cusolver64_10.dll not found
此時tf.test.is_gpu_available()
返回的結果是False,也無法獲取GPU設備,如下:
2.4.1
True
False
/job:localhost/replica:0/task:0/device:CPU:0 /job:localhost/replica:0/task:0/device:CPU:0
/job:localhost/replica:0/task:0/device:CPU:0 /job:localhost/replica:0/task:0/device:CPU:0
warmup: 0.7154982999999997 0.6833096000000003
run time: 0.6948550999999998 0.6916026000000004
解決辦法:在C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin
路徑下,將cusolver64_11.dll文件復制一份並改名為cusolver64_10.dll,再重新運行程序即可順利解決問題並得到正確的結果。