こんにちは!ABEJA で ABEJA Platform 開発を行っている坂井(@Yagami360)です。
先日の記事では、NVIDIA のロボティクス用3Dシミュレーター「Isaac Sim & Lab」を使用して、物理演算が考慮された3Dシミュレーター上でロボティクスモデルを学習させたり推論させたりしながらロボットを動かす方法を紹介しました。
今回の記事では、同じく Isaac Sim & Lab を使用して、シミュレーター上でのロボット遠隔操作や Isaac Lab Mimic により、ロボティクスモデルの学習用データセットを生成したり、生成したデータセットでモデルを学習&推論する方法を紹介します。
なお Isaac Sim & Lab の3Dシミュレーターを動かすための各種環境構築に関しては、前回の記事を見てもらえればと思います。本記事では環境構築後の手順を紹介します。
- 何故シミュレーター上での学習用データセットを作成するのか?
- 単腕アームロボット(Franka)でオブジェクトを積みあげるタスク用の学習用データセットを生成する
- Isaac Lab Mimic を使用したデータセット自動生成効果の定量評価
- まとめ
- We Are Hiring!
何故シミュレーター上での学習用データセットを作成するのか?
Isaac Sim & Lab を使用したシミュレーター上での学習用データセット作成のやり方を述べる前に、何故シミュレーター上で学習用データセットを作成するのかという意義から説明します。
ロボティクス領域では近年 VLA モデルの活用が進んできていますが、VLA などの Transformer ベースのモデルはデータハングリーなモデルであり、大量の学習用データセットが必要になります(事後学習では少なくともOKですが、事前学習だと大量の学習用データセットが必要です)。また模倣学習で行う場合も、正解データが含まれる学習用データセットが多く必要になってきます。
しかしながら、インターネット上に公開されている OSS のロボティクス用の学習用データセットには限りがあります。
実際にロボットを人手で動かしながら学習用データセットを作成する方法も存在しますが、ロボットの実機が必要で、なおかつ人手での骨の折れる作業であり、特に大量の学習用データセットを作成しようとすると困難になるのかと思ってます。
そのため、シミュレーター上でより手軽かつ自動的に学習用データセットを大量生成することが重要になってきます。
単腕アームロボット(Franka)でオブジェクトを積みあげるタスク用の学習用データセットを生成する
本記事で紹介する学習用データセット生成のためのワークフローは以下のような図になります

シミュレーター上での手動遠隔操作により少数の学習用データセットを作成する
まずは、シミュレーター上のロボットへの手動遠隔操作(Teleoperation)により少数の学習用データセットを作成します。 幸い Isaac Lab ではそのためのスクリプトを公開しているので、提供されているスクリプトを下記手順で実行するだけで良いです。
この際に設定可能なシミュレーター上のロボットを遠隔操作するための入力デバイスとしては、{キーボード・SpaceMouse・ハンドトラッキング付きXRデバイス}が利用できます。 キーボードがもっとも手軽ですが、思い通りにロボットを操作するのが難しいと思います。
ロボット遠隔操作(Teleoperation)による学習用データセット作成スクリプトを実行する
キーボードで操作する場合
mkdir -p datasets/teleop_franka ./isaaclab.sh -p scripts/tools/record_demos.py \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --teleop_device keyboard \ --dataset_file datasets/teleop_franka/dataset.hdf5 \ --num_demos 10今回の例では、単腕アームロボット(Franka)でオブジェクトを積みあげるための学習用データセットを作成したいので、
—-task引数にIsaac-Stack-Cube-Franka-IK-Rel-v0を設定します。その他のロボットやタスクでの学習用データセットを作成したい場合は、以下ページの定義済み環境一覧のものを
—-task引数に設定すればよいです。シミュレーター起動後、以下のキーボード入力でロボット遠隔操作できるので、
--num_demos引数の回数分の成功タスク(今回の場合は、物を掴んで積み上げるタスク)をデモンストレーションしてください。デモ中に操作ミスした場合は、Rキーでキャンセルして再実行してくださいKeyboard Controller for SE(3): Se3Keyboard Reset all commands: R Toggle gripper (open/close): K Move arm along x-axis: W/S Move arm along y-axis: A/D Move arm along z-axis: Q/E Rotate arm along x-axis: Z/X Rotate arm along y-axis: T/G Rotate arm along z-axis: C/V以下動画は実際にキーボード入力しながらロボットを手動遠隔操作している様子です。 (VNCサーバー経由で Mac 上にGUI表示させているのでネットワーク遅延等でレンダリング遅延が発生していますが、Ubuntu Descktop 環境や WIndows 環境で直接 Isaac Sim を動かせばこのような遅延なく動かせると思います)

SpaceMouse で操作する場合
mkdir -p datasets/teleop_franka ./isaaclab.sh -p scripts/tools/record_demos.py \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --teleop_device spacemouse \ --dataset_file datasets/teleop_franka/dataset.hdf5 \ --num_demos 10SpaceMouse で操作する場合は、先程のキーボード操作のスクリプトで
—teleop_device引数をspacemouseに指定するだけで良いです。手元の環境に SpaceMouse のデバイスをもっていなかったので試していませんが、キーボード操作よりロボットを操作しやすいと思います。ハンドトラッキング付きXRデバイスで操作する場合
mkdir -p datasets/teleop_franka ./isaaclab.sh -p scripts/tools/record_demos.py \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --teleop_device handtracking_abs \ --dataset_file datasets/teleop_franka/dataset.hdf5 \ --num_demos 10ハンドトラッキング付きXRデバイスで操作する場合は、
—teleop_device引数をhandtracking_absを指定してください。手元の環境にXRデバイスをもっていなかったので試していませんが、キーボード操作よりロボットを操作しやすいと思います。
本スクリプトで作成される HDF5形式でのデータセットは、以下のような構造になっています。
demo_Xが各エピソードのデータで、各エピソード毎にロボットの action, state, observation のデータが格納されており、模倣学習に適したデータ構造になっていることがわかるかと思います。h5ls -r dataset.hdf5/ Group /data Group /data/demo_0 Group /data/demo_0/actions Dataset {236, 7} /data/demo_0/initial_state Group /data/demo_0/initial_state/articulation Group /data/demo_0/initial_state/articulation/robot Group /data/demo_0/initial_state/articulation/robot/joint_position Dataset {1, 9} /data/demo_0/initial_state/articulation/robot/joint_velocity Dataset {1, 9} /data/demo_0/initial_state/articulation/robot/root_pose Dataset {1, 7} /data/demo_0/initial_state/articulation/robot/root_velocity Dataset {1, 6} /data/demo_0/initial_state/rigid_object Group /data/demo_0/initial_state/rigid_object/cube_1 Group /data/demo_0/initial_state/rigid_object/cube_1/root_pose Dataset {1, 7} /data/demo_0/initial_state/rigid_object/cube_1/root_velocity Dataset {1, 6} /data/demo_0/initial_state/rigid_object/cube_2 Group /data/demo_0/initial_state/rigid_object/cube_2/root_pose Dataset {1, 7} /data/demo_0/initial_state/rigid_object/cube_2/root_velocity Dataset {1, 6} /data/demo_0/initial_state/rigid_object/cube_3 Group /data/demo_0/initial_state/rigid_object/cube_3/root_pose Dataset {1, 7} /data/demo_0/initial_state/rigid_object/cube_3/root_velocity Dataset {1, 6} /data/demo_0/obs Group /data/demo_0/obs/actions Dataset {236, 7} /data/demo_0/obs/cube_orientations Dataset {236, 12} /data/demo_0/obs/cube_positions Dataset {236, 9} /data/demo_0/obs/eef_pos Dataset {236, 3} /data/demo_0/obs/eef_quat Dataset {236, 4} /data/demo_0/obs/gripper_pos Dataset {236, 2} /data/demo_0/obs/joint_pos Dataset {236, 9} /data/demo_0/obs/joint_vel Dataset {236, 9} /data/demo_0/obs/object Dataset {236, 39} /data/demo_0/states Group /data/demo_0/states/articulation Group /data/demo_0/states/articulation/robot Group /data/demo_0/states/articulation/robot/joint_position Dataset {236, 9} /data/demo_0/states/articulation/robot/joint_velocity Dataset {236, 9} /data/demo_0/states/articulation/robot/root_pose Dataset {236, 7} /data/demo_0/states/articulation/robot/root_velocity Dataset {236, 6} /data/demo_0/states/rigid_object Group /data/demo_0/states/rigid_object/cube_1 Group /data/demo_0/states/rigid_object/cube_1/root_pose Dataset {236, 7} /data/demo_0/states/rigid_object/cube_1/root_velocity Dataset {236, 6} /data/demo_0/states/rigid_object/cube_2 Group /data/demo_0/states/rigid_object/cube_2/root_pose Dataset {236, 7} /data/demo_0/states/rigid_object/cube_2/root_velocity Dataset {236, 6} /data/demo_0/states/rigid_object/cube_3 Group /data/demo_0/states/rigid_object/cube_3/root_pose Dataset {236, 7} /data/demo_0/states/rigid_object/cube_3/root_velocity Dataset {236, 6} /data/demo_1 Group /data/demo_1/actions Dataset {233, 7} /data/demo_1/initial_state Group /data/demo_1/initial_state/articulation Group /data/demo_1/initial_state/articulation/robot Group /data/demo_1/initial_state/articulation/robot/joint_position Dataset {1, 9} /data/demo_1/initial_state/articulation/robot/joint_velocity Dataset {1, 9} /data/demo_1/initial_state/articulation/robot/root_pose Dataset {1, 7} /data/demo_1/initial_state/articulation/robot/root_velocity Dataset {1, 6} /data/demo_1/initial_state/rigid_object Group /data/demo_1/initial_state/rigid_object/cube_1 Group /data/demo_1/initial_state/rigid_object/cube_1/root_pose Dataset {1, 7} /data/demo_1/initial_state/rigid_object/cube_1/root_velocity Dataset {1, 6} /data/demo_1/initial_state/rigid_object/cube_2 Group /data/demo_1/initial_state/rigid_object/cube_2/root_pose Dataset {1, 7} /data/demo_1/initial_state/rigid_object/cube_2/root_velocity Dataset {1, 6} /data/demo_1/initial_state/rigid_object/cube_3 Group /data/demo_1/initial_state/rigid_object/cube_3/root_pose Dataset {1, 7} /data/demo_1/initial_state/rigid_object/cube_3/root_velocity Dataset {1, 6} /data/demo_1/obs Group /data/demo_1/obs/actions Dataset {233, 7} /data/demo_1/obs/cube_orientations Dataset {233, 12} /data/demo_1/obs/cube_positions Dataset {233, 9} ...なお、この方法で作成したデータセットは、https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5/Isaac/IsaacLab/Mimic/dataset.hdf5 からダウンロードすることもできるので、自身で上記操作でデータセット作成するのが難しい場合は、このデータセットを利用して以降の操作を行ってもOKです。
作成した学習用データセットでロボットを動かす
上記作成した学習用データセットが正しい内容になっているか確認するため、学習用データセットに従ってロボットを動かしてみます。Isaac Lab ではそのためのスクリプトも提供しているので、これを利用します。
./isaaclab.sh -p scripts/tools/replay_demos.py \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --dataset_file datasets/teleop_franka/dataset.hdf5—dataset_fileに先ほど作成した学習用データセットのパスを指定してください。スクリプト実行後にシミュレーターが起動するので、以下動画のように学習用データセットの内容に従ってロボットが正しく動いていることを確認してください。(動画はある1エピソード分の動作になっています)

Isaac Lab Mimic を使用して少数の学習用データセットから大量の学習用データセットを自動作成する
ロボティクスモデルに限らずですが、AIモデルでは大量の学習用データセットが必要です(特に VLA などの transformer ベースのアーキテクチャの場合はそれが顕著)。しかしながら上記のロボット手動遠隔操作による学習用データセット作成は人手による方法であり、数に限界があります。
Isaac Lab では、この問題を解決するために人手による少数のデモンストレーションでの学習用データセットから大量の学習用データセットを自動生成するための機能である「Isaac Lab Mimic」を提供しています。
Isaac Lab Mimic では、"state-based policy" か "visuomotor policy" という行動方策(ポリシー)に基づき、学習用データセットを自動生成できるようです。
Isaac Lab のドキュメントに、これらポリシーの説明がなかったですが、恐らく、state-based policy がロボットの状態(例:ロボットの関節角度、位置、速度など)のみを入力として行動を決定する行動方策(ポリシー)で、visuomotor policy がロボットの状態に加えて、カメラ画像などの視覚情報も観測データ(observation)として入力し行動を決定する行動方策(ポリシー)なんだと思います。
詳細が気になる方は、以下の Isaac Lab Mimic 提供スクリプトの中身の実装を見れば良いかと思います。
今回は、カメラ画像なしでの学習用データセット生成を行なうので、state-based policy を使用して学習用データセットを自動生成します。
シミュレーター上の手動遠隔操作で作成した少数の学習用データセットに(自動データ生成のための)アノテーションを付与する
まずは少数のデータセットから大量のデータセットを自動生成するためのアノテーションをデータセットに付与する必要があります。このアノテーション付与操作は、Isaac Lab Mimic が提供している以下のスクリプトを実行するだけでよいです。
state-based policy を使用する場合
./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/annotate_demos.py \ --device cuda \ --task Isaac-Stack-Cube-Franka-IK-Rel-Mimic-v0 \ --auto \ --input_file datasets/teleop_franka/dataset.hdf5 \ --output_file datasets/teleop_franka/annotated_dataset.hdf5--auto引数を指定することで自動でアノテーション付与を行ってくれます。state-based policy を使用した場合、アノテーションが付与されたデータセットの具体的な中身は以下のようになっており、
obs/datagen_infoにアノテーションデータが付与されてます。(base) sakai@sakai-gpu-dev-2:~/personal-repositories/ai-robotics-exercises/datasets/teleop_franka$ h5ls -r annotated_dataset.hdf5 / Group /data Group /data/demo_0 Group /data/demo_0/actions Dataset {236, 7} /data/demo_0/initial_state Group /data/demo_0/initial_state/articulation Group /data/demo_0/initial_state/articulation/robot Group /data/demo_0/initial_state/articulation/robot/joint_position Dataset {1, 9} ... /data/demo_0/obs Group /data/demo_0/obs/actions Dataset {236, 7} /data/demo_0/obs/cube_orientations Dataset {236, 12} /data/demo_0/obs/cube_positions Dataset {236, 9} **/data/demo_0/obs/datagen_info Group /data/demo_0/obs/datagen_info/eef_pose Group /data/demo_0/obs/datagen_info/eef_pose/franka Dataset {236, 4, 4} /data/demo_0/obs/datagen_info/object_pose Group /data/demo_0/obs/datagen_info/object_pose/cube_1 Dataset {236, 4, 4} /data/demo_0/obs/datagen_info/object_pose/cube_2 Dataset {236, 4, 4} /data/demo_0/obs/datagen_info/object_pose/cube_3 Dataset {236, 4, 4} /data/demo_0/obs/datagen_info/subtask_term_signals Group /data/demo_0/obs/datagen_info/subtask_term_signals/grasp_1 Dataset {236} /data/demo_0/obs/datagen_info/subtask_term_signals/grasp_2 Dataset {236} /data/demo_0/obs/datagen_info/subtask_term_signals/stack_1 Dataset {236} /data/demo_0/obs/datagen_info/target_eef_pose Group /data/demo_0/obs/datagen_info/target_eef_pose/franka Dataset {236, 4, 4}** /data/demo_0/obs/eef_pos Dataset {236, 3} /data/demo_0/obs/eef_quat Dataset {236, 4} /data/demo_0/obs/gripper_pos Dataset {236, 2} /data/demo_0/obs/joint_pos Dataset {236, 9} /data/demo_0/obs/joint_vel Dataset {236, 9} /data/demo_0/obs/object Dataset {236, 39} /data/demo_0/states Group /data/demo_0/states/articulation Group /data/demo_0/states/articulation/robot Group /data/demo_0/states/articulation/robot/joint_position Dataset {236, 9} ...
アノテーション付与した少数の学習用データセットから大量の学習用データセットを自動生成する
次に、上記アノテーション付与した少数の学習用データセットから大量の学習用データセットを自動生成します。これには同じく Isaac Lab Mimic が提供している以下のスクリプトを実行するだけで良いです。
state-based policy を使用する場合
./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/generate_dataset.py \ --device cuda \ --headless \ --num_envs 10 \ --generation_num_trials 1000 \ --input_file datasets/teleop_franka/annotated_dataset.hdf5 \ --output_file datasets/teleop_franka/generated_dataset.hdf5
--generation_num_trials引数の値で自動作成する学習用データセットのレコード数を指定し、—-output_file引数に自動生成する学習用データセットのファイルパスを指定してください。今回のスクリプト例では
generated_dataset.hdf5に自動生成に成功した学習用データセットが保存され、generated_dataset_failed.hdf5に自動生成に失敗したデータセットが保存されます。手動遠隔操作で作成した学習用データセットは 10 エピソード分だけの少数でしたが、
--generation_num_trials引数で指定した 1000 エピソード分の大量の学習用データセットになっていることがわかります。# もともとの学習用データセットのエピソード数を確認 (base) sakai@sakai-gpu-dev-2:~/personal-repositories/ai-robotics-exercises/datasets/teleop_franka$ h5ls dataset.hdf5/data/ | wc -l 10 # Isaac Lab Mimic で自動生成した学習用データセットのエピソード数を確認 (base) sakai@sakai-gpu-dev-2:~/personal-repositories/ai-robotics-exercises/datasets/teleop_franka$ h5ls generated_dataset.hdf5/data/ | wc -l 1000自動生成した学習用データセットでロボットを動かす
上記自動生成した学習用データセットが正しいものになっているか確認するため、再度学習用データセットに従ってロボットを動かします
./isaaclab.sh -p scripts/tools/replay_demos.py \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --dataset_file datasets/teleop_franka/generated_dataset.hdf5スクリプト実行後にシミュレーターが起動するので、以下動画のように学習用データセットの内容に従ってロボットが正しく動いていることを確認してください。(動画はある1エピソード分の動作です)

自動生成した学習用データセットでモデルを模倣学習する
大量の学習用データセットが生成できたので、今度は実際にこのデータセットを使用してロボティクスモデルを模倣学習させてみます。
今回の方法で作成したデータセットは HDF5形式でのデータセットですが、Isaac Lab ではこのHDF5形式データセットでそのまま模倣学習できるスクリプトも提供しているのでこれを利用します
./isaaclab.sh -p scripts/imitation_learning/robomimic/train.py \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --algo bc \ --normalize_training_actions \ --dataset datasets/teleop_franka/generated_dataset.hdf5
このスクリプト内部では、Robomimic というスタンフォード大学が開発した模倣学習のための OSS フレームワークを使用して学習を行っているようです。
Robomimic は、Behavior Cloning(--algo bc で指定可能)などの古典的な模倣学習のモデルはサポートしているようですが、最新の VLA モデルなどは現時点サポートされていないようでした。
LeRobot にある π0、SmolVLA や Isaac-GR00T のなどの最新の VLA モデルで学習を行いたい場合は、この HDF5 形式のデータセットを LeRobot の学習用データセットの形式に変換する必要があります。
但し、この変換用のスクリプトは現時点で Isaac Lab では提供されていないようなので、LeRobot にある VLA モデルでの学習に利用したければ自身で変換スクリプトを自作する必要があると思います。(この辺の異なるツールやフレームワーク間での互換性は、まだまだ発展途上で未完成の印象を受けました)
本スクリプトで学習完了後に、logs/robomimic/Isaac-Stack-Cube-Franka-IK-Rel-v0 ディレクトリ以下にモデルの学習済みチェックポイントが出力されるので、次の推論処理でこれを利用します。
また同ディレクトリ以下の normalization_params.txt に学習時の正規化情報が出力されるのでこれも利用します
学習済みモデルで推論しながらロボットを動かす
最後に上記学習済みモデルで推論させながら、シミュレーター上でロボットを動かしてみます。
同じく、Isaac Lab では Robomimic を使用した推論用のスクリプトが提供されているのでこれを利用します
./isaaclab.sh -p scripts/imitation_learning/robomimic/play.py \ --device cuda \ --task Isaac-Stack-Cube-Franka-IK-Rel-v0 \ --num_rollouts 10 \ --norm_factor_min -1.0 \ --norm_factor_max 1.0 \ --checkpoint logs/robomimic/Isaac-Stack-Cube-Franka-IK-Rel-v0/bc_rnn_low_dim_franka_stack/20250716034214/models/model_epoch_XXXX.pth
—checkpoint には上記学習スクリプト実行後にlogs/robomimic/Isaac-Stack-Cube-Franka-IK-Rel-v0 ディレクトリ以下に出力される学習済みチェックポイントのパスを指定してください。
また —norm_factor_min, —norm_factor_max には、同ディレクトリ以下に出力される normalization_params.txt の内容の値を設定してください。
—num_rollouts はエピソードの試行回数になります。
スクリプト実行後にシミュレーターが起動します。以下動画のように模倣学習モデルで推論しながらロボットをうまく動かせていることがわかるかと思います!

Isaac Lab Mimic を使用したデータセット自動生成効果の定量評価
最後に、本手法によるデータセット自動生成の効果を定量評価するために、生成前後の学習用データセットそれぞれで本タスク(オブジェクトを積み重ねるタスク)の成功率を比較してみます。
公正な比較のため、それぞれのデータセットでの模倣学習モデルは同じにしています。
| モデル | 学習用データセット | レコード数(エピソード数) | 学習エポック数 | 成功率(at 10エピソード) |
|---|---|---|---|---|
| Behavior Cloning | 手動遠隔操作で作成した少数学習用データセット | 10 | 100 | 0.00 % |
| ↑ | ↑ | ↑ | 1000 | 0.00 % |
| ↑ | Isaac Lab Mimic で自動生成した大量学習用データセット | 1000 | 100 | 50.00 % |
| ↑ | ↑ | ↑ | 1000 | 90.00 % |

Isaac Lab Mimic で自動生成した大量学習用データセットで学習したモデルのほうが大幅に高いタスク成功率になっており、本手法で大量学習用データセットを自動生成することの有用性が見て取れるかと思います。
なお少数の学習用データセットでも学習エポック数を増やせば成功率を向上させることはできるかもしれませんが、過学習により汎化性能が逆に低下する可能性があります。
今回の推論環境は、オブジェクトの位置以外は学習環境と同じかなり理想的な環境になっていますが、そうでない場合は両者の成功率の差がより顕著になり、汎化性能の面でも自動生成した大量学習用データセットで学習したモデルのほうが高くなると思います
まとめ
ロボティクスモデル開発においては、学習用データセットの不足が大きな課題(特に模倣学習で行う場合)ですが、本記事で紹介したシミュレーター上での手動遠隔操作で少数の学習用データセットを作成して、そこから大量の学習用データセットを自動生成する手法はかなり強力な手法になるなという印象を受けました。 (もちろん実際のロボティクス開発において、自動生成された学習用データセットの品質が十分であるかや、Isaac Lab で提供されているロボットやタスク以外での学習用データセット自動生成は要追加検証ではありますが)
一方で、Isaac Lab Mimic で自動生成される学習用データセットはHDF5形式でのデータセットになっており、IsaccLab が提供している模倣学習用スクリプトを使用しないと学習に利用できないし、このスクリプトが Robomimic という古典的な模倣学習用フレームワークを使用しているので、(現時点では)最新の VLA モデルの学習にそのまま利用できない問題があるなと思いました。
π0 や Isaac-GR00T などの最新の VLA モデルの学習データセットとして利用したければ、LeRobot 形式でのデータセットに変換する必要がありますが、Isaac Lab でこの変換機能がサポートされておらず自身で変換スクリプト自作する必要あったりで、この辺の異なるツールやフレームワークの互換性が、まだまだ発展途中で整備されていないなという印象を受けました。
We Are Hiring!
株式会社ABEJAでは共に働く仲間を募集しています!
ロボティクスやLLMに興味ある方々!機械学習プロダクトに関わるフロントエンド開発やバックエンド開発に興味ある方々! こちらの採用ページから是非ご応募くださいませ!
