Skip to content

[Linux] 在 Ubuntu 18.04 上安裝 CUDA、CuDNN

如果今天我們的電腦上有好的 GPU,那麼,我們通常都很希望這可以拿來進行深度學習。基本上安裝相關的環境並不複雜,通常第一次嘗試也只需要幾個小時就可以上手。

主要的步驟只有 4 個,分別是以下數項:

  1. 將 gcc 版本為 7.x ,我們需要重新安裝 gcc 6.x 版
  2. 下載安裝 GPU 的驅動 (Driver)
  3. 下載安裝 CUDA (推薦版本為 10.0)
  4. 下載安裝 CuDNN

也許中途會再遇到各式這樣的問題也說不定,畢竟每個人安裝時的環境、套件都有所不同。至少我的話,這一年來重灌系統的次數已經快要逼近十次了。當然,是不同的電腦啦,並不是我每次都搞爆我自己的電腦 XD

然而,就連自認重灌許多次、有問題就 Google 一定可以穩穩地找到解答的我 —— 昨天都在重灌系統時遇到 GNU GRUB version 2.02 的問題 —— 然後查了查網路,並沒有找到有效的解決手段,最後拔掉了疑似有問題的硬碟,這才終於重灌成功。

話題扯遠了。

那麼以下,我就開始闡述我的安裝方法吧!如有我的心得沒有紀錄到的部份,一定要仔細確認發生了什麼報錯、並且查詢網路上是否有人提供解決方法哦!


安裝 gcc

之所以建議安裝 gcc 6.x 的版本,而非 Ubuntu 18.04 默認的 gcc 7.x ,是因為之後在編譯一些 CUDA 的套件時 gcc 6.x 比較順利,我便曾經遇過 gcc 7.x 報錯的問題。

gcc 6.x 的安裝我是參考這裡: https://gist.github.com/zuyu/7d5682a5c75282c596449758d21db5ed

這個安裝步驟幾乎是我看過最簡便的:

sudo apt-get update && \
sudo apt-get install build-essential software-properties-common -y && \
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
sudo apt-get update && \
sudo apt-get install gcc-6 g++-6 -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6 && \
gcc -v 

直接複製貼上即可,只要 Output 為 6.x,那便大功告成了。


下載安裝 GPU 驅動程式

現在大部份要使用的 GPU 都是 Nvidia 的,你可以直接到他們官方的驅動程式下載處選擇自己需要的版本: https://www.nvidia.com.tw/Download/index.aspx?lang=tw

選好自己所需要的版本後便開始下載。例如我的話,現在我電腦上裝著 2080 Ti 的 GPU,並且我是 64 位元的 Ubuntu,所以我的選擇如上圖。你也要選擇適合自己的版本。

下載好後,直接來到下載資料夾,使用以下指令安裝:

sudo sh NVIDIA-Linux-x86_64-430.50.run

這時候,應該會出現 “The distribution-provided pre-install script failed! Are you sure you want to continue?” 這樣的問題。

我記得我第一次裝驅動程式的時候就遇過這樣的問題、然後接下來每一次裝基本上遇到這個問題。我不太確定這到底是怎麼回事,不過曾經看過英文論壇上的一個討論說『這是 Nvidia 的工程師跟大家開的一個玩笑!測驗你安裝的決心!』

哇靠,有夠鬼扯的哈哈哈哈(我只是想表達我的驚嘆,那名這樣說的網友很有可能說對了哈哈哈),不過我每次都直接選擇 Continue install ,目前也沒有遇過什麼樣的問題。

持續安裝,一路 ok 繼續,等到 Kernel 裝完,這時候我們需要重新啟動,來讓新的驅動正常運作。

sudo reboot

打開後,現在應該可以用:

nvidia-smi

這個指令來查看 GPU 了。


下載 CUDA 10.0

推薦 10.0 其實是我的私心,因為我現在跑什麼幾乎都是 CUDA 10.0 比較穩。當然,你可以任意挑你想要的版本。

https://developer.nvidia.com/cuda-10.0-download-archive

你可以從這裡選擇你要的版本下載。

下載好了之後來到下載的資料夾,使用:

sudo sh cuda_10.0.130_410.48_linux.run

開始進行安裝。

安裝過程中,因為剛才已經事先安裝過 GPU 的驅動,所以在這邊,我們便不要再安裝 GPU 的驅動了。 (當然,如果不小心一路同意下去也沒關係,至少 CUDA 自動幫忙裝的驅動沒道理無法運行。)

那麼接下來,就來安裝 CuDNN 吧!


CuDNN 下載安裝

下載 CuDNN 比較麻煩,需要有它們的會員。這裡建議還是加入一下,像是我,就下載了 CuDNN 好幾次。

https://developer.nvidia.com/rdp/form/cudnn-download-survey

這裡選擇自己的作業系統、然後挑選適用於 CUDA 10.0 的版本 (如果你前面真的跟我一樣裝 CUDA 10.0 的話)。

然後同樣,點擊了下載。

下載好了之後,如果是 .deb 檔,我們來到下載資料夾後,需要用以下指令安裝。

sudo dpkg -i libcudnn7_7.6.4.38+cuda10.0_amd64.deb

安裝好之後重開機一下,這時候多半就已經可以正常訓練模型了。


測試

不知道能不能訓練模型怎麼能安心呢?這裡給大家一段簡單的 Sample Code 來測試是否有用到 GPU。

首先,我們可能需要安裝四個套件:

sudo pip3 install tensorflow-gpu
sudo pip3 install keras
sudo pip3 install matplotlib
sudo pip3 install pandas

安裝好之後,應該可以執行底下的程式碼:

# coding: utf-8
import os
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras.utils import np_utils, plot_model
from keras.datasets import mnist
import matplotlib.pyplot as plt
import pandas as pd

# Mnist Dataset
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
x_train = X_train.reshape(60000, 1, 28, 28)/255
x_test = X_test.reshape(10000, 1, 28, 28)/255
y_train = np_utils.to_categorical(Y_train)
y_test = np_utils.to_categorical(Y_test)

# Model Structure
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=3, input_shape=(1, 28, 28), activation='relu', padding='same'))
model.add(MaxPool2D(pool_size=2, data_format='channels_first'))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(10, activation='softmax'))
print(model.summary())

# Train
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=10, batch_size=64, verbose=1)

# Test
loss, accuracy = model.evaluate(x_test, y_test)
print('Test:')
print('Loss: %s\nAccuracy: %s' % (loss, accuracy))

# Save model
model.save('./CNN_Mnist.h5')

# Load Model
model = load_model('./CNN_Mnist.h5')

# Display
def plot_img(n):
    plt.imshow(X_test[n], cmap='gray')
    plt.show()

def all_img_predict(model):
    print(model.summary())
    loss, accuracy = model.evaluate(x_test, y_test)
    print('Loss:', loss)
    print('Accuracy:', accuracy)
    predict = model.predict_classes(x_test)
    print(pd.crosstab(Y_test.reshape(-1), predict, rownames=['Label'], colnames=['predict']))

def one_img_predict(model, n):
    predict = model.predict_classes(x_test)
    print('Prediction:', predict[n])
    print('Answer:', Y_test[n])
    plot_img(n)



記得另外開一個 Terminal 來查看是否有吃到 GPU:

watch -n 1 nvidia-smi

這個功能會每一秒刷新 nvidia-smi 的界面,基本上,上面的 MNIST 小程式大概吃約 3% – 10% 左右的 GPU 而已。

希望大家都能順利安裝!

Leave a Reply