diff --git a/docs/source/adding_benchmarks.mdx b/docs/source/adding_benchmarks.mdx index 73a951276..77ccd3d4a 100644 --- a/docs/source/adding_benchmarks.mdx +++ b/docs/source/adding_benchmarks.mdx @@ -26,7 +26,7 @@ During evaluation, data moves through four stages: 1. gym.Env ──→ raw observations (numpy dicts) 2. Preprocessing ──→ standard LeRobot keys + task description - (preprocess_observation, add_envs_task in envs/utils.py) + (preprocess_observation in envs/utils.py, env.call("task_description")) 3. Processors ──→ env-specific then policy-specific transforms (env_preprocessor, policy_preprocessor) @@ -161,6 +161,8 @@ class MyBenchmarkEnv(gym.Env): ... ``` +**GPU-based simulators (e.g. MuJoCo with EGL rendering):** If your simulator allocates GPU/EGL contexts during `__init__`, defer that allocation to a `_ensure_env()` helper called on first `reset()`/`step()`. This avoids inheriting stale GPU handles when `AsyncVectorEnv` spawns worker processes. See `LiberoEnv._ensure_env()` for the pattern. + Also provide a factory function that returns the nested dict structure: ```python @@ -207,7 +209,7 @@ class MyBenchmarkEnvConfig(EnvConfig): def gym_kwargs(self) -> dict: return {"obs_type": self.obs_type, "render_mode": self.render_mode} - def create_envs(self, n_envs: int, use_async_envs: bool = False): + def create_envs(self, n_envs: int, use_async_envs: bool = True): """Override for multi-task benchmarks or custom env creation.""" from lerobot.envs. import create__envs return create__envs(task=self.task, n_envs=n_envs, ...)