GPUディープラーニング環境(CUDA+cuDNN+TensorFlow+Keras)を構築した

どうも、TOMOZO(@TOMOZO)です。

NVIDIAのGPU(GeForce GTX 1050 Ti)を搭載したPCにGPUディープラーニング環境を構築した。
機械学習ライブラリとしてKerasTensorFlow(GPU版)をインストールし、ディープラーニングのチュートリアル「手書き数字を認識できるネットワークを構築する」ところまで。

Python、CUDA、cuDNN、TensorFlowは各々バージョンの組み合わせがシビアで、マイナーバージョンが1つ違うだけでも動作しなかったりする。
筆者もそれで何回かやり直した。
システムを汚したくなければ仮想環境上(Docker等)で構築したほうが良い。てかそうしたのでそちらの記事も更新予定。
スポンサーリンク

実行環境

  • Ubuntu 16.04 LTS
  • NVIDIA GeForce GTX 1050 Ti

インストールするもの

  • NVIDIAドライバ
  • CUDA 9.0
  • cuDNN 7.1.4
  • Python 3.6 by Anaconda
  • TensorFlow(GPU版) 1.12.0
  • Keras 2.2.4

TensorFlowの要件に注意する。
tensorflow-gpuのPython、CUDA、cuDNNの対応バージョン
を意識しながら作業しないと詰む。

NVIDIA-GPUディープラーニング環境の構築手順

古いパッケージを削除

$ sudo apt purge cuda*
$ sudo apt purge nvidia*

NVIDIAドライバ

Ubuntuのデフォルトのグラフィックドライバ”nouveau”を無効化

Ubuntuのデフォルトのグラフィックドライバ”nouveau”を無効化しないといけない。

$ lsmod | grep -i nouveau
$ sudo vi /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
$ sudo update-initramfs -u
$ sudo reboot

NVIDIAの最新ドライバをインストール

チップに対応したドライバを
https://www.nvidia.co.jp/Download/index.aspx?lang=jp
より確認しておく。

$ sudo apt install nvidia-384 #最新ではないが、とりあえずリポジトリにあるもので
$ nvidia-smi
Failed to initialize NVML: Driver/library version mismatch

一度、再起動する。

$ sudo reboot

ここでなかなかログイン画面が起動してこなくて焦った。

$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130                Driver Version: 384.130                   |
|-------------------------------+----------------------+----------------------+
| 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 GTX 105…  Off  | 00000000:01:00.0 Off |                  N/A |
| N/A   48C    P0    N/A /  N/A |    328MiB /  4038MiB |      3%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1144      G   /usr/lib/xorg/Xorg                           214MiB |
|    0      2002      G   compiz                                        67MiB |
|    0      2712      G   …-token=1B556CD959B51F9DF4CB99D5852D1CA1    44MiB |
+-----------------------------------------------------------------------------+

CUDA

CUDA™とはNVIDIA 社の革新的な並列コンピューティング アーキテクチャです。
ハードウェアとソフトウェアを有効にする テクノロジーとして、CUDA は1つのグラフィック プロセッサ内で多数のコンピューティング コアの使用を可能にすることで、演算速度を劇的に速めると同時に汎用数値計算の処理も可能としています。

https://www.nvidia.co.jp/object/cuda_whatis_jp.html

CUDA Toolkit 9.0をインストール

TensorFlowの公式ページ でtensorflow-gpuのCUDA、cuDNNの対応バージョンを確認しておく。

9.2とかはうまくいかないという情報もある。自分も失敗した。
9.0が無難と思われる。

NVIDIAの公式ページ(メンバー登録が必要) からCUDA Toolkit 9.0のdebファイルをダウンロードしインストールする。

$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64.deb
$ sudo apt-key add /var/cuda-repo-9-0-local/7fa2af80.pub
$ sudo apt update
$ sudo apt install cuda

追加のパッチも適応。

$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-local-cublas-performance-update_1.0-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-local-cublas-performance-update-2_1.0-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-local-cublas-performance-update-3_1.0-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-176-local-patch-4_1.0-1_amd64.deb
$ sudo reboot
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130                Driver Version: 384.130                   |
|-------------------------------+----------------------+----------------------+
| 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 GTX 105…  Off  | 00000000:01:00.0 Off |                  N/A |
| N/A   49C    P0    N/A /  N/A |    348MiB /  4038MiB |      2%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1119      G   /usr/lib/xorg/Xorg                           236MiB |
|    0      1962      G   compiz                                        68MiB |
|    0      2788      G   …-token=DBAFC12A29DC1DE9900BEA5377894BD0    41MiB |
+-----------------------------------------------------------------------------+

パスの設定

$ echo -e "\n## CUDA and cuDNN paths"  >> ~/.bashrc
$ echo 'export PATH=/usr/local/cuda-9.0/bin:${PATH}' >> ~/.bashrc
$ echo 'export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:${LD_LIBRARY_PATH}' >> ~/.bashrc
$ source ~/.bashrc

cuDNN

cuDNNはDNNで使われる基本的な機能をまとめたCUDAライブラリであり、すべてのフレームワークから簡単に呼び出して使えるということを目的としている。

cuDNN 7.1.4インストール

NVIDIAの公式ページ(メンバー登録が必要) より、CUDA9.0に対応するcuDNN v7.1.4をダウンロードする。

最新(2019年1月時点でv7.4.1)だとKeras、TensorFlowが動作しない。

以下のファイルをダウンロードしインストールする。

  • cuDNN Runtime Library for Ubuntu16.04 (Deb)
  • cuDNN Developer Library for Ubuntu16.04 (Deb)
  • cuDNN Code Samples and User Guide for Ubuntu16.04 (Deb)
$ sudo dpkg -i libcudnn7_7.1.4.18-1+cuda9.0_amd64.deb
$ sudo dpkg -i libcudnn7-dev_7.1.4.18-1+cuda9.0_amd64.deb
$ sudo dpkg -i libcudnn7-doc_7.1.4.18-1+cuda9.0_amd64.deb

CUDAの動作確認

ここで一回CUDAの動作確認を行う。
サンプルソースをホームディレクトリにコピー、ビルドする。
ビルドには結構時間かかる。

$ cuda-install-samples-9.0.sh ~/
$ cd ~/NVIDIA_CUDA-9.0_Samples/
$ make
$ cd 5_Simulations/particles
$ ./particles
CUDA Particles Simulation Starting…

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

grid: 64 x 64 x 64 = 262144 cells
particles: 16384
GPU Device 0: "GeForce GTX 1050 Ti" with compute capability 6.1

Entering demo mode

このとき、GPUのステータスを見ると、particlesプロセスがGPUを使用していることが分かる。

$ nvidia-smi -l
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130                Driver Version: 384.130                   |
|-------------------------------+----------------------+----------------------+
| 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 GTX 105…  Off  | 00000000:01:00.0 Off |                  N/A |
| N/A   58C    P0    N/A /  N/A |    505MiB /  4038MiB |     96%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1748      G   /usr/lib/xorg/Xorg                           252MiB |
|    0      3188      G   compiz                                       138MiB |
|    0     19042      G   …-token=3C7B2E531279004B95801F65E4E17112     6MiB |
|    0     19760      G   …-token=E56044C2D35446E7240AA9A03B6456AB    51MiB |
|    0     22458    C+G   ./particles                                   53MiB |
+-----------------------------------------------------------------------------+
$ nvidia-smi dmon -s pu -d 5
# gpu   pwr  temp    sm   mem   enc   dec
# Idx     W     C     %     %     %     %
    0     -    51     0     0     0     0
    0     -    49     3     1     0     0
    0     -    54    96    22     0     0
    0     -    54    96    22     0     0

Python(Anaconda)

今回はAnacondaからPython環境を構築する。

Anacondaインストール

Anacondaの公式ページ よりインストーラをダウンロードし実行する。

$ sh ./Anaconda3-2018.12-Linux-x86_64.sh

注意。
最後にAnacondaがインストールした実行ファイルを優先的に使うように環境変数のPATHに含めるかが聞かれる(デフォルトではno)。
[yes]としてPATHに含めるとシステムにインストールされている同コマンドが隠れるので注意する。競合が気になる場合は都度PATHの設定が必要になる。なんか、微妙・・・。やっぱり仮想環境で作ったほうがよさげだけど、ここまできて後には戻れないので・・。

$ which python
/usr/bin/python
$ export PATH=[anacondaをインストールしたパス]/anaconda3/bin:$PATH
$ which python
[anacondaをインストールしたパス]/anaconda3/bin/python

PythonのパスがAnacondaをインストールしたパスで通っていることを確認する。

Python3.6環境

TensorFlowの公式ページ でtensorflow_gpuのPython要件を確認する。
python3.6の環境を作る必要があるので作る。

$ conda install python=3.6
$ conda create -n py3.6 python=3.6
$ source activate py3.6

TensorFlow

tensorflow_gpu-1.12インストール

TensorFlowの公式ページ よりpython3.6に対応したtensorflow_gpuをインストール。

$ source activate py3.6
(py3.6)$ pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.12.0-cp36-cp36m-linux_x86_64.whl

TensorFlowの動作確認

tensorflow_gpuの動作確認。

(py3.6)$ python
Python 3.6.7 |Anaconda, Inc.| (default, Oct 23 2018, 19:16:44)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> session = tf.Session()
2019-01-08 18:52:01.900641: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-01-08 18:52:02.152285: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:964] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-01-08 18:52:02.153736: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties:
name: GeForce GTX 1050 Ti major: 6 minor: 1 memoryClockRate(GHz): 1.62
pciBusID: 0000:01:00.0
totalMemory: 3.94GiB freeMemory: 3.46GiB
2019-01-08 18:52:02.154600: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0
2019-01-08 18:52:11.888053: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-01-08 18:52:11.888145: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988]      0
2019-01-08 18:52:11.888171: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0:   N
2019-01-08 18:52:11.934695: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 3181 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1050 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1)

無事GPU(GeForce GTX 1050 Ti)を認識した。

Keras

Kerasとは

Kerasは,Pythonで書かれた,TensorFlowまたはCNTK,Theano上で実行可能な高水準のニューラルネットワークライブラリです

https://keras.io/ja/

Kerasインストール

$ source activate py3.6
(py3.6)$ pip install --ignore-installed --upgrade keras pydot

pydotは構築したニューラルネットを図示するためにインストールした。

KerasでMNISTディープラーニング

Kerasの動作確認。

手書きの数字0〜9からどの数字かを予測できるニューラルネットを実装したサンプルコードを動かす。データセットにはMNISTを使う。チュートリアルとして広く使われているみたい。
MNISTは、手書きで書かれた数字を画像にしたデータと、その画像に書かれた数字を表すラベルデータから構成されている(手書きの3が描かれた画像データには「3」というラベルが付与される)。
それらのペアが、学習用に60,000個、評価用に10,000個提供される。

ニューラルネットは画像認識などによく使われる畳み込みニューラルネットワーク(CNN)のモデルとする。

サンプルコードをダウンロードし実行してみる。

(py3.6) $ git clone https://github.com/fchollet/keras.git
(py3.6) $ cd keras/examples
(py3.6) $ time python mnist_cnn.py
Using TensorFlow backend.
x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/12
2019-01-08 19:05:41.482605: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-01-08 19:05:41.557805: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:964] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-01-08 19:05:41.558172: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties:
name: GeForce GTX 1050 Ti major: 6 minor: 1 memoryClockRate(GHz): 1.62
pciBusID: 0000:01:00.0
totalMemory: 3.94GiB freeMemory: 3.47GiB
2019-01-08 19:05:41.558206: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0
2019-01-08 19:05:41.763196: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-01-08 19:05:41.763249: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988]      0
2019-01-08 19:05:41.763255: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0:   N
2019-01-08 19:05:41.763391: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 3187 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1050 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1)
60000/60000 [==============================] - 11s 182us/step - loss: 0.2586 - acc: 0.9216 - val_loss: 0.0553 - val_acc: 0.9811
Epoch 2/12
60000/60000 [==============================] - 8s 139us/step - loss: 0.0885 - acc: 0.9726 - val_loss: 0.0417 - val_acc: 0.9856
Epoch 3/12
60000/60000 [==============================] - 8s 135us/step - loss: 0.0637 - acc: 0.9806 - val_loss: 0.0337 - val_acc: 0.9886
Epoch 4/12
60000/60000 [==============================] - 8s 141us/step - loss: 0.0548 - acc: 0.9831 - val_loss: 0.0310 - val_acc: 0.9896
Epoch 5/12
60000/60000 [==============================] - 8s 136us/step - loss: 0.0450 - acc: 0.9860 - val_loss: 0.0300 - val_acc: 0.9905
Epoch 6/12
60000/60000 [==============================] - 8s 134us/step - loss: 0.0422 - acc: 0.9877 - val_loss: 0.0269 - val_acc: 0.9911
Epoch 7/12
60000/60000 [==============================] - 8s 134us/step - loss: 0.0375 - acc: 0.9884 - val_loss: 0.0272 - val_acc: 0.9911
Epoch 8/12
60000/60000 [==============================] - 8s 133us/step - loss: 0.0335 - acc: 0.9897 - val_loss: 0.0252 - val_acc: 0.9918
Epoch 9/12
60000/60000 [==============================] - 8s 136us/step - loss: 0.0317 - acc: 0.9902 - val_loss: 0.0292 - val_acc: 0.9903
Epoch 10/12
60000/60000 [==============================] - 8s 139us/step - loss: 0.0297 - acc: 0.9913 - val_loss: 0.0282 - val_acc: 0.9911
Epoch 11/12
60000/60000 [==============================] - 8s 136us/step - loss: 0.0294 - acc: 0.9911 - val_loss: 0.0259 - val_acc: 0.9918
Epoch 12/12
60000/60000 [==============================] - 8s 136us/step - loss: 0.0251 - acc: 0.9922 - val_loss: 0.0246 - val_acc: 0.9920
Test loss: 0.02455556804120424
Test accuracy: 0.992

real    1m49.833s
user    1m42.279s
sys     0m25.843s

エポック毎に、学習用データの損失値関数によって得られる値(loss)と評価関数によって得られる値(acc)、学習用データの損失値関数によって得られる値(val_loss)と評価関数によって得られる値(val_acc)が出力されている。

今回の場合、初回のエポックで98.1%の認識率となっている。最終的に99.2%まで精度を上げていることが分かる。
気になるのは 「学習にかかった時間」で、おおよそ100秒だった。CPU版での学習時間は10倍の1,000秒だったのでGPUさまさまである。

このときのGPUの状態は、

$ nvidia-smi -l
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130                Driver Version: 384.130                   |
|-------------------------------+----------------------+----------------------+
| 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 GTX 105…  Off  | 00000000:01:00.0 Off |                  N/A |
| N/A   61C    P0    N/A /  N/A |   3891MiB /  4038MiB |     84%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1621      G   /usr/lib/xorg/Xorg                           233MiB |
|    0      3565      G   compiz                                        91MiB |
|    0      5380      G   …-token=13A4D14161A349887D354052495035E6    51MiB |
|    0     15715      C   python                                      3503MiB |
+-----------------------------------------------------------------------------+

だった。ちゃんとGPU使っている。

おしまい。
疲れた。
次は同じ環境を仮想環境(Docker)で作る。

スポンサーリンク