Prologue
_
Mid 2011 の Mac mini は、グラフィックに外付け GPU (AMD Radeon HD 6630M) を選択することができた最後の Mac mini です。
最近の GPU に比べれば全く非力ですし、今はとっても便利な Google Colab. も使えるので出番はあまりありませんが、せっかく搭載しているので PlaidML を使って GPU 支援を有効にして訓練をしています。
Python の実行環境について
_
Homebrew の Python3 実行環境をインストールしています。
$ python3 -V
Python 3.8.5
Homebrew では最近 Python のバージョンが 3.7 → 3.8 に更新されたため、いずれにせよ venv の環境を作り直す必要がありました。
TensorFlow v2.3.0 のインストール
_
venv の環境を新たに作成してインストールします。
特に問題なくインストールできました。
$ mkdir ~/venv
$ cd ~/venv/; python3 -m venv tf2
$ source ~/venv/tf2/bin/activate
(tf2) $ pip3 install -U pip
(tf2) $ pip3 install -U setuptools
(tf2) $ pip3 install -U tensorflow
...
Successfully installed
absl-py-0.9.0 astunparse-1.6.3 cachetools-4.1.1 certifi-2020.6.20 chardet-3.0.4 gast-0.3.3
google-auth-1.20.0 google-auth-oauthlib-0.4.1 google-pasta-0.2.0 grpcio-1.30.0 h5py-2.10.0
idna-2.10 keras-preprocessing-1.1.2 markdown-3.2.2 numpy-1.18.5 oauthlib-3.1.0 opt-einsum-3.3.0
protobuf-3.12.2 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-2.24.0 requests-oauthlib-1.3.0
rsa-4.6 scipy-1.4.1 six-1.15.0 termcolor-1.1.0 urllib3-1.25.10 werkzeug-1.0.1 wheel-0.34.2
wrapt-1.12.1 tensorboard-2.3.0 tensorboard-plugin-wit-1.7.0 tensorflow-estimator-2.3.0
tensorflow-2.3.0
whl のサイズは、なぜか Mac 向けが最も小さいですね。
今回作った venv 環境のストレージ消費量は約 1.0 GB になりました。
PlaidML のインストール
_
PlaidML の最新版である v0.7.0 は OS が 10.15 (Catalina) であることが前提になっており、それ以前の OS で実行すると以下のようなエラーが発生します。
OSError: dlopen(/Users/nobi/venv/tf2/lib/libplaidml.dylib, 6): Symbol not found: ____chkstk_darwin
Referenced from: /Users/nobi/venv/tf2/lib/libplaidml.dylib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
in /Users/nobi/venv/tf2/lib/libplaidml.dylib
そのため私のように古い Mac をご利用の方は、ひとつ前の v0.6.4 をインストールしてください。
(tf2) $ pip3 install -U plaidml\<0.7.0
...
Successfully installed
cffi-1.14.1 enum34-1.1.10 pycparser-2.20 plaidml-0.6.4(tf2) $ pip3 install -U plaidml-keras\<0.7.0
...
Successfully installed
keras-2.2.4 keras-applications-1.0.8 pyyaml-5.3.1 plaidml-keras-0.6.4(tf2) $ plaidml-setup
plaidml-setup のログはここでは割愛します。
ご覧になる場合は、文末のリンク先をご参照ください。
Keras の backend について
_
こうして 2 パターンの実行環境ができました。
- TensorFlow v2.3.0(CPU 実行)
- PlaidML v0.6.4(GPU 支援あり) + Keras v2.2.4 + TensorFlow v2.3.0
Keras v2.2.4 は TF2 に対応する前のバージョンのため、backend として TensorFlow v2.3.0 を利用すると以下のエラーが発生し訓練を実行できません。
AttributeError: module 'tensorflow' has no attribute 'get_default_graph'
改善には TensorFlow のダウングレードが必要ですが、backend を PlaidML に差し替えると問題なく実行できます。
現在は keras.json で直接 PlaidML を指定できるようなので、TensorFlow の機能には全く依存していないのかもしれません。
2 つの環境で計測比較
_
それではこの 2 つの環境で 1 epoch 訓練の所要時間と CPU 負荷の計測を行ってみます。
比較用のコードには、Keras の MNIST example を修正して利用しました。
- mnist_mlp.py
- mnist_cnn.py
それぞれのコードの import 文を以下のように変更し、コメントの範囲を切り替えて比較計測を行いました。
#'''
# case : PlaidML + Keras
import plaidml.keras
plaidml.keras.install_backend()from keras.datasets import mnist
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
'''
# case : TensorFlow v2
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import RMSprop
'''
また、なぜか CNN の方は loss, accuracy が良化しない現象が発生しました。
PlaidML での実行時は、pooling op. の MaxPooling2D を AveragePooling2D に差し替えることで改善しました。
#model.add( MaxPooling2D( pool_size = (2, 2)))
model.add( AveragePooling2D( pool_size = (2, 2)))
TF v2.3 による CPU 実行時には上記では改善しなかったのですが、後ほど、optimizer を AdaDelta から MLP と同じ RMSProp に差し替えることで改善しました。
計測時の数値は良化していない時のものですが、所要時間と CPU 使用率には影響ありませんのでご容赦ください。
計測結果の比較
_
テーブルで書きたいのですが、Medium に機能が無いので…
mnist_mlp.py (customized) :
- TensorFlow v2.3.0 (CPU)
* CPU 使用率(最大) : 89 %
* 所要時間 : 16.170 秒 - PlaidML v0.6.4 (GPU) and Keras v2.2.4
* CPU 使用率(最大) : 42 %
* 所要時間 : 23.334 秒
mnist_cnn.py (customized) :
- TensorFlow v2.3.0 (CPU)
* CPU 使用率(最大) : 92 %
* 所要時間 : 188.279 秒 - PlaidML v0.6.4 (GPU) and Keras v2.2.4
* CPU 使用率(最大) : 37 %
* 所要時間 : 316.005 秒
というわけで、GPU 支援を利用すると CPU 負荷は下がりますが、所要時間は 40 〜 70 % ほど増加するという結果になりました。
CPU 実行時は、PlaidML の GPU 実行時と比べて 1 epoch あたりの所要時間が少ないため、訓練の epoch 数を増やすほどにその差は開きそうです。
ただ CPU 実行時は Mac mini のファンがすごい音を発し、とても酷いことをしている気持ちになるのであまりオススメはできません。
また、iMac などであれば今もオプションで dGPU 搭載のモデルを選べますので、今時の新しい GPU を使った場合は結果も異なるのではないかと思います。
長くなりましたので、訓練実行時と CPU 負荷計測時のログは Qiita の方に貼っています。ご興味がありましたらご参照ください。
https://qiita.com/nobilearn/items/1b1b6dc8466793e4d4e4
今回の内容は以上です。
ご精読頂き、まことにありがとうございます。