這裡介紹如何在 CentOS Linux 中安裝 NVIDIA Docker GPU 計算環境,並在 Docker 中編譯與執行簡單的 CUDA 程式。

NVIDIA Docker 是 NVIDIA 官方所提供的 Docker 執行環境,可以讓有使用 CUDA 的程式放在 Docker 中執行,以下是安裝 NVIDIA Docker 的步驟。

安裝 NVIDIA Docker

Step 1
在 CentOS Linux 中安裝好基本的 Docker 環境,以及 NVIDIA 驅動程式,確認 NVIDIA 顯示卡可以正常運作

Step 2
安裝 nvidia-docker RPM 套件:

wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker-1.0.1-1.x86_64.rpm
sudo rpm -i /tmp/nvidia-docker*.rpm && rm /tmp/nvidia-docker*.rpm
sudo systemctl start nvidia-docker

在 NVIDIA Docker 中執行 nvidia-smi 指令,進行測試:

nvidia-docker run --rm nvidia/cuda nvidia-smi

正常的話,應該就可以看到 NVIDIA 顯示卡的資訊了。

NVIDIA Docker 測試輸出訊息

這樣就完成 NVIDIA Docker 的安裝了。

接著從 Docker Hub 下載最新的 nvidia/cuda Docker 影像:

nvidia-docker pull nvidia/cuda

檢查這個 nvidia/cuda Docker 影像中的 nvcc 編譯器版本:

nvidia-docker run --rm -ti nvidia/cuda nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:03_CST_2017
Cuda compilation tools, release 8.0, V8.0.61

若需要舊版 CUDA 的人,可以直接指定 CUDA 版本:

nvidia-docker run --rm -ti nvidia/cuda:7.0 nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Mon_Feb_16_22:59:02_CST_2015
Cuda compilation tools, release 7.0, V7.0.27

我們可以在 Docker 容器中開啟一個互動式的 bash shell,在這個環境下我們可以檢查此容器中的環境(例如 /usr/local/cuda 之下的 CUDA 安裝內容,或是其他系統套件工具):

nvidia-docker run --rm -ti nvidia/cuda bash

在 Docker 容器中我們可以使用 apt 這類的套件管理工具安裝各種套件,只不過所有的變動在離開 Docker 容器之後就會消失,不會被儲存起來,我們可以放心在這裡面做各種的測試,這個特性也是 Docker 的特色之一,隨後我們將介紹在 Docker 影像中新增內容的方法。

建立 Docker 中的 GPU 應用程式

這裡我們以 CUDA 8.0 的 Docker 影像為基礎,示範如何在 Docker 容器中編譯 deviceQuery 這個最簡單的 CUDA 設備查詢程式,並且在 Docker 容器中執行這個 CUDA 程式。

首先建立一個 Dockerfile,內容如下:

# 基礎的 Docker 影像
FROM nvidia/cuda

# 安裝 deviceQuery 原始碼
RUN apt-get update && apt-get install -y --no-install-recommends 
        cuda-samples-$CUDA_PKG_VERSION && 
    rm -rf /var/lib/apt/lists/*

# 設定工作目錄
WORKDIR /usr/local/cuda/samples/1_Utilities/deviceQuery

# 編譯 deviceQuery
RUN make

# Docker 容器主要的執行程式
CMD ./deviceQuer

關於 Dockerfile 的寫法,請參考 Docker 官方的說明文件

根據這個 Dockerfile 建立 Docker 影像:

nvidia-docker build -t device-query .

建立好之後,檢查一下目前可用的 Docker 影像:

docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
device-query                   latest              924f7af38829        21 seconds ago      1.97 GB
guozhaowang/gtwang-demo        part1               810b6202eaea        16 hours ago        194 MB
nvidia/cuda                    latest              614dcdafa05c        5 days ago          1.67 GB
gcr.io/tensorflow/tensorflow   latest-gpu          85c8f551e1d2        11 days ago         2.89 GB
tensorflow/tensorflow          latest-gpu          85c8f551e1d2        11 days ago         2.89 GB
hello-world                    latest              1815c82652c0        11 days ago         1.84 kB
nvidia/cuda                    7.0                 65b5dd170f5e        6 months ago        1.2 GB

接著執行 device-query 這個剛建立好的 Docker 影像:

nvidia-docker run --rm -ti device-query

正常來說,這樣就可以在 Docker 執行 deviceQuery 這個 CUDA 程式了,其輸出會是 CUDA 設備的資訊。

deviceQuery 輸出訊息

NVIDIA Docker 有提供指定 GPU 的功能,我們可以使用 NV_GPU 這個環境變數來指定 Docker 容器可使用的 GPU 編號,例如讓 Docker 容器使用第二個 GPU 設備(編號 1):

NV_GPU=1 nvidia-docker run --rm -ti device-query

這樣使用 deviceQuery 程式查詢出來,就只會出現一張 CUDA 的顯示卡。

deviceQuery 輸出訊息

佈署 Docker 中的 GPU 應用程式

製作好 GPU 應用程式的 Docker 影像之後,我們就可以仿照一般 Docker 影像的方式,先將 GPU 應用程式的 Docker 影像標上正式的名稱:

nvidia-docker tag device-query guozhaowang/device-query

再將該 Docker 影像上傳至 Docker Cloud:

docker push guozhaowang/device-query

接著我們就可以在任何 Docker 環境下,執行這個 Docker 中的 CUDA 程式了:

nvidia-docker run --rm -ti guozhaowang/device-query

實際應用

NVIDIA DIGITS 是一套可以使用 GPU 運算的深度學習系統,而這套系統也有提供 Docker 包裝的版本,對於任何這類 NVIDIA GPU 的 Docker 應用程式,我們都可以使用相同的方式在任何有 NVIDIA GPU 顯示卡的機器上執行:

nvidia-docker run --name digits -p 5000:5000 nvidia/digits

這是 NVIDIA DIGITS 的網頁操作介面:

NVIDIA DIGITS

Google 的 TensorFlow 機器學習系統也可以用這樣的方式執行(請參考 Docker Hub):

nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:latest-gpu

這是 TensorFlow 的 Jupyter Notebook 網頁介面:

TensorFlow 的 Jupyter Notebook 網頁介面

問題與解決方法

如果出現這樣的錯誤訊息:

nvidia-docker | 2017/06/23 14:00:27 Error: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.27/version: dial unix /var/run/docker.sock: connect: permission denied

就將需要使用 NVIDIA Docker 環境的帳號加入至 docker 群組中即可解決:

sudo usermod -a -G docker seal

參考資料:NvidiaGitHubNvidia Parallel Forall