楽屋

Azure GPU × Chainer で深層学習

経緯

ある日、私が社内で作業しているところに 弊社 CTO が嬉々として近づき 、私のPCにこんなシール↓を貼っていきました。

いや、僕 Azure で〇〇ラーニングとかしたこと無いし、Chainer も 使ったことないんだけどなぁ。。。

と言うと、そこは CTO「じゃあ使えるようになればいいんですよ」という強引な解決策を残して去っていきました。

 

そんな経緯があって私は、PCに貼られた「 Azure × Chainer 」が使えるナイスなエンジニアを目指すことになりました。

でなきゃこのシール、ただのハッタリ

 

というわけで修行の成果を披露すべく、この記事で紹介するのは以下の3つです。

 1. Azure の GPU 搭載 VMの起動方法

2.  Chainer を用いた深層学習を “GPU” で行う方法

3.  GPUインスタンスと 非GPUのローカルマシン(MacOS)との学習速度の比較

 

逆にこの記事で話さない事は以下の項目です。

1. そもそもの深層学習とかCNNの理論

2. Chainer の詳細なコード解説

 

1.  Azure の GPU搭載 VM を起動する

公式のチュートリアルを参考にしています。もともと想定していたのは、

1. GPU インスタンス起動

2. 1のインスタンスにpyenv, anaconda3 などpython実行環境の構築

3. Cuda Driver など、GPUを使えるようにセットアップ

だったのですが、2と3 の要件を満たす深層学習に適したVMイメージが提供されていたので、そちらを利用します。

 

1-1. GPU インスタンスの起動

まずは、GPUインスタンスを作成していきます。

左端の「Virtual Machines」 をクリックして、仮想マシンの一覧を開いたら、上部の「追加」をクリックします。マシンイメージの選択画面が開くので「deep learning」で検索し、「Deep Learning Virtual Machine」を選択してください。

続いて基本設定です。

Nameは「DL-GPU-Server」とし、OS type は 「Linux」、User name は 「ubuntu」としました。場所は、「米国東部2」を選択しました。地域によってはGPU インスタンスが利用できませんので、ご注意ください。

最後にサイズ選択です。

今回は練習ですので、NC6 Standardを選択してください。Storage Accountはデフォルト新規されるものをそのまま利用する形で大丈夫です。

次の画面で検証に成功したら、インスタンスを作成してください。

 

1-2. セキュリティグループの 受信セキュリティ 設定

じつはこのインスタンスですが、デフォルトでSSHやJupyterhubのポートに全IPからのアクセスが可能になっています。

以下は、作成したインスタンスの受信セキュリティ設定の画面です。

今回のような「Deep Learning Virtual Machine」のマシンイメージから作成となると、設定時点ではSSH公開鍵の登録ができず、ユーザ名とパスワードでの認証となります。

そのうえ全IPからのアクセスを許可してしまうのはセキュリティ上良くないので、任意のIPアドレス範囲からのみアクセスできるように設定しましょう。

・default-allow-ssh

・default-allow-jupyterhub

・default-allow-rstudio-server

の3つについて、ソースを「IP Addresses」に変更し、ソースIPアドレス/CIDR 範囲に特定のIPアドレス範囲(例えば自宅とか、会社のもの)を入力してください。

 

1.3 jupyterhub の起動確認

さきほど設定した受信セキュリティを見ると、デフォルトでRstudio ServerとJupyterhubのポートが空いています。

今回は chianer をpythonで書いていくので、jupyterhub にアクセスできるか確認していきます。

「https://GPU インスタンスのグローバルIP:8000 」でWebブラウザからアクセスします。

という警告が出ますが、TLS証明書を設定してないためです。気になる方はあとで証明書を設定すれば良いので、今回は無視して、「詳細設定」→「 xxxxにアクセスする」をクリックしていけば大丈夫です。

続いてログイン画面です。

インスタンスの基本設定のところで設定したユーザ名とパスワードを入力してください。ログインに成功したら「Start My Server」を選択してください。

以上で動作確認は終了です。

 

GPUインスタンスの準備までびっっくりするぐらい手間がかからなかったですね。本体なら、立てたインスタンスにPython 入れて、Cuda Driver 入れて・・・という作業を思えば雲泥の差です。

 

2. Chainer を用いた深層学習を GPU で行う

続いて、実際にChainer のコードを動かしてみます。Chainer は 

 

2-1. Chainer でニューラルネットの実装

MNISTデータセットを用いて、Chianerで手書き文字認識を試してみます。スクリプトは本家 Chianerのチュートリアルこちらを参考にしております。

まずは簡単な全結合の3層ニューラルネットから(人によってはこれを2層と呼ぶかもしれませんが)

ネットワークの定義部分は ThreeLayerNet クラスによって定義されています。

super().__init__で chianer.Chain の__init__メソッドを継承し、レイヤーのパラメタを定義し、実際のネットワーク構造は__call__にて記述します。

これをローカルマシンで実行します。マシンスペックは以下のようになっております。

・OS: Mac OS Sierra

・プロセッサ:1.6 GHz Intel Core i5

・メモリ:8 GB 1600 MHz DDR3

以下がローカルでの実行結果となります。

エポックごとに学習結果が返されます。精度は 97% くらいで、処理時間は5分くらいです。

ローカルマシンでの実行でこの時間だったらGPUにするまでもなさそうです。

 

2-2. Chainer でCNNの実装

そんなわけで、より計算負荷の大きい CNN で試してみましょう。例えば、2つの畳込み層、2つのプーリング層であれば以下のようになります。

全結合ニューラルネットの時と同じで、ネットーワーク構造とレイヤごとのパラメタは 冒頭の CNN クラスにて定義しています。

これをまずはローカルマシンで実行すると、実行結果は以下のようになります。

大体 17分くらいかかって精度は 98% くらいです。次にこれを、GPUで動かすようにしてみましょう。

 

2-3. Chainer のコード を GPU で動かす

前節のコードをGPUで稼働させるには、以下のように変更します。

変更点としては、35~37行目でモデルにGPUをセットし、

51行目と56行目でdevice 引数に0 (コード中では get_device に格納している) を指定しています。

これを先ほど作成した GPU インスタンスで実行すると

35秒に短縮!

 

3. GPUとローカルマシンで速度比較

さて、さきほどは 17分 → 35秒 の短縮結果でしたが、これならまだローカルで実行して我慢できるレベルです。

次はもっと層を深くして実行してみましょう。

 

3-1. CNN の層を深くして実行

まずはローカルマシン、GPU なしで測定してみます。実行したのは以下のコードです。

前節のコードから変更したのは CNN クラスの部分のみです。

実行結果は、65 分・・・ただ精度は99%まで上がってます。

続いてこれをGPUで実行させます。

GPU実行の為に変更した部分は、2-3節と全く一緒です。

以下が実行結果となります。

65 分 → 38 秒まで短縮!! ざっと100倍ぐらい早くなりました。

 

3-2. 速度比較のまとめ

ここまでの結果を表にまとめます。

ネットワークの種類ローカルマシンAzure GPU NC6 Standard

全結合

– 3層ニューラルネット

5分未計測

CNN

-2つの畳込み層

-2つのプーリング層

17分35秒

CNN

-4つの畳込み層

-2つのプーリング層

65分

38秒 

畳込み層が増えたぐらいじゃ、ほとんどGPUの処理時間が変わってないですね。

深層学習となると処理待ち時間が多くなるのがネックですが、分析サイクルを回す上でこれは重宝します!

 

まとめ

深層学習ライブラリ Chainer を実行し、Azure GPU インスタンス上でニューラルネットを実装しました。CNNにおいては圧倒的な処理速度で、モデルのチューニングなど分析サイクルを高速で回すことができます。料金も一時間あたり ¥90 程度なので、スポットとして使えばコストもかかりません。「Deep Learning Virtual Machine」のマシンイメージも合わせれば、GPUインスタンスを立ち上げてすぐコードを実行できるのも魅力的です。

 

これで冒頭の「 Azure × Chainer 」シールに恥じぬエンジニアを名乗れます(ちなみにこのシール、この時の戦利品でしょうね)。

最後までお読みいただきありがとうございました!