LeRobot documentation
Hub에서 환경 로드
Hub에서 환경 로드
EnvHub 기능을 사용하면 Hugging Face Hub에서 시뮬레이션 환경을 한 줄의 코드로 직접 로드할 수 있습니다. 이를 통해 강력한 새로운 협업 모델이 열립니다. 환경이 단일 대형 라이브러리에만 갇혀 있던 것에서 벗어나, 누구나 커스텀 환경을 게시하고 커뮤니티와 공유할 수 있게 됩니다.
EnvHub이란 무엇인가요?
EnvHub를 사용하면 자체 로봇 모델과 시나리오로 맞춤형 로봇 시뮬레이션 환경을 만들고, LeRobot 프레임워크를 통해 누구나 쉽게 활용할 수 있도록 할 수 있습니다.
EnvHub 패키지는 Hugging Face Hub에 저장되며, LeRobot을 통해 한 줄의 코드로 AI 로봇 프로젝트에 손쉽게 가져와 사용할 수 있습니다.
EnvHub 덕분에 다음을 수행할 수 있습니다:
- Hugging Face Hub에 Git 저장소로 환경을 생성하고 게시하여, 패키징의 번거로움 없이 복잡한 물리 시뮬레이션을 배포합니다
- 패키지로 설치하지 않고 환경을 동적으로 로드
- Git 시맨틱을 사용하여 버전 및 트랙 환경 변경 사항을 관리합니다
- 발견 커뮤니티에서 공유하는 새로운 시뮬레이션 작업
이러한 설계 덕분에 Hub에서 흥미로운 환경을 발견한 후 몇 초 만에 실험을 실행하거나, 의존성 충돌이나 복잡한 설치 절차에 대한 걱정 없이 사용자 정의 로봇과 환경을 만들 수 있습니다.
EnvHub 패키지를 생성하면 원하는 것을 자유롭게 구축하고 선호하는 시뮬레이션 도구를 사용할 수 있습니다. 이는 직접 실험해 볼 수 있는 전용 공간입니다. 유일한 요구 사항은 env.py 파일을 포함하여 환경을 정의하고 LeRobot이 EnvHub 패키지를 로드하고 사용할 수 있도록 하는 것입니다.
이 env.py 파일은 LeRobot이 로드하고 실행할 수 있도록 작은 API를 노출해야 합니다. 특히, LeRobot의 주요 진입점인 make_env(n_envs: int = 1, use_async_envs: bool = False) 함수를 제공해야 합니다. LeRobot은 로컬에서 실행할 때와 서빙될 때 모두 설정 없이 이 함수를 호출합니다. 다음 중 하나를 반환해야 합니다:
gym.vector.VectorEnv(가장 일반적)- 단일
gym.Env(자동으로 래핑됩니다) {suite_name: {task_id: VectorEnv}}(멀티 태스크 벤치마크용) 매핑을 나타내는 dict
기본적으로 반환되는 벡터 env는 래핑되지 않은 SyncVectorEnv 또는 AsyncVectorEnv여야 합니다. LeRobot은 env_fns를 가져와 각 환경을 자체적으로 구축합니다. 사용자 정의 벡터 래퍼와 서브클래스는 조용히 제거되는 대신 거부됩니다.
provider 소유의 vector wrapper 또는 GPU-native batch를 사용하는 경우 --env.use_native_batch=true를 사용하세요. 이는 전처리 요구 사항을 포함하여 로컬 batched evaluation을 위해 저장소의 vector 환경을 그대로 유지합니다. 이 옵션은 endpoint 또는 SimRobot과 함께 사용할 수 없습니다. 문자열 API(make_env("user/repo"))도 provider의 환경을 그대로 유지합니다.
env.py는 환경(fps, control_mode, component 이름; EnvHub 및 시뮬레이터 서버 참조)을 설명하는 선택적 LEROBOT_SIM 사전도 정의할 수 있습니다. 이는 로컬에서와 서빙될 때 모두 적용됩니다.
빠른 시작
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}}(멀티 태스크 벤치마크용) 매핑을 나타내는 dict
선택 파일
requirements.txt
- 환경에 필요한 추가 종속성을 나열합니다
- 사용자는 환경을 로드하기 전에 이들을 수동으로 설치해야 합니다
LEROBOT_SIM in env.py
- simulator server에 의해 서빙될 때 환경을 설명하는 모듈 수준의 딕셔너리입니다. 따라서 단일 명령어로 시작합니다
- 모든 키는 선택 사항이며,
LEROBOT_SIM이 없는 저장소는 기본값으로 계속 작동합니다 robot_type은 lerobot에 해당 바디에 대한 클래스가 있을 때 실제 로봇이 기록하는 유형(so_follower,omx_follower)으로, 시뮬레이션 데이터셋과 실제 데이터셋이 일치하도록 합니다
| 키 | 의미 | 기본값 |
|---|---|---|
fps | step()의 속도를 제어 | 30 |
control_mode | 액션 규약: position, delta 또는 eef_pose | "position" |
semantics | 관찰/행동 규칙의 이름 | "envhub-v1" |
state_names | observation.state 구성 요소의 이름, 순서대로 | 일반적인 state_0, state_1, … |
action_names | 순서대로 나열된 액션 컴포넌트 이름 | 일반적인 command_0, command_1, … |
robot_type | 시뮬레이션된 본체, 시뮬레이션 로봇의 데이터셋으로 기록됨 robot_type | 없음 (datasets 레코드 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단계: 환경 정의
make_env 함수가 포함된 env.py 파일을 생성합니다:
# 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_env2단계: 로컬에서 테스트
업로드하기 전에 로컬에서 환경을 테스트하세요:
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.py를 로드합니다 | make_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=truerequirements.txt(pip 규칙으로 설치되므로 --extra-index-url 줄이 동작합니다) 외에도, 이미지는 Hugging Face Spaces와 마찬가지로 선택적인 packages.txt에 나열된 apt 패키지를 한 줄에 하나씩 설치합니다. 이 이미지는 순수한 Ubuntu입니다. GPU 드라이버는 호스트에서 제공되며, CUDA 라이브러리는 필요한 Python wheels(torch, Isaac Sim)에서 제공됩니다.
--envhub를 전달하는 것은 trust_remote_code=True와 마찬가지로 저장소의 코드를 실행하는 것에 대한 명시적인 동의입니다. 커밋을 고정하세요. 그런 다음 다른 환경과 마찬가지로 해당 엔드포인트를 추가하여 평가하세요:
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 배열로 포함합니다. - Actions는 1차원 연속
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가 변경되면 requirements, 그 외에는 저장소의 파일만 다시 빌드합니다. 새로운 환경은 먼저 로컬에서 테스트해 보세요(자세한 내용은 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는 호출될 때 모든 작업을 빌드합니다. 한 번에 하나의 world에서 전체 batch를 스텝하는 GPU 시뮬레이터(예: Isaac Lab)나 여러 작업을 가진 벤치마크의 경우, LeRobot의 자체 통합이 하듯이 env.py에 vector_env_fns를 정의하세요. 이는 팩토리를 반환하며, 실행되는 작업의 팩토리만 호출됩니다:
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")}}각 vector env은 num_envs == n_envs를 만족해야 하며, autoreset를 사용하지 않아야 합니다(metadata["autoreset_mode"] = gym.vector.AutoresetMode.DISABLED). 또한 위에서 설명한 형식으로 배치된 관측값을 반환하고, reset(seed=[...])에서 env별로 하나의 seed를 받아야 하며, env별로 info["is_success"]를 보고해야 합니다. --env.make_env_kwargs는 해당 env에 전달되며, lerobot-eval과 시뮬레이터 서버 모두 make_env 대신 이를 사용합니다. 하나의 vector env가 이미 전체 배치를 step하므로 --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에서 환경을 로드할 때:
- 먼저 코드를 검토하세요: 로딩 전에 저장소를 방문하여
env.py를 검사하세요 - 커밋 고정: 재현성을 위해 특정 커밋 해시를 사용
- 의존성 확인:
requirements.txt에서 의심스러운 패키지를 검토합니다 - 신뢰할 수 있는 출처 사용: 공식 기관이나 잘 알려진 연구자를 우선적으로 선택하세요
- 필요 시 샌드박스: 격리된 환경(컨테이너, VM)에서 신뢰할 수 없는 코드를 실행
안전한 사용 예시:
# ❌ 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_envAPI - 협업: 기존 환경을 포크하고 개선
- 접근성: 연구 공유 장벽 완화
문제 해결
“원격 코드 실행 거부”
trust_remote_code=True를 명시적으로 전달해야 합니다:
env = make_env("user/repo", trust_remote_code=True)“Module X not found”
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
passEnvironment이 잘못된 유형을 반환합니다
make_env 함수는 다음을 반환해야 합니다:
gym.vector.VectorEnv또는gym.Env하나, 또는{suite_name: {task_id: VectorEnv}}딕셔너리
최적의 관행
- 환경 문서화: README에 관찰/액션 공간 설명, 보상 구조, 종료 조건을 포함하세요
- requirements.txt 추가: 버전이 포함된 모든 종속성을 나열
LEROBOT_SIM선언: 하나의 명령어로 시뮬레이터 서버가 환경을 제공하도록 설정- 철저하게 테스트: 푸시하기 전에 로컬에서 환경이 정상적으로 작동하는지 확인하세요
- 의미 있는 버전 관리 사용: 릴리스에 버전 번호를 태그
- 예시 추가: README에 사용 예시를 포함하세요
- 단순하게 유지하기: 가능한 경우 의존성을 최소화하세요
- 작업에 라이선스를 부여: 사용 조건을 명확히 하기 위해 LICENSE 파일을 추가
향후 방향
EnvHub 생태계는 흥미로운 가능성을 열어줍니다:
- GPU 가속 물리: Isaac Gym 또는 Brax 환경 공유
- 포토리얼리스틱 렌더링: 고급 그래픽을 갖춘 환경 배포
- 멀티 에이전트 시나리오: 복잡한 상호작용 작업
- 실세계 시뮬레이터: 물리적 구성의 디지털 트윈
- 절차적 생성: 무한한 작업 변형
- 도메인 랜덤화: 사전 구성된 DR 파이프라인
더 많은 연구자와 개발자가 기여할수록, 사용 가능한 환경의 다양성과 품질이 향상되어 로봇 학습 커뮤니티 전체에 이롭게 될 것입니다.