LeRobot documentation
シミュレーション: ローカルまたはサーブ
シミュレーション: ローカルまたはサーブ
シミュレートされた環境は、2つの方法で駆動できます:
- バッチ化された環境として(
--env.*): 1つのタスクに対して複数の環境を、各step()呼び出しでまとめてステップを進めます。lerobot-evalと学習中の評価で使用されます。 - シミュレーションロボット(
--robot.type=sim)として:Robotインターフェースの背後に1つの環境があり、実ハードウェアと交換可能です。lerobot-rollout、lerobot-record、lerobot-teleoperate、lerobot-replayがこれを使用します。
ローカルで実行するか、環境 API を介して実行するか、lerobot-env-server によってサーブされるかのいずれかです。通常、シミュレーターの依存関係がポリシーの依存関係と衝突しないよう、専用の Docker イメージ内で動作します。endpoint を設定するとサーブ実行が選択されます。どちらのパスも、同じ正規化された観測(HWC uint8 画像、フラットな float32 状態)、エピソードの終了、および制御規約を公開します。
このコードは3つのレイヤーを分離しています:
- env(
lerobot.envs、--env.type)は、LeRobot コマンドが実行する対象であり、EnvConfigによって設定されます。すべての env がシミュレーターであるとは限りません。gym_manipulatorは実物のロボットを制御します。 - sim(
lerobot.sim)は、シミュレートされた環境の背後にあるシミュレーターです。その統合を指定するSimConfigを持ち、LocalVectorEnvによってステップが進められ、torch は使用しません。 - env server(
lerobot.env_server)はシミュレーションを提供し、RemoteVectorEnvはLocalVectorEnvと同じ API を使用してそれを制御します。
チェックポイントの評価
ローカルでは、LeRobotの隣にシミュレーターをインストールします(LIBEROを参照):
lerobot-eval \
--policy.path=lerobot/smolvla_libero \
--policy.pretrained_revision=a24f1f380461b665158d52acd140152c79e8b36d \
--policy.device=cuda \
--env.type=libero --env.task=libero_spatial --env.task_ids='[0]' \
--rename_map='{"observation.images.image": "observation.images.camera1", "observation.images.image2": "observation.images.camera2"}' \
--eval.n_episodes=1 --eval.batch_size=1 \
--output_dir=outputs/eval_liberoServed: 同じ環境でサーバーを起動し(環境のサービングを参照)、そのエンドポイントを追加します:
lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true
lerobot-eval ... --env.server.endpoint=tcp/127.0.0.1:7448サーバーのすべてのオプションは--env.server.*の下にあり、ローカル実行には適用されません。クライアントは、サーバー設定で指定されている--env.typeに由来するデプロイメント名を要求します。別のデプロイメントを使用するには--env.server.deploymentを渡します。エンドポイントまたはデプロイメントが誤っている場合、--env.server.handshake_timeout_s(10秒)以内に失敗し、そのエンドポイントが提供しているものを示します。TLSで保護されたサーバーに対しては、リモート推論と同様に、そのZenoh JSON5ファイルを--env.server.zenoh_config_pathで渡します。サーバーは、コマンドが記述する環境を実行する必要があります。つまり、同じtype、task、制御規約、シミュレートされた本体(robot_type)です。そうでない場合、評価は開始を拒否し、差分を列挙します。その他の異なるオプション(解像度、エピソード長など)は警告としてログに記録されます。
Observation の名前は環境から取得されます(observation.images.<camera>、observation.state)。チェックポイントが他のカメラ名で学習された場合は、他のロボットと同様に --rename_map でそれらをマッピングし、複数のカメラが同じ形状を持つ場合でも、各カメラのアイデンティティを保持してください。プレースホルダーカメラ(empty_cameras)はチェックポイントに保存されるポリシー設定であり、必要に応じて --policy.empty_cameras で上書きしてください。
最初のステップの前に、リネーム後のすべてのチェックポイント入力が環境内に存在し、状態とアクションの次元数およびRGBチャネル数が一致している必要があります。画像の高さと幅は異なっていても構いません。リサイズはポリシーの事前処理が担当します。コントローラーの規約(デルタアクションと絶対アクション、回転形式)はチェックされません。環境の規約で学習されたチェックポイントを使用してください。
各 step() は、バッチ内の未完了のすべての環境を1回ずつ進めます。終了した環境は、次のリセットまでターミナル観測を保持し、他の環境をステップしても再開されません。--eval.use_async_envs=true (デフォルト) を使用すると、各環境はローカルまたはサーバー上で独自のワーカープロセスとして実行され、バッチは並列でステップされます。サーバーはバッチあたり最大 max_envs 個の環境 (デフォルトは32) を受け入れます。--env.server.encoding=jpeg (または --robot.env.server.encoding=jpeg、--env.server.jpeg_quality を併用、デフォルトは90) を指定すると、配信されるカメラフレームをJPEGとして送信します。これにより、リモートサーバーでは応答が小さくなりバッチサイズを大きくできますが、エンコード時間と有圧縮フレームというコストが発生します。localhost では、生フレームの方が高速です。応答にはバッチ内のすべての環境のフレームが含まれ、両端で max_payload_bytes (デフォルトは32 MiB) に収まる必要があります。収まらない場合、サーバーはバッチの開始時に拒否します。大規模なバッチや高解像度カメラを使用する場合は、サーバー側 (YAML の zenoh セクション内の max_payload_bytes、listen_endpoints の隣) とクライアント側 (--env.server.max_payload_bytes、または --robot.env.server.max_payload_bytes) で値を引き上げてください。
シミュレーションロボットを実行する
バッチ化された環境やシミュレーションロボットとして使用する場合と同じ環境:
lerobot-eval --env.type=libero --env.task=libero_spatial --env.task_ids='[0]' ...
lerobot-rollout --robot.type=sim --robot.env.type=libero --robot.env.task=libero_spatial --robot.task_id=0 ...例えば:
lerobot-rollout \
--robot.type=sim --robot.env.type=libero --robot.env.task=libero_spatial --robot.task_id=0 \
--task="pick up the black bowl between the plate and the ramekin and place it on the plate" \
--policy.path=lerobot/smolvla_libero \
--policy.pretrained_revision=a24f1f380461b665158d52acd140152c79e8b36d \
--rename_map='{"observation.images.image": "observation.images.camera1", "observation.images.image2": "observation.images.camera2"}' \
--device=cuda --fps=20 --inference.type=sync \
--display_data=true --display_mode=rerun \
--return_to_initial_position=false --play_sounds=false--robot.env.*は、評価における--env.*と同じオプションを受け取ります。--robot.task_idはロボットが実行する 1 つのタスクを選択しますが、評価ではスイートのすべてのタスク、または--env.task_idsに指定されたタスクが実行されます。EnvHub の環境は--robot.env.type=envhub --robot.env.hub_path=<user/repo> --robot.env.trust_remote_code=trueです。- 一部のポリシーは、環境のプロセッサ(LIBERO上のXVLAとCosmos3、Isaac Lab Arena)が必要です。
lerobot-evalはこれらを適用します。--inference.type=syncを使用したシミュレーションロボットも同様です。リモート推論では適用されないため、起動時にそのようなチェックポイントを拒否します。 --robot.env.server.endpoint=tcp/...は、バッチ化された環境に対して--env.server.endpointが行うのと同様に、環境を env サーバー上で駆動します。ロボットは、そのサーバーがその環境を実行していることを確認します。- 各
send_action()は環境をちょうど1ステップだけ進めます。観測の読み取り、ポリシーの推論、および待機はシミュレーションを進めません。既存の制御ループがリアルタイムのペース配分を管理します。 --fpsは、環境の制御レートに等しくなければなりません。補間を行う場合は、--interpolation_multiplierで割った値に等しくなければなりません。これは、すべてのコマンドが環境を1回進めるためです。録画を行う場合、--dataset.fpsは--fpsに等しくなければなりません。そうでない場合、ロールアウトは開始を拒否します。
シムロボットはロボットです: --robot.type=sim --robot.env.* を実際のフォロワーの --robot.* に置き換えるだけで、それ以外はすべてそのままです。テレオペレーターは、実際のフォロワーを操作するようにシムロボットを操作します (SO-101のツインの場合は --teleop.type=so101_leader)。これは、環境がフォロワーのアクション名と単位を宣言している場合に有効で、不一致がある場合は最初のアクションで報告されます。 lerobot-record は、環境が宣言したボディをデータセットの robot_type として保存します (LIBEROの場合は panda)。宣言がない場合は sim_robot になります。
記録されたエピソードは環境のエピソードに従います。lerobot-record とエピソード単位のロールアウト戦略は、各エピソードの開始時にシミュレーション環境を再起動し、環境のエピソードが終了したとき(成功、終了、またはステップ数の上限に達したとき)またはその期間が満了したとき、いずれか先に起きた時点で終了します。したがって、各記録されたエピソードは、その初期状態からの 1 つのシミュレーションエピソードになります。手動でのリセットは不要なため、エピソード間のリセットフェーズは --dataset.reset_time_s=0 でスキップし、エピソード単位のロールアウト戦略を使用する場合は --strategy.reset_to_initial_position=false も渡してください。エピソードが終了すると、ロボットは停止します。アクションを無視して最終状態を保持し、latest は最終報酬、終了、成功を保持します。その後、テレオペレーションとベースのロールアウト戦略が新しいエピソードを開始します(戦略はポリシーもリセットします)、そしてリプレイは停止します。sentry、highlight、DAgger 戦略は、エピソード単位ではなく時間またはオンデマンドで記録するため、まだシミュレーションロボットをサポートしていません。記録にはエピソード単位の戦略を使用してください。実ロボットには影響ありません。そのエピソードは時間ベースであり、シーンは手動でリセットされます。成功率については、lerobot-eval とバッチ化された環境で評価してください。
ロボットのカメラ機能は、実ハードウェアでの録画と同じobservation.images.<camera>という名前を使用します。無名の単一カメラはobservation.images.imageです。バッチ評価では、単一カメラの場合observation.imageなど、環境自身のキーが保持されます。この名前のチェックポイントをSimRobotを通じてデプロイする場合は、--rename_map='{"observation.images.image": "observation.image"}'を使用してください。
リモート推論では、--robot.* オプションをそのまま維持し、ローカルポリシーおよび推論オプションを以下に置き換えてください。
--inference.type=remote \ --inference.endpoint=tcp/127.0.0.1:7447 \ --inference.deployment=libero \ --inference.semantics=libero-delta-v1
リモート推論セットアップを使用して、ポリシーサーバーを別途起動します。そのスキーマは、--rename_map適用後のロボットの観測値と一致する必要があります。ポリシーサーバーがチェックポイントをロードするため、ロールアウトコマンドから--policy.pathを省略してください。ローカルRTCでは、ポリシーのRTC設定とともに--inference.type=rtcを使用します。
ポリシーが遅延している場合、シミュレーションロボットを保持しても物理シミュレーションは進行しません。シミュレータの障害は、ロールアウトのシャットダウンに伝播します。
環境をサーブする
LeRobotのソースチェックアウト(イメージはこれからビルドされます)から、リポジトリのルートで実行します:
lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true--docker=true は docker/sim/compose.server.yaml を使用し、sim.type からイメージを選択して、有効な YAML をマウントし、ホストネットワーク上でコンテナを実行します。これにより、--zenoh.listen_endpoints で指定がない限り、サーバーは localhost:7448 でリッスンします。別のシミュレーターを選択するには、YAML を差し替えてください。各シミュレーターの制御レート、アクションの規約、コンポーネント名、ロボットタイプは、その統合の conventions() から取得されるため、YAML にはタスク名とシミュレーターのオプションのみを指定します。
lerobot-policy-server については、すべての YAML フィールドがネストされたコマンドライン上書きを受け付け、ファイル自体は変更されません。sim.kwargs のような辞書値は、YAML のものにマージされます:
lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true \
--sim.task=libero_goal \
--sim.kwargs='{gym_kwargs: {observation_height: 256, observation_width: 256}}'有効な設定は$HF_LEROBOT_HOME/sim以下に保存されるため、コンテナを再起動しても検出されます。設定を切り替えるとサーバーが再作成され、アクティブなセッションは終了します。イメージが存在しない場合はビルドされます。シミュレーターやLeRobotのソースを変更した後に再ビルドするには--build=trueを追加し、サーバーを停止するには--stop=trueを追加します。コンテナはEGLレンダリングのためにDockerのGPUアクセスを必要とします。EnvHubリポジトリは--envhub=<user/repo>で提供されます。EnvHubとシミュレーターサーバーを参照してください。
Vulkan でレンダリングするシミュレーター(Isaac Sim、または RoboMME のように独自の Vulkan ファイルをイメージに同梱している ManiSkill/SAPIEN など)が、Docker 外では動作するのにコンテナ内で
vkCreateInstance failedまたはERROR_INCOMPATIBLE_DRIVERで失敗する場合、コンテナには NVIDIA ドライバーのライブラリは存在しますが、それらを指すローダーファイル(/usr/share/vulkan/icd.d/nvidia_icd.json、/usr/share/glvnd/egl_vendor.d/10_nvidia.json)が不足しています。gpus: allで使用される NVIDIA Container Toolkit のデフォルトモードではこれらがマウントされない場合がありますが、CDI モードではマウントされます。CDI 経由で GPU を要求してください(docker runでは--device nvidia.com/gpu=all、docker/sim/compose.server.yamlではgpus: allの代わりにdevices: [nvidia.com/gpu=all]を指定)、またはこれらの 2 つのファイルをイメージに追加してください。
--docker=true を指定しない場合、同じコマンドは現在の環境でサーバーを実行します。シミュレーターのネイティブ依存関係を隔離された環境にインストールし、--no-deps を付けて LeRobot をインストールし、docker/sim/requirements.txt をインストールします。いずれの場合も localhost でリッスンします。他のマシンからの接続を受け入れるには、それらのマシンが到達できるネットワークインターフェースのアドレスを渡します。例えば --zenoh.listen_endpoints='[tcp/192.168.1.20:7448]' のように指定し、YAML の zenoh.config_file で TLS とアクセス制御を追加します。
LIBERO のランタイムイメージは、変換済みの NumPy 初期状態ファイルを使用します。イメージのビルドでは、scripts/ci/convert_libero_init_states.py によって信頼できるアップストリームのアセットを変換し、サーバーは変換済みのファイルが欠落している場合は拒否します。RoboTwin と RoboMME は、それぞれネイティブなプランニングと ManiSkill のために独自の torch を必要とし、それらの torch のインストールはポリシー環境から分離されています。
Serverへのリクエストは再試行されません。曖昧なタイムアウトが発生した場合、クライアントは失敗します。その場合は、クライアントを閉じて新しいセッションを開いてください。
ベンチマークを追加する
シミュレーターモジュール、規約、イメージ、CI統合については、ベンチマークの追加を参照してください。
Update on GitHub