作成した機械学習のプログラムをPythonがインストールされていないWindows環境で動作させるために試行錯誤したメモ。
環境は以下の通り
- Python 3.6.8
- PyInstaller 4.0
- Windows 10 x64
PyInstallerの基本的な使い方
インストール
$ pip install pyinstaller
exeファイル作成
$ pyinstaller main.py --onefile
これで、Pythonの実行環境や関連ライブラリもまとめて1つのexeファイルにまとめてくれる。
ただし、PyInstallerが解決できない依存関係があったりすると、作ったexeファイルがエラーを吐く。
その場合は、--onefile
オプションを使わずにビルドして、以下の2点を1つずつ解消していくとよい。
Pyinstallerでうまくexe化できないとき
*.so not found
が出る
依存している外部ライブラリのバイナリを取り込めていない。直接参照しているものはPyInstallerが自動で取り込んでくれるようだが、間接的に参照しているものは考慮してくれない様子。
--add-binary
オプションで明示的に取り込むように指定すればよい。
Pathの指定の仕方が特殊なので注意
--add-binary "<取り込み元のSOファイルの相対パス>;<配置先のディレクトリの実行時相対パス>"
パスの指定の仕方が正しく記述できているはずなのにうまく配置されない
キャッシュが残っていて悪さをしているようだったので、--clean
オプションをつけると指定した通りに配置されるようになった。
ModuleNotFoundError
が出る
こちらも同様に外部ライブラリが取り込めていない。Pythonのライブラリ系で間接的に参照しているものが該当する様子。
pyinstaller実行時にhidden-importで指定すればよい。
追加しながら、exe化を繰り返して、ModuleNotFoundErrorがなくなるまで続ける。
例えば、tensorflowを使ったテキスト分類プログラムを作った場合はこんな感じになった。
$ pyinstaller main.py ¥
--hidden-import=tensorflow.python.keras.engine.base_layer_v1 ¥
--hidden-import=tensorflow.python.ops.while_v2 ¥
--hidden-import=tensorflow.python.ops.numpy_ops
最終的なpyinstallerの実行時オプション
例えばこんな感じになる。
$ pyinstaller main.py --onefile -y --clean \
--hidden-import=tensorflow.python.keras.engine.base_layer_v1 \
--hidden-import=tensorflow.python.ops.while_v2 \
--hidden-import=tensorflow.python.ops.numpy_ops \
--add-binary "../../../../AppData/Local/Programs/Python/Python36/lib/site-packages/tensorflow/lite/experimental/microfrontend/python/ops/_audio_microfrontend_op.so;tensorflow/lite/experimental/microfrontend/python/ops"