Documentation Index
Fetch the complete documentation index at: https://mintlify.com/huggingface/lerobot/llms.txt
Use this file to discover all available pages before exploring further.
EnvHub: Share Simulation Environments
EnvHub is LeRobot’s reproducible environment hub — a HuggingFace-based platform for sharing, discovering, and loading simulation environments with a single line of code.
Why EnvHub?
Sharing simulation environments has traditionally been challenging:
- Complex dependencies and version conflicts
- Difficult to reproduce exact environment configurations
- No standardized distribution mechanism
- Hard to discover community-contributed tasks
EnvHub solves these problems by:
✅ One-line loading: Load any environment from the Hub instantly
✅ Version control: Pin to specific commits for reproducibility
✅ Community sharing: Discover and contribute environments easily
✅ Zero setup: No manual installation or configuration needed
✅ Trust model: Explicit consent for remote code execution
Quick Start
Load an Environment from the Hub
from lerobot.envs.factory import make_env
# Load environment from HuggingFace Hub
envs_dict = make_env(
"LightwheelAI/leisaac_env:envs/so101_pick_orange.py",
n_envs=1,
trust_remote_code=True # Required: explicit consent
)
# Access the environment
suite_name = next(iter(envs_dict))
vec_env = envs_dict[suite_name][0]
env = vec_env.envs[0].unwrapped
# Use like any Gym environment
obs, info = env.reset()
while True:
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
obs, info = env.reset()
EnvHub supports flexible URL patterns:
# Default: looks for env.py in repo root
make_env("username/repo", trust_remote_code=True)
# Explicit file path
make_env("username/repo:envs/my_env.py", trust_remote_code=True)
# Pin to specific revision (recommended for reproducibility)
make_env("username/repo@v1.0.0:envs/my_env.py", trust_remote_code=True)
# Use commit hash for maximum reproducibility
make_env("username/repo@abc123:envs/my_env.py", trust_remote_code=True)
Creating Your Own EnvHub Repository
Step 1: Create Repository Structure
Your EnvHub repository needs:
your-env-repo/
├── env.py # Main environment module (required)
├── README.md # Documentation
├── requirements.txt # Python dependencies (optional)
└── assets/ # Additional files (optional)
├── models/
└── configs/
Step 2: Implement make_env Function
Your env.py must expose a make_env function:
# env.py
import gymnasium as gym
from typing import Any
def make_env(
n_envs: int = 1,
use_async_envs: bool = False,
cfg: Any = None
) -> dict[str, dict[int, gym.vector.VectorEnv]]:
"""
Create vectorized environments.
Args:
n_envs: Number of parallel environments
use_async_envs: Whether to use AsyncVectorEnv
cfg: Optional environment configuration
Returns:
Dictionary mapping suite_name -> {task_id: vector_env}
"""
env_cls = gym.vector.AsyncVectorEnv if use_async_envs else gym.vector.SyncVectorEnv
# Create environment factories
def _make_one():
return gym.make("YourEnv-v0")
vec_env = env_cls(
[_make_one for _ in range(n_envs)],
autoreset_mode=gym.vector.AutoresetMode.SAME_STEP
)
# Return in standard format
return {"your_suite_name": {0: vec_env}}
Step 3: Upload to the Hub
Upload your repository to HuggingFace:
# Install huggingface_hub
pip install huggingface_hub
# Login to HuggingFace
huggingface-cli login
# Create repository
huggingface-cli repo create your-env-name --type space
# Upload files
huggingface-cli upload your-username/your-env-name ./env.py env.py
huggingface-cli upload your-username/your-env-name ./README.md README.md
Or use the Python API:
from huggingface_hub import HfApi
api = HfApi()
api.create_repo("your-env-name", repo_type="space")
api.upload_folder(
folder_path="./your-env-repo",
repo_id="your-username/your-env-name",
repo_type="space"
)
Step 4: Test Your Environment
from lerobot.envs.factory import make_env
# Test loading your environment
envs = make_env(
"your-username/your-env-name",
n_envs=2,
trust_remote_code=True
)
print("Successfully loaded environment!")
Advanced Features
Configuration Support
Support custom configurations through the cfg parameter:
from dataclasses import dataclass
from lerobot.envs.configs import HubEnvConfig, EnvConfig
@EnvConfig.register_subclass("my_env")
@dataclass
class MyEnvConfig(HubEnvConfig):
hub_path: str = "username/my-env-repo"
difficulty: str = "medium"
task_variant: int = 0
@property
def gym_kwargs(self) -> dict:
return {
"difficulty": self.difficulty,
"task_variant": self.task_variant
}
# In env.py
def make_env(n_envs: int, use_async_envs: bool, cfg=None):
# Use cfg parameters if provided
difficulty = cfg.difficulty if cfg else "medium"
task_variant = cfg.task_variant if cfg else 0
# Create environments with config
...
Multi-Suite Environments
Return multiple suites and tasks:
def make_env(n_envs, use_async_envs, cfg=None):
envs = {}
# Suite 1: Training tasks
envs["training"] = {
0: create_vec_env("task_a", n_envs, use_async_envs),
1: create_vec_env("task_b", n_envs, use_async_envs),
}
# Suite 2: Test tasks
envs["testing"] = {
0: create_vec_env("test_task", n_envs, use_async_envs),
}
return envs
Asset Management
Include assets in your repository:
import os
from pathlib import Path
def make_env(n_envs, use_async_envs, cfg=None):
# Get path to the downloaded repository
repo_path = Path(__file__).parent
# Load assets
model_path = repo_path / "assets" / "models" / "robot.urdf"
config_path = repo_path / "assets" / "configs" / "task.yaml"
# Use assets in environment creation
...
Security and Trust
Remote Code Execution
EnvHub executes Python code from remote repositories. This is powerful but requires careful consideration:
⚠️ Important: Only set trust_remote_code=True for repositories you trust.
# This will fail with security warning
envs = make_env("untrusted/repo") # ❌ Error
# Explicit consent required
envs = make_env("trusted/repo", trust_remote_code=True) # ✅ OK
Best Practices
-
Pin to specific revisions for reproducibility:
make_env("username/repo@v1.0.0", trust_remote_code=True)
-
Review code before trusting: Check the repository contents first
-
Use official repositories: Prefer verified authors when possible
-
Document dependencies: Include clear
requirements.txt
-
Version your releases: Tag stable versions with semantic versioning
Example Repositories
Learn from existing EnvHub repositories:
LeIsaac Environment
- Repository: LightwheelAI/leisaac_env
- Features: IsaacLab integration, multiple tasks, teleoperation support
- Usage:
make_env(
"LightwheelAI/leisaac_env:envs/so101_pick_orange.py",
trust_remote_code=True
)
NVIDIA IsaacLab Arena
- Repository: nvidia/isaaclab-arena-envs
- Features: GPU-accelerated humanoid simulation, RTX rendering
- Usage:
make_env(
"nvidia/isaaclab-arena-envs",
trust_remote_code=True
)
Lightwheel BenchHub
- Repository: LightwheelAI/lw_benchhub_env
- Features: LIBERO and RoboCasa tasks with 268 environments
- Usage:
make_env(
"LightwheelAI/lw_benchhub_env",
trust_remote_code=True
)
Troubleshooting
ModuleNotFoundError
If loading fails due to missing dependencies:
# Install environment-specific dependencies
pip install -e ".[environment_name]"
# Or install from requirements.txt in the repo
pip install -r requirements.txt
Import Errors
Ensure all dependencies are installed locally:
- EnvHub downloads the code but doesn’t install dependencies automatically
- Check the repository README for installation instructions
Version Conflicts
If you encounter version conflicts:
# Create isolated environment
conda create -n env_test python=3.11
conda activate env_test
pip install lerobot[environment_name]
API Reference
make_env
from lerobot.envs.factory import make_env
env_dict = make_env(
cfg: EnvConfig | str,
n_envs: int = 1,
use_async_envs: bool = False,
hub_cache_dir: str | None = None,
trust_remote_code: bool = False
) -> dict[str, dict[int, gym.vector.VectorEnv]]
Parameters:
cfg: Environment config or Hub URL string
n_envs: Number of parallel environments per task
use_async_envs: Use AsyncVectorEnv for better CPU utilization
hub_cache_dir: Custom cache directory for Hub downloads
trust_remote_code: Explicit consent to execute remote code
Returns:
- Dictionary mapping
{suite_name: {task_id: vector_env}}
See Also