Vấn đề: action chunk rất nhanh, nhưng có blind spot
Các VLA policy hiện đại thường không điều khiển robot theo kiểu "mỗi control step gọi model một lần". Cách đó quá đắt, đặc biệt khi backbone là mô hình generative lớn như PI0.5, SmolVLA hoặc X-VLA. Thay vào đó, policy nhận ảnh, instruction và trạng thái hiện tại, rồi sinh ra một action chunk: một chuỗi nhiều action tương lai. Controller lấy một đoạn đầu của chunk đó để thực thi trong vài bước trước khi gọi policy lại. Đoạn thực thi này được gọi là action horizon.
Ý tưởng nghe rất hợp lý: nếu mỗi lần inference sinh được 50 action, robot giảm số lần gọi VLA, trajectory mượt hơn và latency của model không chặn control loop quá nhiều. Nhưng paper VLA-Corrector: Lightweight Detect-and-Correct Inference for Adaptive Action Horizon của Zhejiang University và Alibaba DAMO Academy chỉ ra một lỗi triển khai rất thực tế: trong thời gian robot đang chạy chunk, camera vẫn gửi observation mới, nhưng policy không dùng observation đó cho tới lần replan tiếp theo. Paper gọi khoảng mù này là open-loop blind spot.
Trong manipulation, blind spot này nguy hiểm hơn trong navigation đơn giản. Một cái drawer lệch vài milimet, block trượt khỏi gripper, target bowl bị đẩy nhẹ, hoặc end-effector chạm cạnh hộp hơi sớm đều có thể làm các action còn lại trong queue trở thành stale actions. Nếu controller vẫn "mù quáng" chạy hết queue, lỗi nhỏ biến thành lỗi lớn: robot kẹt, miss grasp, đẩy vật ra ngoài workspace, hoặc vào một state mà policy chưa từng thấy trong training.
VLA-Corrector không cố thay thế action chunking. Ngược lại, nó giữ lợi ích của chunking trong giai đoạn ổn định, nhưng thêm một lớp detect-and-correct ở inference time để cắt ngắn horizon khi chunk không còn đáng tin.
Nguồn chính của bài này là paper arXiv 2607.01804, project page và GitHub repo ZJU-OmniAI/vla-corrector. Repo cho biết implementation dựa trên LeRobot, có modified VLA evaluation entry points và module training cho latent dynamics corrector; dataset, raw demonstration, pretrained checkpoint và trained corrector checkpoint không được đóng gói sẵn.
Ý tưởng cốt lõi: đừng chọn horizon cố định, hãy quyết định khi nào nên dừng chunk
Một cách đơn giản để tăng reactivity là đặt H = 1: mỗi control step gọi VLA lại. Nhưng đây không phải lựa chọn thực tế cho VLA lớn. Inference quá chậm, chi phí GPU tăng, và robot có thể bị trajectory không mượt do policy liên tục sinh chunk mới. Một cách khác là dùng horizon dài như H = 50: ít policy calls hơn, chạy mượt hơn, nhưng robot phản ứng chậm với drift.
Paper đặt lại câu hỏi: thay vì hỏi "horizon cố định nào tốt nhất?", hãy hỏi "chunk hiện tại còn đáng tin không?". Nếu chunk vẫn đi đúng hướng, cứ tiếp tục chạy để tận dụng efficiency. Nếu visual dynamics bắt đầu lệch khỏi dự đoán, dừng sớm, bỏ phần action còn lại và replan theo chế độ corrective.
VLA-Corrector làm điều đó bằng bốn thành phần:
| Thành phần | Vai trò |
|---|---|
| Frozen VLA backbone | Sinh action chunk như bình thường, không cần retrain |
| External latent dynamics corrector | Dự đoán visual latent sẽ thay đổi thế nào nếu action hiện tại đi đúng |
| Latent-space Vision Monitor (LVM) | So sánh latent dự đoán với latent quan sát thật từ camera |
| Online Gradient Guidance (OGG) | Khi có interrupt, hướng lần replan kế tiếp về trajectory có khả năng recovery cao hơn |
Điểm quan trọng cho người mới: VLA-Corrector không phải một policy thứ hai điều khiển robot độc lập. Nó giống một lớp kiểm tra runtime đặt cạnh policy. VLA vẫn là bộ sinh action chính. Corrector chỉ học tín hiệu "visual evolution có còn hợp lý không" và can thiệp khi chunk đang chạy lệch.

Kiến trúc chi tiết
Pipeline chuẩn của action-chunked VLA có thể viết đơn giản như sau:
camera + state + language instruction
|
v
VLA policy sinh action chunk [a_t, a_{t+1}, ..., a_{t+C-1}]
|
v
controller thực thi H action đầu tiên
|
v
gọi VLA lại khi queue hết
Vấn đề nằm ở bước controller. Trong H bước đó, observation mới xuất hiện liên tục nhưng không được dùng để kiểm tra chunk còn hợp lệ hay không. VLA-Corrector sửa bằng cách tách action generation và execution monitoring:
VLA policy sinh action chunk
|
+--> action queue cho controller
|
+--> LVM theo dõi latent visual dynamics trong lúc queue chạy
|
+-- ổn định: tiếp tục chunk
|
+-- drift kéo dài: interrupt, bỏ stale actions, OGG-guided replan
External latent dynamics corrector
Sau khi có VLA policy đã fine-tune, paper freeze backbone đó. Visual encoder của VLA được dùng để trích latent từ demonstration trajectories. Với một transition, corrector học dự đoán latent residual ngắn hạn: nếu robot đang ở latent visual state hiện tại và thực thi action này, latent ở vài bước sau nên thay đổi theo hướng nào?
Điều này khác với world model đầy đủ. World model cố dự đoán cả tương lai phong phú của scene. VLA-Corrector chỉ cần một bài toán hẹp hơn: local visual dynamics có đang giống các trajectory thành công hay không. Vì bài toán hẹp, repo dùng corrector kiểu MLP. Paper báo cáo residual MLP khoảng 38-42M parameters, thường được gọi gọn là corrector khoảng 40M. So với VLA backbone, đây là lớp nhẹ.
LVM: Latent-space Vision Monitor
LVM chạy trong lúc action queue đang được thực thi. Nó nhận latent thật từ observation mới, latent dự đoán từ corrector, rồi tạo một inconsistency score. Nếu score chỉ spike một bước, hệ thống chưa interrupt ngay. Paper dùng sliding window, median absolute deviation và hysteresis threshold để tránh việc robot liên tục bật tắt trạng thái bất thường chỉ vì noise camera hoặc jitter nhỏ.
Thông số runtime được paper mô tả như sau: monitor giữ cửa sổ recent scores kích thước 15, cần deviation vượt activation threshold trong nhiều bước liên tiếp mới trigger, cần 5 safe steps để reset, và dùng cooldown 10 steps sau intervention để tránh trigger dồn dập. Vì vậy, đây không phải kiểu "thấy pixel khác là dừng", mà là phát hiện drift có tính bền vững.
Event-triggered truncation
Khi LVM xác nhận drift kéo dài, VLA-Corrector tạo interrupt event. Controller bỏ phần action chưa chạy trong queue hiện tại. Horizon cố định ban đầu, ví dụ H = 50, trở thành horizon thực tế ngắn hơn, ví dụ robot mới chạy 17 bước thì dừng. Đây là lý do paper gọi phương pháp là event-triggered adaptive action horizon.
Truncation là thành phần rất mạnh vì nó cắt lỗi trước khi robot đi quá xa. Nếu gripper đã miss block nhưng vẫn chạy tiếp 30 action còn lại, replan sau đó có thể quá muộn. Nếu bỏ queue ngay khi visual dynamics lệch, policy còn cơ hội quay lại trạng thái recoverable.
OGG: Online Gradient Guidance
Sau interrupt, gọi VLA lại theo cách naive chưa chắc đủ. Observation hiện tại có thể đã hơi lệch khỏi distribution của demo; policy có thể sinh action chunk mới nhưng vẫn chưa biết cách hồi phục. Online Gradient Guidance dùng discrepancy giữa expected và observed latent evolution để thêm hướng dẫn gradient trong lần generation kế tiếp. Trong paper, OGG chỉ áp dụng cho một policy query ngay sau interrupt, sau đó hệ thống quay lại inference bình thường cho tới khi LVM phát hiện drift mới.
Cách hiểu thực dụng: truncation trả quyền quyết định về model sớm hơn, còn OGG làm lần replan ngay sau đó "có mục tiêu recovery" hơn. Ablation của paper cho thấy truncation alone đã cải thiện lớn, nhưng truncation + OGG mới đạt kết quả tốt nhất.
Cài đặt repo với LeRobot
Repo chính thức mô tả cài đặt bằng Conda:
conda env create -f environment.yml
conda activate lerobot
python -m pip install -e . --no-build-isolation
Nếu chỉ muốn smoke test PushT simulation:
python -m pip install -e '.[pusht]' --no-build-isolation
Hoặc dùng requirements trực tiếp:
python -m pip install -r requirements.txt
Tên environment mặc định trong environment.yml là lerobot. Nếu máy của bạn đã có LeRobot environment khác, nên đổi name: trước khi tạo env để tránh nhầm package. Repo này là một codebase dựa trên LeRobot, nên không nên chạy các script từ một virtualenv rời rạc thiếu policy wrapper và modified VLA module.
Bạn cần tự chuẩn bị các path sau:
<DATASET_DIR> # LeRobot, MetaWorld hoặc LIBERO dataset
<EXTRACTED_CACHE_DIR> # latent cache sau bước extraction
<POLICY_CHECKPOINT> # PI0.5, SmolVLA hoặc X-VLA checkpoint
<CORRECTOR_CHECKPOINT> # checkpoint của latent dynamics corrector
<OUTPUT_DIR> # thư mục output, thường nằm ngoài source tracked
Repo nhắc rõ rằng dataset, raw demos, extracted cache, pretrained weights, fine-tuned VLA checkpoints, trained corrector checkpoints, logs và caches không nằm trong repository. Đây là điểm quan trọng khi beginner thử lại: nếu chỉ clone repo rồi chạy evaluation command, bạn sẽ thiếu model và dataset.
Training: từ demo sang latent dynamics corrector
Workflow training gồm hai tầng. Tầng một là VLA policy, ví dụ PI0.5 hoặc SmolVLA, đã được fine-tune cho benchmark hoặc robot task. Tầng hai là external corrector. VLA-Corrector không retrain full backbone trong bước corrector training.
Bước đầu tiên là trích latent:
python -m siglip_dynamics.extract \
--dataset-path <DATASET_DIR> \
--dataset-repo-id <DATASET_REPO_ID> \
--dataset-loader parquet \
--dataset-format <metaworld_or_libero> \
--output-path <EXTRACTED_CACHE_DIR> \
--encoder-backend <pi05_or_smolvla_or_xvla> \
--use-normalized-delta-action \
--encoder-policy-path <POLICY_CHECKPOINT> \
--encoder-local-files-only
Các tham số cần chú ý:
| Tham số | Ý nghĩa |
|---|---|
--dataset-format |
Chọn format benchmark, hiện repo document metaworld hoặc libero |
--encoder-backend |
Chọn visual backend: pi05, smolvla hoặc xvla |
--use-normalized-delta-action |
Dùng action delta đã normalize để latent dynamics dễ học hơn |
--encoder-policy-path |
Trỏ tới checkpoint VLA đã có |
--encoder-local-files-only |
Hữu ích khi weights đã tải sẵn, tránh pull lại từ mạng |
Cache sau extraction thường có:
metadata.json
z_q.npy
z_scale.npy
actions.npy
episode_index.npy
Đừng commit các file này. Chúng có thể rất lớn và phụ thuộc experiment.
Sau khi có latent cache, train MLP corrector:
torchrun --nproc_per_node=1 -m siglip_dynamics.train \
--model-type mlp \
--h-window 1 \
--k-step-list 10 \
--dataset-path <EXTRACTED_CACHE_DIR> \
--batch-size 512 \
--epochs 30 \
--train-loss-type cosine \
--checkpoint-dir <CORRECTOR_CHECKPOINT>
h-window 1 nghĩa là MLP nhìn local context ngắn. k-step-list 10 nghĩa là học dự đoán residual ở khoảng tương lai ngắn, phù hợp với mục tiêu monitor drift chứ không phải lập kế hoạch dài hạn. train-loss-type cosine nhấn vào directional alignment của latent residual. Paper cũng nhắc loss có thể cân bằng residual accuracy và directional alignment; trong thực tế, hướng latent thay đổi đúng thường quan trọng hơn absolute scale hoàn hảo.
Repo còn có siglip_dynamics.train_split_sweep để kiểm tra corrector cần bao nhiêu data. Logic là split episode-level, giữ validation/test cố định, train từ đầu với các train_ratio khác nhau, rồi so sánh cosine similarity và MSE. Điều này hữu ích nếu bạn có demo ít: hãy train sweep trước để xem corrector đã đủ ổn chưa, thay vì đổ thêm hàng trăm episode một cách mù mờ.
Inference và evaluation
Entry point evaluation chính trong repo:
python -m lerobot.scripts.lerobot_eval_modified_detection --help
Một command PI0.5-style cho MetaWorld:
export MUJOCO_GL=egl
export PYOPENGL_PLATFORM=egl
export EGL_PLATFORM=surfaceless
python -m lerobot.scripts.lerobot_eval_modified_detection \
--policy.path=<POLICY_CHECKPOINT> \
--policy.device=cuda \
--policy.n_action_steps=10 \
--policy.chunk_size=50 \
--policy.compile_model=false \
--env.type=metaworld \
--env.task=<TASK_SPLIT> \
--env.episode_length=300 \
--eval.batch_size=1 \
--eval.n_episodes=20 \
--eval.use_async_envs=false \
--env.max_parallel_tasks=1 \
--seed=1000 \
--safety_model_path=<CORRECTOR_CHECKPOINT> \
--safety_k=10 \
--guidance_eta=1 \
--guidance_apply_every=1 \
--guidance_loss_objective=attract_delta_z_correction \
--guidance_compare_baseline=true \
--meltdown_cooldown_steps=10 \
--output_dir=<OUTPUT_DIR> \
--save_analysis=false \
--save_raw_video=false \
--save_summary_csv=true \
--save_summary_json=true
Ở đây --policy.chunk_size=50 là kích thước chunk model sinh ra. --policy.n_action_steps=10 là số action thường được dùng trong mỗi window của policy config. --safety_model_path là corrector checkpoint. --safety_k=10 tương ứng khoảng dự đoán latent residual. --guidance_eta=1 là guidance strength mặc định mà paper thấy hợp lý. Nếu eta quá lớn, OGG có thể kéo action quá mạnh và làm task khó tệ hơn.
Với SmolVLA và X-VLA, entry point giống nhau nhưng policy arguments sẽ khác theo backbone. Điều kiện thực tế để chạy full benchmark vẫn gồm GPU, simulator dependencies, dataset, policy checkpoint và corrector checkpoint đã train.
Kết quả paper báo cáo
Project page và README tóm tắt các kết quả chính:
| Setting | Baseline | + VLA-Corrector | Thay đổi |
|---|---|---|---|
| MetaWorld, PI0.5 avg. success | 48.70 | 64.35 | +15.65 |
| MetaWorld, SmolVLA avg. success | 61.90 | 66.65 | +4.75 |
| MetaWorld, X-VLA avg. success | 55.55 | 59.60 | +4.05 |
| LIBERO, PI0.5 few-shot avg. success | 94.00 | 97.80 | +3.80 |
| AgileX PiPER real-world avg. success | 55.6 | 73.3 | +17.7 |
Con số đáng chú ý nhất là PI0.5 trên MetaWorld: baseline trung bình 48.70, thêm VLA-Corrector lên 64.35. Điều này cho thấy lỗi không chỉ nằm ở policy yếu, mà nằm ở cách execution queue bị để chạy quá lâu sau khi visual state đã lệch.

Paper cũng phân tích success-per-call efficiency. Với PI0.5 ở horizon 50, success tăng từ 48.7% lên 58.7% trong khi average policy calls giảm nhẹ từ 5.15 xuống 4.98, tương đương gain success-per-call khoảng 24.6%. Với SmolVLA ở horizon 10, success tăng từ 61.90% lên 73.00% trong khi policy calls giảm từ 19.27 xuống 15.64. Đây là điểm hay: VLA-Corrector không chỉ gọi policy nhiều hơn để mua success bằng compute. Nó cố làm mỗi policy call hữu ích hơn bằng cách không lãng phí call vào stale queue.
Trên LIBERO, paper báo cáo few-shot fine-tuned model + VLA-Corrector đạt 97.8% average success, vượt fully fine-tuned baseline 96.9%. Cách đọc đúng là: corrector giúp giảm phụ thuộc vào việc backbone phải thấy đủ mọi failure recovery trong training data. Nó không thay thế data tốt, nhưng có thể bù cho thiếu coverage ở các drifted states.
Trên robot thật AgileX PiPER 6-DoF, paper chia task thành pick-place, alignment và disturbance recovery. Average success tăng từ 55.6% lên 73.3%. Gain nhỏ hơn ở pick-place vì baseline đã thường chạy được khi object và target không đổi. Gain lớn hơn ở alignment và disturbance recovery, nơi action còn lại trong chunk dễ trở nên lỗi thời.

Ablation: truncation quan trọng, OGG cộng thêm recovery
Ablation trong paper rất đáng đọc vì nó tách hai câu hỏi:
- Chỉ dừng chunk sớm có đủ không?
- Sau khi dừng, có cần OGG không?
Trên MetaWorld, README tóm tắt rằng truncation alone tăng average success từ 48.70% lên 60.35%. Thêm OGG đạt 64.35%. Điều này nói rằng event-triggered truncation là phần "cứu hỏa" chính: đừng để robot tiếp tục chạy stale actions. OGG là phần "định hướng phục hồi": replan kế tiếp nên đi theo hướng latent recovery thay vì chỉ re-infer như bình thường.
Paper cũng báo cáo 83.7% truncations xảy ra trong các critical phases được annotate thủ công, chẳng hạn precise grasping và alignment. Đây là dấu hiệu tốt: monitor không trigger ngẫu nhiên khắp episode, mà tập trung vào các pha manipulation nhạy với lỗi.
Khi nào nên dùng VLA-Corrector?
VLA-Corrector phù hợp nhất khi bạn có đủ ba điều kiện:
| Điều kiện | Vì sao cần |
|---|---|
| Policy dùng action chunk | Nếu policy đã closed-loop từng step, lợi ích adaptive horizon nhỏ hơn |
| Task có contact-rich hoặc precision phase | Đây là nơi stale chunk dễ gây compounding errors |
| Có demonstration trajectories thành công | Corrector học local latent dynamics từ demo |
Các task hợp lý gồm mở drawer, place vào bowl, insertion, align object, thao tác có target bị dịch chuyển, hoặc bimanual manipulation có pha tiếp xúc. Các task quá đơn giản, ít interaction, object không đổi và horizon ngắn có thể không cần corrector.
Bạn cũng cần nhớ giới hạn. Paper nói VLA-Corrector vẫn thất bại nếu object hoặc fixture bị đẩy ra khỏi reachable region, disturbance xảy ra quá muộn khi gripper đã vào pose xấu, hoặc visual ambiguity quá nặng do occlusion và contrast kém. OGG vẫn phụ thuộc vào frozen VLA action prior: nó có thể bias generation theo hướng tốt hơn, nhưng không thể tạo skill recovery mà backbone hoàn toàn không biểu diễn được.
Checklist triển khai cho lab nhỏ
Nếu bạn muốn thử hướng này trong lab, hãy đi theo thứ tự:
- Chạy baseline VLA với fixed horizon trước. Log success, policy calls, failure phase và video.
- Chọn một task có lỗi rõ do stale chunk, ví dụ object bị lệch sau grasp hoặc placement target bị dịch.
- Chuẩn bị demonstration trajectories thành công ở format LeRobot/MetaWorld/LIBERO phù hợp.
- Fine-tune hoặc dùng checkpoint VLA backbone đã có.
- Chạy
siglip_dynamics.extractđể tạo latent cache từ frozen visual encoder. - Train MLP corrector bằng
siglip_dynamics.train. - Evaluation với
lerobot_eval_modified_detection, bật summary CSV/JSON để so sánh baseline và corrector. - Chỉ sau khi simulation ổn mới chạy robot thật; bắt đầu với speed thấp, workspace rõ, emergency stop sẵn.
Một mẹo thực tế: đừng tune guidance_eta trước khi bạn nhìn video lỗi. Nếu baseline fail vì perception không thấy object, OGG không giải quyết gốc rễ. Nếu baseline fail vì stale chunk sau drift nhỏ, VLA-Corrector đúng vấn đề hơn.
Kết luận
VLA-Corrector là một hướng rất thực dụng cho robotics năm 2026: không cần thay backbone, không cần retrain toàn bộ VLA, nhưng thêm một cơ chế runtime để biết khi nào action chunk đã lỗi thời. Với LVM, robot có tín hiệu phát hiện visual drift. Với event-triggered truncation, robot bỏ stale actions trước khi lỗi tích lũy quá xa. Với OGG, lần replan sau interrupt có thêm hướng dẫn recovery.
Điểm đáng học nhất không phải chỉ là một module 40M parameters, mà là tư duy hệ thống: VLA policy mạnh vẫn cần runtime monitor. Trong manipulation thật, policy không chỉ cần "biết làm gì" ở đầu chunk; nó còn cần biết khi nào nên ngừng tin vào kế hoạch cũ.



