LeRobot 文件
新增基準測試 (Benchmark)
並獲得增強的文件體驗
開始使用
新增基準測試
本指南將引導您如何在 LeRobot 中新增模擬基準測試。請按照步驟順序操作,並將現有的基準測試作為範本。
LeRobot 中的基準測試是一組 Gymnasium 環境,這些環境將第三方模擬器(如 LIBERO 或 Meta-World)封裝在標準的 gym.Env 介面之後。隨後,lerobot-eval CLI 會統一在所有基準測試中執行評估。
現有基準測試概覽
在深入研究之前,以下是已經整合的內容:
| 基準測試 | 環境檔案 | 配置類別 | 任務 (Tasks) | 動作維度 | 處理器 |
|---|---|---|---|---|---|
| LIBERO | envs/libero.py | LiberoEnv | 5 個套件組共 130 個 | 7 | LiberoProcessorStep |
| Meta-World | envs/metaworld.py | MetaworldEnv | 50 (MT50) | 4 | None |
| IsaacLab Arena | Hub 託管 | IsaaclabArenaEnv | 可配置 | 可配置 | IsaaclabArenaProcessorStep |
請使用 src/lerobot/envs/libero.py 和 src/lerobot/envs/metaworld.py 作為參考實作。
整體運作方式
資料流
在評估過程中,資料會經過四個階段:
1. gym.Env ──→ raw observations (numpy dicts)
2. Preprocessing ──→ standard LeRobot keys + task description
(preprocess_observation, add_envs_task in envs/utils.py)
3. Processors ──→ env-specific then policy-specific transforms
(env_preprocessor, policy_preprocessor)
4. Policy ──→ select_action() ──→ action tensor
then reverse: policy_postprocessor → env_postprocessor → numpy action → env.step()大多數基準測試只需關注階段 1(產生正確格式的觀測結果),以及(如有需要環境專屬轉換時)選用階段 3。
環境結構
make_env() 會回傳一個巢狀字典的向量化環境。
dict[str, dict[int, gym.vector.VectorEnv]]
# ^suite ^task_id單任務環境(例如 PushT)看起來像 {"pusht": {0: vec_env}}。多任務基準測試(例如 LIBERO)看起來像 {"libero_spatial": {0: vec0, 1: vec1, ...}, ...}。
評估執行方式
所有基準測試皆透過 lerobot-eval 以相同方式進行評估。
make_env()會建立巢狀的{suite: {task_id: VectorEnv}}字典。eval_policy_all()會迭代每個套件組和任務。- 對於每個任務,它會透過
rollout()執行n_episodes次運行。 - 結果會按階層進行匯總:單次片段、任務、套件組、整體。
- 指標包含
pc_success(成功率)、avg_sum_reward(平均累計獎勵) 和avg_max_reward(平均最大獎勵)。
關鍵點:您的環境必須在每次 step() 呼叫時回傳 info["is_success"]。評估迴圈就是以此判斷任務是否完成。
您的環境必須提供什麼
LeRobot 不強制執行嚴格的觀測結構描述。取而代之的是,它依賴一套所有基準測試都遵循的規範。
環境屬性
您的 gym.Env 必須設定這些屬性:
| 屬性 | 類型 | 原因 |
|---|---|---|
_max_episode_steps | int | rollout() 使用此屬性限制單次片段長度。 |
task_description | str | 作為語言指令傳遞給 VLA 策略。 |
task | str | 若未設定 task_description 時的後備識別碼。 |
成功回報
您的 step() 和 reset() 必須在 info 字典中包含 "is_success"。
info = {"is_success": True} # or False
return observation, reward, terminated, truncated, info觀測值 (Observations)
最簡單的方法是將模擬器的輸出映射到 preprocess_observation() 已知的標準鍵。請在您的 gym.Env 內(例如在 _format_raw_obs() 輔助函式中)執行此操作。
| 您的環境應輸出 | LeRobot 將其映射至 | 它是什麼 |
|---|---|---|
"pixels" (單一陣列) | observation.image | 單一相機影像,HWC uint8 |
"pixels" (字典) | observation.images.<cam> | 多個相機,每個皆為 HWC uint8 |
"agent_pos" | observation.state | 本體感知狀態向量 |
"environment_state" | observation.env_state | 完整環境狀態 (例如 PushT) |
"robot_state" | observation.robot_state | 巢狀機器人狀態字典 (例如 LIBERO) |
如果您的模擬器使用不同的鍵名稱,您有兩個選擇:
- 推薦做法:在您的
gym.Env封裝器內將其重新命名為標準鍵。 - 替代做法:編寫一個環境處理器,在
preprocess_observation()執行後轉換觀測結果(請參見下方的第 4 步)。
動作
動作是 gym.spaces.Box 中的連續 numpy 陣列。維度取決於您的基準測試(LIBERO 為 7,Meta-World 為 4 等)。策略透過其 input_features / output_features 配置來適應不同的動作維度。
特徵宣告
每個 EnvConfig 子類別都會宣告兩個字典,告知策略預期內容:
features— 將特徵名稱映射至PolicyFeature(type, shape)(例如動作維度、影像形狀)。features_map— 將原始觀測鍵映射至 LeRobot 規範鍵 (例如"agent_pos"映射至"observation.state")。
逐步指南
至少,您需要三個檔案:一個 **gym.Env 封裝器**、一個 **EnvConfig 子類別**,以及一個 **Factory 分派分支**。其他皆為選用或文件說明。
檢查清單
| 檔案 | 必要 | 原因 |
|---|---|---|
src/lerobot/envs/<benchmark>.py | 是 | 將模擬器封裝為標準 gym.Env |
src/lerobot/envs/configs.py | 是 | 為 CLI 註冊您的基準測試 |
src/lerobot/envs/factory.py | 是 | 告訴 make_env() 如何建立您的環境 |
src/lerobot/processor/env_processor.py | 可選配置 | 自訂觀測/動作轉換 |
src/lerobot/envs/utils.py | 可選配置 | 僅在需要新的原始觀測鍵時使用 |
pyproject.toml | 是 | 宣告基準測試專屬的依賴套件 |
docs/source/<benchmark>.mdx | 是 | 面向使用者的說明文件頁面 |
docs/source/_toctree.yml | 是 | 將您的頁面新增至文件側邊欄 |
1. gym.Env 封裝器 ( src/lerobot/envs/<benchmark>.py )
建立一個封裝第三方模擬器的 gym.Env 子類別。
class MyBenchmarkEnv(gym.Env):
metadata = {"render_modes": ["rgb_array"], "render_fps": <fps>}
def __init__(self, task_suite, task_id, ...):
super().__init__()
self.task = <task_name_string>
self.task_description = <natural_language_instruction>
self._max_episode_steps = <max_steps>
self.observation_space = spaces.Dict({...})
self.action_space = spaces.Box(low=..., high=..., shape=(...,), dtype=np.float32)
def reset(self, seed=None, **kwargs):
... # return (observation, info) — info must contain {"is_success": False}
def step(self, action: np.ndarray):
... # return (obs, reward, terminated, truncated, info) — info must contain {"is_success": <bool>}
def render(self):
... # return RGB image as numpy array
def close(self):
...同時提供一個回傳巢狀字典結構的 Factory 函式。
def create_mybenchmark_envs(
task: str,
n_envs: int,
gym_kwargs: dict | None = None,
env_cls: type | None = None,
) -> dict[str, dict[int, Any]]:
"""Create {suite_name: {task_id: VectorEnv}} for MyBenchmark."""
...請參考 create_libero_envs() (多套件組、多任務) 和 create_metaworld_envs() (依難度分組的任務) 作為範例。
2. 配置 ( src/lerobot/envs/configs.py )
註冊一個配置資料類別 (dataclass),以便使用者可以使用 --env.type=<name> 選擇您的基準測試。
@EnvConfig.register_subclass("<benchmark_name>")
@dataclass
class MyBenchmarkEnvConfig(EnvConfig):
task: str = "<default_task>"
fps: int = <fps>
obs_type: str = "pixels_agent_pos"
features: dict[str, PolicyFeature] = field(default_factory=lambda: {
ACTION: PolicyFeature(type=FeatureType.ACTION, shape=(<action_dim>,)),
})
features_map: dict[str, str] = field(default_factory=lambda: {
ACTION: ACTION,
"agent_pos": OBS_STATE,
"pixels": OBS_IMAGE,
})
def __post_init__(self):
... # populate features based on obs_type
@property
def gym_kwargs(self) -> dict:
return {"obs_type": self.obs_type, "render_mode": self.render_mode}要點:
register_subclass的名稱即為使用者在 CLI 中傳入的名稱 (--env.type=<name>)。features告知策略環境會產生什麼。features_map將原始觀測鍵映射至 LeRobot 規範鍵。
3. Factory 分派 ( src/lerobot/envs/factory.py )
在 make_env() 中新增一個分支以呼叫您的 Factory 函式。
elif "<benchmark_name>" in cfg.type:
from lerobot.envs.<benchmark> import create_<benchmark>_envs
if cfg.task is None:
raise ValueError("<BenchmarkName> requires a task to be specified")
return create_<benchmark>_envs(
task=cfg.task,
n_envs=n_envs,
gym_kwargs=cfg.gym_kwargs,
env_cls=env_cls,
)如果您的基準測試需要環境處理器,請將其新增至 make_env_pre_post_processors()。
if isinstance(env_cfg, MyBenchmarkEnvConfig) or "<benchmark_name>" in env_cfg.type:
preprocessor_steps.append(MyBenchmarkProcessorStep())4. 環境處理器 (選用 — src/lerobot/processor/env_processor.py )
僅當您的基準測試需要超出 preprocess_observation() 處理範圍的觀測轉換時才需要(例如影像翻轉、座標轉換)。
@dataclass
@ProcessorStepRegistry.register(name="<benchmark>_processor")
class MyBenchmarkProcessorStep(ObservationProcessorStep):
def _process_observation(self, observation):
processed = observation.copy()
# your transforms here
return processed
def transform_features(self, features):
return features # update if shapes change
def observation(self, observation):
return self._process_observation(observation)請參見 LiberoProcessorStep 以取得完整範例(影像旋轉、四元數轉軸角轉換)。
5. 依賴套件 ( pyproject.toml )
新增一個選用依賴組。
mybenchmark = ["my-benchmark-pkg==1.2.3", "lerobot[scipy-dep]"]版本鎖定規則:
- 永遠鎖定:為了重現性,基準測試套件務必鎖定確切版本 (例如
metaworld==3.0.0)。 - 新增平台標記:必要時加上平台標記 (例如
; sys_platform == 'linux')。 - 鎖定不穩定的傳遞依賴:若已知某些依賴套件不穩定,請務必鎖定 (例如 Meta-World 使用
gymnasium==1.1.0)。 - 記錄限制:在您的基準測試文件頁面中記錄這些限制。
使用者透過以下方式安裝:
pip install -e ".[mybenchmark]"6. 文件說明 ( docs/source/<benchmark>.mdx )
編寫一個面向使用者的頁面,請遵循下一節中的範本。完整範例請參考 docs/source/libero.mdx 和 docs/source/metaworld.mdx。
7. 目錄 ( docs/source/_toctree.yml )
將您的基準測試新增至「Benchmarks」區段。
- sections:
- local: libero
title: LIBERO
- local: metaworld
title: Meta-World
- local: envhub_isaaclab_arena
title: NVIDIA IsaacLab Arena Environments
- local: <your_benchmark>
title: <Your Benchmark Name>
title: "Benchmarks"驗證您的整合
完成上述步驟後,請確認一切運作正常:
- 安裝 — 執行
pip install -e ".[mybenchmark]"並確認依賴組安裝無誤。 - 冒煙測試環境建立 — 在 Python 中使用您的配置呼叫
make_env(),檢查回傳的字典是否具有預期的{suite: {task_id: VectorEnv}}結構,以及reset()是否回傳正確鍵名的觀測結果。 - 執行完整評估 — 執行
lerobot-eval --env.type=<name> --env.task=<task> --eval.n_episodes=1 --eval.batch_size=1 --policy.path=<any_compatible_policy>以完整驗證管線的端到端運作。 - 檢查成功偵測 — 確認當任務真正完成時,
info["is_success"]會變更為True。這正是評估迴圈用來計算成功率的依據。
編寫基準測試說明頁面
每個基準測試 .mdx 頁面應包含:
- 標題與描述 — 1-2 段文字,說明該基準測試測試什麼以及其重要性。
- 連結 — 論文、GitHub 儲存庫、專案網站 (若有)。
- 概覽圖或 GIF。
- 可用任務 — 包含任務套件組數量及簡短說明的表格。
- 安裝 —
pip install -e ".[<benchmark>]"以及任何額外步驟 (環境變數、系統套件)。 - 評估 — 建議的
lerobot-eval指令,包含用於獲得可重現結果的n_episodes和batch_size。若適用,請包含單任務與多任務範例。 - 策略輸入與輸出 — 帶有維度的觀測鍵、動作空間描述。
- 推薦評估片段數 — 每個任務標準的片段數。
- 訓練 — 範例
lerobot-train指令。 - 重現已發表成果 — 連結至預訓練模型、評估指令、結果表格 (若有)。
請參考 docs/source/libero.mdx 和 docs/source/metaworld.mdx 以取得完整範例。