AWS の GPU インスタンスで TensorFlow を動かしてみた(2016.07)
前回は TensorFlow のチュートリアルを触ってみたわけですが、当然のごとく手元のノートPCではさほど速度を出すことができません。DNNをあつかう宿命としてGPU上で動作させることは避けては通れないものです。
というわけで、GPU で TensorFlow を動かすために AWS のインスタンスをたてようと試みたわけですが、Chainer の時のようにさくっとは行かず。。。
どうやら依存している CUDA のバージョンの関係で、AWS の NVIDIA インスタンスでは動作させることができないようです。じゃあ適当なインスタンスに CUDA 入れればいいだけじゃんと油断したのが裏目に出てしまい、色々と手こずってしまったので、個人的な備忘録としてGPU インスタンスで TensorFlow を動作させるまでの手順を残しておきたいと思います。
TensorFlow ってどういうことができるのって方は、まずは下記の記事をお読みの上で以降に進まれることをおすすめします。
前提
今回利用したもののバージョン等は下記のようになります。
- AWSインスタンス:g2.2xlarge
- AMI :Ubuntu Server 14.04 LTS (HVM), SSD Volume Type - ami-2d39803a
- TensorFlow:r0.9
- python:3.4.3
- CUDA:7.5
- cuDNN:v4
cuDNN をインストールするには、NVIDIA のサイトから利用申請をしておく必要がありますので、処理を進める前に早めに完了しておくことをおすすめします。 以降は、TensorFlow のDownload and Setup、Optional: 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