TensorFlowをGPUで高速に処理させたいと思っていましたが、実際にGPUを買うより手軽にAWS(Amazon Web Services)で試せるのでやってみました。


(0)GPU搭載インスタンスの作成
(1)インストール前の準備
(2)GPUのドライバをインストールする
(3)GPU向け開発環境(CUDA)をインストールする
(4)CUDAのニューラルネットワークライブラリ(cuDNN)をインストールする
(5)TensorFlowをインストールする


(0)GPU搭載インスタンスの作成

最終的にはサーバ上で動作させたいので、Redhat/CentOS系のAmazon Linuxを選択。
AMI(Amazon Machine Image)の中には全て導入済みイメージからの構築も可能でしたが、CentOS系でGPUでTensorFlowで、というとマーケットプレイスで追加料金が必要なものしかなかったので、自分で諸々インストールです。

リージョンは価格の面と種類の充実面からバージニア北部。
ややSSHでのレスポンスが遅く感じますが、許容範囲です。

インスタンスはg2.2xlarge。GPU搭載マシンの中では最も安いインスタンスです。
これを選択してすぐ作ることも可能ですが、ステップ4のストレージまで進みます。
デフォルトでは8Gのディスク容量なので、各種インストーラや一時領域で不足しかねません。
節約するなら20Gで大丈夫ですが、余裕をもたせるなら30Gあれば安心です。

セキュリティなど他の設定は割愛します。

最後にキーペアの作成で、新規であれば秘密鍵がダウンロードされます。
権限を600にして、目立たないかつ無くさない場所に保存してください。

インスタンスが出来上がったら、Public DNSという項目にec2-*****amazonaws.comとかアドレスらしきものが出るかと思うので、
早速SSHします。ログインIDはec2-userで、パスワードは不要です。




(1)インストール前の準備

時期の問題でURLなど異なる部分がありましたが、ドライバのインストールまでは以下のページが参考になりました。
https://blog.animereview.jp/gpu-aws-1tflops/

1−1 rootになる
 毎回必要に応じてsudoを付けるのは面倒だし、構築段階なのでrootになって作業を進めます。
 sudo -i または sudo su -
 手順の中で再起動もありますが、再ログイン時はrootになった前提で手順を記載します。

1−2 yumの準備
 yum update -y で一通り最新にします。

1−3 GPUの存在を確認する
 これはおまけですが、作ったインスタンスにGPUがついているか確認したい場合、以下のコマンドです。
lspci | grep -i nvidia


(2)GPUのドライバをインストールする


このあたりはAmazonのドキュメントが参考になりました。


2−1 別のドライバを停止
vim /etc/grub.conf
kernelの行の末尾に半角空白と rdblacklist=nouveau nouveau.modeset=0 を追記。2つパラメータを書きましたが、片方だけでも大丈夫かもしれません。
書き換えたらrebootコマンドで再起動。

2−2 最適のドライバをダウンロードする
ドライバのダウンロードページは以下。
http://www.nvidia.com/Download/index.aspx?lang=en-us
製品の種類などの情報を入れないとダウンロードできないのですが、製品の情報はAmazon内のページのG2インスタンスの部分を参照してください。

ダウンロードできるURLが確認できたら、URLをコピーして、サーバ側(インスタンス上)でwgetする方が楽かと思います。

2−3 gccコンパイラとkernel-develパッケージのインストール
yum install -y gcc kernel-devel-`uname -r`

2−4 ドライバのインストール
chmod 755 (ダウンロードしたrunファイル)
bash (ダウンロードしたrunファイル)
 
 エラーなく最後まで行けたらインストール完了です。
 私の場合、ここで最初のエラーとなりましたが、ドライバのバージョンが正しくないものでした。

 ここまで上手くいったら一旦再起動します。

(3)GPU向け開発環境(CUDA)をインストールする


 この文章の作成段階(2017/02/17)時点では、TensorFlowはCUDA 8.0が必要とされるので、8.0のインストールを行います。
 どのバージョンが必要かはTensorFlowの公式ページを参照してください。
 CentOS向けではないですが、このページのCUDAとcuDNNのインストール部分を活用させていただきました。

3−1 ダウンロード
 ダウンロードページから適切なCUDA toolkitを見つけます。
  
 Amazon LinuxなのでCentOSの最新版で、種類はrunファイルとしました。
 これもURLが特定できたら、サーバ側でwgetが効率的です。

3−2 インストール
chmod 755 (ダウンロードしたrunファイル)
bash (ダウンロードしたrunファイル)-extract=`pwd`/nvidia_installers
 オプションなしで実行して失敗したので要注意です。
modprobe nvidia
cd nvidia_installers/
bash cuda-linux64-rel-8.x.xx-xxxxxxxx.run
 規約を読まされたり対話型でいろいろ聞かれますが、規約をqで止めて同意のacceptを打つ以外エンターキーだけでよいかと思います。

3−3 bashrcへの追記
vim ~/.bashrc
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
. ~/.bashrc


(4)CUDAのニューラルネットワークライブラリ(cuDNN)をインストールする


この文章の作成段階(2017/02/17)時点では、TensorFlowはcuDNN 5.1が必要とされるので、5.1のインストールを行います。

4−1 NVIDIAのアカウント作成
 https://developer.nvidia.com/cudnn からDownloadボタンを押すとアカウント認証が求められます。
 アカウントを持ってない場合は作って、ログインしてください。

4−2 ダウンロード
 ログインできたらダウンロードページでcuDNN v5.1 Library for Linuxをダウンロードします。
 これについてはサーバ上からのwgetができなかったので、落としてからサーバに上げました。

4−3 インストール
 展開後のファイルを/usr/local/cuda以下にコピーします。
tar zxfv (ダウンロードしたtgzファイル)
cp -p cuda/lib64/* /usr/local/cuda/lib64/
cp -p cuda/include/cudnn.h /usr/local/cuda/include/


(5)TensorFlowをインストールする


5−1 pipの最新化
pip install --upgrade pip
その後なぜかpipコマンドが使えなくなったので、PATHの追加をしました。
vim ~/.bashrc
export PATH="$PATH:/usr/local/bin"

5−2 インストール
pip install tensorflow
pip install tensorflow-gpu

 これが上手く通っても油断してはなりません。
 pythonを起動して、対話モードで試してみます。

import tensorflow as tf
sess = tf.Session()

 

この2つのコマンドが問題なく終了すれば大丈夫かと思います。
 多少メッセージが出るくらいなら問題ありませんが、ErrorとかAbortedとか言われたら問題ありです。
 私の場合は、tf.Session()を実行しようとすると終了してしまう事象がありましたが、NVIDIAドライバのバージョンを変更して解消されました。


5−3 一般ユーザでの動作確認

 rootで全部セットアップしましたが、これ以降の開発は一般ユーザでやるかもしれないのでそれについても言及します。
 /root/.bashrcに書いた内容は一般ユーザは読み込めないので、/home/ec2-user/.bashrcなど、ユーザのbashrc内にも今回の手順で追記した内容を入れておく必要があります。

vim ~/.bashrc
# 追記内容
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
export PATH="$PATH:/usr/local/bin"
. ~/.bashrc







トラブル例


・tensorflow-gpuのインストールが成功したが、importできない
ImportError: libcudart.so.8.0: cannot open shared object file: No such file or directory

→ .bashrcにPATHなどの記載して再読込することで解消しました。

・tensorflow-gpuのインストールが成功し、importもできるがtf.Session()を呼び出すと終了してしまう

F tensorflow/stream_executor/cuda/cuda_driver.cc:94] Check failed: s.ok() could not find cuDevicePrimaryCtxSetFlags in libcuda DSO; dlerror: /usr/lib64/libcuda.so.1: undefined symbol: cuDevicePrimaryCtxSetFlags
Aborted

→ nvidiaのドライバがちょっと古いものでした。以下のURLでドライバを探し直して入れ直したら解決しました。
http://www.nvidia.com/Download/index.aspx?lang=en-us