【2021年3月版】Windowsにおける深層学習環境の構築(PlaidML/Keras)

7 min read読了の目安(約6700字

前置き

筆者の環境について

OS: Windows 10 Education Bulld 21337.1000 (Insider Preview)
CPU: Intel Core i7-4790K
GPU: AMD Radeon RX Vega 56
RAM: DDR3-1600 16GB

Windows環境でAMDGPUで深層学習したい

本当はLinuxでやるのが良いんだろうけど,めんどくさいのでメインPCのWindows環境でやりたい.
ROCmでやろうとするとLinuxが必要だし,LinuxのAMDGPU周りはとても混沌としているので出来れば触りたくない.
WSL2からDirectML版のTensorflowを叩けると聞いてInsider Previewを入れて試してみたものの,Preview版のGPUドライバが必要なのが嫌で断念(ゲームにも使うPCなので). ← (2021/3/20追記) 勘違いしてたけどWSL2経由しなくてもWindowsから直接叩けば通常のドライバでもいけるっぽい.
金さえあれば計算用に適当なNvidiaのGPUを載せたサブ機を組みたいが,金がないのでとりあえずこのPCで手軽に(環境を壊さずに)深層学習できるようにしたい.

PlaidML

機械学習のライブラリといえばTensorflowが有名だが,悲しいことにNvidia製以外のGPUでは基本的に扱えない.
筆者はAMDGPUなのでtensorflow-rocmなりtensorflow-directmlなり使えば使えなくもないが、前者は環境構築が面倒だし後者は執筆時点で正式リリースされていない.
OpenCLで動く機械学習ライブラリがあれば動くのでは?と思って探してみたらPlaidMLというものがヒットしたので今回はそれを用いる.Tensorflow同様Kerasのバックエンドとして使用できる模様.

https://plaidml.github.io/plaidml/
WindowsやLinuxは勿論のこと,macOSでも動くとのこと.

Scoop

筆者は普段使いにWindowsを使用しているが,Windowsが好きかと言われるとそういう訳でもなく,むしろLinuxの方が好きである.普段の開発も大抵はWSL2上のArch Linuxで行っている.
WindowsはLinuxの各ディストリビューションで見られるような洗練されたパッケージ管理システムが無いため,基本的に各ソフトウェアは個別のインストーラーからインストールする事になる.
(最近はMicrosoftよりwingetというパッケージマネージャのPreview版が提供されているが,まだまだ発展途上といったところ)
Linuxにある程度慣れ親しんだ身としてはそれが嫌なので、環境構築の際はScoopというパッケージ管理システムを使用している.ざっくり言うとHomebrewのWindows版といった感じである.

https://scoop.sh

手順

1. Scoopのインストール

本稿ではScoopを用いてPythonをインストールするので,まずはScoopをインストールする必要がある.
既にPythonをインストールしている場合は手順3まで飛ばしてよい.ただしpipを用いるのでAnacondaを使用している場合は要注意.
Powershellより以下のコマンドを実行する.

iwr -useb get.scoop.sh | iex

もしエラーが出た場合は以下を実行してから再度実行するとよい.

Set-ExecutionPolicy RemoteSigned -scope CurrentUser

2. Pythonのインストール

機械学習で使われるモジュールは最新版のPythonだと動作しない可能性があるので,Python3.6をインストールしておくとよい.
でも機械学習以外では最新のPythonを使いたいので,最新版と3.6を共存させる必要がある.

scoop bucket add versions #過去のバージョンをインストールする際に必要
scoop install python python36 #最新版のPythonとPython3.6をインストール
scoop reset python #機械学習以外では最新のPythonを使いたいので,最新版のPythonをデフォルトにする.

Pythonの各バージョンが起動するか確認.

python
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
python36
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()

pipにPathが通っているかも確認.もし通っていない場合は以下をPathに追加する.
C:\Users<username>\scoop\apps\python\current\Scripts

3. Python3.6の仮想環境を作成

virtualenvを用いて,Python3.6の仮想環境を作成する.

pip install virtualenv
virtualenv -p python3.6 plaidml
plaidml\Scripts\activate

ここで,インストールされていない(Pathが通っていない)バージョンを指定すると以下のエラーが発生する.

virtualenv -p python3.8 plaidml
RuntimeError: failed to find interpreter for Builtin discover of python_spec='python3.8'

4. plaidml-kerasのインストール

(plaidml) pip install plaidml-keras

この際にh5pyというモジュールの最新版もインストールされるが,最新版だとエラーが発生する為,一度アンインストールしてバージョン2.10.0をインストールする.
尚,h5py 2.10.0はPython 3.9以上だとインストールに失敗する.

(plaidml) pip uninstall h5py
(plaidml) pip install h5py==2.10.0

5. PlaidMLの設定

PlaidMLの設定を行う.
"Enable experimental device support?"は"Default Config Device"の欄に使用したいGPUが記載されていない場合のみyにする.
"Default device?"のところでllvm.cpuを選択するとCPU処理になってしまうので,必ずGPU(AMDの場合はopencl_amd_gfxxx)を選択する.

(plaidml)  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)
   opencl_amd_gfx900.0 : Advanced Micro Devices, Inc. gfx900 (OpenCL)

Experimental Config Devices:
   llvm_cpu.0 : CPU (via LLVM)
   opencl_amd_gfx900.0 : Advanced Micro Devices, Inc. gfx900 (OpenCL)

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

Enable experimental device support? (y,n)[n]:n

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

   1 : llvm_cpu.0
   2 : opencl_amd_gfx900.0

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

Selected device:
    opencl_amd_gfx900.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 C:\Users\<username>\.plaidml? (y,n)[y]:y
Success!

6. 動作確認

まずはベンチマークを動かしてみる.以下は正常に動作した場合.

(plaidml) pip install plaidbench
(plaidml) plaidbench keras mobilenet
Running 1024 examples with mobilenet, batch size 1, on backend plaid
INFO:plaidml:Opening device "opencl_amd_gfx900.0"
Compiling network... Warming up... Running...
Example finished, elapsed: 7.136s (compile), 8.838s (execution)

-----------------------------------------------------------------------------------------
Network Name         Inference Latency         Time / FPS
-----------------------------------------------------------------------------------------
mobilenet            8.63 ms                   1.37 ms / 728.21 fps
Correctness: PASS, max_error: 1.8053706298815086e-05, max_abs_error: 9.760260581970215e-07, fail_ratio: 0.0

何らかのエラーが発生した場合は,Pythonやh5pyのバージョンやPlaidMLの設定を確認する.

Kerasのバックエンドとして正常にPlaidMLを使用できるかについても確認しておく.
以下のコードを実行する."plaidml"と出力されればOK.

import plaidml.keras
plaidml.keras.install_backend()
import keras
print(keras.backend.backend())

筆者の環境では問題なくplaidmlと出力された.
tensorflow等になっている場合はKERAS_BACKEND環境変数をplaidml.keras.backendに設定すればよいと思われる(以下の記事参照).

https://qiita.com/lindq_yu/items/0f7543bc1d426cb36f31

おわりに

これで環境構築は一通り終わり.
Kerasを用いたプログラムを書く際は,頭に

import plaidml.keras
plaidml.keras.install_backend()

と記述すればKerasのバックエンドとしてPlaidMLを使用できる.

仮想環境から抜けたいときは、仮想環境を作成したディレクトリ上で以下のコマンドを実行する.

deactivate

PlaidMLはOpenCL1.2が動くハードウェアであれば動く(筈)なのだが,Navi世代以降のAMDGPUでは現状動かないらしい(筆者は所持していないので検証不可).
現在新品で出回っているAMDGPUはほぼNavi世代以降のものなので,機械学習を考慮してGPUの購入を検討している方はNvidia GPUを購入した方が恐らく幸せになれるだろう.

参考文献

Windowsで環境を極力汚さずにPythonを動かす方法 (Scoop編) - Qiita

https://qiita.com/rhene/items/a5616857981293d06940
【対応例】AttributeError: ‘str’ object has no attribute ‘decode’ | 子供プログラマー
https://child-programmer.com/h-error/