GR00T whole-body VLA data: có cần data real?
Disclosure: Bài viết có thể chứa affiliate/referral links. Nếu bạn mua hoặc đăng ký qua các link đó, VnRobo có thể nhận commission hoặc credit. Nội dung kỹ thuật ưu tiên tính đúng và khả năng chạy được.
Phần 1 dùng open dataset. Phần 2 dùng sim data. Phần 3 trả lời câu hỏi thực tế nhất: có cần data real không?
Câu trả lời ngắn:
- Nếu mục tiêu là học format, debug loader, chạy open-loop: không cần real data.
- Nếu mục tiêu là demo trong simulator hoặc task sim-to-sim: sim + public có thể đủ.
- Nếu mục tiêu là chạy humanoid thật với camera thật, latency thật, contact thật, lighting thật: gần như chắc chắn cần data real hoặc ít nhất real calibration/eval data.
Với whole-body VLA kiểu Unitree G1 + GEAR-SONIC, data real thường đi qua workflow:
VR teleop + SONIC deploy + camera server
-> data exporter
-> GR00T-LeRobot dataset
-> process/clean/merge
-> fine-tune Isaac-GR00T
-> PolicyServer
-> SONIC inference client + C++ deploy
3.1 Khi nào cần data real?
Mục tiêu
Quyết định có nên đầu tư vào real data collection hay chưa. Thu data real đắt, rủi ro và chậm; nhưng bỏ qua nó quá lâu sẽ khiến policy fail khi ra robot.
Khi sim/public có thể đủ
Bạn có thể chưa cần data real nếu:
- Bạn chỉ muốn verify GR00T-LeRobot format.
- Bạn đang viết converter, loader, training script.
- Task chỉ chạy trong Isaac Lab / IsaacLab-Arena.
- Camera/object distribution giống dataset public.
- Controller/action space còn đang thay đổi.
- Robot thật chưa có safety rig, E-stop, current limit, camera sync.
Ở giai đoạn này, mục tiêu không phải "robot chạy được", mà là:
dataset loads
training starts
checkpoint saves
open-loop predicts action
server-client pipeline responds
Khi bắt buộc phải có real data
Bạn nên thu real data khi thấy một trong các dấu hiệu:
| Dấu hiệu | Vì sao sim/public không đủ |
|---|---|
| Camera thật khác sim | Lens distortion, exposure, motion blur, rolling shutter, timestamp lệch. |
| Contact task | Grasp, push, carry, door, drawer rất nhạy với friction và compliance. |
| Whole-body balance | Base sway, foot slip, torso motion khác sim. |
| Wrist/hand khác dataset | Hand joint mapping và gripper affordance lệch. |
| Latency lớn | Sim không phản ánh camera server, ZMQ, policy server, C++ deploy loop. |
| Object/domain mới | Public dataset không có vật, scene, pose, lighting tương tự. |
Với humanoid, sim-to-real gap không chỉ là ảnh. Nó còn là:
- controller latency,
- joint backlash,
- IMU drift,
- foot-ground contact,
- hand compliance,
- camera placement,
- operator style,
- action scaling.
Quy tắc ra quyết định
Nếu task không có contact thật:
public + sim + domain randomization có thể đủ lâu hơn.
Nếu task có grasp/carry/push hoặc robot phải đi trong không gian thật:
cần real data sớm.
Nếu policy trong sim tốt nhưng real robot fail ngay ở approach:
kiểm tra camera calibration + latency trước khi đổ lỗi model.
Nếu policy approach được nhưng fail khi grasp/contact:
cần real data cho final interaction.
3.2 Thu data real với VR teleop + SONIC
Mục tiêu
Thu demonstration trên robot thật hoặc sim loop bằng GR00T-WholeBodyControl, xuất thành LeRobot dataset có:
outputs/<timestamp>-G1-robot01/
├── data/
│ ├── train-00000.parquet
│ └── ...
├── videos/
│ ├── observation.images.ego_view/
│ │ └── episode_000000.mp4
│ ├── observation.images.left_wrist/
│ └── observation.images.right_wrist/
└── meta/
├── info.json
├── modality.json
├── episodes.jsonl
└── tasks.jsonl
Theo docs GR00T-WholeBodyControl, data exporter chạy cùng SONIC deployment và VR teleop stack, capture robot state, SMPL teleop pose và camera images. Camera server chạy onboard robot computer, thường là Jetson Orin, và publish JPEG frames qua ZMQ.
Yêu cầu môi trường
Robot/onboard:
- Unitree G1 hoặc embodiment tương thích stack bạn dùng.
- Jetson Orin hoặc robot computer kết nối camera.
- OAK camera là setup được docs nói test/support; RealSense/USB webcam có driver nhưng cần kiểm chứng vì docs nói chưa test gần đây.
- Network ổn định giữa robot và workstation.
- E-stop vật lý, giới hạn current/torque, safety area.
Workstation:
- Ubuntu/Debian.
- CUDA Toolkit.
- Repo
NVlabs/GR00T-WholeBodyControl. - Python env cho data collection, teleop, inference.
- PICO VR nếu dùng VR whole-body teleop.
Training GPU:
- Debug: 1x GPU 48-80 GB VRAM.
- Production-ish whole-body fine-tune: 4+ GPUs 80 GB recommended theo tinh thần GEAR workflow.
- Inference PolicyServer: 1 GPU đủ load checkpoint; VRAM phụ thuộc model/checkpoint/inference mode.
Clone và cài data collection env
Trên workstation:
git clone https://github.com/NVlabs/GR00T-WholeBodyControl.git
cd GR00T-WholeBodyControl
bash install_scripts/install_data_collection.sh
Script này tạo .venv_data_collection và cài LeRobot, PyAV, OpenCV, các dependency data exporter.
Setup camera server trên robot
SSH vào robot/onboard computer:
git clone https://github.com/NVlabs/GR00T-WholeBodyControl.git
cd GR00T-WholeBodyControl
bash install_scripts/install_camera_server.sh
Kiểm tra service:
sudo systemctl status composed_camera_server.service
journalctl -u composed_camera_server.service -f
Nếu không dùng systemd, chạy camera server thủ công theo README/script của repo. Cần kiểm chứng command cụ thể theo camera driver.
Launch data collection all-in-one
Trên workstation:
python gear_sonic/scripts/launch_data_collection.py \
--camera-host 192.168.123.164 \
--task-prompt "pick up the soda can and place it in the bin"
Nếu muốn record wrist cameras:
python gear_sonic/scripts/launch_data_collection.py \
--camera-host 192.168.123.164 \
--task-prompt "pick up the soda can and place it in the bin" \
--record-wrist-cameras
Tên flag wrist camera cần kiểm chứng bằng:
python gear_sonic/scripts/launch_data_collection.py --help
Docs mô tả all-in-one tmux launcher mở bốn pane:
Pane 0: C++ Deploy
Pane 1: PICO Teleop
Pane 2: Data Exporter
Pane 3: Camera Viewer
Trong buổi thu data, mỗi episode nên có:
- Task prompt rõ ràng, một hành động chính.
- Start pose giống nhau vừa đủ để học, nhưng không quá cứng.
- Success/fail marking nhất quán.
- Không giữ frame khi operator pause lâu.
- Không để robot mất balance hoặc va chạm mạnh.
Số lượng episode
Theo VLA workflow docs, nên thu ít nhất 50-100 demonstrations cho target task để fine-tune ổn hơn. Thực tế:
| Task | Số episode khởi đầu |
|---|---|
| Pick object đơn giản | 50-100 |
| Pick-and-place với nhiều pose | 100-300 |
| Mobile manipulation có approach | 200-500 |
| Multi-object / long horizon | 500+ và nên chia subtask |
Đừng thu 500 episode lỗi. 80 episode sạch thường tốt hơn 300 episode lẫn fail không annotation.
Post-process real dataset
Mục tiêu
Loại bỏ discarded episodes, stale SMPL frames, frame drop và session không cùng config.
Chạy trong data collection env:
source .venv_data_collection/bin/activate
python gear_sonic/scripts/process_dataset.py \
--dataset-path outputs/2026-04-03-14-30-00-G1-robot01 \
--output-path outputs/my_task_cleaned
Merge nhiều session:
python gear_sonic/scripts/process_dataset.py \
--dataset-path outputs/session1 outputs/session2 outputs/session3 \
--output-path outputs/my_task_merged
Hoặc dùng list file:
cat > datasets.txt <<'TXT'
outputs/session1
outputs/session2
outputs/session3
TXT
python gear_sonic/scripts/process_dataset.py \
--dataset-list datasets.txt \
--output-path outputs/my_task_merged
Nếu chỉ muốn merge, không remove stale SMPL:
python gear_sonic/scripts/process_dataset.py \
--dataset-list datasets.txt \
--output-path outputs/my_task_merged_no_clean \
--no-remove-stale-smpl
Thông thường không nên dùng --no-remove-stale-smpl trừ khi bạn biết rõ stale detector làm mất data hợp lệ.
Verify dataset sau post-process
cd Isaac-GR00T
export REAL_DATASET=/abs/path/to/GR00T-WholeBodyControl/outputs/my_task_cleaned
uv run python tools/verify_groot_lerobot_dataset.py "$REAL_DATASET"
python -m json.tool "$REAL_DATASET/meta/modality.json" | head -120
Kiểm tra video:
find "$REAL_DATASET/videos" -name "*.mp4" | head -5
ffprobe "$(find "$REAL_DATASET/videos" -name '*.mp4' | head -1)"
Kiểm tra parquet:
uv run python - <<'PY'
from pathlib import Path
import pandas as pd
root = Path("$REAL_DATASET")
p = sorted((root / "data").rglob("*.parquet"))[0]
df = pd.read_parquet(p)
print(p)
print(df.head())
print(df.columns.tolist())
PY
Lưu ý: trong heredoc trên, shell sẽ không expand $REAL_DATASET vì dùng quote đơn nếu copy nguyên. Cách chắc hơn:
uv run python -c "from pathlib import Path; import os, pandas as pd; root=Path(os.environ['REAL_DATASET']); p=sorted((root/'data').rglob('*.parquet'))[0]; df=pd.read_parquet(p); print(p); print(df.head()); print(df.columns.tolist())"
Train với real data
Trước khi train, chạy preflight giống Phần 1:
cd Isaac-GR00T
uv run python gr00t/experiment/launch_finetune.py --help | \
grep -E "dataset|embodiment|modality|base-model|max-steps|num-gpus"
test -d "$REAL_DATASET"
test -f "$REAL_DATASET/meta/modality.json"
python -m json.tool "$REAL_DATASET/meta/modality.json" >/tmp/real_modality.pretty.json
UNITREE_G1_SONIC
cd Isaac-GR00T
export NUM_GPUS=4
export REAL_DATASET=/abs/path/to/outputs/my_task_cleaned
export MODALITY_CONFIG=gr00t/configs/data/embodiment_configs.py
export OUT=/mnt/checkpoints/groot_g1_sonic_real_my_task
test -f "$MODALITY_CONFIG"
uv run torchrun --nproc_per_node=$NUM_GPUS --master_port=29500 \
gr00t/experiment/launch_finetune.py \
--base-model-path nvidia/GR00T-N1.7-3B \
--dataset-path "$REAL_DATASET" \
--embodiment-tag UNITREE_G1_SONIC \
--modality-config-path "$MODALITY_CONFIG" \
--num-gpus $NUM_GPUS \
--output-dir "$OUT" \
--save-total-limit 5 \
--save-steps 5000 \
--max-steps 20000 \
--use-wandb \
--global-batch-size 32 \
--color-jitter-params brightness 0.3 contrast 0.4 saturation 0.5 hue 0.08 \
--dataloader-num-workers 4
NEW_EMBODIMENT
Nếu robot/action schema không phải SONIC latent:
export NUM_GPUS=1
export REAL_DATASET=/abs/path/to/outputs/my_task_cleaned
export MODALITY_CONFIG=/abs/path/to/configs/my_robot_config.py
export OUT=/mnt/checkpoints/groot_new_embodiment_real_my_task
test -f "$MODALITY_CONFIG"
CUDA_VISIBLE_DEVICES=0 uv run python \
gr00t/experiment/launch_finetune.py \
--base-model-path nvidia/GR00T-N1.7-3B \
--dataset-path "$REAL_DATASET" \
--embodiment-tag NEW_EMBODIMENT \
--modality-config-path "$MODALITY_CONFIG" \
--num-gpus $NUM_GPUS \
--output-dir "$OUT" \
--save-total-limit 3 \
--save-steps 1000 \
--max-steps 5000 \
--global-batch-size 4 \
--dataloader-num-workers 2
Mix real + sim + public
Khi nào mix?
| Mix | Dùng khi |
|---|---|
| Real only | Task nhỏ, domain rất cụ thể, đã có 100+ demo sạch. |
| Real + sim | Muốn tăng pose/object/lighting diversity nhưng vẫn anchor vào robot thật. |
| Real + public | Public cùng embodiment/action schema, giúp regularize. |
| Real + sim + public | Task cần generalization, nhưng phải đảm bảo schema/action space giống nhau. |
Tỉ lệ bắt đầu
| Giai đoạn | Tỉ lệ |
|---|---|
| Ít real data, sim tốt | 30% real / 70% sim |
| Real data đã có 100-300 demo | 60% real / 40% sim/public |
| Deployment thật đang fail ở contact | 80% real / 20% sim/public |
| Public dataset khác task nhưng cùng embodiment | 10-30% public để regularize |
Nếu schema giống nhau, dùng script merge ở Phần 2:
cat > mix_real_sim_public.txt <<'TXT'
/abs/path/to/outputs/my_task_cleaned
/abs/path/to/datasets/g1_pick_place_lerobot
/abs/path/to/datasets/arena_g1_loco/lerobot
TXT
uv run python tools/merge_groot_lerobot_datasets.py \
--dataset-list mix_real_sim_public.txt \
--output-dir datasets/g1_mix_real_sim_public
Nếu modality.json khác nhau, không merge trực tiếp. Bạn cần:
- Convert tất cả về cùng action/state schema.
- Hoặc train riêng từng stage:
base GR00T
-> fine-tune sim/public
-> continue fine-tune real
-> deploy/evaluate
Continue fine-tune command cần kiểm chứng theo version repo; thường sẽ dùng --base-model-path /path/to/previous/checkpoint thay vì base Hugging Face model.
Inference trên robot thật
Start PolicyServer
Trên GPU machine:
cd Isaac-GR00T
uv run python gr00t/eval/run_gr00t_server.py \
--model-path /mnt/checkpoints/groot_g1_sonic_real_my_task/checkpoint-20000 \
--embodiment-tag UNITREE_G1_SONIC \
--device cuda:0 \
--port 5550
Run inference client + SONIC
Từ GR00T-WholeBodyControl:
python gear_sonic/scripts/launch_inference.py \
--policy-host <gpu_machine_ip> \
--policy-port 5550 \
--camera-host 192.168.123.164 \
--prompt "pick up the soda can and place it in the bin"
Manual setup nếu không dùng tmux:
Terminal 1:
cd Isaac-GR00T
uv run python gr00t/eval/run_gr00t_server.py \
--model-path /path/to/checkpoint \
--embodiment-tag UNITREE_G1_SONIC \
--device cuda:0 \
--port 5550
Terminal 2:
cd GR00T-WholeBodyControl/gear_sonic_deploy
./deploy.sh --input-type zmq_manager real
Terminal 3:
cd GR00T-WholeBodyControl
python gear_sonic/scripts/launch_inference.py \
--policy-host <gpu_machine_ip> \
--policy-port 5550 \
--camera-host <robot_camera_host> \
--prompt "pick up the object"
Safety checklist trước khi chạy real robot
- E-stop hoạt động và người vận hành đứng gần.
- Không có người trong vùng motion.
- Test
--simtrước real. - Bắt đầu với prompt đơn giản, object nhẹ.
- Giới hạn tốc độ/torque nếu controller hỗ trợ.
- Log camera/state/action ngay cả khi inference.
- Có rollback checkpoint cũ.
Lỗi thường gặp và cách fix
| Lỗi | Nguyên nhân | Fix |
|---|---|---|
| Camera server không có frame | Sai IP, camera service chết, firewall | journalctl -u composed_camera_server.service -f, ping robot, kiểm tra port ZMQ. |
| Frame delay lớn | Network yếu hoặc encode quá nặng | Dùng Ethernet, giảm resolution/fps, tách camera host. |
| Stale SMPL frames | VR stream pause/drop | Chạy process_dataset.py, loại episode lỗi. |
| Data có nhiều failed demos | Operator marking không nhất quán | Tách success/fail, bỏ fail khỏi first fine-tune. |
| Policy server action shape sai | Sai embodiment tag hoặc checkpoint | Dùng đúng UNITREE_G1_SONIC vs NEW_EMBODIMENT; kiểm tra checkpoint config. |
| Real robot đứng im | Client không publish action hoặc deploy không subscribe | Kiểm tra ZMQ ports, gear_sonic_deploy, topic/action manager. |
| Robot mất ổn định | Action scale/latency/safety issue | Dừng ngay, test sim, giảm speed, kiểm tra SONIC/deploy config. |
| Training overfit real data | Ít episode, scene quá giống nhau | Mix sim/public, augment lighting/camera, collect thêm pose/object. |
Tiêu chí "đã làm đúng"
Bạn đã làm đúng Phần 3 nếu:
- Camera server chạy ổn trên robot.
- Data collection launcher mở đủ deploy/teleop/export/viewer.
- Dataset output có
data,videos,meta. process_dataset.pyclean được data.verify_groot_lerobot_dataset.pypass.- Fine-tune chạy qua ít nhất vài nghìn step không NaN.
- PolicyServer load checkpoint.
- Inference sim chạy trước real.
- Real robot chạy task nhỏ với safety limit trước khi tăng độ khó.
Tổng kết toàn pipeline
| Nguồn data | Download/collect | Format | Train | Infer | Khi dùng |
|---|---|---|---|---|---|
| Public/open | hf download ... --repo-type dataset |
Verify meta/modality.json, data, videos |
launch_finetune.py --dataset-path <public> |
open_loop_eval.py hoặc run_gr00t_server.py |
Học format, baseline, regularization. |
| Sim | Isaac Lab / IsaacLab-Arena / Mimic / scripted rollout | Convert HDF5/trajectory -> GR00T-LeRobot | Sim-only hoặc mix public | Sim inference trước, real sau nếu gap nhỏ | Scale data rẻ, randomization, task exploration. |
| Real | VR teleop + SONIC + camera server | GR00T-WholeBodyControl exporter -> process/merge | Real-only hoặc continue from sim/public checkpoint | PolicyServer + SONIC deploy | Deployment thật, contact, camera/latency/robot-specific behavior. |
| SONIC controller | Bones-SEED / SMPL / SOMA / robot motion | Convert/filter sang motion_lib PKL | gear_sonic/train_agent_trl.py trong Isaac Lab |
Export ONNX -> C++ deploy | Cần controller/motion foundation mới hoặc embodiment mới. |
Checklist cuối series
[ ] Chọn embodiment/action space: UNITREE_G1_SONIC hay NEW_EMBODIMENT
[ ] Dataset có meta/info.json
[ ] Dataset có meta/episodes.jsonl
[ ] Dataset có meta/tasks.jsonl
[ ] Dataset có meta/modality.json
[ ] Parquet có observation.state/action đúng dim
[ ] Video key trong modality khớp videos/
[ ] Verify script pass
[ ] Fine-tune smoke test 100-500 step pass
[ ] Checkpoint save đúng
[ ] Open-loop eval không NaN/shape mismatch
[ ] PolicyServer load được checkpoint
[ ] Sim inference pass trước real
[ ] Nếu dùng UNITREE_G1_SONIC, đã có SONIC checkpoint/ONNX/deploy path kiểm chứng
[ ] Không trộn raw joint action với SONIC latent action trong cùng dataset
[ ] Real safety checklist pass
[ ] Log real rollout để cải thiện vòng sau
Bài viết liên quan
- GR00T whole-body VLA data: dùng open dataset
- GR00T whole-body VLA data: sinh data sim
- GR00T whole-body VLA: train SONIC controller
- WBC + VLA mới nhất cho humanoid