Theano による Amazon Web Service (AWS) 上での GPU 計算

本文書ではAWSのGPU計算サーバ(GPUインスタンス)上でTheanoを使用する方法を説明します. Theano入門 で紹介したプログラムをCPUとGPUで実行し, その計算速度を比較します.

(2014年7月16日 株式会社知能情報システム エンジニア 吉岡琢)

はじめに

本文書では, GPU上での数値計算をGPU計算と呼ぶこととします. GPU計算の科学技術計算への応用は一般的になりつつあります. しかし, 個人で利用するためにはまだ敷居が高いように思われます. その理由の一つがハードウェアの問題です. 個人で使用するマシンは通常GPUを一つしか持たないため, GPUを計算のために占有させると, 画面表示に問題が起こる場合があります. そこで, 本文書ではクラウドサービスの一つであるAmazon Web Service (AWS)を利用してGPU計算を行う具体的な手順を説明します.

AWSは様々なサービスを提供します. その中の一つであるElastic Compute Cloud (EC2)はデータストレージサーバ, ウェブサーバといった各種の専用サーバを提供します. EC2が提供するサーバの一つに, 最新のGPUを載せたものがあります. これはゲームやグラフィック処理などGPU本来の目的に使用されるのですが, GPU計算サーバとして使用する事もできます.

本文書の説明で用いるGPU計算サーバのCPUとGPUは以下の通りです:

  • CPU: Intel Xeon E5-2670 (Sandy Bridge) 2.6GHz 166.4GFlops
  • GPU: NVIDIA GRID GK104 1,536 cores 4GB 2,289 GFlops

単純な演算性能では10倍以上の差があります.

EC2上のGPU計算サーバを使ってTheanoを実行するために覚える必要があるのは, AWSそのものの利用方法だけです. これはAWSとTheanoの以下のような特徴のためです

  • EC2が提供するGPUサーバにはGPU計算のためのライブラリであるCUDAが(本稿執筆時点では)インストール済みであり, 面倒な設定が不要です.
  • サーバへの接続はSSHで行われ, xtermなどのターミナル上で作業ができます.
  • Theanoは設定を少し変えるだけでCPU計算とGPU計算を切り替えることができます. ソースコードの修正は不要です.
  • GPU利用時にはCUDAを用いて計算が実行されますが, CUDAのコード生成とコンパイルはTheanoが自動的に行います.

AWS上でのGPUの利用を検討されている方にとって, 本文書がその足掛かりになれば幸いです.

AWS (EC2)ではサーバの使用時間によって課金されます. 金額はサーバの種類によって異なります (参考: 料金表). 本文書の例で用いるサーバの使用料金は1時間あたり1ドル未満でした. 本文書で紹介する手順をスムーズに進めれば, 1時間以内で作業が終わります. もし本文書の作業手順を実際に試される場合, 事前に説明を通読することをお勧めします.

作業手順の概要

以下で作業手順の概要を説明します. 同時にAWSで用いられるいくつかの用語(太字)を説明します.

  1. AWSアカウント の作成: AWSにログインするためのアカウントを作成します. AWSアカウントの作成には クレジットカード電話 が必要です.
  2. リージョン の指定: リージョンとは, サーバの実体が置いてある場所を指します. リージョンによってサポートされるハードウェア(インスタンス, 後述)が変わる場合(例えば新しいインスタンスが限られたリージョンから順に配置される)があるようです. また, リージョンによってインスタンスの料金が異なりますのでご注意下さい.
  3. GPU計算サーバの起動: AWS上のサーバの起動には, OSとハードウェアを指定する必要があります. EC2では, OSのイメージを Amazon Machine Image (AMI), ハードウェアを インスタンス と呼びます. インスタンスの種類は”m3.medium”や”r3.large”などといった名前で区別されます. 今回使用するのは”g2.2xlarge”というインスタンスです. GPU計算サーバ起動時に認証用の公開暗号鍵が発行されます. これをローカルに保存します.
  4. GPU計算サーバへのログイン: ローカルに保存された認証用のキーを指定して, ローカルのターミナルを用いてSSHでサーバへログインします.
  5. グラフィックカード, ドライバ, CUDAコンパイラの確認: いくつかのコマンドでこれらを確認します.
  6. ソフトウェアのインストール: GPU計算サーバ起動直後から利用可能(インストール済み)のPythonのライブラリは限られています. そこでAnacondaをインストールします. これによって, Pythonの実行環境と, Theanoの実行に必要な全てのモジュールがインストールされます.
  7. Theanoを用いたプログラムの実行: .theanorcファイルを編集してGPUを使うように設定してから, Theanoを用いたプログラムを実行します.
  8. 結果ファイルのローカルへのコピー: プログラムにより作成される結果ファイルを, scpコマンドを用いてローカルにコピーします.
  9. GPU計算サーバの停止: 上記の手順の終了後, GPU計算サーバを停止します. これによって不必要に課金されないようにします.
  10. 結果の確認: 結果ファイルに含まれる実行時間の情報を表示します.
  11. 料金の確認: 料金の明細を確認します.

GPU計算サーバを起動してから停止するまで(上記の手順5.から9.まで)の間は利用時間に応じて料金が発生するのでご注意ください.

各作業の説明

ここでは各作業を具体的に説明します.

1. AWSアカウントの作成

クレジットカードと電話を準備して, ここの説明 の通りに作業を行います. 「AWSサポートプランの選択」ではどのプランを選択しても構いません. ここではBasicを選択します.

2. リージョンの指定

  1. 作成したアカウントを用いてAWSにログインします. ログインするとAWSマネージメントコンソール(画像を参照)が表示されます.
_images/step2-1.png
  1. リンク (下図の赤で囲った部分) をクリックしてEC2ダッシュボードに移動します.
_images/step2-2.png
  1. EC2ダッシュボードの画面は次の通りです.
_images/step2-3.png
  1. リージョンを選択します. 前述した通り, リージョンによってインスタンスの料金が変わります. 本稿執筆時点(2014年7月11日)でTokyoリージョンでのg2.2xlargeインスタンス(後述)の料金は0.9$/hr(+消費税)だったのに対して, Virgeniaリージョンでは0.65$/hrと安価です. Tokyoリージョンの方がネットワークのラグは短いのですが, 今回のようにバッチ的に処理を行う場合はラグが多少長くても問題ないと思います.
_images/step2-4.png

3. GPU計算サーバの起動

  1. インスタンス起動ボタンをクリックします.
_images/step3-1.png
  1. 最初にAMI選択画面が表れます. AMIとして, NVIDIAのGRIDというGPUのドライバやCUDAがインストール済みである”Amazon Linux AMI with NVIDIA GRID GPU Driver”を選びます. このAMIは, この画面のリストの中にはありません.
_images/step3-2.png
  1. 目的とするAMIは, AMI Market placeにあります. リンクをクリックして移動します.
_images/step3-3.png
  1. “grid”というキーワードでAMIを検索します.
_images/step3-4.png
  1. “Amazon Linux AMI with NVIDIA GRID GPU Driver”が見つかります. “Select”ボタンを押してこのAMIを選択します.
_images/step3-5.png
  1. インスタンス選択画面が表示されます. AMIとして”Amazon Linux AMI with NVIDIA GRID GPU Driver”を選択した時点で, インスタンスとして自動的にg2.2xlargeが選択されます. 起動ボタンをクリックします.
_images/step3-6.png
  1. 警告画面が表示されます. このサーバのIPアドレスがどこからでも参照可能である事と, 選択したインスタンスに利用料金が発生する事を確認します.
_images/step3-7.png
  1. 暗号鍵の使用を促す画面が表れます.
_images/step3-8.png
  1. “Create a new key pair”を選びます. これは使い捨ての公開鍵暗号を使う事を意味します. “Key pair name”を入力して秘密鍵に名前をつけ, “Download Key Pair”を押して秘密鍵ファイル(.pem)をダウンロードします. ダウンロードした秘密鍵ファイルは他の人に見られないように注意します. ダウンロードするときにファイルの拡張子が.txtとなった場合は.pemと修正します. 更に, chmod 400 (key-pair-name).pemとしてファイルの実行権を修正します.
_images/step3-9.png
  1. サーバ起動の確認画面が表れます. この時点から料金が発生します.
_images/step3-10.png

4. GPU計算サーバへのログイン

  1. 3-10の画面右下にある, 起動中のインスタンス一覧へのボタンを押します.
_images/step4-1.png
  1. 起動中のインスタンス一覧が表示されます. 現在起動中なのは一つのg2.2xlargeインスタンスだけです.
_images/step4-2.png
  1. サーバへの接続ボタンを押します.
_images/step4-3.png
  1. sshによる接続コマンドの例が表示されます. この例では秘密鍵のファイル名だけが書かれていますが, カレントディレクトリにファイルが無い場合, パスを適切に指定する必要があります. また, ユーザ名はここで表示されているrootではなく, ec2-userとします.
_images/step4-4.png
  1. ログイン直後の画面の例は次の通りです.
_images/step4-5.png

この先, 手順5.から8.まではGPU計算サーバに接続されたターミナル上で作業を行います.

5. CUDAコンパイラのパスの確認と設定

  1. “nvcc -V”と入力し, CUDAコンパイラが使用可能である事を確認します:
[ec2-user@ip-172-31-5-86 ~]$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2013 NVIDIA Corporation
Built on Wed_Jul_17_18:36:13_PDT_2013
Cuda compilation tools, release 5.5, V5.5.0
  1. “which nvcc”と入力し, CUDAコンパイラのパスを確認します:
[ec2-user@ip-172-31-5-86 ~]$ which nvcc
/opt/nvidia/cuda/bin/nvcc
  1. 環境変数PATHとLD_LIBRARY_PATHを次のように設定します:
echo "export PATH=/opt/nvidia/cuda/bin:\$PATH" >> .bashrc
echo "export LD_LIBRARY_PATH=/opt/nvidia/cuda/lib64:\$LD_LIBRARY_PATH" >> .bashrc

6. Anaconda(およびTheano)のインストール

  1. “wget”でLinux版のAnacondaをダウンロードします:
[ec2-user@ip-172-31-5-86 ~]$ wget http://09c8d0b2229f813c1b93-c95ac804525aac4b6dba79b00b39d1d3.r79.cf1.rackcdn.com/Anaconda-2.0.1-Linux-x86_64.sh
--2014-07-10 13:18:09--  http://09c8d0b2229f813c1b93-c95ac804525aac4b6dba79b00b39d1d3.r79.cf1.rackcdn.com/Anaconda-2.0.1-Linux-x86_64.sh
09c8d0b2229f813c1b93-c95ac804525aac4b6dba79b00b39d1d3.r79.cf1.rackcdn.com (09c8d0b2229f813c1b93-c95ac804525aac4b6dba79b00b39d1d3.r79.cf1.rackcdn.com) をDNSに問いあわせています... 23.61.249.40, 23.61.249.64, 2600:140e:1::17c9:660a, ...
09c8d0b2229f813c1b93-c95ac804525aac4b6dba79b00b39d1d3.r79.cf1.rackcdn.com (09c8d0b2229f813c1b93-c95ac804525aac4b6dba79b00b39d1d3.r79.cf1.rackcdn.com)|23.61.249.40|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 343791922 (328M) [application/x-sh]
`Anaconda-2.0.1-Linux-x86_64.sh' に保存中

100%[=============================================================================>] 343,791,922 9.02MB/s 時間 43s    

2014-07-10 13:18:53 (7.61 MB/s) - `Anaconda-2.0.1-Linux-x86_64.sh' へ保存完了 [343791922/343791922]

AnacondaにはTheanoと関連するモジュールが含まれています.

  1. ダウンロードした.shファイルを実行し, インストーラを開始します:
[ec2-user@ip-172-31-5-86 ~]$ bash Anaconda-2.0.1-Linux-x86_64.sh

インストーラ実行中にパスを.bashrcファイルに追加するかどうか聞かれるので, Yesを選択します.

  1. 以下のコマンドで, .bashrcへの変更(手順5.3, 6.2)を反映させます:
[ec2-user@ip-172-31-5-86 ~]$ source .bashrc
  1. (この手順は必須ではありませんが, 推奨します) もしTheanoの実行時にコンパイルエラーが発生する場合, Anacondaに含まれるTheanoのバージョンが古いかもしれません. Theanoを開発版にアップデートする事でコンパイルエラーが解消される場合があります. アップデートのためにはGitが必要です. 次のコマンドでGitをインストールします.
sudo yum install git

続いてPythonのpipコマンドを用いてGithubに置いてあるTheanoをインストールします:

pip install --upgrade git+git://github.com/Theano/Theano.git

7. Theanoを用いたプログラムの実行

  1. TheanoでGPUを使用するために, .theanorcファイルで”device”にGPUを指定します. 以下の通りに入力します:
[ec2-user@ip-172-31-5-86 ~]$ echo '[global]
floatX = float32
device = gpu0

[nvcc]
fastmath = True' > .theanorc

このファイルの設定は, Pythonの処理系がTheanoのモジュールを読み込んだときに反映されます.

  1. Theano入門 のプログラムで使用する, MNIST文字データをダウンロードします:
[ec2-user@ip-172-31-5-86 ~]$ wget http://deeplearning.net/data/mnist/mnist.pkl.gz
  1. (注: この手順はローカルで実行します) “scp”コマンドを使って, Theano入門 のプログラム(既にダウンロード済みであると仮定します)をローカルからGPU計算サーバにコピーします:
taku-y$ scp -i /Users/taku-y/aws/my-key-tokyo.pem bbrbm.py gbrbm.py test_rbms.py ec2-user@54.92.45.32:~/

“wget”コマンドを使って, 直接ホームページからプログラムをダウンロードしても構いません.

  1. ipythonコンソールを起動し, 下記のコマンドを入力してプログラムを実行します:
>>> import test_rbms
>>> test_rbms.train_bbrbm(0, 100, n_components=512)

RBMの学習が開始され, 終了後ファイルが保存されます. このファイルには, 学習されたRBMのモデルパラメータだけでなく, 実行時間も記録されています.

8. 結果ファイルのローカルへのコピー

  1. プログラムの実行結果が保存されたファイルを, GPU計算サーバからローカルへコピーします:
taku-y$ scp -i /Users/taku-y/aws/my-key-tokyo.pem ec2-user@54.92.45.32:~/*.pklz ./

GPUを使って計算したことを示すため, コピーしたファイル名(手順7.4)の末尾を.pklz.gpuと変更します.

9. GPU計算サーバの停止

  1. 計算終了後, インスタンス一覧が表示されている画面に移動して”Actions”ボタンを押します. メニューが表れるので(下図参照), その中から”Terminate”を選択します.
_images/step9-1.png
  1. GPU計算サーバのボリュームが消去される事に関する警告が表示されます. 必要なファイルは既に手順8.1でローカルにコピーしているので, “Yes, Terminate”ボタンを押します.
_images/step9-2.png
  1. “Instance State”が”shutting-do..”となります.
_images/step9-3.png
  1. しばらく待つと, 表示が”terminated”となります. これでGPU計算サーバをシャットダウンできました.
_images/step9-4.png

10. 結果の確認

プログラム plot_result.py を用いて経過時間を表示します. プログラムと同じディレクトリにCPU/GPUによる計算結果が保存されており, それらのファイル名の末尾がそれぞれ”.pklz.cpu”と”.pklz.gpu”であるとします. plot_result.plot_time_bbrbm()を実行すると, 次のような図が表示されます:

_images/step10-1.png

上の図が横軸を実計算時間, 縦軸を復元誤差とした学習曲線です. 横軸のスケール以外は同一のグラフとなります. 総計算時間を比較したのが下の図です. GPUによって, CPUと比べて計算速度が約14倍高速である事が分かります.

11. 料金の確認

  1. 画面右上のAWSアカウント名をクリックするとメニューが表示されます. “Billing & Cost Management”をクリックします.
_images/step11-1.png
  1. 当月の料金が表示されます. 右上の”Bill Details”をクリックすると明細が表示されます.
_images/step11-2.png

まとめ

本文書ではAWSのGPU計算サーバを用いてGPU計算を実行する具体的な手順を説明しました. 例として, Theanoを用いてRBMの学習を実行しました. GPUにより, 現時点の標準的なCPUと比べて14倍の計算速度が得られました. GPU計算サーバの利用を意図して作成されたAMIを用いる事で, GPUのドライバやCUDAコンパイラのインストールといった作業を行う必要がありませんでした. また, Theanoを用いる事で, GPUのためにソースコードを書き換える必要がありませんでした.

私は今回初めてAWSを利用しました. AWS上でGPU計算を行うため, ネット上の様々な記事を参考にさせて頂きました. 最初は何から手をつければ良いか分からなかったのですが, こうしてまとめてみると, 作業量そのものは少ないことが分かります. 実際の作業を行う前は, インスタンスとAMIの概念と具体的な計算サーバへの接続方法に関する情報が見つけにくかったのですが, 本文書により, これらの問題が少しでも緩和されれば幸いです.

本格的にGPU計算を行う場合は自分で専用ハードウェアを購入するのが良いと思います. しかし, システムの消費電力や最新ドライバへの対応などの維持費を考えると, AWSを利用するという選択肢もあると思います. 個人的には, AWS以外にもこのような計算に特化したクラウドサービスが表れ, 競争を通して品質やユーザの利便性が向上することを期待します.

更新履歴

日付  
2014/07/16 第一版公開.

免責事項

本文書の情報については充分な注意を払っておりますが, その内容の正確性等に対して一切保障するものではありません. 本文書の利用で起きたいかなる結果について, 一切責任を負わないものとします。