Ubuntu16.04にGeforge GTX 1050tiをインストールし,TensoFlowの処理を高速化してみた

スポンサード リンク

いうまでもなく,行列の積和演算のような処理はGPGPUを使えば高速化できる。 ここでは

  • Ubuntu Server 16.04にGPUのドライバをあてて
  • CUDAとcuDNNをインストールし,
  • さらにnvidia-dockerをインストールしたうえで
  • TensorFlowで適当なベンチマークを実行する

ところまでのやり方を示す。

ついでにnvidia-dockerを挟むか,挟まないかで性能が変わるのかチェックしてみる。

GPUの選定理由

現在できるだけ低コストでかつそれなりのパフォーマンスを得たい場合はGeforce GTX1050tiがベスト。 2017/05/29現在では1.5万円程度で購入できた。 もっと安いGPUはあるが,あまり低性能だと将来でてくるライブラリを動かせなかったりしそうなので避けた。

GPUはすぐに陳腐化するようなのでその都度最新のアーキテクチャで一番コスパのよいGPUを選定するべきだ。

GPUのドライバインストール

# kernelが認識しているか確認
$ dmesg | grep -i nouveau
[1.091896] nouveau 0000:07:00.0: unknown chipset (137000a1)
[1.091899] nouveau: probe of 0000:07:00.0 failed with error -12

# nvidiaのドライバをubuntuのリポジトリからインストール。375はドライバのバージョンを示す。
# 将来的に自動アップデートしたいのでaptを使う。とりあえず最大の数字をインストールしておけばOKかな?
$ sudo apt install nvidia-375

# nvidiaのドライバ適用を確認
$ dmesg | grep -i nvidia
[    5.485548] input: HDA NVidia HDMI/DP,pcm=3 as /devices/pci0000:00/0000:00:03.0/0000:07:00.1/sound/card1/input16
[    5.485641] input: HDA NVidia HDMI/DP,pcm=7 as /devices/pci0000:00/0000:00:03.0/0000:07:00.1/sound/card1/input17
[    5.485729] input: HDA NVidia HDMI/DP,pcm=8 as /devices/pci0000:00/0000:00:03.0/0000:07:00.1/sound/card1/input18

nvidia-dockerのセットアップ

公式のドキュメント NVIDIA/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs に従って作業するだけ。

# Install nvidia-docker and nvidia-docker-plugin
$ sudo apt-get install nvidia-modprobe
$ wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
$ sudo dpkg -i /tmp/nvidia-docker*.deb && rm -f /tmp/nvidia-docker*.deb

# Test nvidia-smi
$ nvidia-docker run --rm nvidia/cuda nvidia-smi
Mon May 29 14:32:48 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 375.51                 Driver Version: 375.51                    |
|-------------------------------+----------------------+----------------------+
| 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  | 0000:07:00.0     Off |                  N/A |
| 54%   45C    P8    35W /  75W |      0MiB /  4038MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

TensorFlowのセットアップ

次のDockerfileをbuildしてrunする。

FROM nvidia/cuda:8.0-cudnn5-runtime

LABEL maintainer "test"

RUN apt-get update
RUN apt-get -y install python3-pip curl
RUN pip3 install keras tensorflow-gpu
$ dokcer build -t tensorflow-bench .
$ docker run -it --rm tensorflow-bench /bin/bash

nvidia-dockerならば不要: CUDAのインストール

CUDA Toolkit Download | NVIDIA Developer より,Ubuntu 16.04用のリポジトリのdebファイルを取得し,cudaパッケージをインストールする。パッケージサイズが大きいため,ダウンロードに1時間以上かかるので退屈。こんなところにもnvidia-dockerを使う恩恵があったとは。

$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
$ sudo apt update
$ sudo apt install cuda libcupti-dev

nvidia-dockerならば不要: cuDNNのインストール

cuDNN Download | NVIDIA Developer でユーザ登録をした上で,インストールしたcudaにあったバージョンのcuDNNをダウンロードし,インストールし再起動する。

$ sudo tar xvf cudnn-8.0-linux-x64-v5.1.tgz -C /usr/local
$ sudo reboot

ベンチマーク CPU vs GPU

コンテナ内部・外部で次のコマンドを実行する。

$ echo 'from keras.datasets import mnist \n mnist.load_data()' > mnist_loda_data.py
$ python mnist_load_data.py
$ curl -O https://raw.githubusercontent.com/fchollet/keras/master/examples/mnist_cnn.py
$ echo 'K.clear_session()' >> mnist_cnn.py
$ time python mnist_cnn.py

結果は以下の通り。ただし,mnist_cnn.pyの初回実行にはGPUデバイス作成の時間が含まれる。 以下には二回目の所要時間を示した。

                                      epoc                total
Core i5 750     on baremetal    :     171s              2063.73s
GTX1050ti (4GB) on baremetal    :      10s               128.15s
GTX1050ti (4GB) on nvidia-docker:      10s               128.52s

GPUなら1エポックあたり10秒で終わり,CPUよりも16~17倍高速という結果になった。 また,Dockerによるオーバヘッドは1秒以下であり,ほとんど無視できる程度。

17倍の差が出たが,Core i5 750は2009年発売のCPUだから性能がでなくてもしかたない。 あとSSE4.2を有効化してTensorFlowを再コンパイルしたらもう少し早くなるはず。 Dockerで動かす場合も既存イメージを使わずに,Dockerfile内部でコンパイルするようにすると高速化できるだろう。

Comments !

social