Giới thiệu: Tại sao LeRobot là bước ngoặt?
Trong thế giới robotics, việc huấn luyện robot thực hiện các tác vụ manipulation luôn là thách thức lớn. Mỗi lab có framework riêng, format dữ liệu riêng, và pipeline riêng — khiến việc tái sử dụng kết quả nghiên cứu trở nên cực kỳ khó khăn. LeRobot ra đời để giải quyết đúng vấn đề này.
LeRobot là framework mã nguồn mở từ HuggingFace, cung cấp một hệ sinh thái thống nhất cho robot learning — từ thu thập dữ liệu, huấn luyện policy, đến deploy lên robot thật. Nếu bạn đã quen với hệ sinh thái HuggingFace cho NLP (Transformers, Datasets, Hub), LeRobot mang triết lý tương tự vào robotics.
Trong bài viết này — bài đầu tiên của series VLA & LeRobot Mastery — chúng ta sẽ đi sâu vào kiến trúc của LeRobot, hiểu từng thành phần, và viết code thực tế để bắt đầu làm việc với framework này.
Kiến trúc tổng quan của LeRobot
LeRobot được thiết kế theo kiến trúc module, với 4 thành phần chính:
| Thành phần | Mô tả | Module |
|---|---|---|
| Dataset | Format dữ liệu thống nhất, tích hợp HuggingFace Hub | lerobot.common.datasets |
| Policy | Zoo các thuật toán học (ACT, Diffusion, VLA...) | lerobot.common.policies |
| Environment | Interface với simulator (MuJoCo, robosuite) | lerobot.common.envs |
| Robot | Interface với phần cứng robot thật | lerobot.common.robot_devices |
Điểm mạnh của thiết kế này là tính tách biệt: bạn có thể thay đổi policy mà không cần sửa dataset code, hoặc chuyển từ simulation sang real robot mà không cần train lại từ đầu.
Cài đặt LeRobot
# Cài đặt từ source (khuyến nghị để có version mới nhất)
git clone https://github.com/huggingface/lerobot.git
cd lerobot
pip install -e ".[dev]"
# Hoặc cài đặt từ PyPI
pip install lerobot
# Verify cài đặt thành công
python -c "import lerobot; print(lerobot.__version__)"
LeRobotDataset: Format dữ liệu thống nhất
Trái tim của LeRobot là LeRobotDataset — một format chuẩn hóa cho dữ liệu robot demonstration. Nó giải quyết vấn đề lớn nhất trong robot learning: mỗi lab dùng format khác nhau.
Cấu trúc dữ liệu
Một LeRobotDataset bao gồm:
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
# Tải dataset từ HuggingFace Hub
dataset = LeRobotDataset("lerobot/pusht")
# Xem thông tin dataset
print(f"Số frames: {dataset.num_frames}")
print(f"Số episodes: {dataset.num_episodes}")
print(f"FPS: {dataset.fps}")
print(f"Features: {dataset.features}")
# Truy cập một frame
frame = dataset[0]
print(frame.keys())
# dict_keys(['observation.image', 'observation.state', 'action',
# 'episode_index', 'frame_index', 'timestamp'])
Mỗi frame chứa:
- observation.image: Ảnh từ camera (có thể nhiều camera)
- observation.state: Trạng thái robot (joint positions, gripper state)
- action: Hành động tương ứng (joint velocities hoặc positions)
- episode_index: Số thứ tự episode
- frame_index: Số thứ tự frame trong episode
- timestamp: Thời gian thực
Tải và khám phá dataset
import torch
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
# Tải dataset ALOHA từ Hub
dataset = LeRobotDataset("lerobot/aloha_sim_transfer_cube_human")
# Xem cấu trúc observation
print("Observation keys:")
for key in dataset.features:
if key.startswith("observation"):
shape = dataset[0][key].shape if hasattr(dataset[0][key], 'shape') else type(dataset[0][key])
print(f" {key}: {shape}")
# Lấy tất cả frames của episode 0
episode_0 = dataset.filter(lambda x: x["episode_index"] == 0)
print(f"\nEpisode 0 có {len(episode_0)} frames")
# Visualize action distribution
actions = torch.stack([dataset[i]["action"] for i in range(min(1000, len(dataset)))])
print(f"\nAction shape: {actions.shape}")
print(f"Action mean: {actions.mean(dim=0)}")
print(f"Action std: {actions.std(dim=0)}")
Tạo dataset riêng
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
# Tạo dataset mới
dataset = LeRobotDataset.create(
repo_id="my-username/my-robot-dataset",
fps=30,
robot_type="so100",
features={
"observation.image": {
"dtype": "video",
"shape": (480, 640, 3),
"names": ["height", "width", "channels"],
},
"observation.state": {
"dtype": "float32",
"shape": (6,),
"names": ["joint_positions"],
},
"action": {
"dtype": "float32",
"shape": (6,),
"names": ["joint_velocities"],
},
},
)
# Thêm dữ liệu từng frame
for episode_idx in range(num_episodes):
for frame in episode_frames:
dataset.add_frame({
"observation.image": frame["image"],
"observation.state": frame["state"],
"action": frame["action"],
})
dataset.save_episode() # Kết thúc episode
# Upload lên HuggingFace Hub
dataset.push_to_hub()
Policy Zoo: Từ ACT đến VLA
LeRobot cung cấp một "sở thú" các policy đã được implement sẵn. Đây là điểm khác biệt lớn so với các framework khác — bạn có thể thử nghiệm nhiều thuật toán khác nhau trên cùng một dataset chỉ bằng cách thay đổi config.
Các policy có sẵn
| Policy | Paper | Ưu điểm | Nhược điểm |
|---|---|---|---|
| ACT | Zhao et al. 2023 | Nhanh, ổn định, chunk actions | Cần nhiều demo chất lượng cao |
| Diffusion Policy | Chi et al. RSS 2023 | Multi-modal, robust | Inference chậm hơn ACT |
| TDMPC | Hansen et al. 2024 | Model-based, sample efficient | Phức tạp hơn khi tune |
| VLA | Kim et al. 2024 | Language-conditioned, zero-shot | Cần GPU mạnh |
| SmolVLA | HuggingFace 2024 | Nhẹ hơn VLA, edge-friendly | Ít powerful hơn VLA full |
| pi0 | Black et al. 2024 | Flow matching, fast inference | Mới, ít benchmarks |
Khởi tạo và sử dụng policy
from lerobot.common.policies.act.configuration_act import ACTConfig
from lerobot.common.policies.act.modeling_act import ACTPolicy
# Cấu hình ACT policy
config = ACTConfig(
input_shapes={
"observation.image": [3, 480, 640],
"observation.state": [6],
},
output_shapes={
"action": [6],
},
input_normalization_modes={
"observation.image": "mean_std",
"observation.state": "min_max",
},
output_normalization_modes={
"action": "min_max",
},
chunk_size=100, # Số actions predict cùng lúc
n_action_steps=100, # Số actions thực thi
dim_model=512, # Kích thước transformer
n_heads=8, # Số attention heads
n_layers=6, # Số transformer layers
)
# Tạo policy
policy = ACTPolicy(config)
print(f"Số parameters: {sum(p.numel() for p in policy.parameters()):,}")
Chuyển đổi giữa các policy
# Chỉ cần thay đổi import và config
from lerobot.common.policies.diffusion.configuration_diffusion import DiffusionConfig
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy
diffusion_config = DiffusionConfig(
input_shapes={
"observation.image": [3, 480, 640],
"observation.state": [6],
},
output_shapes={
"action": [6],
},
num_inference_steps=100, # Số bước diffusion khi inference
down_dims=[256, 512, 1024],
)
diffusion_policy = DiffusionPolicy(diffusion_config)
Training Pipeline
LeRobot sử dụng Hydra cho configuration management, giúp việc thay đổi hyperparameters trở nên cực kỳ linh hoạt.
Training cơ bản
# Train ACT trên PushT dataset
python lerobot/scripts/train.py \
--policy.type=act \
--dataset.repo_id=lerobot/pusht \
--training.num_epochs=100 \
--training.batch_size=64 \
--training.lr=1e-4 \
--output_dir=outputs/act_pusht
# Train Diffusion Policy trên cùng dataset
python lerobot/scripts/train.py \
--policy.type=diffusion \
--dataset.repo_id=lerobot/pusht \
--training.num_epochs=200 \
--training.batch_size=64 \
--output_dir=outputs/diffusion_pusht
Training bằng Python API
from lerobot.scripts.train import train
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.policies.act.configuration_act import ACTConfig
from lerobot.common.policies.act.modeling_act import ACTPolicy
import torch
# Load dataset
dataset = LeRobotDataset("lerobot/pusht")
# Tạo dataloader
dataloader = torch.utils.data.DataLoader(
dataset,
batch_size=64,
shuffle=True,
num_workers=4,
pin_memory=True,
)
# Tạo policy
config = ACTConfig(
input_shapes={
"observation.image": [3, 96, 96],
"observation.state": [2],
},
output_shapes={"action": [2]},
chunk_size=100,
)
policy = ACTPolicy(config)
policy.train()
# Training loop
optimizer = torch.optim.AdamW(policy.parameters(), lr=1e-4)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
policy.to(device)
for epoch in range(100):
total_loss = 0
for batch in dataloader:
batch = {k: v.to(device) for k, v in batch.items()}
loss_dict = policy.forward(batch)
loss = loss_dict["loss"]
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
avg_loss = total_loss / len(dataloader)
print(f"Epoch {epoch}: loss = {avg_loss:.4f}")
Evaluation: Đánh giá policy
Sau khi train, bạn cần đánh giá policy trong môi trường simulation.
# Evaluation bằng CLI
# python lerobot/scripts/eval.py \
# --policy.path=outputs/act_pusht/checkpoints/last \
# --env.type=pusht \
# --eval.n_episodes=50 \
# --eval.batch_size=10
# Evaluation bằng Python
import gymnasium as gym
import torch
from lerobot.common.policies.act.modeling_act import ACTPolicy
# Load trained policy
policy = ACTPolicy.from_pretrained("outputs/act_pusht/checkpoints/last")
policy.eval()
device = torch.device("cuda")
policy.to(device)
# Tạo environment
env = gym.make("lerobot/pusht")
success_count = 0
n_episodes = 50
for ep in range(n_episodes):
obs, info = env.reset()
done = False
while not done:
# Chuyển observation sang tensor
obs_tensor = {
k: torch.tensor(v).unsqueeze(0).to(device)
for k, v in obs.items()
}
# Predict action
with torch.no_grad():
action = policy.select_action(obs_tensor)
# Thực thi action
obs, reward, terminated, truncated, info = env.step(
action.squeeze(0).cpu().numpy()
)
done = terminated or truncated
if info.get("is_success", False):
success_count += 1
print(f"Success rate: {success_count/n_episodes*100:.1f}%")
Robot Interfaces: Kết nối phần cứng
LeRobot hỗ trợ nhiều loại robot phần cứng thông qua các driver tích hợp:
| Robot | Loại | DOF | Ghi chú |
|---|---|---|---|
| SO-100 | Single arm | 6 | Budget-friendly, Feetech servos |
| Moss v1 | Single arm | 6 | Koch v1.1 compatible |
| ALOHA | Dual arm | 2x6 | Bimanual manipulation |
| Stretch RE1 | Mobile manip | 7+ | Hello Robot, mobile base |
| LeKiwi | Mobile base | 3 | Holonomic, budget |
from lerobot.common.robot_devices.robots.manipulator import ManipulatorRobot
from lerobot.common.robot_devices.motors.feetech import FeetechMotorsBus
# Kết nối robot SO-100
robot = ManipulatorRobot(
robot_type="so100",
leader_arms={"main": FeetechMotorsBus(port="/dev/ttyACM0", ...)},
follower_arms={"main": FeetechMotorsBus(port="/dev/ttyACM1", ...)},
cameras={"laptop": OpenCVCamera(camera_index=0, fps=30, width=640, height=480)},
)
robot.connect()
# Calibrate nếu lần đầu
robot.home()
So sánh LeRobot với các framework khác
| Tiêu chí | LeRobot | robomimic | robosuite | RLBench |
|---|---|---|---|---|
| Mục đích | End-to-end platform | Policy training | Simulation | Benchmarks |
| Dataset Hub | HuggingFace Hub | Local | N/A | Local |
| Policy zoo | ACT, Diffusion, VLA, pi0 | BC, BC-RNN, HBC | N/A | N/A |
| Real robot | Tích hợp sẵn | Không | Không | Không |
| Community | Lớn (HF ecosystem) | Nghiên cứu | Nghiên cứu | Nghiên cứu |
| Dễ dùng | Cao | Trung bình | Trung bình | Thấp |
LeRobot nổi bật ở khả năng kết nối end-to-end: từ thu thập dữ liệu trên robot thật, upload lên Hub để chia sẻ, train nhiều policy khác nhau, và deploy lại lên robot. Không framework nào khác cung cấp trải nghiệm liền mạch như vậy.
Papers quan trọng
Để hiểu sâu hơn về các thành phần của LeRobot, bạn nên đọc các paper sau:
- LeRobot — HuggingFace, 2024 — Framework paper, mô tả kiến trúc tổng thể
- ACT: Action Chunking with Transformers — Zhao et al., 2023 — Policy chủ lực cho manipulation
- Diffusion Policy — Chi et al., RSS 2023 — Diffusion-based policy cho multi-modal actions
- TDMPC2 — Hansen et al., 2024 — Model-based approach cho robot learning
Kết luận và bước tiếp theo
LeRobot là một framework mạnh mẽ và dễ tiếp cận cho robot learning. Với kiến trúc module, policy zoo phong phú, và tích hợp HuggingFace Hub, nó đang trở thành chuẩn mực cho cộng đồng robotics nghiên cứu và ứng dụng.
Trong bài tiếp theo của series — Thu thập dữ liệu bằng Teleoperation trong Simulation — chúng ta sẽ thực hành thu thập dữ liệu demonstration bằng teleop, từ đó xây dựng dataset để train các policy đã giới thiệu ở trên.
Nếu bạn muốn tìm hiểu thêm về các model VLA trước khi đi sâu vào LeRobot, hãy đọc bài tổng quan về VLA Models và bài thực hành LeRobot cơ bản.
Bài viết liên quan
- VLA Models: Vision-Language-Action cho Robot — Tổng quan về các mô hình VLA hiện đại
- LeRobot Hands-on: Thực hành từ zero — Hướng dẫn bắt đầu nhanh với LeRobot
- Diffusion Policy: Từ lý thuyết đến thực hành — Deep dive vào Diffusion Policy cho robotics