wholebody-vlahumanoid-vlawholebody-vlaevaluationoperator-scaleagibot-x2lamlmogr00t-wbc

Scale 20 người và eval whole-body VLA

Cách đánh giá WholeBodyVLA, LMO 50 Hz và WBC ONNX khi mở rộng đội thu dữ liệu humanoid lên 20 operator.

Nguyễn Anh Tuấn10 tháng 6, 202615 phút đọc
Scale 20 người và eval whole-body VLA

Mục tiêu của bài này

Đến bài cuối của series, ta không còn hỏi "làm sao record một episode?" nữa. Câu hỏi thực tế là: nếu có 20 operator, một humanoid whole-body VLA, nhiều task dài hơn 30 giây, và một controller chân chạy realtime, làm sao biết hệ thống đang tốt lên hay chỉ đang tạo thêm dữ liệu nhiễu?

Trong bài 1, ta bắt đầu bằng pilot 2 người để đo throughput và lỗi cơ bản. Bài 3 chuẩn hóa raw log bằng ROS 2 và MCAP để còn replay. Bài 5 dùng synthetic data và QA để lọc demo trước khi train. Bài 6 ghép các phần đó thành một bảng đánh giá vận hành cho 20 operator.

Ta lấy WholeBodyVLA làm mô hình tham chiếu vì paper và project page mô tả đúng bài toán đang cần: humanoid AgiBot X2 thực hiện loco-manipulation trong không gian lớn, dùng Latent Action Model (LAM) để học latent action tokens từ video egocentric không có action annotation, VLM decode khoảng 10 Hz, và Loco-Manipulation-Oriented RL policy (LMO) chạy 50 Hz trên proprioception. Nguồn chính nên đọc:

Ngoài series này, hai bài nền hữu ích là Huấn luyện tracker và LMO RLBản đồ repo VLA/WBC cho humanoid. Nếu bạn đang xây dashboard nội bộ, bài này nên được đọc như một spec cho bảng metric đầu tiên.

humanoid evaluation lab
humanoid evaluation lab

Kiến trúc cần đánh giá

Một hệ whole-body VLA không giống robot arm chỉ chạy policy ảnh sang pose tay. Trong humanoid, quyết định high-level và ổn định cơ thể có tần số khác nhau. WholeBodyVLA mô tả runtime như sau: ảnh egocentric và instruction được VLM encode thành latent action tokens; action decoder phát dual-arm joint actions và locomotion commands khoảng 10 Hz; LMO RL policy nhận proprioceptive state và chạy 50 Hz để thực thi locomotion command. Paper cũng nêu deployment tách máy: VLA chạy trên workstation RTX 4090, RL policy chạy trên onboard computer, giao tiếp qua ZeroMQ over Ethernet.

Với beginner, hãy hình dung hệ thống thành ba vòng lặp:

camera + language
      |
      v
VLM / LAM action decoder (~10 Hz)
      |        \
      |         -> dual-arm joint actions
      v
locomotion command: forward, sidestep, turn, squat
      |
      v
LMO RL policy on proprioception (50 Hz)
      |
      v
whole-body robot + WBC / PD / safety layer

Điểm quan trọng: bảng đánh giá phải tách lỗi của từng vòng. Nếu task fail vì robot không hiểu instruction, đó là lỗi VLA/perception. Nếu robot hiểu đúng nhưng bước ngang lệch và mất vị trí đặt, đó là lỗi locomotion command hoặc LMO. Nếu policy chân ổn nhưng tay đẩy hộp làm robot mất thăng bằng, đó là lỗi whole-body coupling. Nếu dữ liệu bị loại vì camera lệch timestamp, đó là lỗi data pipeline, không phải lỗi model.

Trong thực tế, nhiều nhóm cũng muốn so sánh hoặc thay thế low-level stack bằng GR00T WholeBodyControl. Tài liệu GR00T WBC mô tả đây là nền tảng cho controller humanoid, có decoupled WBC dùng trong Isaac GR00T / GR00T N1.x và hỗ trợ workflow teleop, VLA data collection, inference. Với Unitree G1, repo có các ONNX policy đáng chú ý:

GR00T-WholeBodyControl-Balance.onnx
GR00T-WholeBodyControl-Walk.onnx

Hai file này không làm AgiBot X2 tự nhiên biến thành G1, và cũng không thay thế trực tiếp LMO của WholeBodyVLA nếu morphology khác. Nhưng chúng cho ta một pattern deploy rõ: low-level controller phải được export thành artifact ổn định, load được trong runtime, đo latency được, và có mode balance/walk tách bạch để kiểm thử an toàn.

Vì sao scale 20 operator phải có eval trước?

Khi chỉ có 2 operator, bạn có thể xem từng episode bằng mắt. Khi lên 20 operator, dữ liệu xấu sẽ tăng theo cấp số vận hành: người mới điều khiển quá nhanh, prompt đặt không thống nhất, scene reset lệch, robot bị fatigue nhiệt, camera bị lệch mount, và một số người có tỷ lệ discard cao nhưng không ai phát hiện trong ngày.

Mục tiêu của eval không phải xếp hạng con người. Mục tiêu là giữ cho hệ thống học từ dữ liệu tốt hơn qua từng tuần. Vì vậy dashboard nên trả lời sáu câu:

Câu hỏi Metric chính Ai dùng metric
Robot hoàn thành task không? Task success Research lead, model owner
Robot có ngã hoặc mất ổn định không? Balance failures Safety owner, WBC owner
Operator phải can thiệp nhiều không? Intervention rate Ops lead, trainer
Vòng điều khiển có trễ không? Latency Infra, realtime owner
Episode có đủ sạch để train không? Data acceptance Data QA, training owner
Lỗi nằm ở task nào? Benchmark breakdown Product, research, ops

Nếu thiếu một trong sáu metric này, bạn rất dễ scale sai. Ví dụ task success tăng nhưng intervention rate cũng tăng, nghĩa là operator đang cứu robot nhiều hơn chứ model chưa chắc tốt hơn. Hoặc data acceptance cao nhưng latency jitter tăng, dataset có thể vẫn save được nhưng policy train ra sẽ học hành vi lệch thời gian.

Bảng KPI cho 20 operator

Bảng dưới đây là baseline tốt cho tuần đầu khi mở rộng từ pilot lên 20 operator. Mỗi operator làm 3 task: bag packing, box loading, cart pushing. Mỗi task có 10 trial/người/ngày ở phase eval, sau đó mới tăng số lượng thu dữ liệu training.

Metric Định nghĩa Công thức gợi ý Ngưỡng tuần 1
Task success Task đạt tiêu chí cuối cùng mà không vi phạm safety success_trials / total_trials Theo task, không gộp mù
Subgoal success Từng bước như grasp, sidestep, squat, place subgoal_pass / total_trials Ít nhất log 2 subgoal/task
Balance failure Fall, emergency stop vì nghiêng, CoM/IMU vượt ngưỡng balance_fail_trials / total_trials Càng gần 0 càng tốt
Intervention rate Operator bấm pause, reset, manual override, hoặc safety captain cứu scene interventions / minute hoặc trials_with_intervention / trials Giảm theo từng tuần
Command latency Từ frame camera/state đến action command được robot nhận p50, p95, p99 Theo từng loop 10 Hz và 50 Hz
Loop miss rate VLA hoặc LMO miss deadline missed_ticks / expected_ticks LMO nghiêm hơn VLA
Data acceptance Episode được QA cho vào training set accepted_episodes / recorded_episodes Không nên chỉ tối đa hóa
Discard reason Lý do loại episode taxonomy cố định Bắt buộc có
Operator throughput Episode accepted/giờ accepted / active_hours So với median nhóm
Recovery time Thời gian từ fail đến trial tiếp theo median, p90 Dùng để tối ưu ops

Một schema CSV tối thiểu:

date,operator_id,robot_id,task,trial_id,success,subgoal_1,subgoal_2,balance_failure,interventions,accepted,discard_reason,vla_p95_ms,lmo_p95_ms,total_seconds
2026-06-10,op_03,x2_01,bag_packing,trial_004,true,true,true,false,0,true,,118,8,42.6
2026-06-10,op_03,x2_01,box_loading,trial_005,false,true,false,false,1,false,place_miss_after_turn,126,9,51.2
2026-06-10,op_11,x2_01,cart_pushing,trial_002,false,true,false,true,2,false,balance_push_load,135,11,28.4

Đừng bắt đầu bằng dashboard phức tạp. Bắt đầu bằng một bảng sự kiện sạch. Nếu mỗi row có task, operator, trial, success, failure mode và latency, bạn đã có đủ dữ liệu để quyết định tuần sau cần train operator, sửa controller hay thu thêm dataset.

Định nghĩa success cho ba benchmark

WholeBodyVLA dùng ba task chính: Bag Packing, Box Loading và Cart Pushing. Project page mô tả chuỗi hành động gồm bimanual grasping, side-step, squat, grasp/lift box, turn to cart, grasp cart handle, push forward, và đẩy tải hơn 50 kg. Appendix paper mô tả thêm các biến thể object/load: thay bag bằng bag khác, thay đồ trong box bằng plastic containers, và thay carton trên cart bằng 60 kg barbell plates.

Ta không cần copy nguyên benchmark để bắt đầu, nhưng cần giữ tinh thần: mỗi task phải buộc robot phối hợp chân, tay, thân và thăng bằng.

Task Subgoal 1 Subgoal 2 Success cuối Failure mode nên log
Bag Packing Grasp bag bằng hai tay hoặc tay chính theo setup Sidestep/squat tới carton Bag nằm trong carton, robot vẫn ổn định miss grasp, bag drop, squat drift, place outside
Box Loading Squat và grasp box Rise, turn toward cart Box đặt lên cart đúng vùng box tilt, turn overshoot, hand slip, torso lean
Cart Pushing Grasp handle Push ahead theo đường Cart đi đủ khoảng cách, robot không drift/lệch mạnh handle miss, lateral drift, foot slip, balance fail

Với beginner, hãy luôn tách task_successsubgoal_success. Một trial box loading có thể fail ở bước place nhưng vẫn chứng minh squat + grasp đã tiến bộ. Nếu chỉ lưu success cuối cùng, model owner không biết nên sửa perception, action decoder hay LMO.

Một cấu hình benchmark YAML dễ đọc:

benchmark:
  name: humanoid_wholebody_vla_eval_v1
  robot: agibot_x2
  trials_per_operator_per_task: 10
  operators: 20
  tasks:
    bag_packing:
      subgoals: [grasp_bag, move_and_squat, place_in_carton]
      success:
        object_in_target: true
        no_balance_failure: true
        max_interventions: 0
    box_loading:
      subgoals: [squat_and_grasp, rise_and_turn, place_on_cart]
      success:
        box_on_cart: true
        no_balance_failure: true
        max_interventions: 0
    cart_pushing:
      subgoals: [grab_handle, push_ahead]
      success:
        cart_distance_m: 2.0
        lateral_drift_m_max: 0.35
        no_balance_failure: true

Latency: đo riêng 10 Hz và 50 Hz

WholeBodyVLA cho ta một bài học quan trọng: VLA và LMO không chạy cùng tần số. VLA khoảng 10 Hz có thể chấp nhận inference chậm hơn vì nó làm perception/reasoning và phát command mức cao. LMO 50 Hz thì không được jitter nhiều, vì nó giữ locomotion và balance trên proprioception.

Vì vậy bảng latency nên có hai lớp:

Lớp Tần số Đo gì Vì sao
VLA decode Khoảng 10 Hz camera timestamp -> latent/action decoded -> command sent Trễ cao làm instruction/action bị lỗi thời
LMO/WBC loop 50 Hz proprio read -> policy inference -> action applied Jitter cao làm gait và balance xấu
Network bridge Tùy stack command sent -> command received ZeroMQ/ROS 2/Ethernet có thể tạo spike
Data recorder Tùy camera frame saved -> metadata indexed Recorder chậm làm data lệch dù robot vẫn chạy

Instrumentation tối thiểu:

from time import monotonic_ns

def now_ms():
    return monotonic_ns() / 1_000_000

event = {
    "trial_id": trial_id,
    "camera_frame_ts_ms": frame.ts_ms,
    "vla_decode_start_ms": now_ms(),
}

latent_action = vla.decode(frame, instruction)
event["vla_decode_end_ms"] = now_ms()

command = action_decoder.to_robot_command(latent_action)
event["command_sent_ms"] = now_ms()
command_bus.send(command)

# On the low-level side:
low_event = {
    "command_received_ms": now_ms(),
    "proprio_ts_ms": proprio.ts_ms,
    "lmo_start_ms": now_ms(),
}
action = lmo_policy(proprio, command)
low_event["lmo_end_ms"] = now_ms()
robot.apply(action)
low_event["action_applied_ms"] = now_ms()

Sau đó tính p50/p95/p99 theo task và theo operator. Nếu p95 VLA tăng ở cart pushing, có thể camera scene phức tạp hơn hoặc model decode dài hơn do prompt. Nếu p95 LMO tăng, ưu tiên debug onboard compute, thread scheduling, memory allocation, logging hoặc network receive. Đừng trộn hai lớp latency vào một số trung bình.

Balance failures và intervention rate

Balance failure phải được định nghĩa chặt. Nếu mỗi người hiểu "suýt ngã" khác nhau, dashboard sẽ vô nghĩa. Hãy bắt đầu với bốn nhãn:

Nhãn Điều kiện
fall Robot chạm đất hoặc cần reset vật lý
estop_balance Emergency stop vì nghiêng, trượt chân hoặc mất kiểm soát
operator_catch Người can thiệp để robot không va/ngã
controller_abort Safety layer tự dừng do state vượt ngưỡng

Intervention cũng cần taxonomy:

intervention_types:
  pause: operator pauses policy but keeps trial alive
  manual_override: operator takes over motion
  scene_fix: human fixes object/scene during trial
  safety_stop: emergency stop or safety abort
  prompt_correction: instruction changed after trial start

Trong báo cáo training, trial có intervention thường không nên tính là success sạch. Có thể lưu hai cột:

Cột Ý nghĩa
task_success_raw Object/task cuối cùng đạt yêu cầu, kể cả có can thiệp
task_success_clean Đạt yêu cầu mà không có intervention bị cấm

Khi mở rộng 20 operator, task_success_clean mới là metric để so sánh model. task_success_raw hữu ích cho ops vì nó cho biết operator có cứu được task không, nhưng nếu dùng để chọn checkpoint thì dễ tự lừa.

Data acceptance: episode nào được train?

Data acceptance không đồng nghĩa với task success. Một episode fail vẫn có thể hữu ích nếu nó ghi rõ failure và dùng cho negative analysis. Nhưng dataset behavior cloning/VLA chính nên ưu tiên episode thành công, timestamp sạch, prompt đúng, không có intervention, và không có sensor drop.

Checklist acceptance:

Kiểm tra Accept nếu Reject nếu
Prompt Khớp task và object Prompt đổi giữa trial hoặc quá mơ hồ
Camera Đủ frame, không mất exposure nặng Drop dài, blur mạnh ở giai đoạn quyết định
State/action Shape đúng, timestamp tăng đều NaN, joint order sai, action spike không giải thích được
Latency Nằm trong budget p99 vượt budget ở đoạn quan trọng
Safety Không fall/estop Fall hoặc human catch
Outcome Success hoặc failure có nhãn rõ Không biết vì sao fail

Một rule engine đơn giản:

def accept_episode(ep):
    if ep.prompt_changed:
        return False, "prompt_changed"
    if ep.camera_drop_ms_max > 250:
        return False, "camera_drop"
    if ep.state_has_nan or ep.action_has_nan:
        return False, "bad_state_action"
    if ep.balance_failure:
        return False, "balance_failure"
    if ep.interventions > 0:
        return False, "intervention"
    if ep.vla_latency_p99_ms > 250:
        return False, "vla_latency"
    if ep.lmo_latency_p99_ms > 20:
        return False, "lmo_latency"
    if not ep.task_success:
        return False, "task_fail"
    return True, ""

Các ngưỡng trên chỉ là điểm bắt đầu. Với stack thật, hãy lấy distribution từ pilot và đặt budget theo hardware. Điều quan trọng là mọi reject phải có reason cố định, để cuối tuần bạn biết 38% reject đến từ operator training, camera, model hay controller.

Lịch vận hành cho 20 operator

Đừng cho 20 người thu production data ngay ngày đầu. Chia thành ba vòng:

Vòng Số người Mục tiêu Gate để qua vòng
Calibration 4 So sánh operator mới với 2 người pilot Prompt đúng, intervention taxonomy đúng
Eval batch 20 Mỗi người chạy cùng benchmark nhỏ Có bảng success/balance/latency/data acceptance
Production 20 Thu data theo task ưu tiên Chỉ mở task/operator đạt gate

Gate gợi ý:

operator_gate:
  min_trials: 30
  prompt_error_rate_max: 0.02
  unsafe_intervention_rate_max: 0.05
  accepted_episode_rate_min: 0.70
  median_reset_seconds_max: 90

robot_gate:
  balance_failure_rate_max: 0.02
  lmo_loop_miss_rate_max: 0.01
  no_unexplained_estop: true

model_gate:
  clean_success_rate_min_by_task:
    bag_packing: 0.60
    box_loading: 0.45
    cart_pushing: 0.50

Các con số này không phải benchmark học thuật. Chúng là guardrail vận hành. Nếu tuần đầu chưa đạt, đừng cố thu nhiều hơn. Hãy sửa failure mode lớn nhất trước. Scale dữ liệu xấu chỉ làm chi phí train, QA và debug tăng.

Dashboard tuần đầu nên trông như thế nào?

Một dashboard tốt không cần đẹp, nhưng phải ra quyết định được. Tôi thường dùng bốn bảng:

Bảng Cột bắt buộc Quyết định hỗ trợ
Operator scorecard operator, trials, clean success, interventions, accepted rate, median reset Ai cần train lại, ai được mở production
Task scorecard task, subgoal success, balance fail, latency p95, top discard reason Task nào đang nghẽn
Latency health VLA p50/p95/p99, LMO p50/p95/p99, loop miss Có cần sửa infra/realtime không
Data QA accepted, rejected, reject reason, camera drop, prompt error Dataset có đáng train không

SQL mẫu cho operator scorecard:

select
  operator_id,
  count(*) as trials,
  avg(case when task_success_clean then 1 else 0 end) as clean_success_rate,
  avg(interventions) as interventions_per_trial,
  avg(case when accepted then 1 else 0 end) as accepted_rate,
  percentile_cont(0.5) within group (order by reset_seconds) as median_reset_seconds
from eval_trials
where date = '2026-06-10'
group by operator_id
order by accepted_rate desc;

SQL mẫu cho failure reasons:

select
  task,
  discard_reason,
  count(*) as n
from eval_trials
where accepted = false
group by task, discard_reason
order by n desc;

Nếu cart_pushing có nhiều balance_push_load, WBC/LMO và force interaction cần được ưu tiên. Nếu bag_packing có nhiều place_outside, hãy xem perception, calibration tay, hoặc action decoder. Nếu mọi task đều có camera_drop, đừng fine-tune model; sửa recorder trước.

Kết luận

Bài cuối của series đưa ta từ "thu được data" sang "biết data và robot có tốt không". WholeBodyVLA cho một blueprint kỹ thuật rõ: LAM học latent action tokens, VLA decode khoảng 10 Hz, LMO chạy 50 Hz, và benchmark phải ép robot phối hợp đi, xoay, squat, grasp, place và push. GR00T WBC cho một blueprint deploy khác: controller thấp tầng cần artifact rõ ràng như ONNX balance/walk policy, runtime đo được và test được.

Khi mở rộng lên 20 operator, đừng chỉ đếm số episode. Hãy đếm task success sạch, balance failures, intervention rate, latency, data acceptance và breakdown theo bag packing/box loading/cart pushing. Nếu sáu metric này ổn định, bạn có thể tăng ca thu dữ liệu với ít rủi ro hơn. Nếu chúng mâu thuẫn, hãy tin bảng lỗi hơn là cảm giác "robot có vẻ chạy được".

Bài viết liên quan

NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Bài viết liên quan

Pilot 2 người cho dữ liệu humanoid VLA
wholebody-vla

Pilot 2 người cho dữ liệu humanoid VLA

10/6/202615 phút đọc
NT
Chọn teleoperation stack cho humanoid
wholebody-vla

Chọn teleoperation stack cho humanoid

10/6/202616 phút đọc
NT
Đánh giá VLA toàn thân
wholebody-vla

Đánh giá VLA toàn thân

10/6/202615 phút đọc
NT