Ubuntu 18.04 で NVIDIA GeForce RTX 2070 を動かすまでの道のり

ついに弊研にもGPUが!

ということで、届いたGPUサーバをさっそくセットアップしてみました。 OSインストール後から、MNISTがGPUで動くまでに何をしたかを中心に書いていきます。

サーバスペック

こんな感じです。 家にもこれくらいのマシンが1台あったらいろいろ充実しそうです。

GPUの利用環境構築

今回はansibleを使って構築していきます。 下記のようなplaybookが出来上がりました。 なお、playbookの実行後にはOSの再起動が必要です。

- hosts: all
  remote_user: server
  gather_facts: no
  become: yes

  tasks:
    - name: inventory_hostname is
      debug: var=inventory_hostname
    - name: Update and upgrade apt packages
      apt:
        upgrade: yes
        update_cache: yes
        cache_valid_time: 86400 # One day

    # CUDA, cuDNN, NCCL, TensorRT
    - name: Add NVIDIA key
      apt_key:
        url: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
    - name: Install NVIDIA network deb from the network
      apt:
        deb: "{{ item }}"
      with_items:
        - https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
        - https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
        - https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvinfer-runtime-trt-repo-ubuntu1804-5.0.2-ga-cuda10.0_1-1_amd64.deb
    - name: Install CUDA, cuDNN, NCCL, TensorRT based on network deb's config
      apt:
        update_cache: yes
        force: yes
        name: "{{ packages }}"
      vars:
        packages:
          - cuda-10-0
          - libcudnn7=7.5.0.56-1+cuda10.0
          - libcudnn7-dev=7.5.0.56-1+cuda10.0
          - libnccl2=2.4.2-1+cuda10.0
          - libnccl-dev=2.4.2-1+cuda10.0
          - libnvinfer5=5.0.2-1+cuda10.0
          - libnvinfer-dev=5.0.2-1+cuda10.0
    - name: Prevent cuda related packages from upgrading
      command: aptitude hold "{{ item }}"
      with_items:
        - cuda-repo-ubuntu1804
        - nvidia-machine-learning-repo-ubuntu1804
        - nvinfer-runtime-trt-repo-ubuntu1804-5.0.2-ga-cuda10.0
        - cuda-10-0
        - libcudnn7
        - libcudnn7-dev
        - libnccl2
        - libnccl-dev
        - libnvinfer5
        - libnvinfer-dev

このplaybookの中では以下のものをインストールしています。

  • NVIDIAドライバ
  • CUDA
  • cuDNN
  • NCCL
  • TensorRT

NVIDIA ドライバ

NVIDIAが公開しているaptレポジトリを追加しておくことで、CUDAをaptでインストールするときに一緒にインストールされます。

CUDA

CUDA は、NVIDIAが開発しているGPU上でプログラミングをするためのソフトウェアプラットフォームです。 今回インストールするバージョンは、CUDA10.0です。 Ubuntu 18.04 が CUDA10.0 からサポートされたというのと、TensorFlow 1.13.0 が CUDA10.0 をサポートした、という理由からです。

参考: docs.nvidia.com github.com

cuDNN

cuDNNは、NVIDIAが公開しているDeep Learning用のライブラリです。 これを入れておくことでDNNに関連する計算が高速化されます。 NVIDIAが公開しているaptレポジトリを追加しておくことで、aptでインストールできます。

NCCL

NCCLは、NVIDIA Collective Communications Libraryの略で、マルチGPU、マルチノードに対応するためのライブラリです。 TensorFlowのドキュメント ではOptionalとされていますが一応入れます。 こちらも、NVIDIAが公開しているaptレポジトリを追加しておくことで、aptでインストールできます。

TensorRT

TensorRTは、推論の高速化用のランタイムです。 TensorFlowのドキュメント ではOptionalとされていますが一応入れます。 こちらも、NVIDIAが公開しているaptレポジトリを追加しておくことで、aptでインストールできます。

その他

最後に aptitude hold コマンドでインストールしたパッケージのバージョンを固定しています。 こうすることによって、後々 apt-get upgrade したときにCUDAのバージョンが上がってしまっていろいろなものが動かなくなるという悲劇を避けることができます。

GPU関連コマンド

nvidia-smi

nvidia-smi -l 1 で1秒ごとにGPUの仕様状況を表示できます。

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.39       Driver Version: 418.39       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 2070    On   | 00000000:01:00.0  On |                  N/A |
| 29%   26C    P2    43W / 175W |    575MiB /  7949MiB |     13%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      6476      G   /usr/lib/xorg/Xorg                            39MiB |
|    0      6508      G   /usr/bin/gnome-shell                          70MiB |
|    0     21667      C   python                                       453MiB |
+-----------------------------------------------------------------------------+

動作確認

前提:

  • anaconda3 で python の環境構築済み

Keras (TensorFlow backend) と chainer の MNIST を動かしてみます。 GPUなしとありの場合の実行時間を time コマンドで比較します。 今回試した MNIST のサンプルでは、GPUありの場合のほうが3倍前後速くなりました。

Keras (TensorFlow backend) を使う場合

インストール方法

pip install tensorflow-gpu>=1.13.1
pip install keras

実行例

コード: https://github.com/keras-team/keras/blob/master/examples/mnist_mlp.py

GPUなし

CUDA_VISIBLE_DEVICES= python mnist_mlp.py
# time コマンドでの実行時間測定結果
300.26user 10.73system 0:44.04elapsed 706%CPU (0avgtext+0avgdata 630744maxresident)k
0inputs+8outputs (0major+164547minor)pagefaults 0swaps

GPU あり

python mnist_mlp.py
# time コマンドでの実行時間測定結果
32.12user 3.86system 0:18.24elapsed 197%CPU (0avgtext+0avgdata 1663376maxresident)k
0inputs+8outputs (0major+354232minor)pagefaults 0swaps

chainer

インストール方法

export CHAINER_BUILD_CHAINERX=1
export CHAINERX_BUILD_CUDA=1
export CUDNN_ROOT_DIR=/usr/local/cuda-10.0
export MAKEFLAGS=-j8  # Using 8 parallel jobs.
pip install --pre cupy
pip install --pre chainer

実行例

コード: https://github.com/chainer/chainer/blob/master/examples/mnist/train_mnist.py

GPUなし

python train_mnist.py --unit 512 --noplot --device -1 --gpu -1
# time コマンドでの実行時間測定結果
687.14user 1008.63system 2:23.76elapsed 1179%CPU (0avgtext+0avgdata 371364maxresident)k
0inputs+14664outputs (0major+119892minor)pagefaults 0swaps

GPUあり

python train_mnist.py --unit 512 --noplot --device 0 --gpu 0
# time コマンドでの実行時間測定結果
39.36user 1.09system 0:39.75elapsed 101%CPU (0avgtext+0avgdata 1895712maxresident)k
0inputs+14576outputs (0major+454376minor)pagefaults 0swaps

詰まったところ

TensorFlow 1.13.0 は CUDA 10.0 をサポートしていますが、 CUDA 10.1 はサポートしていないようです。 現時点で CUDA の最新は 10.1 なので、うっかりしていると 10.1 が入ってしまいます。 こうなると pythonimport tensorflow したときに ImportError: libcublas.so.10.0: cannot open shared object file: No such file or directory などとエラーが出てしまいます。 (CUDA 10.1 はアンインストールしたはずなのに、 nvidia-smi コマンドで "CUDA Version: 10.1" のままになってるのはなんでだろう...)

感想

GPUでの機械学習を成功させるためには、OS, NVIDIA ドライバ, CUDA関連のパッケージ, 機械学習ライブラリのバージョンの組み合わせがかなり限定されるということがわかりました。 何のどのバージョンをインストールすべきなのか、という選択を間違えないことが大切なようです。 一方、そこ以外は想像していたよりはシンプルでした。 GPUを使うまでにはいろんなものをソースコードからビルドしなきゃいけないみたいなイメージがあったのですが、基本的にはaptとpipでなんとかなりました。

参考URL