MacBookProでのGPU環境作り

#概要

MacBookProのLocal環境でGPUを用いて機械学習を行えないかと検索したところ良い記事を見つけた。PlamidMLを試してみる。PlaimdMLのgithubのリンクを下に貼る。

https://github.com/plaidml/plaidml



#環境
```
macOS: Catalina 10.15.7
xCode: version 12.4
```
#PlaidMLのインストール
`pip`でPlaidMLとplaidbenchをインストールする。

```bash:terminal
$pyenv activate XXX
$pip install plaidml-keras plaidbench
```

#PlaidMLの設定

```bash:terminal
$plaidml-setup

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)_iris(tm)_plus_graphics.0 : Intel(R) Iris(TM) Plus Graphics (Metal)

Experimental Config Devices:
   llvm_cpu.0 : CPU (via LLVM)
   opencl_intel_iris(tm)_plus_graphics.0 : Intel Inc. Intel(R) Iris(TM) Plus Graphics (OpenCL)
   metal_intel(r)_iris(tm)_plus_graphics.0 : Intel(R) Iris(TM) Plus Graphics (Metal)

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

Enable experimental device support? (y,n)[n]:y
```
yを入力して進める。

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

   1 : llvm_cpu.0
   2 : opencl_intel_iris(tm)_plus_graphics.0
   3 : metal_intel(r)_iris(tm)_plus_graphics.0

Default device? (1,2,3)[1]:1
```
使いたいデバイスを選択する。

```bash:terminal
Selected device:
    llvm_cpu.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/mtakashi/.plaidml? (y,n)[y]:y
Success!

```
yを押して、設定を保存。PlaidMLの設定が完了する。

#PlaidMLのベンチマークテスト
plaidbenchで、ベンチマークテストを行うことができる。

```bash:terminal
$plaidbench keras mobilenet
Running 1024 examples with mobilenet, batch size 1, on backend plaid
INFO:plaidml:Opening device "llvm_cpu.0"
Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.6/mobilenet_1_0_224_tf.h5
17227776/17225924 [==============================] - 5s 0us/step
'str' object has no attribute 'decode'
Set --print-stacktraces to see the entire traceback
```
`'str' object has no attribute 'decode'`と出て、ベンチマークテストが行われないので検索。下記の症例と同じようだったので対策した。

https://qiita.com/Hiroki-Fujimoto/items/b078bfb680fb710c38c1

```bash:terminal
$ pip show h5py
Name: h5py
Version: 3.4.0
Summary: Read and write HDF5 files from Python
Home-page: http://www.h5py.org
Author: Andrew Collette
Author-email: andrew.collette@gmail.com
License: BSD
Requires: cached-property, numpy
Required-by: Keras, Keras-Applications, plaidbench
```
やはり、`h5py`のバージョンが問題のようだ。以下でアンインストールして再インストールする。

```bash:terminal
$pip uninstall h5py
$pip install h5py==2.10.0
```

再チャレンジしたところ、ベンチマークテストができた。

```bash:terminal
$plaidbench keras mobilenet
Running 1024 examples with mobilenet, batch size 1, on backend plaid
INFO:plaidml:Opening device "llvm_cpu.0"
Compiling network... Warming up... Running...
Example finished, elapsed: 3.342s (compile), 113.324s (execution)

-----------------------------------------------------------------------------------------
Network Name         Inference Latency         Time / FPS          
-----------------------------------------------------------------------------------------
mobilenet            110.67 ms                 108.46 ms / 9.22 fps
Correctness: PASS, max_error: 1.7640328223933466e-05, max_abs_error: 7.040798664093018e-07, fail_ratio: 0.0
```

`plaidml-setup`で、デバイスを変えながら、ベンチマークテストをした結果を下にまとめる。

```bash:terminal
Running 1024 examples with mobilenet, batch size 1, on backend plaid
INFO:plaidml:Opening device "opencl_intel_iris(tm)_plus_graphics.0"
Compiling network... Warming up... Running...
Example finished, elapsed: 9.995s (compile), 28.006s (execution)

-----------------------------------------------------------------------------------------
Network Name         Inference Latency         Time / FPS          
-----------------------------------------------------------------------------------------
mobilenet            27.35 ms                  16.83 ms / 59.42 fps
Correctness: PASS, max_error: 8.218973562179599e-06, max_abs_error: 1.341104507446289e-06, fail_ratio: 0.0
```


```bash:terminal
Running 1024 examples with mobilenet, batch size 1, on backend plaid
INFO:plaidml:Opening device "metal_intel(r)_iris(tm)_plus_graphics.0"
Compiling network... Warming up... Running...
Example finished, elapsed: 4.723s (compile), 18.055s (execution)

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

#まとめ

ベンチマークテストでInference Latencyを見ると、gpuである"metal_intel(r)_iris(tm)_plus_graphics.0"を用いたものが一番早いようだ。今後、機械学習する際に、設定を変更しながら確認してみる。

#参考リンク

https://chalow.net/2020-03-30-1.html

https://qiita.com/gabe-ds/items/3c7eb3d9844837ad63d5