MacでGPU ~PlaidMLの実装~(2020年5月現在)


今回の設定が一度終わっている方向け

次回以降のjupyter起動手順です。
簡易版を用意したので、こちらを参考してもらえると幸いです。

【備忘録】PlaidML Keras実行順序

実行環境


実行環境1
machine MacBook Air(Retina, 13-inch,2019)
OS MacOS Catalina version 10.15.4
メモリ 8 GB 2133 MHz LPDDR3
グラフィック Intel UHD Graphics 617 1536 MB
module version
Keras 2.2.4
plaidml 0.7.0
plaidml-keras 0.7.0
plaidbench 0.7.0



実行環境2
machine MacBook (Retina, 12-inch, 2017)
OS MacOS Catalina version 10.15.4
メモリ 8 GB 1867 MHz LPDDR3
グラフィック Intel HD Graphics 615 1536 MB
module version
Keras 2.2.4
plaidml 0.7.0
plaidml-keras 0.7.0
plaidbench 0.7.0


PlaidML実装の動機

GWに無料で機械学習を勉強することができるコンテンツが増えたことや元々やりたいと考えていた画像処理系の機械学習に手を出してみようと思ったため。
誇るほど高いスペックのマシーンを持っているわけでもなく、実行環境にも書いた通り、実行環境がMacBookということもあり、NVIDIA製のGPUを使うことができない環境は、PCにかける負担もですが、時間がとてもかかる。CPUだけでは学習に限界を感じたため、MacBookでもGPUを使って学習をすることができると噂のPlaidMLの実装をしてみました。

参考文献

Plaid MLのGitHubをメインに参考にしました。

PlaidMLの実装について

何をするモジュールなのか

PlaidMLは、intelなどが開発している科学数理計算ライブラリのフレームワークです。
標準でKerasがサポートしてる科学数理計算ライブラリのフレームワークは、tensorflowTheanoなどがあります。
これらのライブラリで、PCのGPU(グラフィック)を使おうとした時NVIDIA製のGPUでしかサポートされておりませんでした。
AMD製のGPUを搭載しているMacではGPUを使って計算することができませんでした。

しかし、このPlaidMLはNVIDIA製という縛りがなく、GPUを使えるようにするためのモジュールとなっており、Kerasのバックエンドのフレームワークとして採用されているモジュールとなっています。
今回の実装では、このKerasのバックエンドにPlaidMLを設定するまでを行います。

詰まるところ

Macで、GPUを使って、機械学習ができる
ということです。

実装

PlaidML Github QuickStart Link
QuickStarでは、virtualenvを使った仮想環境を構築していますが、僕はしませんでした。
特に理由はないです。

必要なモジュールのインストール

module_install
pip3 install plaidml-keras plaidbench
pip3 install keras

PlaidMLセットアップ

PlaidMLのセットアップを行います。
PlaidMLでCPUを使って計算をするのか、GPUを使って計算をするのかなどのセットアップを行います。

plaidml-setup
plaidml-setup

Quick Start通りに進めましたが、ここでエラーが出ました。
エラー文は下記の通りとなっています。

error
Traceback (most recent call last):
  File "/usr/local/bin/plaidml-setup", line 5, in <module>
    from plaidml.plaidml_setup import main
  File "/usr/local/lib/python3.7/site-packages/plaidml/__init__.py", line 50, in <module>
    import plaidml.settings
  File "/usr/local/lib/python3.7/site-packages/plaidml/settings.py", line 33, in <module>
    _setup_config('PLAIDML_EXPERIMENTAL_CONFIG', 'experimental.json')
  File "/usr/local/lib/python3.7/site-packages/plaidml/settings.py", line 30, in _setup_config
    'Could not find PlaidML configuration file: "{}".'.format(filename))
plaidml.exceptions.PlaidMLError: Could not find PlaidML configuration file: "experimental.json".

こちらのエラーに関して、GitHubの方で、すでに議論がありました。
興味がある方は覗いてみてください。
plaidml.exceptions.PlaidMLError: Could not find PlaidML configuration file: "experimental.json". #370

結論として、
PATHが通っていないため、エラーが出ているという結論があったため、記載されていたPATHを設定します。
再度exportを実行し、設定したPATHが通っていることを確認したら...

PATH
export PLAIDML_NATIVE_PATH=/usr/local/lib/libplaidml.dylib
export RUNFILES_DIR=/usr/local/share/plaidml

export

再度セットアップを実行

plaidml-setup
plaidml-setup
~~
Enable experimental device support? (y,n)[n]:y #y を選択

Multiple devices detected (You can override by setting PLAIDML_DEVICE_IDS).
Please choose a default device:

   1 : llvm_cpu.0
   2 : opencl_intel_uhd_graphics_617.0
   3 : metal_intel(r)_uhd_graphics_617.0

Default device? (1,2,3)[1]:3 # 下二つが、GPU今回は、グラフィックの3を選択
~~
# 今回の選択結果を保存するかどうか
Save settings to /Users/linda/.plaidml? (y,n)[y]:y #yを選択


実行結果(全体)
PlaidML Setup (0.7.0)

Thanks for using PlaidML!

The feedback we have received from our users indicates an ever-increasing need
for performance, programmability, and portability. During the past few months,
we have been restructuring PlaidML to address those needs.  To make all the
changes we need to make while supporting our current user base, all development
of PlaidML has moved to a branch — plaidml-v1. We will continue to maintain and
support the master branch of PlaidML and the stable 0.7.0 release.

Read more here: https://github.com/plaidml/plaidml 

Some Notes:
  * Bugs and other issues: https://github.com/plaidml/plaidml/issues
  * Questions: https://stackoverflow.com/questions/tagged/plaidml
  * Say hello: https://groups.google.com/forum/#!forum/plaidml-dev
  * PlaidML is licensed under the Apache License 2.0


Default Config Devices:
   llvm_cpu.0 : CPU (via LLVM)
   metal_intel(r)_uhd_graphics_617.0 : Intel(R) UHD Graphics 617 (Metal)

Experimental Config Devices:
   llvm_cpu.0 : CPU (via LLVM)
   opencl_intel_uhd_graphics_617.0 : Intel Inc. Intel(R) UHD Graphics 617 (OpenCL)
   metal_intel(r)_uhd_graphics_617.0 : Intel(R) UHD Graphics 617 (Metal)

Using experimental devices can cause poor performance, crashes, and other nastiness.

Enable experimental device support? (y,n)[n]:y
Multiple devices detected (You can override by setting PLAIDML_DEVICE_IDS).
Please choose a default device:

   1 : llvm_cpu.0
   2 : opencl_intel_uhd_graphics_617.0
   3 : metal_intel(r)_uhd_graphics_617.0

Default device? (1,2,3)[1]:3

Selected device:
    metal_intel(r)_uhd_graphics_617.0

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/linda/.plaidml? (y,n)[y]:y
Success!


推論性能のベンチマーク

次に、MobileNetの推論性能をベンチマークしてみます。

plaidbench keras mobilenet
Running 1024 examples with mobilenet, batch size 1, on backend plaid
INFO:plaidml:Opening device "metal_intel(r)_uhd_graphics_617.0"
Compiling network...INFO:plaidml:Analyzing Ops: 266 of 413 operations complete
 Warming up... Running...
Example finished, elapsed: 2.280s (compile), 32.101s (execution)

-----------------------------------------------------------------------------------------
Network Name         Inference Latency         Time / FPS          
-----------------------------------------------------------------------------------------
mobilenet            31.35 ms                  0.00 ms / 1000000000.00 fps
Correctness: PASS, max_error: 6.440454399125883e-06, max_abs_error: 5.811452865600586e-07, fail_ratio: 0.0

上から2行目INFO:plaidml:Opening device "metal_intel(r)_uhd_graphics_617.0"
で、自分がセットアップしたアクセラレーターのベンチマークを取られていることが確認できます。

実際にここまでで、設定自体は終わっていますが、本当にKerasのバックエンドが、PlaidMLに変わっているかを確認します。

このPATHなどを通してあるターミナル上で、jupyterを起動させる。

要注意
ここで別のターミナルの窓でJupyterを起動させたり、今まで設定していたターミナルの窓を消すと設定がし直しになる。

PlaidMLの確認

jupyter上で

import plaidml.keras
plaidml.keras.install_backend() #バックエンドに設定
import keras
print(keras.backend.backend()) #Kerasのバックエンドの確認

>>> tensorflow

kerasのバックエンドが、tensorflowのままです。

実際にはPlaidmlをkerasのバックエンドに設定するためには、

plaidml.keras.install_backend() #バックエンドに設定

ではなく、バックエンドに設定するPATHを設定してあげる必要がある。

export KERAS_BACKEND=plaidml.keras.backend

このPATHを設定した後に確認すると...
```

import keras
print(keras.backend.backend())

>>>plaidml.keras.backend

変更されていることが確認できる。

最後に

今後画像解析系の学習をさせていきたいと思います。 

関連文献

脱NVIDIAを夢見て ~ PlaidML ~