執筆者:野口 裕貴
監修者:稲葉 貴昭・高橋 浩和
※ 「Isaac Gym入門」連載記事一覧はこちら
1. はじめに
前回の環境構築編では、深層強化学習とIsaac Gymの解説を行い、Isaac Gymの環境構築を行いました。 本稿では、Isaac Gym入門の活用編ということでIsaac Gymでの学習の実行方法について必要な知識等を解説していきます。
2. 実行環境
前回の環境構築編と同じ環境で実施していきます。
- Ubuntu 20.04
- Conda 23.7.4
- Python3.7(conda)
- GeForce RTX 3060 Laptop (VRAM 6GB)
- NVIDIA driver version 535.113.01
- Isaac Gym Preview 4
- Isaac Gym Env Release 1.5.1
実行するタスクによってはシミュレーションの描写がカクつく、またはGPUのメモリ不足による影響で実行できなくなることがあります。 実行する際にパラメータを設定することで一部対処することはできますが、VRAMが8GB以上のNVIDIA GPUを使用することを強く推奨します。
3. Isaac Gymで深層強化学習
3.1 実行方法について
Isaac Gymで深層強化学習を行う際には、IsaacGymEnvs/isaacgymenvs
内にあるtrain.py
を使用します。
train.py
は実行時にコマンドライン引数を渡すことで、学習するタスクを選択することができます。
前回は動作確認として、Cartpole(倒立振子)での学習を実施しましたが、今回はBall Balanceを実行してみます。
Ball Balanceはテーブルの上でボールが落ちないように、テーブルがバランスを取るための動きを学習するタスクとなります。
以下のコマンドから実行できます。
# python3 train.py task=BallBalance
実行すると以下のような画面が表示されます。
コマンドの引数であるtask=
にはそれぞれIsaac Gym Envに用意されているタスク名を指定することで、対応したタスクの学習を行うことができます。
用意されているタスクとして以下のものがあります。
- Ant
四足歩行ロボットが移動する - Humanoid
人型ロボットが移動する - Shadow Hand
ロボットハンド(Shadow Hand)が所持するキューブの向きを目標と一致するよう持ち替える - Allegro Hand
Shadow Handと同じタスク。ただし使用するロボットモデルが異なる - ANYmal
四足歩行ロボット(ANYmal)が平坦な地形を移動する - ANYmal Rough Terrain
ANYmalのタスクと基本的に同じだが、起伏の多い地形を移動する - TriFinger
3本指のロボットハンド(TriFinger)で物体の向きを目標の向きと一致するよう移動させる - NASA Ingenuity Helicopter
小型の自律型ヘリコプター(Ingenuity Helicopter)の単純化されたモデルを使用し、移動する物体を追従する - Cartpole
倒立振子のモデルが棒を倒さないようにする - Ball Balance
上から降ってくるボールを落とさないようにテーブルを制御する - Franka Cabinet
ロボットアームが棚の引き出しを開ける
この他にも、モーションキャプチャーから得られたデータを元に人間の動作を学習させる手法(AMP: Adversarial Motion Priors)を用いたタスクなど複数のタスクが利用できます。
より詳細な情報を確認したい場合は、以下のリンク先を参照してください。
3.2 実行時の引数について
train.py
は実行時に引数を渡すことで様々なオプションを実行することができます。
以下、引数について解説します。
task=
学習するタスクを指定するtrain=
学習に使用するニューラルネットワークのモデルやパラメータなどの設定が記載されたファイルを指定する。指定できるファイルはIsaacGymEnvs/isaacgymenvs/cfg/train
にある。AllegroHandを例に取ると、AllegroHandPPO.yaml
とAllegroHandLSTMPPO.yaml
の2つのファイルが存在する。この2つは明確な違いとしては学習に使用されるニューラルネットワークのモデルが異なるnum_envs=
並行してシミュレーションを行う環境の数。ここでの環境というのは強化学習における環境(Environment)のことを指す。前回の記事で記載した強化学習の概要図での赤丸部分が該当する。環境の数を増やすことで、学習を効率化し、学習にかかる時間を短縮することができる。しかし増やしすぎるとGPUのメモリ不足のエラーが発生しやすくなる。
デフォルトの値はIsaacGymEnvs/isaacgymenvs/cfg/task
にある各タスクのyamlファイルに記載されているseed=
学習におけるランダム性を制御するための値seed
を設定する
(ランダム化される対象:エージェントの初期位置や姿勢など)値を設定することで学習の再現性が確保される。そのため、同じ値で学習や推論を行えば、基本的には常に同じ結果を生成される*1。 デフォルトではこの値は
seed=42
になるように設定されている。再現性に関する詳細な情報はIsaacGymEnvs/docs
にあるreproducibility.mdに記載されているsim_device=
シミュレーションの物理演算に使用されるデバイスを指定する。GPUを使用する場合はcuda:0
。CPUならcpu
とする。デフォルトはsim_device=cuda:0
(GPU)rl_device=
学習に使用されるデバイスを指定する。デフォルトはrl_device=cuda:0
(GPU)graphics_device_id=
シミュレーションの描画に使用するVulkan*2 のグラフィックス デバイス IDを指定する。デフォルトはgraphics_device_id=0
。基本的にはデフォルトの設定で問題ないが、複数のGPUを利用している場合やIDの確認を行いたい場合はvulkaninfo
を実行することで、それぞれのIDで利用できるGPUを確認できる。例として、筆者の実行環境での
vulkaninfo
の実行時の出力を以下に示す。VK_LAYER_LUNARG_standard_validation (LunarG Standard Validation Layer) Vulkan version 1.0.131, layer version 1: Layer Extensions: count = 0 Devices: count = 3 GPU id : 0 (Intel(R) UHD Graphics (CML GT2)) Layer-Device Extensions: count = 0 GPU id : 1 (NVIDIA GeForce RTX 3060 Laptop GPU) Layer-Device Extensions: count = 0 GPU id : 2 (llvmpipe (LLVM 12.0.0, 256 bits)) Layer-Device Extensions: count = 0
ID 0はIntelの統合グラフィクス、ID 1はNVIDIAのGPU、ID 2はグラフィックハードウェアが存在しない場合に出力される。 この場合、筆者は
graphics_device_id=
として、0か1のいずれかを選択することができる。pipeline=PIPELINE
どのAPIパイプラインを使用するか選択できる。GPUパイプラインを使用するとすべてのデータはGPU上に残るため高速に処理が行える。CPUを使用する場合は常に各ステップでCPU↔GPU間でデータのコピーが行われるため、処理が遅くなる。デフォルトはpipeline=gpu
(GPU)test=
デフォルトはtest=False
であり、学習のみが実施される。test=True
に設定することで推論のみが実施され、学習済みの方策の評価を行うことができるcheckpoint=
途中で終了した学習や学習済みの方策を推論するのに使用される。/runs
に保存されているディレクトリを指定することで使用できるheadless=
headless=True
に設定することで、シミュレーションの描写を無効化する。無効化することで描写に割くリソースが削減されるため、学習にかかる時間が短縮されるexperiment=
実験の名前を設定する。推論や再学習の際に使用するチェックポイントの名称を自由に設定可能max_iterations=
タスクを実行する反復回数を指定する。デフォルトの値はIsaacGymEnvs/isaacgymenvs/cfg/task
にある各タスクのyamlファイルに記載されている
これらの引数の説明だけではイメージがしづらいと思いますので、以下に具体的な使用例を紹介します。
1. Antタスク・シミュレーションの描写無効
python3 train.py task=Ant headless=True
描写の無効化を行うと以下のようにTerminal (CUI)から学習の様子を確認できます。
fps step: 41360 fps step and policy inference: 30946 fps total: 30207 epoch: 1/500 frames: 0 fps step: 429814 fps step and policy inference: 380742 fps total: 319300 epoch: 2/500 frames: 65536 fps step: 252399 fps step and policy inference: 232556 fps total: 207916 epoch: 3/500 frames: 131072 fps step: 435901 fps step and policy inference: 372269 fps total: 312375 epoch: 4/500 frames: 196608 fps step: 425134 fps step and policy inference: 363559 fps total: 307593 epoch: 5/500 frames: 262144 fps step: 419380 fps step and policy inference: 359696 fps total: 302603 epoch: 6/500 frames: 327680 fps step: 431078 fps step and policy inference: 369211 fps total: 309127 epoch: 7/500 frames: 393216 fps step: 428803 fps step and policy inference: 367575 fps total: 311003 epoch: 8/500 frames: 458752 fps step: 413447 fps step and policy inference: 354608 fps total: 299470 epoch: 9/500 frames: 524288 fps step: 412243 fps step and policy inference: 353059 fps total: 297661 epoch: 10/500 frames: 589824
2. Antタスク・環境数を制限する
python3 train.py task=Ant num_envs=2048
num_envs
の値を設定すると、学習に使用する環境の数を調整することができます。これにより学習時に割り当てるメモリが削減されるため、今回使用しているGPU(GeForce RTX 3060 Laptop)でも学習を行うことができるようになります。
学習実行時に以下のようにメモリ不足のエラーが出た際にはこのパラメータを調整する必要があります。
[Error] [carb.gym.plugin] Gym cuda error: out of memory: ../../../source/plugins/carb/gym/impl/Gym/GymPhysX.cpp: 1721
しかし注意点もあります。それはコマンドライン引数として渡すnum_envs
は値によっては、デフォルトのnum_envs
よりも値を小さくしたにもかかわらず、メモリ不足のエラーが発生します。
このような場合にはnum_envs
の他にも、学習時の1回毎のパラメータ更新に用いられるデータ数であるminibatch_size
の値を変更するなど、対処する必要があります。*3
3. ShadowHandタスク・LSTM*4での学習
python3 train.py task=ShadowHand train=ShadowHandPPOLSTM
一部のタスクでは使用するニューラルネットワークモデルを変更して学習を行うことができます。
3.3 Isaac Gymの推論とチェックポイント
Isaac Gymは学習の記録をIsaacGymEnvs/isaacgymenvs/runs
にセーブします。
このセーブを行う周期はIsaacGymEnvs/isaacgymenvs/cfg/train
にある各タスクのyamlファイルに記載されているパラメータsave_frequency
の値によって変化します。
例えば、CartPoleの場合はIsaacGymEnvs/isaacgymenvs/cfg/train/CartpolePPO.yaml
に記載されており、パラメータはsave_frequency: 25
となっています。
この値は学習中のepoch数が25の倍数になるたびにチェックポイントのファイルが生成されることを指します。
以下、Cartpoleの学習を完了した際のチェックポイントファイルの一覧です。
gymuser@hiroki:/gymworkspace/IsaacGymEnvs/isaacgymenvs/runs/Cartpole_12-12-40-36/nn$ ls Cartpole.pth last_Cartpole_ep_100_rew__492.75_.pth last_Cartpole_ep_50_rew_484.99435.pth last_Cartpole_ep_100_rew_492.75037.pth last_Cartpole_ep_25_rew_137.96257.pth last_Cartpole_ep_75_rew_491.30405.pth
これを見ると、epoch数が25, 50, 75, 100になるタイミングでチェックポイントが生成されていることがわかります。
また/runs
に生成されるチェックポイントのディレクトリ名は基本的には以下のような規則で命名されます。
# task名 + '_{date:%d-%H-%M-%S}' 例:CartPoleで12月10日の9時25分15秒に実行した場合 # CartPole_10-9-25-15
ただし、コマンドライン引数でexperiment=
で何らかの名称を設定している場合は、前述したtask名の部分が変更されます。
例:CartPoleで12月4日の8時23分35秒に実行 experiment=learning_test_No1に設定 # learning_test_No1_4-8-23-35
生成されたチェックポイントとして使用することで、途中で終了させた学習の再開や、学習済みの方策の推論を行うことができます。
以下に具体的な使用例を示します。
1. Cartpoleタスク・途中で終了させた学習を再開させる場合
python3 train.py task=Cartpole checkpoint=runs/Cartpole_12-12-40-36/nn/Cartpole.pth
コマンド実行時以下のような出力が表示されれば、checkpointの読み込みに成功している
=> loading checkpoint '/gymworkspace/IsaacGymEnvs/isaacgymenvs/runs/Cartpole_12-12-40-36/nn/Cartpole.pth'
2. Cartpoleタスク使用・学習済みの方策を推論し、評価する場合
python3 train.py task=Cartpole checkpoint=runs/Cartpole_12-12-40-36/nn/Cartpole.pth test=True
テスト時には以下のようにsteps数と報酬が表示される。 test終了時には報酬とstep数の平均が表示される。
reward: 499.57 steps: 500.0 reward: 499.55 steps: 500.0 reward: 499.56 steps: 500.0 reward: 499.56 steps: 500.0 1023098.359375 av reward: 499.5597457885742 av steps: 500.0
3.4 学習パラメータの設定方法
学習に使用されるパラメータ等が記載された設定ファイルはyamlファイルで記載されています。 Isaac GymはこのyamlファイルをHydraで管理するようにしています。 これにより、学習に使用される各種変数は対象となるyamlファイルを編集するか、またはコマンドライン引数として設定することもできます。
これらのyamlファイルはisaacgymenvs/cfg/
のディレクトリ内にあります。
学習のタスクに対する設定はisaacgymenvs/cfg/task/
のディレクトリにあり、学習に使用されるパラメータ等の設定はisaacgymenvs/config/train/
内にあります。
task
にあるyamlファイルには
- env
学習環境に関するパラメータ。numEnvs
(環境数)などが該当 - sim
シミュレーションに関するパラメータ。dt
やgravity
(重力加速度)などの物理パラメータなどが該当 - task
環境のランダム化に関するパラメータ。randomize
(ランダム化を有効にするかどうかのフラグ)などが該当
などがあり
train
にあるyamlファイルには
- network
学習に使用するニューラルネットワークモデルの設定 - config
学習時に使用するパラメータ。学習率やバッチサイズなどが該当
などがあります。
これらの設定ファイルはIsaac Gymを用いた学習環境を作成する上で必ず必要となるファイルになります。
4. 最後に
今回はIsaac Gymで学習を実行する上で必要な知識について解説しました。次回はこれらの知識を活用し、オリジナルの学習環境を作成します。
ex. Dockerでの環境構築
前回の環境構築編ではcondaを利用した環境構築のみを紹介しましたが、本稿のおまけとして、Dockerを用いた環境構築についても紹介します。
Isaac GymをDockerで環境構築するためには以下をインストールする必要があります。
- Docker Engine
Dockerを使用するために必要 - NVIDIA Container Toolkit
構築したコンテナでNVIDIA GPUを使用できるようにするために必要
これらに関しては、リンク先を参照して環境構築を行ってください。
上記がインストールし終わった後、前回と同じように、公式のWebsiteからIsaac Gym Preview 4 releaseをダウンロードします。
Isaac Gym - Preview Release | NVIDIA Developer
ダウンロード後、以下のコマンドで展開します。
# tar -xf IsaacGym_Preview_4_Package.tar.gz
展開後、以下のコマンドで環境構築を行ってください。
# cd isaacgym/docker # ./build.sh # ./run.sh $DISPLAY
コンテナを起動できたら、以下のコマンドを実行し、動作確認を行ってください。
# cd python/examples # python3 joint_monkey.py
以下のような画面が出れば、成功です。
これでisaacgym
の機能を使用できるようになります。
しかし、このままでは、本稿で解説したtrain.py
などを含むIsaacGymEnvs
を使用することができません。
そこで構成とファイルを一部編集し、isaacgym
とIsaacGymEnvs
の両方を使用できるようにします。
ファイル構成を以下のように変更してください。
~/gymworkspace ├── isaacgym ├── IsaacGymEnvs └── docker
ホームディレクトリにgymworkspace
という名前のディレクトリを作成し、その中にisaacgym
とIsaacGymEnvs
を入れてください。docker
については後述しますが、isaacgym
にあるdocker
をコピーしたものになります。
以下に作成方法について記載しておきます。
# cd ~ # mkdir gymworkspace # cd gymworkspace # mv ~/Downloads/IsaacGym_Preview_4_Package.tar.gz . # tar -xf IsaacGym_Preview_4_Package.tar.gz # git clone https://github.com/NVIDIA-Omniverse/IsaacGymEnvs.git # cp -r isaacgym/docker ./docker
isaacgym
からコピーしてきたdocker
はそのままでは使用できないので、以下の2つのファイルを編集します。
Dockerfile
run.sh
以下の内容に書き換えてください。
Dockerfile
FROM nvcr.io/nvidia/pytorch:21.09-py3 ENV DEBIAN_FRONTEND=noninteractive # dependencies for gym # RUN apt-get update \ && apt-get install -y --no-install-recommends \ libxcursor-dev \ libxrandr-dev \ libxinerama-dev \ libxi-dev \ mesa-common-dev \ zip \ unzip \ make \ gcc-8 \ g++-8 \ vulkan-utils \ mesa-vulkan-drivers \ pigz \ git \ libegl1 \ git-lfs # Force gcc 8 to avoid CUDA 10 build issues on newer base OS RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8 RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8 # WAR for eglReleaseThread shutdown crash in libEGL_mesa.so.0 (ensure it's never detected/loaded) # Can't remove package libegl-mesa0 directly (because of libegl1 which we need) RUN rm /usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0 /usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0.0.0 /usr/share/glvnd/egl_vendor.d/50_mesa.json COPY docker/nvidia_icd.json /usr/share/vulkan/icd.d/nvidia_icd.json COPY docker/10_nvidia.json /usr/share/glvnd/egl_vendor.d/10_nvidia.json WORKDIR /gymworkspace RUN useradd --create-home gymuser USER gymuser # copy gym repo to docker COPY --chown=gymuser . . # install gym modules ENV PATH="/home/gymuser/.local/bin:$PATH" RUN cd isaacgym/python && pip install -q -e . ENV NVIDIA_VISIBLE_DEVICES=all NVIDIA_DRIVER_CAPABILITIES=all RUN cd IsaacGymEnvs && pip install -q -e .
run.sh
#!/bin/bash set -e set -u if [ $# -eq 0 ] then echo "running docker without display" docker run -it --network=host --gpus=all --name=isaacgym_container isaacgym /bin/bash else export DISPLAY=$DISPLAY echo "setting display to $DISPLAY" xhost + docker run -it --rm -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY --network=host --gpus=all --name=isaacgym_container -v $HOME/gymworkspace:/gymworkspace:rw isaacgym /bin/bash xhost - fi
ファイル編集後、以下のコマンドを実行し、コンテナを作成・実行してください。
# cd ~/gymworkspace/docker # ./build.sh # ./run.sh $DISPLAY
コンテナ起動後、以下のコマンドを実行し、isaacgym
とIsaacGymEnvs
の両方の機能が使用できるかどうか確認してください。
isaacgymの動作確認
# cd isaacgym/python/examples/ # python3 joint_monkey.py
IsaacGymEnvsの動作確認
# cd IsaacGymEnvs/isaacgymenvs # python3 train.py task=Cartpole
両方で動作確認ができれば、dockerでの環境構築は終了となります。
VA Linux は、千葉工業大学 未来ロボティクス学科のロボカップチーム「CIT Brains」をスポンサーとして応援しており、インターン生も数名受け入れています。
本記事は、その一環としてインターン生の野口さんが記事を執筆し、弊社が監修を行いました。
*1:学習に使用されるPyTorchの再現性に関するドキュメントにも記載されているが、同一のシード値を利用しても、使用するCPU、GPUが異なることで計算結果が異なることがあります。
*2:主にゲームなどに使用されるグラフィクスAPIです。OpenGLの後継であり、NVIDIAのGPUの多くはこれをサポートしています。https://developer.nvidia.com/vulkan#vulkan
*3:https://forums.developer.nvidia.com/t/gym-cuda-error-running-out-of-memory
*4:「Long Short Term Memory」と呼ばれるRNN(再帰型 ニューラル ネットワーク)の一種です。