LeRobot documentation

从 Hub 加载环境

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

从 Hub 加载环境

EnvHub 功能允许你通过一行代码直接从 Hugging Face Hub 加载模拟环境。这开启了一种强大的协作新模式:环境不再被封闭在庞大的单体库中,任何人都可以发布自定义环境并与社区共享。

什么是 EnvHub?

EnvHub 允许您使用自己的机器人模型和场景创建自定义机器人仿真环境,并通过 LeRobot 框架轻松供任何人使用。

EnvHub 包存储在 Hugging Face Hub 上,您可以通过 LeRobot 用一行代码无缝拉取并在您的 AI 机器人项目中使用它们。

得益于 EnvHub,您可以:

  1. 在 Hugging Face Hub 上以 Git 仓库的形式创建并发布环境,从而无需打包即可分发复杂的物理模拟
  2. 动态加载环境,而无需将其作为包安装
  3. 使用 Git 语义来版本化和跟踪环境变更
  4. 发现社区共享的新模拟任务

这种设计意味着,您可以从在 Hub 上发现一个有趣的环境,到在几秒内开始运行实验;或者创建您自己的自定义机器人和环境,而无需担心依赖冲突或复杂的安装流程。

创建 EnvHub 包时,你可以在其中构建任何内容,并使用任意仿真工具:这是你自由探索的空间。唯一的要求是包中必须包含一个 env.py 文件,用于定义环境并允许 LeRobot 加载和使用你的 EnvHub 包。

此 env.py 文件需要暴露一个小型 API,以便 LeRobot 能够加载并运行它。特别是,您必须提供一个 make_env(n_envs: int = 1, use_async_envs: bool = False) 函数,它是 LeRobot 的主要入口点。LeRobot 会在本地和作为服务运行时调用它,且不传入配置。它应返回以下之一:

  • gym.vector.VectorEnv(最常见)
  • 单个 gym.Env(将自动包装)
  • 一个字典,映射关系为 {suite_name: {task_id: VectorEnv}}(用于多任务基准测试)

默认情况下,返回的向量环境必须是一个未包装的 SyncVectorEnv 或 AsyncVectorEnv:LeRobot 会获取其 env_fns 并自行构建每个环境。自定义的向量包装器和子类会被拒绝,而不是被静默移除。

对于由提供商拥有的向量封装器或 GPU 原生批次,请使用 --env.use_native_batch=true。这可以保持仓库的向量环境完整,以便进行本地批量评估,包括其预处理要求。它不能与端点或 SimRobot 结合使用。字符串 API(make_env("user/repo"))同样会保持提供商的环境完整。

env.py 还可以定义一个可选的 LEROBOT_SIM 字典,用于描述环境(fps、control_mode、组件名称;参见 EnvHub 和模拟器服务器)。该配置在本地和作为服务提供时均生效。

快速入门

从 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)
**Security Notice**: Loading environments from the Hub executes Python code from third-party repositories. Only use `trust_remote_code=True` with repositories you trust. We strongly recommend pinning to a specific commit hash for reproducibility and security.

仓库结构

要使您的环境能够从 Hub 加载,您的仓库至少必须包含以下内容:

必需文件

env.py(或自定义 Python 文件)

  • 必须暴露一个 make_env(n_envs: int, use_async_envs: bool) 函数
  • make_env 的额外关键字参数是环境自身的选项:--env.make_env_kwargs='{"episode_length": 900}' 用于传递这些参数(对于模拟机器人,使用 --robot.env.make_env_kwargs),而服务器则通过 --sim.kwargs='{make_env_kwargs: {episode_length: 900}}' 接收它们
  • 此函数应返回以下之一:
    • gym.vector.VectorEnv(最常见)
    • 单个 gym.Env(将自动包装)
    • 一个字典,映射关系为 {suite_name: {task_id: VectorEnv}}(用于多任务基准测试)

可选文件

requirements.txt

  • 列出您的环境所需的任何其他依赖项
  • 用户需要在加载您的环境之前手动安装这些

LEROBOT_SIM 位于 env.py 中

  • 一个模块级字典,用于描述由simulator server提供服务时的环境,因此它以一个单一命令开头
  • 每个键都是可选的;不包含 LEROBOT_SIM 的仓库将继续使用默认值正常工作
  • robot_type 是真实机器人记录的类型(so_follower、omx_follower),前提是 lerobot 中存在对应本体的类,从而确保模拟数据集与真实数据集相匹配
密钥含义默认
fps控制一次 step() 的速率30
control_mode动作约定:position、delta 或 eef_pose"position"
semantics观察/动作约定的名称"envhub-v1"
state_namesobservation.state 组件的名称,按顺序排列通用 state_0、state_1、……
action_names按顺序排列的操作组件名称通用 command_0、command_1、……
robot_type模拟身体,记录为模拟机器人的数据集 robot_type无(数据集记录 sim_robot)

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

创建您的环境仓库

步骤 1:定义您的环境

创建一个 env.py 文件,其中包含一个 make_env 函数:

# env.py
import gymnasium as gym

# Optional: describes the environment to the simulator server (see "Optional Files").
LEROBOT_SIM = {"fps": 50, "control_mode": "position"}

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

步骤 2:本地测试

在上传之前,请在本地测试您的环境:

import numpy as np

from lerobot.envs.configs import HubEnvConfig

# Build the envs from the local folder that holds env.py, as lerobot-eval and the env server do
envs = HubEnvConfig(hub_path="./my-env", trust_remote_code=True).create_envs(n_envs=2)

# Verify it works
suite_name = next(iter(envs))
env = envs[suite_name][0]
obs, info = env.reset(seed=0)
print({key: value.shape for key, value in obs.items()})  # LeRobot keys, e.g. observation.state
env.step(np.zeros(env.action_space.shape, np.float32))
env.close()

步骤 3:上传到 Hub

将您的仓库上传到 Hugging Face:

# Install huggingface_hub if needed
pip install huggingface_hub

# Login to Hugging Face
hf auth login

# Create a new repository
hf repos 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",
)

从 Hub 加载环境

基本用法

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
)

URL 格式参考

Hub URL 格式支持以下几种模式:

模式描述示例
user/repo从主分支加载 env.pymake_env("lerobot/cartpole-env")
user/repo@revision从特定修订版本加载make_env("lerobot/cartpole-env@main")
user/repo:path加载自定义文件make_env("lerobot/envs:pusht.py")
user/repo@rev:path修订 + 自定义文件make_env("lerobot/envs@v1:pusht.py")

EnvHub 和模拟器服务器

默认情况下,EnvHub 环境在评估进程内运行:make_env 会下载仓库的 env.py,并将其依赖项安装在 LeRobot 旁边。为了将环境的依赖项与策略的依赖项隔离,请改用 simulator server 来提供该环境。一条命令即可构建包含该仓库及其 requirements.txt 的镜像,并启动服务器:

lerobot-env-server --envhub=username/my-env@<commit> --docker=true

除了 requirements.txt(按 pip 的规则安装,因此 --extra-index-url 行有效)之外,该镜像还会安装可选的 packages.txt 中列出的 apt 软件包,每行一个,与 Hugging Face Spaces 中的方式相同。该镜像是纯 Ubuntu:GPU 驱动程序来自宿主机,CUDA 库则来自需要它们的 Python 轮子(torch、Isaac Sim)。

传入 --envhub 即表示明确同意运行该仓库的代码,类似于 trust_remote_code=True。请固定一个 commit。然后像评估其他环境一样对其进行评估,并添加其端点:

lerobot-eval --policy.path=<checkpoint> \
  --env.type=envhub --env.hub_path=username/my-env@<commit> --env.server.endpoint=tcp/127.0.0.1:7448 \
  --rename_map='{"observation.images.front": "observation.images.camera1"}' \
  --eval.n_episodes=10

如果不使用 --env.server.endpoint,相同的命令将在本地运行环境(使用 --trust_remote_code=true);仿真机器人在 --robot.env.* 下接受相同的选项。

服务器会从仓库的 LEROBOT_SIM 中读取控制频率、动作约定和组件名称,对于未声明的项则使用默认值。可以在命令行中覆盖某个值,其优先级高于仓库中的配置,例如 --sim.fps=15。

要提供服务,环境必须遵循以下约定:

  • make_env 返回由每个环境的工厂构建的向量环境(如上文示例中的 SyncVectorEnv/AsyncVectorEnv)或单个 gym.Env。服务器会从这些工厂构建自己的环境,并在会话结束时关闭它们。
  • env.py 在每个服务器进程中只执行一次,因此它可以维护进程级的状态,例如只能启动一次的模拟器应用(Isaac Sim 的 SimulationApp)。
  • Observations 是 LeRobot 在本地读取的字典:pixels(一张 HWC uint8 图像或一个包含多个相机的字典)、agent_pos 和 environment_state,均为 NumPy 数组。
  • 动作是一维连续Box。
  • 回合通过 terminated/truncated 或 _max_episode_steps(默认值为 500)结束,info["is_success"] 用于报告是否成功。任务文本来自环境的 task_description(或 task)属性。
  • LEROBOT_SIM 是可选的,但每当默认设置(30 fps、位置控制)与您的环境不匹配时,请声明它。

示例请参见 EnvHub 环境集合:lerobot/so101-tabletop-mujoco(MuJoCo)和 lerobot/so101-tabletop-isaac(Isaac Sim,通过 requirements.txt 和 packages.txt 安装)提供相同的 SO-101 场景,具有相同的观测、动作和 LEROBOT_SIM。

该仓库会通过您的 Hugging Face 登录信息(HF_TOKEN 或 hf auth login)下载到您的机器上,因此私有仓库也可以使用,并且镜像构建过程不会接触到任何令牌。--envhub 还可以接受一个包含 env.py 的本地目录,以便在推送之前提供该环境:lerobot-env-server --envhub=./my-env --docker=true。--build=true 只会重新构建发生变化的部分:当 packages.txt 更改时重新安装 apt 包,当 requirements.txt 更改时重新安装依赖项,否则仅更新仓库中的文件。请先在本地测试新环境(参见 步骤 2:本地测试)。

多任务环境

对于包含多个任务的基准测试(例如 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)]),
        }
    }

make_env 在被调用时会构建所有任务。对于在单个世界中以批量方式推进的 GPU 模拟器(例如 Isaac Lab),或包含许多任务的基准测试,请改为在 env.py 中定义 vector_env_fns,正如 LeRobot 自身的集成所做的那样。它返回工厂函数,并且只会调用实际运行的任务对应的工厂函数:

from functools import partial


def vector_env_fns(task: str, n_envs: int, **make_env_kwargs):
    # {suite_name: {task_id: factory}}, each factory building one vector env of n_envs envs
    return {"suite_1": {0: partial(MyBatchedEnv, n_envs, "Task1"), 1: partial(MyBatchedEnv, n_envs, "Task2")}}

每个向量环境必须满足 num_envs == n_envs,且不得自动重置(metadata["autoreset_mode"] = gym.vector.AutoresetMode.DISABLED),以上述格式返回批量观测,在 reset(seed=[...]) 中为每个环境接收一个种子,并按环境报告 info["is_success"]。--env.make_env_kwargs 会传递给该环境,并且 lerobot-eval 和模拟器服务器都会使用它来替代 make_env。由于一个向量环境已经对整个批次执行了步进,请使用 --eval.use_async_envs=false 进行评估:工作进程只会将每个观测批次在进程间复制,而服务器则会在工作进程中再次构建模拟器。

安全注意事项

**Important**: The `trust_remote_code=True` flag is required to execute environment code from the Hub. This is by design for security.

从 Hub 加载环境时:

  1. 先审查代码:在加载之前,访问该仓库并检查 env.py
  2. 固定到提交:使用特定的提交哈希值以确保可复现性
  3. 检查依赖项:审查 requirements.txt 中是否存在可疑的包
  4. 使用可信来源:优先选择官方机构或知名研究人员
  5. 必要时使用沙箱:在隔离环境(容器、虚拟机)中运行不受信任的代码

安全使用示例:

# ❌ 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)

示例:来自 Hub 的 CartPole

以下是使用参考 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()

EnvHub 的优势

面向环境作者

  • 轻松分发:无需进行 PyPI 打包
  • 版本控制:使用 Git 进行环境版本管理
  • 快速迭代:即时推送更新
  • 文档:Hub README 渲染效果极佳
  • 社区:直接联系 LeRobot 用户

面向研究人员

  • 快速实验:一行代码加载任意环境
  • 可复现性:固定到特定提交
  • 发现:在 Hub 上浏览环境
  • 无冲突:无需安装冲突的包

面向社区

  • 不断壮大的生态系统:更多样化的模拟任务
  • 标准化:通用的 make_env API
  • 协作:Fork 并改进现有环境
  • 可访问性:降低研究共享的门槛

故障排除

“拒绝执行远程代码”

您必须显式传入 trust_remote_code=True:

env = make_env("user/repo", trust_remote_code=True)

“未找到模块 X”

Hub 环境包含需要安装的依赖项:

# Check the repo's requirements.txt and install dependencies
pip install gymnasium numpy

“在模块中未找到 make_env”

您的 env.py 必须暴露一个 make_env 函数:

def make_env(n_envs: int, use_async_envs: bool):
    # Your implementation
    pass

Environment 返回了错误的类型

make_env 函数必须返回:

  • gym.vector.VectorEnv,或
  • 单个 gym.Env,或
  • 一个字典 {suite_name: {task_id: VectorEnv}}

最佳实践

  1. 记录您的环境:在您的 README 中包含观察/动作空间描述、奖励结构和终止条件
  2. 添加 requirements.txt:列出所有依赖项及其版本
  3. 声明 LEROBOT_SIM:通过一条命令让环境由模拟器服务器提供服务
  4. 彻底测试:在推送之前,验证你的环境在本地可以正常工作
  5. 使用语义化版本控制:为发布打上版本号
  6. 添加示例:在您的 README 中包含使用示例
  7. 保持简洁:尽可能减少依赖
  8. 为您的工作添加许可证:添加 LICENSE 文件以明确使用条款

未来方向

EnvHub 生态系统带来了令人兴奋的可能性:

  • GPU 加速物理:共享 Isaac Gym 或 Brax 环境
  • 照片级真实感渲染:分发具有高级图形效果的环境
  • 多智能体场景:复杂的交互任务
  • 现实世界模拟器:物理装置的数字孪生
  • 程序化生成:无限的任务变体
  • 域随机化:预配置的 DR 流水线

随着越来越多的研究人员和开发者参与贡献,可用环境的多样性和质量将不断提升,从而惠及整个机器人学习社区。

另请参阅

Update on GitHub