MacBook Air(or Pro)でGPUを外付けしChainerを動作させるまでの手順
はじめに
本記事は、大規模な学習はクラウドで、デバックはローカルで、(ついでに小規模な学習も)と言う人向けの記事です。
目的は、Mac(MacBook AirやMacBook Pro)で深層学習を行う環境を整えることになります。
グラフィックカード、深層学習用のライブラリ(Chainer)の順で、準備をします。
グラフィックカードの準備
私は、ノート型のMacを使っているので、GPUは外付けにしました。
GPUは、深層学習用のライブラリが動作するNVIDIAのGTXシリーズの中から選びます。
最近、アップルが外付けGPUを発表しましたが、AMD Radeonなので、今回の目的には合いません。
External Graphics Development Kit - Apple Developer
既製品を利用する場合
GTX 1070が搭載されているので、今回の目的にうってつけだと思います。
www.gigabyte.com
自分で組み立てる場合
私が環境を構築した当時、上記の製品は売っていなかったため、パーツを買ってきて組み立てました。
この方法は、System Integrity Protection(SIP)を無効化する必要が出てきます。気にする人は止めておきましょう。
- 以下のサイトを参考に進めていきます。
まず、選択するのは以下の3点です。
- グラフィックカード
- Thunderboltに対応したPCIeの外付けボックス(enclosures)
- 電源
選ぶ時のポイント
パーツ選びのポイントを解説していきます。
まずは自分の目的に沿った性能が得られるか、を考えます。
私は、画像系の深層学習も手元でちょっと動かしてみたかったので、メモリが8GByteあることと、速度面(pascalアーキテクチャでそこそこ早いもの)と言う理由で、GTX 1070を選択しました。また、akitio thunder2で動作させたかったので、short modelを選んでいます。
具体的には以下の製品を購入しました。
http://www.kuroutoshikou.com/product/graphics_bord/nvidia/gf-gtx1070-e8gb_oc_short/
- Thunderboltに対応したPCIeの外付けボックス(enclosures)
まずは、thunderboltの2系か3系かを、選択します。
自分の利用しているMacBook Air(もしくはpro)のインタフェースに適合するのが一番良いと思います。ただ、変換コネクタもあるので、そこまで気にする必要もないですね。
(ちなみにMacBookは、そもそもthunderboltに対応していません。)
次に、選択したグラフィックカードが箱に収容できるか、と言うのも大切なポイントです。
私は、自分のMacBook Airがthunderbolt2系だったので、akitio thunder2を選びました。ただし、akitio thunder2は、小さめなので収容できるグラボに制限が出てしまうのと、電源を別に購入しないといけないので、購入する場合は注意してください。
- 電源
そもそも、PCIeの外付けボックスに、初めから搭載されている電源の出力で賄えるのであれば、購入する必要はありません。
購入する場合、当たり前ですが、グラフィックカードの消費電力を賄えるか、を考えて購入します。
GTX 1070であれば、NVIDIAの公式HPにgraphics card powerが150Wとあるので、以下の252Wの電源を購入しました。
http://www.mouser.jp/ProductDetail/Mean-Well/GST280A12-C6P/?qs=XfZQyRplo5S6bkFXOs4q7w==
また、購入するグラフィックカードの補助給電スロットに合うように、変換コネクタも購入します。
最近のグラボは性能が良いので、PCIeの6ピンが2つもしくは、8ピンになっていると思います。
私の購入したGTX 1070は、PCIeの8ピンでした。
上記の電源であれば、PCIeの6ピンで出力するので、6ピン8ピンの変換ケーブルを購入しました。
組み立て
- 買ってきたPCIeの外付けボックス、グラフィックカード、電源をつなぎます。
- System Integrity Protection(SIP)を解除します。
- Macを再起動し、以下のautomate-eGPU.shを実行します。
- GitHub - goalque/automate-eGPU
- sudo ./automate-eGPU.sh
- このスクリプトの中で、ドライバもインストールしてくれます。
- GitHub - goalque/automate-eGPU
- MacとPCIeのボックスを、thunderboltケーブルで接続します。
- Macを再起動します。
「このMacについて」から「システムレポート」を呼び出し、グラフィックスカード欄に購入したグラボが記載されていれば認識されています。
深層学習用ライブラリ(Chainer)のインストール
大雑把に言うと以下のコンポーネントが必要になります。
- CUDA toolkit
- cuDNNのインストール
- GPUを深層学習用に最適化して利用するために必要です。
- CuPy
- CUDA上で計算を行うNumPyサブセットです。
- Chainer
- 深層強化学習用のライブラリです。
CUDA toolkitのインストール
- 以下のウェブページに沿ってインストールします。
- この過程でXcodeとCommand-Line Toolsもインストールします。
- トラブルシューティング
cuDNNのインストール
- NVIDIAのサイトからダウンロードします。 (要:ユーザー登録)
- cupyのサイトhttps://docs-cupy.chainer.org/en/latest/install.html#install-cudnnで、対応しているcuDNNを選びます。
- 17年9月2日現在、v6までの対応のようですので、cuDNNのv6を選びます。
- cupyのサイトhttps://docs-cupy.chainer.org/en/latest/install.html#install-cudnnで、対応しているcuDNNを選びます。
- DLしたファイルを解凍し、必要なファイルをコピーします。(コピー先は、自分がCUDA toolkitをインストールした先に読み換えてください。)
- tar xzvf (落としたcuDNNの名前).tar (cudaというディレクトリが作成される)
- cd cuda
- sudo cp include/* /usr/local/cuda/include/
- sudo cp lib/* /usr/local/cuda/lib/
環境変数の設定
(ここも、各自のCUDA toolkitの場所に読み換えてください)
CuPyのインストール
- 以下のサイトを参考に、インストールします。
- 具体的には、以下のコマンドです。
- sudo pip install -U setuptools
- pip install cupy --no-cache-dir
- 既に、cupyが入っている方は、一度uninstallしてください。
Chainerのインストール
- 以下のサイトを参考に、インストールします.
- Installation Guide — Chainer 3.0.0rc1 documentation
- sudo pip install chainer --no-cache-dir
- こちらも既にchainerが入っている人は、uninstallしてから行います。
効果測定
Chainerのサンプル(chainer/examples at master · chainer/chainer · GitHub)から、mnistを選んで比較してみました。
サンプルの中のtrain_mnist.pyの実行結果です。
当たり前ですが、最終的に得られる精度に差はありません。
ただ、学習に必要な時間は、CPUが1エポック50秒程度かかっているのに対し、GPUは、5秒程度と10倍ほど高速になっているのが確認できました。
以下がCPUを使った場合の結果です。
# unit: 1000
# Minibatch-size: 100
# epoch: 20
epoch | main/accuracy | validation/main/accuracy | elapsed_time |
1 | 0.942133 | 0.9699 | 42.2322 |
2 | 0.97755 | 0.9739 | 86.9796 |
3 | 0.984867 | 0.9794 | 131.715 |
4 | 0.987483 | 0.9823 | 176.681 |
5 | 0.990617 | 0.9802 | 222.018 |
6 | 0.992367 | 0.98 | 276.583 |
7 | 0.992017 | 0.9809 | 324.01 |
8 | 0.994883 | 0.9815 | 370.21 |
9 | 0.995067 | 0.9807 | 417.02 |
10 | 0.99425 | 0.984 | 464.117 |
11 | 0.996317 | 0.9784 | 511.821 |
12 | 0.9959 | 0.9813 | 560.13 |
13 | 0.996567 | 0.9839 | 608.949 |
14 | 0.996033 | 0.9824 | 659.155 |
15 | 0.996433 | 0.9829 | 709.139 |
16 | 0.997783 | 0.9819 | 759.985 |
17 | 0.996917 | 0.9826 | 811.511 |
18 | 0.997167 | 0.9804 | 863.433 |
19 | 0.9971 | 0.9753 | 916.173 |
20 | 0.996767 | 0.982 | 969.896 |
こちらがGPUを使った場合。
# unit: 1000
# Minibatch-size: 100
# epoch: 20
epoch | main/accuracy | validation/main/accuracy | elapsed_time |
1 | 0.943417 | 0.9706 | 7.06982 |
2 | 0.977766 | 0.971 | 12.0191 |
3 | 0.984982 | 0.9796 | 16.8749 |
4 | 0.987398 | 0.9782 | 21.8097 |
5 | 0.991315 | 0.9788 | 26.8118 |
6 | 0.991865 | 0.9819 | 31.9384 |
7 | 0.994015 | 0.9802 | 36.8659 |
8 | 0.992449 | 0.9815 | 41.8097 |
9 | 0.994632 | 0.9808 | 46.9009 |
10 | 0.995415 | 0.9803 | 51.9401 |
11 | 0.995549 | 0.983 | 57.0252 |
12 | 0.995315 | 0.9814 | 62.0933 |
13 | 0.997849 | 0.9811 | 67.0458 |
14 | 0.996182 | 0.9831 | 72.1063 |
15 | 0.996398 | 0.978 | 77.0816 |
16 | 0.996449 | 0.9836 | 81.9985 |
17 | 0.997199 | 0.9809 | 87.0473 |
18 | 0.996616 | 0.9826 | 91.9781 |
19 | 0.998866 | 0.9825 | 96.8835 |
20 | 0.996532 | 0.9808 | 101.705 |