Kerasの作者のfcholletさんがTwitterで紹介していた、PlaidMLという新しい機械学習用のライブラリを試してみた。Early Alpha Quality
とのことであるが、試してみたらとても速いしKerasで書いてたコードが(ほぼ)そのまま使えて感激した。これは機械学習が捗る…かも?
短くまとめると
- PlaidMLという新しいフレームワークを使うと、nVidia積んでないMacでもGPU使って高速に機械学習できるかも
- Kerasのバックエンドとして使えるので、今まで書いてきたKerasのコードを(ほぼ)そのまま使える
- 動かしてみたら、確かに速い。
- 10月に試した段階では不具合があったが、アップデートで修正された!
PlaidML
PlaidML is an open-source Keras backend that runs on OpenCL, with good performance relative to TensorFlow: https://t.co/tCmzXHfFUO pic.twitter.com/3YAQI0EMX5
— François Chollet (@fchollet) 2017年10月21日
TensorFlowと違って、OpenCLサポートがあるためAMDのGPUでもハードウェアアクセラレーションが効くらしい。そして、このPlaidMLはKerasのバックエンドとして使える。つまり、今まで書いてきたKerasのコードを、そのままバックエンドをPlaidMLに切り替えるだけで高速に実行できる可能性があるということ。
これはMacで機械学習を楽しむ上ではとても意味のあることなので、早速試してみた。
OpenCLが使えるか調べる
clinfo
を使って、使用中のMacのGPUでOpenCLが使えるか調べておこう。
brew install clinfo
clinfo
Number of platforms
が1以上になっていたらOK。
インストール
2017年10月末現在、PlaidMLはpip
経由でのインストールが可能になっている。基本的にはpip経由でインストールする方が手軽でオススメ。
pipでインストールする
2017/10/27から、Mac版もpip経由でのインストールが可能になったので、特別理由がなければpip経由でインストールするのが良い(2017/10/29追記)
virtualenvで環境を作る
必須ではないが、試行錯誤するにあたって環境を汚したくないのでvirtualenvで新しい環境を作る。
virtualenv --system-site-packages ~/plaidml
source ~/plaidml/bin/activate
pip install setuptools --upgrade
pipでインストールする
pip install plaidml-keras
ソースコードからビルドする(リリース前の実装を試したい場合)
レポジトリ上の最新のコードからビルドしたい場合は、下記の手順でビルドできる。
必要なライブラリを入れる
brewで必要なライブラリを入れておく。古い場合は適宜アップデートすること。(特にbazelは0.6.0以降が必要)
brew install bazel
brew install bison
brew install flex
virtualenvで環境を作る
必須ではないが、試行錯誤するにあたって環境を汚したくないのでvirtualenvで新しい環境を作る。
virtualenv --system-site-packages ~/plaidml
source ~/plaidml/bin/activate
pip install setuptools --upgrade
setuptools
が古いとビルド/インストールに失敗するため、念のためアップデートしておく。36.6.0
ではうまくいった。
ソースコードをクローンする
git clone https://github.com/plaidml/plaidml.git
ビルド+インストール
bazel
を使ってビルド、作成されたwheelをインストールする。
bazel build -c opt plaidml:wheel plaidml/keras:wheel
pip install -U bazel-bin/plaidml/*whl bazel-bin/plaidml/keras/*whl
PlaidMLの設定
インストールが完了したら、plaidml-setup
を実行して環境の設定を行う。ここで計算に使用するGPUを指定する。
plaidml-setup
基本的には質問に答えていくだけ。
PlaidML Setup (0.0.0.dev0)
...
Default Config Devices:
No devices.
Experimental Config Devices:
amd_radeon_pro_570_compute_engine.0 : AMD AMD Radeon Pro 570 Compute Engine
intel(r)_core(tm)_i5-7500_cpu_@_3.40ghz.0 : Intel Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
Using experimental devices can cause poor performance, crashes, and other nastiness.
Enable experimental device support? (y,n)[n]:y
検証されていないハードウェアだとExperimental
にリストされるようだが、とりあえず試してみる。
Multiple devices detected (You can override by setting PLAIDML_DEVICE_IDS).
Please choose a default device:
1 : amd_radeon_pro_570_compute_engine.0
2 : intel(r)_core(tm)_i5-7500_cpu_@_3.40ghz.0
Default device? (1,2)[1]:1
Selected device:
amd_radeon_pro_570_compute_engine.0
AMDを選んでみた。
PlaidML sends anonymous usage statistics to help guide improvements.
We'd love your help making it better.
Enable telemetry reporting? (y,n)[y]:y
Almost done. Multiplying some matrices...
Tile code:
function (B[X,Z], C[Z,Y]) -> (A) { A[x,y : X,Y] = +(B[x,z] * C[z,y]); }
Whew. That worked.
Save settings to /Users/foo/.plaidml? (y,n)[y]:
Success!
マトリクスの計算が行われ、どうやらうまく動いたようだ。この設定を.plaidml
に保存すると、次回以降PlaidML
を実行する際に、このハードウェア設定が使われるようだ。
Kerasのバックエンドとして使ってみる
Kerasのバックエンドとして使う場合は、import keras
より前に下記のコードを呼んであげれば良い。
import plaidml.keras
plaidml.keras.install_backend()
VGG-LIKEなサンプルで比較してみる
試しに、KerasのホームページにあるVGG-LIKEのサンプルをそれぞれのバックエンドで実行してパフォーマンスを計測してみた。fitの処理にかかった時間のみを計測。参考までに、FloydHub(GPU使用)の結果も。
なお、処理が早く終わりすぎてしまうのでEPOCHは50に増やした。
ライブラリ | マシン | 時間(四捨五入) |
---|---|---|
TensorFlow | Intel Core i5 2.9GHz | 145秒 |
TensorFlow | Intel Core i5 3.4GHz | 117秒 |
PlaidML | Intel Iris Graphics 550 | 110秒 |
PlaidML | AMD Radeon Pro 570 | 55秒 |
TensorFlow | FloydHub(GPUインスタンス) | 14秒 |
- iMac 2017 CPU 3.4 GHz Intel Core i5 + AMD Radeon Pro 570
- MacBook Pro 2016 CPU 2.9GHz Intel Core i5 + Intel Iris Graphics 550
なるほど。
本題から外れるけど、FloydHub圧倒的にはええ。
自分のコードで試してみた結果
バックエンドの置き換えは簡単
自分のコードでも試してみた。
TensorFlow + Kerasでフレンズ識別する - その1: 学習データの準備編
こちらの記事で使ったコードのバックエンドをPlaidMLに置き換えてみた。バックエンドの置き換え自体は本当に簡単で
import plaidml.keras
plaidml.keras.install_backend()
を加える以外、ほとんどやることはなかったのだが、TensorBoardなど一部TensorFlowの機能に依存した実装部分は当然外す必要があった。
学習に失敗した(不具合、解決済み)
ただ実際に学習を走らせてみたところ、途中でTrain Loss / Train Accuracy / Val Loss / Val Accuracy全てがゼロに収束してしまうという現象が起きてしまい、うまくいかなかった。
2017.10.23追記: どうやら、これはMac版のバグのようだ。
Thanks Andy, we've seen issues on Mac as well and are working on tracking them down. Once we get that all ironed out we'll mark Mac "supported" and ship a new release with binaries.
2017.11.04追記: アップデートで対策された。
Yes, the CPU issue is an known limitation of Apple's CPU OpenCL which allows only 1 thread per work-group. We have not addressed this, as the resulting CPU performance is likely to be underwhelming. As for the main issue, I've tracked the problem down to a set of kernels that behave incorrectly, but only on AMD and only on Apple's drivers. I'm still checking, but the kernels strongly appear to be correct, and I believe this may be a bug in the OpenCL drivers themselves. There is some discussion of similar correctness issues with Apple's OpenCL drivers in other OpenCL projects. That said, it appears to happen only for a subset of kernels. There is a configuration change that seems to work around the problem by avoiding such kernels. There may be a performance penalty for the change, and since I don't know what the specific driver issue is, I'm not sure if this workaround will fully resolve all correctness issues. However, it did fix the issue for me.
どうやら、この問題はmacOS用のOpenCLドライバーの問題のようだ。パフォーマンスは若干犠牲になるが、Ver.0.1.2でこの問題にはワークアラウンドが適用され、正しい計算結果が出るようになった。今後、ドライバーが修正されることを期待したい。
まだ使うには早すぎるが、今後にとても期待
Macは公式には未対応、Early Alpha Quality
の段階ということもあり、まだ実戦で使うには早すぎるのは当然かもしれないが、OpenCL対応で、かつKerasのコードをそのまま使えるというのは本当にありがたい。数週間以内にMacにも公式に対応予定とのことで、今後に期待したい。