Help us understand the problem. What is going on with this article?

AWSのGPUインスタンスでTensorFlowを動かす

More than 3 years have passed since last update.

以下の環境で試したので、インストール時の作業記録を残しておきます。

なお、TensoFlowはWindowsで動作しません。TensorFlowが採用しているGoogle製のビルドツールBazelが、LinuxとMacのみの対応です。手元にMacかLinuxマシンが無ければ、AWSでUbuntu環境を用意するのが簡単だと思います。

Mac OS X

CPUのみで動作するパッケージをインストールしました。最もお手軽です。
スペック
- MacBook Pro (Retina, 15-inch, Mid 2014)
- CPU: 2.2 GHz Intel Core i7
- メモリ: 16 GB 1600 MHz DDR3

公式ドキュメント通りpipでパッケージを導入。

$ sudo easy_install --upgrade six
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.6.0-py2-none-any.whl

テストとして、CIFAR-10 datasetを学習してみます。

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

実行すると、データセットがダウンロードされ学習が開始されます。
途中の経過がターミナルに出力されるので、学習が安定した100stepごろを見ると、1つのバッチ学習に0.540秒かかりました。

2015-12-31 15:00:08.397460: step 100, loss = 4.49 (237.0 examples/sec; 0.540 sec/batch)

Amazon web service(AWS)

AWS EC2のG2インスタンスを使用して、環境構築します。

注意: TensorFlowはCuda compute capability 3.5以下の場合は特別な対応が必要です。
Cuda compute capabilityはGPUのアーキテクチャのようなもので、GPUによって決まっています。AWS G2インスタンスに搭載されているGRID K520はCuda compute capability3.0なので、そのままではTensorFlowのGPU計算を実行できません。ここで3.0への対応が議論されています。

料金の安かったオレゴン(米国)のインスタンスを使用しました。
以下の料金や情報は2015年12月30日時点の情報です。

モデル GPU vCPU メモリ(GiB) SSDストレージ(GB) 料金 - オレゴン(米国)
g2.2xlarge GRID K520 x 1 8 15 1 x 60 $0.65 /1 時間
g2.8xlarge GRID K520 x 4 32 60 2 x 120 $2.6 /1 時間

インストール

Linuxインスタンスへの接続はここを参照。
こちらを参考に進めました。
まずは必要なソフトウェアをインストール。

$ sudo apt-get update
$ sudo apt-get upgrade -y # “install package maintainers version”を選択
$ sudo apt-get install -y build-essential python-pip python-dev git python-numpy swig python-dev default-jdk zip zlib1g-dev ipython

NVIDIAドライバとの衝突をさけるため、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
# Install latest Linux headers
$ sudo apt-get install -y linux-source linux-headers-`uname -r`

次に、CUDAとcuDNNをインストールします。公式ドキュメントのここも参考に作業を進めます。なお、インストールするバージョンは必ず下記のものである必要があります。
- CUDA Toolkit 7.0
- cuDNN Toolkit 6.5

まずは、CUDAをインストール。

# Install CUDA 7.0
$ wget http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.28_linux.run
chmod +x cuda_7.0.28_linux.run
$ ./cuda_7.0.28_linux.run -extract=`pwd`/nvidia_installers
$ cd nvidia_installers
$ sudo ./NVIDIA-Linux-x86_64-346.46.run
$ sudo modprobe nvidia
$ sudo ./cuda-linux64-rel-7.0.28-19326674.run

次にcuDNNをインストールします。cuDNNはDeep neural networkの学習をGPUで高速化することに特化したライブラリです。この記事が参考になります。cuDNNを入手するには、NVIDIAのデベロッパーアカウントへの登録が必要です。wgetで入手できないので、一度ローカル環境でここからダウンロードします。
ダウンロードしたファイルをローカルからSCPで転送します。
以下はLinuxからの転送例。xxxxx.amazonaws.comはAMIのパブリックDNS。

# ローカルで作業
# SCPでAMIへ転送
$ scp -i /path/my-key-pair.pem cudnn-6.5-linux-x64-v2.tgz ubuntu@xxxxx.amazonaws.com:~

転送が終わったら解凍し、cudaのディレクトリにコピーする。

# AMIで作業
$ cd
$ tar -xzf cudnn-6.5-linux-x64-v2.tgz
$ sudo cp cudnn-6.5-linux-x64-v2/libcudnn* /usr/local/cuda/lib64
$ sudo cp cudnn-6.5-linux-x64-v2/cudnn.h /usr/local/cuda/include/

パスを通します。

$ vi .bashrc # viやnanoなどで以下の2行を.bashrcに追加
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
$ source .bashrc # .bashrcの設定を反映

AMIで利用出来るディスク領域はあまり大きくありません。この後、Bazelでビルドする際や、学習用データをダウンロードする場合に、十分に大きなディスク容量が必要になります。
インスタンス作成時に割り当てられるエフェメラルストレージ(/mnt/以下)には十分なディスク領域があるので、シンボリックリンクを作っておきます。
なお、もう使用しないnvidia_installersやcudnn-6.5-linux-x64-v2.tgzは削除しても構いません。

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             7687184      12   7687172   1% /dev
tmpfs            1540096     344   1539752   1% /run
/dev/xvda1       8115168 5874536   1805356  77% /
none                   4       0         4   0% /sys/fs/cgroup
none                5120       0      5120   0% /run/lock
none             7700472       0   7700472   0% /run/shm
none              102400       0    102400   0% /run/user
/dev/xvdb       66946696   53144  63486192   1% /mnt
# /mnt/tmp/へのシンボリックリンクを作成
$ sudo mkdir /mnt/tmp
$ sudo chmod 777 /mnt/tmp
$ sudo rm -rf /tmp
$ sudo ln -s /mnt/tmp /tmp

注意: インスタンス停止時に、/mnt/以下の内容は全て削除されます。AMIイメージに残す必要があるデータは/tmp/に保存しないでください。
後述する公開AMIにはインスタンスの作成時やリスタート時に、エフェメラルストレージにtmpを作成するシェルスクリプト(create_tmp_on_ephemeral_storage.sh)を用意しました。

ビルドツールであるBazelをインストールします。

$ cd /mnt/tmp
$ git clone https://github.com/bazelbuild/bazel.git
$ cd bazel
$ git checkout tags/0.1.0
$ ./compile.sh
$ sudo cp output/bazel /usr/bin

次にTensorFlowをインストールします。
"./configure"は、ここで議論されている通り、"TF_UNOFFICIAL_SETTING=1 ./configure"のようにオプションをつけて実行します。これにより、Cuda compute capability 3.0にも対応可能なアンオフィシャル設定になります。

$ cd /mnt/tmp
$ git clone --recurse-submodules https://github.com/tensorflow/tensorflow
$ cd tensorflow
$ TF_UNOFFICIAL_SETTING=1 ./configure

コンフィグレーション中に、以下のような質問があります。デフォルトでは、Cuda compute capability 3.5と5.2のみの対応ですので、以下のように3.0を追加します。

Please specify a list of comma-separated Cuda compute capabilities you want to build with.
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
Please note that each additional compute capability significantly increases your build time and binary size.
[Default is: "3.5,5.2"]: 3.0,3.5,5.2   #3.0を追加

TensorFlowをビルド。

$ bazel build -c opt --config=cuda //tensorflow/cc:tutorials_example_trainer

次にTensorFlowのPythonパッケージをビルド、インストールします。
"/tmp/tensorflow_pkg/tensorflow-0.6.0-cp27-none-linux_x86_64.whl"の部分は、実際に生成されたバージョンのファイル名に合わせてください。

$ bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
$ sudo pip install /tmp/tensorflow_pkg/tensorflow-0.6.0-cp27-none-linux_x86_64.whl

これで、インストール完了です。

テスト

まずはg2.2xlargeインスタンスで試します。

$ cd tensorflow/models/image/cifar10/
$ python cifar10_multi_gpu_train.py

結果は以下のとおり。

2016-01-01 09:08:55.345446: step 100, loss = 4.49 (285.9 examples/sec; 0.448 sec/batch)

さらに、g2.8xlargeで試します。
以下のように、cifar10_multi_gpu_train.pyの63行目あたりでGPUの数を4に設定します。これを行わない場合、見かけはGPUを4つ使用しますが、並列化が正常に行われないためか高速化されません。

tf.app.flags.DEFINE_integer('num_gpus', 4,
                            """How many GPUs to use.""")

実行結果。かなり高速されました。

2016-01-01 09:33:24.481037: step 100, loss = 4.49 (718.2 examples/sec; 0.178 sec/batch)

コミュニティAMI

AWS オレゴン(米国)のコミュニティAMIに今回作成したイメージを公開しています。
ubuntu14.04_tensorflow0.6.0_gpu - ami-69475f08
インスタンスの作成後、create_tmp_on_ephemeral_storage.shを実行して、エフェメラルストレージ上の/tmpディレクトリを作成してください。

$ ./create_tmp_on_ephemeral_storage.sh
h860a
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away