終末 A.I.

データいじりや機械学習するエンジニアのブログ

AWS の GPU インスタンスで TensorFlow を動かしてみた(2016.07)

前回は TensorFlow のチュートリアルを触ってみたわけですが、当然のごとく手元のノートPCではさほど速度を出すことができません。DNNをあつかう宿命としてGPU上で動作させることは避けては通れないものです。

というわけで、GPU で TensorFlow を動かすために AWSインスタンスをたてようと試みたわけですが、Chainer の時のようにさくっとは行かず。。。

どうやら依存している CUDA のバージョンの関係で、AWSNVIDIA インスタンスでは動作させることができないようです。じゃあ適当なインスタンスに CUDA 入れればいいだけじゃんと油断したのが裏目に出てしまい、色々と手こずってしまったので、個人的な備忘録としてGPU インスタンスで TensorFlow を動作させるまでの手順を残しておきたいと思います。

TensorFlow ってどういうことができるのって方は、まずは下記の記事をお読みの上で以降に進まれることをおすすめします。

前提

今回利用したもののバージョン等は下記のようになります。

cuDNN をインストールするには、NVIDIA のサイトから利用申請をしておく必要がありますので、処理を進める前に早めに完了しておくことをおすすめします。 以降は、TensorFlow のDownload and SetupOptional: Install CUDA (GPUs on Linux) を元に進めていきますので、もしバージョンが変わって必要な処理が変わっている場合は、リンク先の情報に従って処理を行うことをおすすめします。

前準備

処理に必要なもののインストールおよびモジュールのアップデートを行います。Python 3.4 の場合は最低限必要な下記をインストールしておいて貰えば十分です。

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install python3-dev python3-pip git -y

CUDA のインストール

最初で最後のハマりポイントと言っても過言ではありません。ここで、特に何も考えずに言われる通りに CUDA をインストールしてしまうとえらい目に合います。Nouveau をブラックリストに入れ、CUDA と一緒にインストールされる NVIDIA ドライバと衝突しないようにしてやる必要があります。 Nouveau を無効にするにあたって下記の記事を参考にさせていただきました。

Nouveau の無効化は上記の記事のものをそのまま利用して、以下の処理を実行することで行うことができます。

echo -e "blacklist nouveau\nblacklist lbm-nouveau\noptions nouveau modeset=0\nalias nouveau off\nalias lbm-nouveau off\n" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf
sudo update-initramfs -u
sudo reboot

sudo apt-get install -y linux-image-extra-virtual
sudo reboot

上記で Nouveau を無効化後、下記を実行することで、Ubuntu x64 環境向けの CUDA 7.5 をインストールすることができます。ビルドに必要となる Linux ソースのインストール以外は、CUDA のダウンロードサイトに記載されている内容をそのまま実行しているだけですので、手順が変更されている場合は、そちらに記載の方法をまず実行することをおすすめします。

sudo apt-get install -y linux-source linux-headers-`uname -r`

wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_7.5-18_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1404_7.5-18_amd64.deb
sudo apt-get update
sudo apt-get install cuda -y

※ 2016/10/8 追記 なぜかネットワークインストーラでは最新のCUDAが入ってしまい、TensorFlow がうまく動かない事があるようです。 少々サイズが必要になりますがローカルインストーラをダウンロードしてきてCUDAをインストールすることをおすすめします。

インストール完了後、nvidia-smiコマンドを実行し下記のように出力されれば CUDA のインストールは成功です。

nvidia-smi

+------------------------------------------------------+                       
| NVIDIA-SMI 352.93     Driver Version: 352.93         |                       
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GRID K520           Off  | 0000:00:03.0     Off |                  N/A |
| N/A   38C    P0    38W / 125W |     11MiB /  4095MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

cuDNN のインストール

cuDNN のインストールは、CUDA のインストールパスに cuDNN 用のファイルを配置することで実現できます。あらかじめ cuDNN のページから Linux 向けの cuDNN v4 をローカルにダウンロード後、scp でインスタンスのホームにファイルを配置しておいてください。あとは、Optional: Install CUDA (GPUs on Linux)を参考にファイルを配置すればOKです。

tar xvf cudnn-7.0-linux-x64-v4.0-prod.tar
sudo cp cuda/include/cudnn.h /usr/local/include
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/

※ 2016/10/8 追記 TensorFlow のバージョン 0.10.0 以降では、cuDNN の ver.5.x が推奨となっていますので、そちらをインストールすることをおすすめします。

TensorFlow のインストール

最後は、TensorFlow をインストールして完了です。Download and Setupを参考に pip で Python3.4 向けにインストールする処理は下記のとおりです。他のバージョンや環境でインストールする場合は、その場合の処理が記載されていると思いますので、そちらを参考に行ってください。

export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl
sudo pip3 install --upgrade $TF_BINARY_URL

インストール完了後、~/.bash_profile などに下記の(Optional, Linux) Enable GPU Support に記載の通りに、GPUを利用するためのおまじないを記載して実行すれば完了です。

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda

動作確認

これでインストールは完了です。ちゃんとインストールされているかをTest the TensorFlow installationにそって確認してみましょう。

まずは、GPU を使用する設定がちゃんと動作するかを確認します。下記のコマンドを実行して、CUDA をロードしているようなログが出れば成功です。

python3 -c 'import os; import inspect; import tensorflow; print(os.path.dirname(inspect.getfile(tensorflow)))'

I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally
/usr/local/lib/python3.4/dist-packages/tensorflow

続いて処理をちゃんと行えているかを見てみましょう。チュートリアルにそって MNIST の CNN モデルをロードする処理で確認します。下記のコマンドを実行後、Found device 0 with properties:のようなログが出ていれば GPU をロードして処理が行われています。

python3 -m tensorflow.models.image.mnist.convolutional 

I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting data/train-images-idx3-ubyte.gz
Extracting data/train-labels-idx1-ubyte.gz
Extracting data/t10k-images-idx3-ubyte.gz
Extracting data/t10k-labels-idx1-ubyte.gz
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:924] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties: 
name: GRID K520
major: 3 minor: 0 memoryClockRate (GHz) 0.797
pciBusID 0000:00:03.0
Total memory: 4.00GiB
Free memory: 3.95GiB
I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:806] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0)
Initialized!
Step 0 (epoch 0.00), 9.4 ms
Minibatch loss: 12.054, learning rate: 0.010000
Minibatch error: 90.6%
Validation error: 84.6%

最後に、チュートリアル外ですがちゃんと速度がでるようになったかを確認しましょう。今回は、TendorFlow のコードに付属している CIFA のサンプルコードで確認を行っています。下記のように学習を実行すると、minibatch 単位で学習過程をログに流してくれます。g2.2xlarge ではだいたいbatch あたり 0.2 sec で学習を進めてくれるようになります。

git clone https://github.com/tensorflow/tensorflow
cd tensorflow/tensorflow/models/image/cifar10/
python3 cifar10_train.py