Vì sao bài cuối nói về stack?
Năm bài trước đi qua từng nguồn dữ liệu humanoid: bản đồ sở hữu, VR teleoperation, view alignment, dữ liệu mô phỏng và video người. Bài 1 đặt câu hỏi "ai tạo giá trị ở lớp nào?". Bài 2 cho thấy teleop không chỉ là joystick, mà là một chuỗi sensor, operator, robot và action log. Bài 5 giải thích khi nào video người trở thành training data, derived robot data hoặc benchmark evidence.
Bài 6 gom tất cả lại vào một vòng đời thực dụng của VLA: dữ liệu được chuyển sang LeRobot, thống kê normalization được tính, pi0.5 được train, checkpoint được lưu, policy server được bật, robot gửi observation lên server, server trả action về robot. Đây là nơi câu hỏi sở hữu dữ liệu trở nên cụ thể nhất. Không còn nói chung chung "dữ liệu thuộc về ai"; ta có thể chỉ vào từng file, từng key và từng command.
Nguồn kỹ thuật chính cho bài này là EgoHumanoid README, EgoHumanoid paper, OpenPI config, OpenPI remote inference docs và tài liệu LeRobot Dataset. Nếu bạn muốn đọc thêm phần tooling VLA ngoài series, xem LeRobot và pi0-FAST training và EXPO-FT: RL online cho VLA π0.5.
Vòng đời VLA trong một sơ đồ
Hãy đọc stack này từ trái sang phải:
raw human / robot demonstrations
-> processed HDF5 trajectories
-> LeRobot dataset
-> normalization statistics
-> pi0.5 training run
-> checkpoint directory
-> policy server on GPU host
-> robot-side deployment client
-> action chunks executed by humanoid controller
-> telemetry and rollout review
Trong EgoHumanoid, workflow này gắn với các lệnh cụ thể:
# 1. Convert processed data to LeRobot format
python convert_to_lerobot.py \
--src-path /path/to/processed/data \
--output-path /path/to/lerobot/data \
--repo-id my_dataset \
--fps 20 \
--task "task description"
# 2. Compute normalization statistics
uv run python scripts/compute_norm_states_ultra_fast.py --config-name=norm_compute
# 3. Train pi0.5 on a G1 custom config with 4 FSDP devices
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 uv run scripts/train.py pi05_g1_custom \
--exp_name=my_experiment \
--fsdp-devices 4
# 4. Serve a trained checkpoint
uv run scripts/serve_policy.py policy:checkpoint \
--policy.config=<config_name> \
--policy.dir=checkpoints/<config_name>/<exp_name>/<iteration>
# 5. Run robot-side deployment client
python scripts/deploy.py --host <server_ip> --port 8000
Beginner nên chú ý một điều: đây không phải năm lệnh rời rạc. Mỗi lệnh tạo ra hoặc tiêu thụ một artifact có quyền sở hữu, rủi ro và trách nhiệm riêng. convert_to_lerobot.py biến dữ liệu đã xử lý thành dataset có schema. compute_norm_states_ultra_fast.py tạo thống kê phụ thuộc dataset. train.py tạo checkpoint. serve_policy.py biến checkpoint thành dịch vụ inference. deploy.py đưa observation thật từ robot vào policy và biến output thành action thật.
Bảng ownership theo từng artifact
| Artifact | Sinh ra ở bước nào | Ai thường tạo giá trị? | Rủi ro chính |
|---|---|---|---|
| Raw video / teleop log | Thu thập dữ liệu | Người demo, operator, chủ robot, chủ môi trường | Consent, privacy, quyền dùng lại |
| Processed HDF5 | Alignment, cleaning, merge | Data engineer, pipeline owner | Mất provenance, sai timestamp, sai frame |
| LeRobot dataset | convert_to_lerobot.py |
Dataset owner, annotation owner, task designer | Schema mismatch, license không rõ, task prompt mơ hồ |
| Norm stats | compute_norm_states_ultra_fast.py |
Training engineer | Leakage từ split test, lệch distribution |
| Checkpoint | train.py pi05_g1_custom |
Model owner, data contributors, infrastructure owner | Memorization, contamination, khó xóa dữ liệu |
| Policy server | serve_policy.py policy:checkpoint |
MLOps / robotics engineer | Lộ endpoint, sai checkpoint, thiếu audit log |
| Robot action | deploy.py và controller |
Robot runtime owner, safety engineer | Action unsafe, latency, observation spoofing |
| Rollout telemetry | Sau triển khai | Product team, user, robot operator | Dữ liệu khách hàng, incident evidence, retraining rights |
Bảng này là bản đồ cuối của series. Nếu bạn có thể điền owner và risk cho từng dòng, bạn đã đi từ "AI data ownership" trừu tượng sang governance vận hành được.
Bước 1: Convert sang LeRobot
EgoHumanoid dùng convert_to_lerobot.py để chuyển processed HDF5 datasets sang LeRobot format. Tham số --fps 20 nói rằng dữ liệu được đóng gói với nhịp 20 frame mỗi giây. Tham số --task lưu mô tả task dạng ngôn ngữ, ví dụ "pick up the object" hoặc "open the drawer and place the item inside". Với VLA, prompt không phải metadata trang trí; nó là một phần input của policy.
cd data_alignment
python convert_to_lerobot.py \
--src-path /datasets/g1_kitchen_processed \
--output-path /datasets/g1_kitchen_lerobot \
--repo-id vnrobo/g1-kitchen-v1 \
--fps 20 \
--task "pick up the cup and place it on the tray"
Nếu dùng multi-thread, README EgoHumanoid cũng đưa ví dụ thêm --num-workers 16:
python convert_to_lerobot.py \
--src-path /datasets/g1_kitchen_processed \
--output-path /datasets/g1_kitchen_lerobot \
--repo-id vnrobo/g1-kitchen-v1 \
--num-workers 16 \
--fps 20 \
--task "pick up the cup and place it on the tray"
Ở bước ownership, câu hỏi không chỉ là "file output thuộc về ai?". Hãy hỏi:
| Câu hỏi | Vì sao quan trọng |
|---|---|
| Raw data có đến từ human egocentric demo, robot teleop hay simulation? | Quyền và consent khác nhau |
--task do ai viết? |
Prompt có thể encode rule, nhãn và intent của task |
| FPS có thay đổi action semantics không? | Resampling sai có thể làm policy học sai timing |
| Dataset có chứa camera ngoài và wrist camera không? | Camera view có thể lộ môi trường hoặc tài sản khách hàng |
| Dataset có được phép upload lên Hub không? | LeRobot tiện cho chia sẻ, nhưng chia sẻ không đồng nghĩa có quyền công khai |
LeRobot giúp chuẩn hóa dataset robotics để training dễ hơn, nhưng chuẩn hóa không tự động giải quyết quyền dữ liệu. Một dataset đã đẹp, load được bằng tooling phổ biến và có prompt rõ ràng vẫn cần dataset card: nguồn, robot, camera, action space, consent, license, allowed use, retention và cách xóa khỏi future training.
Bước 2: Tính normalization statistics
Sau khi dataset ở đúng format, EgoHumanoid yêu cầu tính normalization statistics:
uv run python scripts/compute_norm_states_ultra_fast.py --config-name=norm_compute
Với beginner, normalization nghĩa là đưa state và action về scale mà model train ổn định hơn. Nếu joint position có range lớn, gripper có range nhỏ, action velocity có phân phối khác, model sẽ học khó nếu mọi thứ đi vào loss ở scale thô. Norm stats thường gồm mean, std hoặc quantile tùy pipeline.
Nhưng norm stats cũng là dữ liệu phái sinh. Nó không chứa frame ảnh hay trajectory đầy đủ, nhưng nó tiết lộ distribution của dataset. Nếu bạn tính norm stats trên dữ liệu khách hàng A, rồi dùng lại cho khách hàng B, có thể tạo hai vấn đề. Một là kỹ thuật: distribution không khớp làm model yếu. Hai là governance: artifact của khách hàng A đã đi vào pipeline của khách hàng B.
Checklist thực dụng:
norm_stats_review:
computed_from:
- train_split_only
excludes:
- heldout_test_episodes
- private_customer_eval_rollouts
stores:
- state_mean
- state_std
- action_mean
- action_std
owner: training_platform_team
reusable_across_customers: false
Nếu bạn train nội bộ cho một robot lab nhỏ, điều này có vẻ quá chặt. Nhưng khi bán humanoid SaaS hoặc policy-as-a-service, norm stats là một artifact cần version. Khi checkpoint fail, câu hỏi đầu tiên thường là: dataset version nào, norm stats version nào, config nào, checkpoint iteration nào?
Bước 3: Train pi0.5 và lưu checkpoint
EgoHumanoid đưa ví dụ train custom dataset bằng config pi05_g1_custom, và multi-GPU training với FSDP:
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 uv run scripts/train.py pi05_g1_custom \
--exp_name=g1_kitchen_v1 \
--fsdp-devices 4
pi05_g1_custom là tên config. --exp_name là tên experiment. --fsdp-devices 4 cho biết training dùng 4 thiết bị theo kiểu FSDP. README EgoHumanoid nói checkpoint được lưu ở:
checkpoints/<config_name>/<exp_name>/
Ví dụ:
checkpoints/pi05_g1_custom/g1_kitchen_v1/
1000/
2000/
5000/
10000/
Checkpoint là artifact nhạy cảm nhất trong stack. Nó không phải dataset theo nghĩa file Parquet/video, nhưng nó hấp thụ thông tin từ dataset. Nếu dataset có video người không đủ consent, checkpoint có thể mang rủi ro. Nếu dataset có task prompt chứa thông tin khách hàng, checkpoint có thể học pattern từ prompt. Nếu training mixture trộn robot data, human data và simulation data, checkpoint là nơi mọi quyền bị nén lại.
Một manifest tối thiểu cho checkpoint nên có:
checkpoint: checkpoints/pi05_g1_custom/g1_kitchen_v1/10000
base_model: pi0.5
config_name: pi05_g1_custom
experiment_name: g1_kitchen_v1
training_data:
- repo_id: vnrobo/g1-kitchen-v1
split: train
allowed_use: internal_policy_training
norm_stats: assets/norm_compute/g1_kitchen_v1
contains_human_video_derivatives: true
contains_customer_environment: false
serving_allowed:
- lab_robot
- staging_demo
serving_blocked:
- public_api
- third_party_resale
Đây không phải thủ tục giấy tờ vô nghĩa. Nó giúp team trả lời nhanh khi cần rollback: checkpoint nào đang chạy, train từ dataset nào, có quyền deploy ở môi trường nào, và có được dùng để retrain model tiếp theo không.
Bước 4: Serve policy trên GPU host
Trong triển khai VLA, robot thường không chạy model lớn trực tiếp trên máy điều khiển. OpenPI và EgoHumanoid dùng policy server: máy GPU giữ checkpoint, robot hoặc evaluation script gửi observation qua mạng, server trả action. Lệnh trong EgoHumanoid là:
uv run scripts/serve_policy.py policy:checkpoint \
--policy.config=pi05_g1_custom \
--policy.dir=checkpoints/pi05_g1_custom/g1_kitchen_v1/10000
README ghi server mặc định lắng nghe port 8000. Tài liệu remote inference của OpenPI cũng mô tả mô hình policy server cho robot code query qua mạng. Về kỹ thuật, đây là cách thực tế: GPU host xử lý inference, robot-side client giữ control loop nhẹ hơn.
Về ownership, policy server là ranh giới giữa model artifact và product runtime. Khi server chạy, các observation thật bắt đầu đi qua network:
observation = {
"observation/exterior_image_1_left": camera_left_image,
"observation/wrist_image_left": wrist_image,
"observation/state": joint_positions,
"prompt": "pick up the object",
}
action_chunk = policy.infer(observation)["actions"]
Các key này xuất hiện trong ví dụ inference của EgoHumanoid. OpenPI config cũng cho thấy cách repack dữ liệu DROID/LeRobot sang các key như observation/exterior_image_1_left, observation/wrist_image_left, observation/joint_position, observation/gripper_position, actions và prompt. User yêu cầu bài này nhấn vào observation/state; trong EgoHumanoid G1 inference, state được minh họa như joint_positions. Điểm cần nhớ là state/proprioception không chỉ là số vô hại. Nó mô tả tư thế robot, và nếu gắn với video/timestamp, nó có thể tái dựng hành vi vận hành.
Bước 5: Deploy robot-side client
Robot-side command trong EgoHumanoid:
python scripts/deploy.py --host <server_ip> --port 8000
README mô tả client kết nối tới OpenPI policy server qua websocket để inference action và điều khiển Unitree G1 qua GR00T WBC framework. Các phím runtime như activate policy, preparation phase, start/pause inference loop, silent mode và emergency stop cho thấy deployment không chỉ là model serving. Nó là một vòng điều khiển người-máy có trạng thái.
Trong production, bạn nên tách rõ ba lớp log:
| Log | Nội dung | Ai cần xem? | Retention gợi ý |
|---|---|---|---|
| Server inference log | checkpoint id, request time, latency, action shape | ML/infra team | Ngắn, có sampling |
| Robot safety log | mode, emergency stop, controller state | robotics/safety team | Dài hơn, phục vụ incident |
| Product telemetry | task success, user feedback, environment class | product/data team | Theo consent khách hàng |
Đừng lưu raw camera mặc định nếu không cần. Nếu cần lưu để debug, hãy biến nó thành lựa chọn có kiểm soát: sampling rate, redaction, retention, quyền truy cập và mục đích retraining rõ ràng. Đây là điểm khác biệt giữa demo lab và sản phẩm thương mại.
Map rủi ro từ input đến action
| Input vào policy | Vai trò kỹ thuật | Rủi ro ownership | Cách giảm rủi ro |
|---|---|---|---|
observation/exterior_image_1_left |
Camera ngoài, thấy scene và object | Lộ môi trường, người xung quanh, tài sản khách hàng | Mask vùng nhạy cảm, logging tối thiểu, consent tại site |
observation/wrist_image_left |
Camera gần gripper, thấy thao tác chi tiết | Lộ vật thể, nhãn sản phẩm, quy trình thao tác | Retention ngắn, chỉ lưu khi incident/debug |
observation/state |
Proprioception/joint state | Tái dựng hành vi robot, phát hiện lỗi vận hành | Aggregate metrics, hạn chế raw state export |
prompt |
Task instruction | Lộ intent, tên vật thể, workflow khách hàng | Prompt templates, redaction, audit prompt source |
actions |
Output policy để robot thực thi | Safety, liability, traceability | Action limits, controller guardrails, emergency stop |
Điểm quan trọng: ownership không dừng ở dataset train. Khi robot deploy, mỗi request inference có thể tạo dữ liệu mới. Nếu bạn dùng rollout telemetry để fine-tune checkpoint kế tiếp, telemetry đó quay lại đầu vòng đời và trở thành training data. Vì vậy terms of service và customer data policy phải nói rõ "runtime data có được dùng để cải thiện model không?".
Checklist triển khai cho team nhỏ
Nếu bạn là startup robotics hoặc lab mới bắt đầu với VLA, hãy dùng checklist này trước khi bật robot:
before_training:
dataset_card_exists: true
source_data_provenance_checked: true
consent_for_human_demonstrations: true
task_prompts_reviewed: true
train_eval_split_locked: true
before_checkpoint_release:
norm_stats_versioned: true
config_name_recorded: true
exp_name_recorded: true
checkpoint_path_recorded: true
eval_results_attached: true
unsafe_rollouts_reviewed: true
before_serving:
policy_dir_matches_release: true
server_port_restricted: true
request_logging_minimized: true
rollback_checkpoint_ready: true
robot_side_emergency_stop_tested: true
before_retraining_from_runtime:
customer_permission_checked: true
private_frames_filtered: true
incident_data_labeled: true
deletion_request_process_defined: true
Checklist này không thay thế legal review, nhưng giúp kỹ sư không bỏ sót các điểm kỹ thuật. Trong nhiều team, rủi ro không đến từ ác ý mà đến từ việc artifact được copy quá dễ: dataset sample lên Hub, checkpoint share qua bucket, norm stats dùng lại giữa project, hoặc server log giữ raw observation lâu hơn cần thiết.
Kết luận: sở hữu nằm trong lifecycle, không nằm trong một file
Series "Ai sở hữu dữ liệu robot hình người 2026" bắt đầu bằng bản đồ và kết thúc bằng stack. Bài học chính là: không có một câu trả lời duy nhất cho "ai sở hữu dữ liệu humanoid". Dữ liệu đổi trạng thái liên tục. Video người có thể thành LeRobot dataset. Dataset tạo norm stats. Norm stats và dataset tạo checkpoint. Checkpoint chạy trong policy server. Policy server nhận observation thật và trả action. Action tạo rollout telemetry. Telemetry có thể trở thành training data cho vòng sau.
Nếu chỉ nhìn file cuối cùng, bạn sẽ bỏ lỡ quyền của người demo, operator, robot owner, môi trường thu thập, người viết prompt, người thiết kế alignment pipeline, người train model, người deploy robot và khách hàng tạo runtime telemetry. Nếu nhìn lifecycle, bạn có thể đặt policy rõ ràng cho từng artifact.
Quy tắc cuối cùng:
- Ghi provenance ở điểm convert, không đợi tới lúc deploy.
- Version dataset, norm stats, config và checkpoint cùng nhau.
- Xem prompt là dữ liệu, không phải text phụ.
- Tách quyền train, quyền serve, quyền log và quyền retrain.
- Với humanoid chạy trong môi trường người thật, runtime telemetry phải được quản trị nghiêm như training data.
Khi bạn chạy:
python scripts/deploy.py --host <server_ip> --port 8000
bạn không chỉ gọi một model. Bạn đang nối toàn bộ lịch sử dữ liệu vào hành động vật lý của robot. Đó là lý do ownership trong robotics không thể chỉ là dòng license trong repo. Nó phải là thiết kế của toàn bộ VLA lifecycle.