ML-Agents + SACで学習中にMultiProcessingのエラーで落ちてしまう現象の対策法
結論
Python 3.11.3以上にしましょう。
問題が発生した環境
MacBook Pro (14インチ, M2 Pro, 2023)
Python 3.9.16
ml-agents 0.30.0 (release-20)
ml-agents-envs 0.30.0 (release-20)
問題発生の経緯
ML-Agentsは、Unityで強化学習が出来る便利なパッケージです。
今回、ML-AgentsのSACという強化学習アルゴリズムを使って強化学習をしていたところ、以下のようなエラーで学習が途中で止まってしまう現象に遭遇しました。
UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown
どうやら並列処理のプロセス解放がうまくいかずにエラーとなっているようです。
ML-Agentsには並列処理によって高速化を行うthreadedというオプションがあり、それを無効にして試してみたのですが、それでも同様のエラーが発生しました。もう一つの強化学習アルゴリズムであるPPOでは発生しなかったので、SACはthreadedの有効無効に関係なく、(おそらくポリシーのアップデートなどのために)内部で並列処理をしているのでしょう。
この現象が発生する頻度が10回の学習に対して1回とかなら(強化学習の性質上、学習の開始から完了まで何日もかかるのはザラなので本当は嫌ですが)まだ許容できるのですが、1000万回ほどステップを回すとほぼ確実に発生してしまうので、3000万回のステップが必要な今回のタスクでは、そもそも学習が完了できないという困ったことになってしまいました。
エラー文でググったところ、ML-Agentsに限らず並列処理を使った多くのライブラリのリポジトリに同様の問題が報告されていました。どうやら、Pythonの標準ライブラリのmultiprocessingの問題のようです。
もう少し調べていくと、この問題を指摘しているissueが見つかりました。
確かに、ここに記載されている問題再現用スクリプトを実行してみると、同じエラーが発生します。さらに、ここに記載されているPRの変更を手元の環境に適用してみるとエラーが出なくなりました。言い訳をすると、普段はこんな対処はしないのですが、僕が使っていたPythonが2022年の12月にリリースされた3.9.16で、このPRが2022年の11月末のものだったので、この修正だけでも反映すればとりあえず応急的に使えるだろうと思ったのです。
再現用スクリプトでエラーが解消できたのが嬉しくて、この時点で早とちりしてツイートしました。
ところが、上記のissueの再現スクリプトのエラーは解消できたにも関わらず、ML-Agentsでは相変わらずエラーが発生していました。
よく調べてみると、僕が使っていたPython 3.9.16に対してメインラインの変更は2022年の5月分までしか反映されていませんでした。
ということは、この問題の原因は他にもありそうです。関連する修正を探してきて手動で反映してもよかったのですが、ここまでくると正式にリリースされているものを使いたくなってきます。
上記のPRが反映されたリリースを探したところ、Python 3.11.3がヒットしました。これをインストールすることにします。
Python環境の再構築
Python3.11.3のインストール
もともと、ML-Agentsの正式なサポートがPython 3.9.xまでだったため、pyenvを使ってML-Agents用に3.9.16を入れていました。今回も同様に、pyenvを使って3.11.3を入れます。僕の環境では、3.11.3を入れるためにpyenvのアップデートが必要でした。
ml-agentsとml-agents-envsのインストール
ML-Agentsを動かすために必要なパッケージをインストールします。インストールは公式の方法に従って以下のコマンドで行います。
% pip3 install -e ./ml-agents-envs
% pip3 install -e ./ml-agents
すると、ML-Agentsが依存しているライブラリのバージョンが合わずにエラーが出ました。この辺りも修正する必要がありそうです。
いろいろバージョンを変えて相性の良い組み合わせを探した結果、最終的に以下のようにsetup.pyの`install_requires`に記述されているバージョン指定を変更しました。
ml-agents/setup.py
...
install_requires=[
"cloudpickle",
"grpcio>=1.11.0",
"numpy>=1.14.1",
"Pillow>=4.2.1",
"protobuf~=3.20.0",
"pyyaml>=3.1.0",
"gym>=0.21.0",
"pettingzoo>=1.15.0",
"numpy~=1.23.0",
"filelock>=3.4.0",
],
...
ml-agents-envs/setup.py
...
install_requires=[
# Test-only dependencies should go in test_requirements.txt, not here.
"grpcio>=1.11.0",
"h5py>=2.9.0",
f"mlagents_envs=={VERSION}",
"numpy~=1.23.0",
"Pillow>=4.2.1",
"protobuf~=3.20.0",
"pyyaml>=3.1.0",
# Windows ver. of PyTorch doesn't work from PyPi. Installation:
# https://github.com/Unity-Technologies/ml-agents/blob/release_20_docs/docs/Installation.md#windows-installing-pytorch
# Torch only working on python 3.9 for 1.8.0 and above. Details see:
# https://github.com/pytorch/pytorch/issues/50014
"torch>=1.8.0;(platform_system!='Windows' and python_version>='3.9')",
"torch>=1.6.0,<1.9.0;(platform_system!='Windows' and python_version<'3.9')",
"tensorboard>=1.15",
# cattrs 1.1.0 dropped support for python 3.6, but 1.0.0 doesn't work for python 3.9
# Since there's no version that supports both, we have to draw the line somwehere.
"cattrs<1.1.0; python_version<'3.8'",
"cattrs>=1.1.0,<1.7; python_version>='3.8'",
"attrs>=19.3.0",
'pypiwin32==223;platform_system=="Windows"',
"importlib_metadata==4.4; python_version<'3.8'",
],
...
インストールが無事終わったら、`mlagents-learn --help`を試してみます。
% mlagents-learn --help
usage: mlagents-learn [-h] [--env ENV_PATH] [--resume] [--deterministic] [--force] [--run-id RUN_ID] [--initialize-from RUN_ID] [--seed SEED] [--inference] [--base-port BASE_PORT] [--num-envs NUM_ENVS]
[--num-areas NUM_AREAS] [--debug] [--env-args ...] [--max-lifetime-restarts MAX_LIFETIME_RESTARTS] [--restarts-rate-limit-n RESTARTS_RATE_LIMIT_N]
[--restarts-rate-limit-period-s RESTARTS_RATE_LIMIT_PERIOD_S] [--torch] [--tensorflow] [--results-dir RESULTS_DIR] [--width WIDTH] [--height HEIGHT] [--quality-level QUALITY_LEVEL]
[--time-scale TIME_SCALE] [--target-frame-rate TARGET_FRAME_RATE] [--capture-frame-rate CAPTURE_FRAME_RATE] [--no-graphics] [--torch-device DEVICE]
[trainer_config_path]
...
うまく実行できました。
実際に学習を回したところ、エラーが発生することなく学習を無事に終えることができました。めでたしめでたし。
まとめ
今回の問題はMacもしくはLinuxのPython 3.8.x以降で確認されているようですが、Intel Mac + Python 3.8.xでは発生せず、M2 Mac + Python 3.9.xでは発生したため、いろいろな原因が絡み合っていそうです。現在使っているバージョンのPythonにこの修正が反映されるまでは、Python 3.11.3を使うか、PPOを使いましょう。
この記事が気に入ったらサポートをしてみませんか?