EnvHub 功能允许你用一行代码直接从 Hugging Face Hub 加载 simulation environment。这开启了一种强大的协作新模式:环境不再被锁在庞大的库内部,任何人都可以发布自定义环境并与社区分享。
EnvHub 让你可以使用自己的机器人模型和场景创建自定义的机器人 simulation environment,并通过 LeRobot 框架让任何人都能轻松使用它们。
EnvHub 包存储在 Hugging Face Hub 上,可以通过 LeRobot 用一行代码无缝拉取并在你的 AI 机器人项目中使用。
借助 EnvHub,你可以:
这种设计意味着你可以在几秒钟内从在 Hub 上发现有趣的环境,到运行实验;或者创建自己的自定义机器人和环境,而无需担心依赖冲突或复杂的安装流程。
创建 EnvHub 包时,你可以在其中构建任何你想要的内容,并使用任何你喜欢的 simulation 工具:这是你自己的发挥空间。唯一的要求是该包包含一个定义环境的 env.py 文件,使 LeRobot 能够加载和使用你的 EnvHub 包。
这个 env.py 文件需要暴露一个小的 API,以便 LeRobot 加载和运行它。具体来说,你必须提供一个 make_env(n_envs: int = 1, use_async_envs: bool = False) 或 make_env(n_envs: int = 1, use_async_envs: bool = False, cfg: EnvConfig) 函数,它是 LeRobot 的主要入口点。它应返回以下之一:
gym.vector.VectorEnv(最常见)gym.Env(将被自动包装){suite_name: {task_id: VectorEnv}} 的字典(用于多任务 benchmark)你还可以向 make_env 传递一个 EnvConfig 对象来配置环境(例如环境数量、任务、相机名称、初始 state、控制模式、episode 长度等)。
最后,你的环境必须实现标准的 gym.vector.VectorEnv 接口,才能与 LeRobot 配合使用,包括诸如 reset 和 step 之类的方法。
从 Hub 加载环境非常简单:
from lerobot.envs import make_env
# Load a hub environment (requires explicit consent to run remote code)
env = make_env("lerobot/cartpole-env", trust_remote_code=True)**安全须知**:从 Hub 加载环境会执行第三方仓库中的 Python 代码。请仅对你信任的仓库使用 `trust_remote_code=True`。我们强烈建议固定到特定的提交哈希,以保证可复现性和安全性。
要让你的环境可以从 Hub 加载,你的仓库至少必须包含:
env.py(或自定义 Python 文件)
make_env(n_envs: int, use_async_envs: bool) 函数gym.vector.VectorEnv(最常见)gym.Env(将被自动包装){suite_name: {task_id: VectorEnv}} 的字典(用于多任务 benchmark)requirements.txt
README.md
.gitignore
my-environment-repo/
├── env.py # Main environment definition (required)
├── requirements.txt # Dependencies (optional)
├── README.md # Documentation (recommended)
├── assets/ # Images, videos, etc. (optional)
│ └── demo.gif
└── configs/ # Config files if needed (optional)
└── task_config.yaml创建一个包含 make_env 函数的 env.py 文件:
# env.py
import gymnasium as gym
def make_env(n_envs: int = 1, use_async_envs: bool = False):
"""
Create vectorized environments for your custom task.
Args:
n_envs: Number of parallel environments
use_async_envs: Whether to use AsyncVectorEnv or SyncVectorEnv
Returns:
gym.vector.VectorEnv or dict mapping suite names to vectorized envs
"""
def _make_single_env():
# Create your custom environment
return gym.make("CartPole-v1")
# Choose vector environment type
env_cls = gym.vector.AsyncVectorEnv if use_async_envs else gym.vector.SyncVectorEnv
# Create vectorized environment
vec_env = env_cls([_make_single_env for _ in range(n_envs)])
return vec_env上传之前,请先在本地测试你的环境:
from lerobot.envs.utils import _load_module_from_path, _call_make_env, _normalize_hub_result
# Load your module
module = _load_module_from_path("./env.py")
# Test the make_env function
result = _call_make_env(module, n_envs=2, use_async_envs=False)
normalized = _normalize_hub_result(result)
# Verify it works
suite_name = next(iter(normalized))
env = normalized[suite_name][0]
obs, info = env.reset()
print(f"Observation shape: {obs.shape if hasattr(obs, 'shape') else type(obs)}")
env.close()将你的仓库上传到 Hugging Face:
# Install huggingface_hub if needed
pip install huggingface_hub
# Login to Hugging Face
hf auth login
# Create a new repository
hf repo create my-org/my-custom-env
# Initialize git and push
git init
git add .
git commit -m "Initial environment implementation"
git remote add origin https://huggingface.co/my-org/my-custom-env
git push -u origin main或者,使用 huggingface_hub Python API:
from huggingface_hub import HfApi
api = HfApi()
# Create repository
api.create_repo("my-custom-env", repo_type="space")
# Upload files
api.upload_folder(
folder_path="./my-env-folder",
repo_id="username/my-custom-env",
repo_type="space",
)from lerobot.envs import make_env
# Load from the hub
envs_dict = make_env(
"username/my-custom-env",
n_envs=4,
trust_remote_code=True
)
# Access the environment
suite_name = next(iter(envs_dict))
env = envs_dict[suite_name][0]
# Use it like any gym environment
obs, info = env.reset()
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)为了保证可复现性和安全性,请固定到特定的 Git 修订版本:
# Pin to a specific branch
env = make_env("username/my-env@main", trust_remote_code=True)
# Pin to a specific commit (recommended for papers/experiments)
env = make_env("username/my-env@abc123def456", trust_remote_code=True)
# Pin to a tag
env = make_env("username/my-env@v1.0.0", trust_remote_code=True)如果你的环境定义不在 env.py 中:
# Load from a custom file
env = make_env("username/my-env:custom_env.py", trust_remote_code=True)
# Combine with version pinning
env = make_env("username/my-env@v1.0:envs/task_a.py", trust_remote_code=True)为了在多个环境下获得更好的性能:
envs_dict = make_env(
"username/my-env",
n_envs=8,
use_async_envs=True, # Use AsyncVectorEnv for parallel execution
trust_remote_code=True
)Hub URL 格式支持多种模式:
| 模式 | 描述 | 示例 |
|---|---|---|
user/repo | 从 main 分支加载 env.py | make_env("lerobot/pusht-env") |
user/repo@revision | 从特定修订版本加载 | make_env("lerobot/pusht-env@main") |
user/repo:path | 加载自定义文件 | make_env("lerobot/envs:pusht.py") |
user/repo@rev:path | 修订版本 + 自定义文件 | make_env("lerobot/envs@v1:pusht.py") |
对于具有多个任务的 benchmark(如 LIBERO),请返回一个嵌套字典:
def make_env(n_envs: int = 1, use_async_envs: bool = False):
env_cls = gym.vector.AsyncVectorEnv if use_async_envs else gym.vector.SyncVectorEnv
# Return dict: {suite_name: {task_id: VectorEnv}}
return {
"suite_1": {
0: env_cls([lambda: gym.make("Task1-v0") for _ in range(n_envs)]),
1: env_cls([lambda: gym.make("Task2-v0") for _ in range(n_envs)]),
},
"suite_2": {
0: env_cls([lambda: gym.make("Task3-v0") for _ in range(n_envs)]),
}
}**重要**:执行来自 Hub 的环境代码需要 `trust_remote_code=True` 标志。这是出于安全考虑的设计。
从 Hub 加载环境时:
env.pyrequirements.txt 中是否有可疑的包安全用法示例:
# ❌ BAD: Loading without inspection
env = make_env("random-user/untrusted-env", trust_remote_code=True)
# ✅ GOOD: Review code, then pin to specific commit
# 1. Visit https://huggingface.co/trusted-org/verified-env
# 2. Review the env.py file
# 3. Copy the commit hash
env = make_env("trusted-org/verified-env@a1b2c3d4", trust_remote_code=True)下面是使用参考 CartPole 环境的完整示例:
from lerobot.envs import make_env
import numpy as np
# Load the environment
envs_dict = make_env("lerobot/cartpole-env", n_envs=4, trust_remote_code=True)
# Get the vectorized environment
suite_name = next(iter(envs_dict))
env = envs_dict[suite_name][0]
# Run a simple episode
obs, info = env.reset()
done = np.zeros(env.num_envs, dtype=bool)
total_reward = np.zeros(env.num_envs)
while not done.all():
# Random policy
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
done = terminated | truncated
print(f"Average reward: {total_reward.mean():.2f}")
env.close()make_env API你必须显式传递 trust_remote_code=True:
env = make_env("user/repo", trust_remote_code=True)Hub 环境有你需要安装的依赖:
# Check the repo's requirements.txt and install dependencies
pip install gymnasium numpy你的 env.py 必须暴露一个 make_env 函数:
def make_env(n_envs: int, use_async_envs: bool):
# Your implementation
passmake_env 函数必须返回:
gym.vector.VectorEnv,或gym.Env,或{suite_name: {task_id: VectorEnv}}EnvHub 生态系统带来了令人兴奋的可能性:
随着越来越多的研究人员和开发者做出贡献,可用环境的多样性和质量将不断提升,造福整个机器人学习社区。