Giới thiệu: Khi Robot tự học từ thế giới thực
Trong các bài trước của series VLA & LeRobot Mastery, chúng ta đã học cách dùng imitation learning — thu thập demonstrations rồi huấn luyện policy bắt chước hành vi của người. Phương pháp này hoạt động tốt, nhưng có một giới hạn cốt lõi: policy chỉ giỏi bằng dữ liệu demo. Nếu demo không hoàn hảo, policy cũng không hoàn hảo.
Reinforcement learning (RL) giải quyết vấn đề này bằng cách cho phép robot tự cải thiện thông qua thử và sai. Nhưng RL truyền thống trên robot thật cực kỳ khó — robot cần hàng nghìn lần thử, mỗi lần thất bại có thể gây hỏng phần cứng, và không có cách nào "reset" môi trường như trong simulation.
HIL-SERL (Human-in-the-Loop Sample-Efficient Reinforcement Learning) là câu trả lời của LeRobot v0.5 cho thách thức này. Thay vì để robot hoàn toàn tự học, con người đứng cạnh và can thiệp khi cần — giống như dạy một đứa trẻ tập đi xe đạp, bạn giữ yên phía sau và chỉ đỡ khi sắp ngã.
Trong bài này, chúng ta sẽ đi qua toàn bộ workflow HIL-SERL từ A đến Z — từ setup phần cứng, thu thập demo, đến huấn luyện RL trên robot thật với human interventions.
HIL-SERL là gì? Ba thành phần cốt lõi
HIL-SERL kết hợp ba yếu tố để biến RL trên robot thật từ "gần như không thể" thành "vài giờ là xong":
1. Offline Demonstrations + Reward Classifier
Trước khi robot bắt đầu tự học, bạn cần cung cấp "điểm xuất phát" — một tập demos nhỏ (~15 episodes) để policy có baseline ban đầu. Đồng thời, bạn huấn luyện một reward classifier — một mạng CNN nhỏ phân loại "thành công" vs "thất bại" — để robot tự biết khi nào nó đang làm đúng.
Nếu bạn đã đọc bài về RL cơ bản, đây chính là cách giải quyết bài toán sparse reward — thay vì thiết kế reward function phức tạp, bạn dùng một classifier học từ data.
2. Actor-Learner SAC Loop + Human Interventions
Kiến trúc training chia thành hai process chạy song song:
| Process | Vai trò | Chạy ở đâu |
|---|---|---|
| Actor | Điều khiển robot thật, thu thập experience | Máy có kết nối robot |
| Learner | Cập nhật policy từ replay buffer | GPU mạnh (có thể cùng máy hoặc khác máy) |
Hai process giao tiếp qua gRPC — Actor gửi transitions (state, action, reward, next_state) cho Learner, Learner gửi lại policy weights mới cho Actor.
Thuật toán RL được dùng là SAC (Soft Actor-Critic) — một off-policy algorithm nổi tiếng về sample efficiency, hoàn hảo cho robot thật vì mỗi interaction đều quý giá.
Điểm then chốt: trong quá trình Actor chạy policy, con người cầm gamepad và có thể can thiệp bất cứ lúc nào. Khi policy chuẩn bị làm điều nguy hiểm (va chạm, rơi vật), bạn nhấn trigger để take over và điều khiển thủ công vài giây rồi trả lại quyền cho policy.
3. Safety Tools
HIL-SERL cung cấp các công cụ an toàn:
- Joint limits: giới hạn không gian exploration để robot không vượt ra ngoài vùng làm việc an toàn
- End-effector control: thay vì điều khiển từng joint (nguy hiểm), điều khiển vị trí end-effector (an toàn hơn)
- Emergency stop: nhấn nút dừng ngay lập tức
- Workspace bounds: vùng 3D mà robot được phép di chuyển
So sánh với SimpleVLA-RL
Nếu bạn đã đọc về SimpleVLA-RL, điểm khác biệt lớn nhất:
| Đặc điểm | SimpleVLA-RL | HIL-SERL |
|---|---|---|
| Môi trường | Simulation only | Robot thật |
| Human involvement | Không | Can thiệp real-time |
| Safety | Sim reset | Joint limits + workspace bounds |
| Sample efficiency | Trung bình | Cao (SAC + demos) |
| Hardware | GPU only | GPU + robot + gamepad + camera |
Phần cứng cần thiết
Trước khi bắt tay vào code, hãy chuẩn bị phần cứng:
| Thiết bị | Yêu cầu | Chi phí ước tính |
|---|---|---|
| GPU | NVIDIA với ≥8GB VRAM (RTX 3060 trở lên) | Đã có |
| Robot arm | SO-100 hoặc SO-101 follower | $200–$500 |
| Leader arm (tùy chọn) | SO-100/SO-101 leader cho teleop | $200–$500 |
| Gamepad | Xbox/PS controller USB | $30–$50 |
| USB Camera | Logitech C920 hoặc tương đương, 1–2 cái | $50–$80/cái |
| Bàn làm việc | Phẳng, đủ rộng cho robot + vật thể | Đã có |
Tổng chi phí tối thiểu: ~$300 (nếu dùng gamepad thay leader arm)
Step 1: Cài đặt LeRobot với HIL-SERL
HIL-SERL là một module mở rộng trong LeRobot v0.5. Cài đặt rất đơn giản:
# Clone LeRobot nếu chưa có
git clone https://github.com/huggingface/lerobot.git
cd lerobot
# Cài đặt với extras cho HIL-SERL
pip install -e ".[hilserl]"
Package hilserl sẽ kéo thêm các dependencies:
grpcio— giao tiếp Actor-Learnergymnasium— gym environment wrapper- Các utils cho reward classification và data processing
Verify cài đặt thành công:
python -c "from lerobot.rl import actor, learner; print('HIL-SERL ready!')"
Step 2: Tìm giới hạn không gian làm việc (Joint Limits)
Bước này cực kỳ quan trọng và thường bị bỏ qua. Bạn cần xác định vùng an toàn mà robot được phép di chuyển trong quá trình exploration.
lerobot-find-joint-limits \
--robot.type=so100_follower \
--teleop.type=so100_leader \
--teleop.port=/dev/ttyACM1
Lệnh này sẽ:
- Kết nối với robot follower và leader arm
- Bạn dùng leader arm di chuyển follower đến các vị trí cực hạn của workspace
- Script ghi lại min/max của từng joint
- Output ra file config với joint limits
Tại sao cần làm điều này?
Trong RL, policy sẽ thử những action ngẫu nhiên — đặc biệt ở giai đoạn đầu training. Nếu không có joint limits:
- Robot có thể đập vào bàn
- Gripper có thể cố mở quá giới hạn
- Arm có thể xoay vào vị trí self-collision
Joint limits tạo ra một "hộp an toàn" — policy chỉ được explore trong hộp này.
Nếu bạn dùng gamepad thay vì leader arm:
lerobot-find-joint-limits \
--robot.type=so100_follower \
--teleop.type=gamepad \
--teleop.port=/dev/input/js0
Dùng analog sticks để di chuyển robot đến các vị trí cực hạn, sau đó nhấn nút xác nhận.
Lưu ý quan trọng: Joint limits cũng cho phép chuyển sang end-effector control mode — thay vì gửi target angle cho từng joint, bạn gửi target position (x, y, z) và orientation cho end-effector. Điều này an toàn hơn rất nhiều cho RL vì action space nhỏ hơn và trực quan hơn.
Step 3: Thu thập Demonstrations (~15 Episodes)
HIL-SERL cần một tập demos nhỏ để:
- Warm-start policy — cho policy một baseline tốt thay vì bắt đầu từ random
- Huấn luyện reward classifier — phân biệt thành công vs thất bại
- Điền replay buffer — SAC cần data ban đầu để bắt đầu learning
Cấu hình environment
Tạo file env_config.json:
{
"mode": "record",
"fps": 10,
"control_mode": "gamepad",
"robot_type": "so100_follower",
"cameras": {
"top": "/dev/video0",
"wrist": "/dev/video2"
},
"workspace_bounds": {
"x": [-0.15, 0.15],
"y": [0.10, 0.40],
"z": [0.01, 0.25]
},
"episode_length": 300,
"dataset_repo_id": "your-username/hilserl-pickup-demos"
}
Thu thập với gamepad
python -m lerobot.rl.gym_manipulator --config_path env_config.json
Mapping gamepad khi thu thập:
| Nút | Chức năng |
|---|---|
| Left stick | Di chuyển end-effector X/Y |
| Right stick | Di chuyển end-effector Z / xoay |
| Right trigger (RT) | Đóng gripper |
| Left trigger (LT) | Mở gripper |
| A (Xbox) / X (PS) | Đánh dấu episode thành công |
| B (Xbox) / O (PS) | Đánh dấu episode thất bại |
| Y (Xbox) / △ (PS) | Ghi lại episode hiện tại (rerecord) |
| Start | Kết thúc session |
Mẹo thu thập demo tốt
- Đa dạng vị trí khởi đầu: Đặt vật thể ở nhiều vị trí khác nhau trên bàn
- Đa dạng chiến thuật: Đôi khi tiếp cận từ trái, đôi khi từ phải
- Tốc độ tự nhiên: Không quá nhanh, không quá chậm — khoảng 2-3 giây cho mỗi hành động
- ~15 episodes là đủ: HIL-SERL được thiết kế cho ít data. Quá nhiều demo không giúp nhiều hơn
- Chất lượng quan trọng hơn số lượng: Mỗi demo phải thành công và mượt mà
Step 4: Xử lý Dataset — Crop ROI
Đây là bước mà nhiều người bỏ qua nhưng ảnh hưởng lớn đến kết quả. RL rất nhạy cảm với background distractions — nếu camera thấy cả phòng, policy có thể "phân tâm" bởi những thứ không liên quan.
python -m lerobot.rl.crop_dataset_roi \
--repo-id your-username/hilserl-pickup-demos
Lệnh này sẽ:
- Hiển thị frame đầu tiên của mỗi camera
- Bạn vẽ bounding box quanh vùng làm việc (workspace)
- Tất cả frames được crop theo ROI đã chọn
- Resize về 128x128 pixels
Tại sao 128x128? Đây là trade-off giữa information và speed:
- RL cần inference nhanh (10 FPS real-time)
- Với SAC policy (không phải VLA lớn), 128x128 chứa đủ thông tin
- GPU memory usage thấp → có thể lưu nhiều frames trong replay buffer
Tại sao crop quan trọng?
Hãy tưởng tượng bạn đang học nấu ăn. Nếu có người liên tục đi qua đi lại phía sau, bạn sẽ bị phân tâm. RL cũng vậy — policy cố gắng tìm pattern trong toàn bộ image, và background noise làm chậm quá trình learning đáng kể. Crop về workspace giúp policy focus vào những gì quan trọng.
Step 5: Huấn luyện Reward Classifier
Reward classifier là một mạng CNN nhỏ phân loại trạng thái hiện tại thành "thành công" hoặc "thất bại". Bước này không bắt buộc nhưng rất khuyến khích vì:
- Không cần thiết kế reward function bằng tay (rất khó cho manipulation)
- Classifier tự học từ demos bạn đã thu thập
- Chính xác hơn binary reward (thành công cuối episode hay không)
Thu thập dữ liệu reward (tùy chọn)
Nếu muốn classifier chính xác hơn, thu thập thêm dataset với terminate_on_success=false:
{
"mode": "record",
"terminate_on_success": false,
"episode_length": 500
}
Khi terminate_on_success=false, episode tiếp tục ngay cả sau khi task thành công → bạn có thêm positive examples (frames ở trạng thái thành công).
Huấn luyện classifier
Tạo file reward_classifier_train_config.json:
{
"model": "resnet10",
"cameras": ["top", "wrist"],
"classification": "binary",
"dataset_repo_id": "your-username/hilserl-pickup-demos",
"batch_size": 32,
"num_epochs": 50,
"learning_rate": 1e-3,
"output_dir": "./reward_classifier"
}
lerobot-train --config_path reward_classifier_train_config.json
Classifier dùng ResNet-10 — một CNN nhỏ gọn nhưng đủ mạnh cho binary classification. Nó nhận input từ 2 cameras (top + wrist) và output probability thành công.
Validation accuracy nên đạt >90% trước khi sang bước tiếp theo. Nếu thấp hơn, thu thập thêm demos hoặc kiểm tra lại labels.
Step 6: Huấn luyện RL với Actor-Learner Architecture
Đây là phần chính — nơi robot thật sự "tự học". Bạn cần mở hai terminal chạy song song.
Tạo training config
File train_config.json:
{
"policy": {
"type": "sac",
"actor_lr": 3e-4,
"critic_lr": 3e-4,
"temperature_init": 1e-2,
"discount": 0.99,
"tau": 0.005,
"image_encoder": "resnet10",
"storage_device": "cuda"
},
"environment": {
"fps": 10,
"robot_type": "so100_follower",
"cameras": {
"top": "/dev/video0",
"wrist": "/dev/video2"
},
"control_mode": "end_effector",
"workspace_bounds": "from_joint_limits"
},
"training": {
"replay_buffer_size": 100000,
"batch_size": 256,
"utd_ratio": 10,
"policy_parameters_push_frequency": 4,
"max_episodes": 500,
"warmup_episodes": 0
},
"human_intervention": {
"enabled": true,
"device": "gamepad",
"port": "/dev/input/js0"
},
"reward_classifier": {
"path": "./reward_classifier/best_model.pt"
},
"dataset": {
"demo_repo_id": "your-username/hilserl-pickup-demos"
}
}
Terminal 1: Khởi động Learner
python -m lerobot.rl.learner --config_path train_config.json
Learner sẽ:
- Load demo data vào replay buffer
- Khởi tạo SAC policy
- Bắt đầu lắng nghe transitions từ Actor qua gRPC
- Liên tục sample batch từ replay buffer và update policy
- Push policy weights mới cho Actor mỗi 4 giây
Terminal 2: Khởi động Actor
python -m lerobot.rl.actor --config_path train_config.json
Actor sẽ:
- Kết nối với robot thật
- Nhận policy weights từ Learner
- Chạy policy trên robot, thu thập (state, action, reward, next_state)
- Gửi transitions cho Learner
- Lắng nghe gamepad input — nếu bạn nhấn trigger, Actor chuyển sang manual control
Luồng dữ liệu Actor-Learner
Actor (robot thật) Learner (GPU)
│ │
│ ─── transitions (gRPC) ──────────> │
│ │ → Thêm vào replay buffer
│ │ → Sample batch
│ │ → Update SAC (critic + actor)
│ <── policy weights (gRPC) ──────── │
│ │
│ → Chạy policy mới │
│ → Thu thập transition mới │
└──────────────────────────────────────┘
(lặp liên tục)
Nghệ thuật Human Intervention
Human intervention là yếu tố quyết định thành công của HIL-SERL. Đây không chỉ là "nhấn nút cứu robot" — nó là một kỹ năng cần luyện tập.
Khi nào nên can thiệp
| Tình huống | Can thiệp? | Lý do |
|---|---|---|
| Robot chuẩn bị va chạm mạnh | Có — ngay lập tức | Bảo vệ phần cứng |
| Robot đi sai hướng nhưng an toàn | Không | Để nó trải nghiệm failure → học |
| Robot lặp đi lặp lại cùng lỗi | Có — nhẹ nhàng | Cho nó thấy đường đi đúng |
| Robot gần thành công nhưng miss | Không | Nó sẽ tự điều chỉnh qua nhiều lần thử |
| Robot hoàn toàn "đơ" | Có | Reset episode và bắt đầu lại |
Nguyên tắc vàng
-
Để policy explore trước: Trong 5-10 episodes đầu, hạn chế can thiệp (trừ khi nguy hiểm). Policy cần trải nghiệm failure để học.
-
Can thiệp ngắn, không dài: Khi take over, chỉ can thiệp đủ để điều chỉnh hướng đi, rồi trả lại quyền cho policy ngay. Can thiệp dài = bạn đang demo, không phải teaching RL.
-
Intervention rate phải giảm dần: Đây là metric quan trọng nhất.
- Episode 1-20: intervention rate ~50-70% (policy còn non)
- Episode 50-100: intervention rate ~20-30% (đang học)
- Episode 100+: intervention rate <10% (gần converge)
- Nếu intervention rate không giảm → kiểm tra config/reward
-
Consistency: Can thiệp theo cùng một "phong cách". Nếu lần trước bạn dạy robot tiếp cận từ bên trái, đừng đột nhiên dạy từ bên phải.
Hyperparameters quan trọng
temperature_init: 1e-2
Đây là entropy temperature của SAC — kiểm soát mức độ exploration vs exploitation.
- Cao (1e-1): policy ngẫu nhiên hơn, explore nhiều → tốt cho giai đoạn đầu nhưng chậm converge
- Thấp (1e-3): policy deterministic hơn, exploit knowledge → converge nhanh nhưng dễ stuck
- 1e-2 là sweet spot cho hầu hết manipulation tasks
SAC tự động adjust temperature trong quá trình training, nên giá trị init không quá quan trọng. Nhưng nếu quá cao, robot sẽ hành xử "điên" ở đầu training.
policy_parameters_push_frequency: 4 (giây)
Tần suất Learner push weights mới cho Actor.
- Thấp (1-2s): Actor luôn dùng policy mới nhất → learning nhanh hơn nhưng tốn bandwidth
- Cao (10-20s): Actor dùng policy cũ → learning chậm, nhưng ổn định hơn
- 4s là mặc định tốt — cân bằng giữa freshness và stability
storage_device: "cuda"
Quyết định replay buffer lưu ở đâu.
- "cuda": Lưu trên GPU → sampling nhanh hơn 10x nhưng tốn VRAM
- "cpu": Lưu trên RAM → chậm hơn nhưng tiết kiệm VRAM
Nếu bạn có GPU ≥16GB VRAM, dùng "cuda". Với 8GB, dùng "cpu" an toàn hơn.
utd_ratio: 10
Update-to-Data ratio — số lần update policy cho mỗi transition mới.
- Cao (20-50): policy được update nhiều hơn per sample → sample efficient hơn nhưng dễ overfit
- Thấp (1-4): ít update → ổn định nhưng cần nhiều data hơn
- 10 là chuẩn cho HIL-SERL, đã được kiểm chứng trên nhiều tasks
Thời gian huấn luyện dự kiến
| Task | Demos | RL Episodes | Thời gian thực | Hardware |
|---|---|---|---|---|
| Pick & place đơn giản | 15 | 100-200 | 1-2 giờ | RTX 3060 + SO-100 |
| Stacking 2 cubes | 15 | 200-400 | 2-4 giờ | RTX 3060 + SO-100 |
| Insertion (peg-in-hole) | 20 | 300-500 | 3-5 giờ | RTX 4070 + SO-101 |
| Multi-step assembly | 25 | 500-1000 | 5-8 giờ | RTX 4090 + SO-101 |
So sánh: Pure RL (không có demos, không có human interventions) thường cần 10-100x thời gian hơn cho cùng một task. HIL-SERL đạt được sample efficiency đáng kinh ngạc nhờ kết hợp cả ba yếu tố.
Troubleshooting thường gặp
Robot "run" không mượt, giật liên tục
Nguyên nhân: FPS quá cao so với khả năng inference.
Fix: Giảm fps trong config từ 10 xuống 5. Kiểm tra GPU utilization — nếu >95%, model inference đang là bottleneck.
Intervention rate không giảm sau 100+ episodes
Nguyên nhân: Reward classifier không chính xác, hoặc task quá khó cho số lượng demo hiện tại.
Fix:
- Kiểm tra reward classifier accuracy trên validation set
- Thu thập thêm 10-15 demos nếu task phức tạp
- Đơn giản hóa task (ví dụ: giảm variation trong vị trí vật thể)
Actor và Learner mất kết nối
Nguyên nhân: gRPC timeout hoặc network issue.
Fix: Kiểm tra cả hai process chạy trên cùng máy. Nếu chạy trên máy khác nhau, đảm bảo firewall mở port gRPC (mặc định 50051).
Policy "quên" sau khi đã học tốt
Nguyên nhân: Catastrophic forgetting — replay buffer bị đè bởi data mới kém chất lượng.
Fix: Tăng replay_buffer_size và đảm bảo demo data luôn được giữ trong buffer (check config demo_ratio).
So sánh: HIL-SERL vs Pure Imitation Learning
Sau khi đã hiểu cả hai phương pháp trong series này (imitation learning qua SmolVLA và RL qua HIL-SERL), hãy so sánh:
| Tiêu chí | Imitation Learning | HIL-SERL |
|---|---|---|
| Data cần | 50-200 demos | 15 demos + RL episodes |
| Thời gian demo | 30-60 phút | 10-15 phút |
| Thời gian train | 2-8 giờ (GPU only) | 1-5 giờ (GPU + robot) |
| Cần robot khi train | Không | Có |
| Tự cải thiện | Không | Có |
| Vượt demo quality | Không | Có |
| Độ phức tạp setup | Trung bình | Cao |
Khi nào dùng gì?
- Imitation Learning: Task đơn giản, demo chất lượng cao, không cần vượt qua human performance
- HIL-SERL: Task khó, cần policy tốt hơn demo, có thời gian ngồi cạnh robot
Workflow lý tưởng: Bắt đầu với imitation learning (nhanh, đơn giản), nếu chưa đủ tốt → fine-tune bằng HIL-SERL. Đây chính là triết lý "best of both worlds" trong bài tiếp theo về PEFT/LoRA deploy.
Kết luận
HIL-SERL là một trong những tính năng đột phá nhất của LeRobot v0.5. Nó biến reinforcement learning trên robot thật — từng được coi là "chỉ dành cho lab có triệu đô" — thành thứ mà bất kỳ ai có SO-100 robot, một chiếc gamepad, và vài giờ rảnh đều có thể làm.
Hãy nhớ ba nguyên tắc cốt lõi:
- Demos tốt = khởi đầu tốt — 15 episodes chất lượng cao
- Crop ROI = focus — loại bỏ distraction, tăng tốc learning
- Human intervention = nghệ thuật — can thiệp đúng lúc, đúng mức, và giảm dần
Trong bài tiếp theo, chúng ta sẽ kết thúc series bằng workflow production-ready: PEFT/LoRA fine-tuning để tiết kiệm GPU và deploy VLA lên robot thật với Real-Time Chunking. Đọc tiếp tại PEFT/LoRA Fine-tune & Deploy VLA.
Bài viết liên quan
- LeRobot v0.5: Tổng quan tính năng mới — Xem toàn bộ tính năng mới trong phiên bản v0.5
- RL cơ bản cho Robotics — Nền tảng lý thuyết RL cần biết trước khi dùng HIL-SERL
- LeRobot Ecosystem Guide — Hướng dẫn toàn diện về hệ sinh thái LeRobot