PoseVLA là một hướng rất đáng chú ý cho nhóm Vision-Language-Action (VLA) vì nó không bắt đầu bằng câu hỏi "làm sao sinh action tốt hơn?", mà bắt đầu bằng câu hỏi cơ bản hơn: "mô hình có thật sự hiểu 3D pose của vật và end-effector chưa?". Paper Universal Pose Pretraining for Generalizable Vision-Language-Action Policies của Haitao Lin, Hanyang Yu, Jingshun Huang, He Zhang, Yonggen Ling, Ping Tan, Xiangyang Xue và Yanwei Fu được chấp nhận tại RSS 2026, đi kèm project page, code open-source, checkpoint Stage-1 trên Hugging Face, checkpoint RoboTwin trên ModelScope, script pre-training, post-training, inference 3D grounding và adapter đánh giá RoboTwin.
Bài này là hướng dẫn thực hành cho beginner đã biết Python/PyTorch cơ bản. Mục tiêu không phải là hứa rằng bạn có thể train full PoseVLA trên laptop. Mục tiêu là giúp bạn hiểu paper đang làm gì, cài repo đúng cách, biết checkpoint nào cần tải, biết luồng pretrain 3D pose khác gì post-train robot action, chạy inference 3D grounding, rồi đánh giá trên RoboTwin. Điểm số cần đọc chính xác: paper báo cáo Pose-VLA đạt khoảng 79.5% trung bình trên RoboTwin 2.0 và 96.0% trên LIBERO; project page/repo cập nhật tháng 7-8/2026 cho thấy scaled training của checkpoint release đạt 89.4% Clean và 88.6% Random trên 50 task RoboTwin. Vì vậy khi nói "đạt 89%" trong bài này, ta đang nói về checkpoint/recipe release mạnh hơn paper checkpoint, không phải bảng strict 80k-step trong paper.
PoseVLA giải quyết vấn đề gì?
Nhiều VLA hiện đại dựa trên VLM như PaliGemma, Qwen-VL hoặc các backbone tương tự. Chúng rất giỏi nhận dạng semantic: đâu là cái cốc, đâu là chai, lệnh người dùng muốn gì. Nhưng robot manipulation không chỉ cần semantic. Nếu cốc xoay lệch 15 độ, tay gắp phải đổi hướng; nếu chai đứng sát mép bàn, trajectory phải khác; nếu laptop mở một phần, policy cần biết góc khớp và pose tương đối của nắp. Những khác biệt này thường nhỏ trong pixel nhưng lớn trong action.
Paper gọi vấn đề này là feature collapse và training kém hiệu quả khi high-level perception bị trộn trực tiếp với action supervision thưa, phụ thuộc embodiment. Nếu chỉ fine-tune VLM bằng robot demo, gradient action rất ít so với lượng tri thức semantic đã học từ web/VQA. Mô hình có thể học shortcut: nhìn instruction và vật thể chính, nhưng không học geometry đủ sắc để điều khiển chính xác trong scene mới.
PoseVLA tách bài toán thành hai giai đoạn:
| Giai đoạn | Mục tiêu | Dữ liệu | Output học được |
|---|---|---|---|
| Pre-training | Học prior không gian 3D trong camera-centric space | Omni3D, Omni6D, BOP, GraspClutter6D, Agibot, DROID, RDT, UMI, Xtrainer, InternData-A1 | VLM biết object pose, 2D box, 3D grounding và trajectory geometry |
| Post-training | Căn chỉnh với robot cụ thể | RoboTwin hoặc dataset robot riêng dạng HDF5/LeRobot | Action expert sinh action trong action space robot |
Điểm hay là pose token trở thành interface chung. Thay vì token hóa tọa độ kiểu từng chữ số, PoseVLA dùng discrete pose token với bin không đều theo phân bố dữ liệu. Vùng pose xuất hiện dày được chia nhỏ hơn, vùng đuôi phân bố được chia rộng hơn. Cách này giúp chuỗi token ngắn hơn và tận dụng vocabulary hiệu quả hơn. Với beginner, có thể hiểu đơn giản: PoseVLA biến 3D pose thành "từ vựng" mà VLM có thể học bằng next-token prediction, giống học text nhưng nội dung là geometry.
Kiến trúc tổng quan

Kiến trúc PoseVLA dựa trên mẫu dual-system phổ biến trong π0/π0.5: một VLM backbone hiểu ảnh và ngôn ngữ, cộng với Action Expert dùng Flow Matching để sinh action liên tục. Trong repo, phần model nằm ở posevla/: modeling_posevla.py định nghĩa PoseVLAPolicy, paligemma_with_expert.py chứa kiến trúc dual-stream PaliGemma + expert, patch_embed.py xử lý vision patch embedding và prior fusion, còn _lerobot_compat.py giữ lớp tương thích LeRobot.
Pipeline có ba ý tưởng chính.
Thứ nhất là camera-centric pose representation. PoseVLA không ép mọi thứ về base frame của robot ngay từ đầu. Nó học pose trong hệ tọa độ gắn với camera quan sát. Điều này thực dụng vì nhiều dataset 3D không phải robot dataset, nhưng vẫn có object pose, depth hoặc camera calibration. Khi policy đã hiểu quan hệ 3D trong camera frame, bước post-training mới học cách chuyển prior đó sang action space cụ thể của robot.
Thứ hai là auxiliary 3D geometry prior. Project page mô tả RGB embedding được cộng thêm depth/raymap prior theo kiểu tương tự positional encoding. Nói dễ hiểu: ảnh RGB cho biết vật là gì, depth/raymap cho biết vật nằm ở đâu trong không gian. Trong ablation, RGB-only đã tốt trên Objectron, nhưng full model với depth và raymap vẫn cho kết quả tốt nhất tổng thể, đặc biệt trên SUN RGB-D.
Thứ ba là decoupled training. VLM học 3D object grounding bằng next-token prediction. Action expert học robot action bằng flow matching. Hai nhánh có thể train riêng hoặc co-training trong cùng optimization step. Repo expose các switch như co_training.vlm_training, co_training.action_training, data_3d, training.pi05, training.is_knowledge_insulation, training.use_lora, training.add_prior. Điều này quan trọng nếu bạn muốn dùng PoseVLA như framework nghiên cứu thay vì chỉ tải checkpoint chạy demo.
Kết quả 3D grounding

Trước khi bàn về robot action, hãy nhìn phần 3D grounding. Paper đánh giá trên SUN RGB-D và Objectron trong Omni3D, dùng mAP ở IoU threshold 0.15. PoseVLA đạt 45.5 AP15 trên SUN RGB-D và 87.3 AP15 trên Objectron. Trên Objectron, paper nói đây là cải thiện lớn so với open-source baseline mạnh nhất trong bảng, gồm Qwen3-VL 235B Thinking ở 71.2.
Điểm này rất quan trọng với robotics. Objectron chứa nhiều object tabletop như bottle, cup, camera. Đây là nhóm vật robot thường phải cầm, đẩy, đặt, treo hoặc tránh va chạm. Một VLM chỉ biết "đây là bottle" chưa đủ; policy cần biết bottle nghiêng thế nào, tâm ở đâu, cạnh nào đang hướng về gripper. Khi PoseVLA học được pose token từ nhiều dataset 3D, phần post-training không phải học lại toàn bộ spatial understanding từ vài nghìn robot demo.
Cài đặt repo
Repo chính là https://github.com/hetolin/PoseVLA. Môi trường khuyến nghị trong README là Python 3.10.12, PyTorch 2.7.0 với CUDA 12.6, bf16/TF32 tốt nhất trên Ampere hoặc Hopper. Nếu chỉ đọc code và chạy inference 3D grounding nhỏ, một GPU 16-24 GB có thể đủ tùy checkpoint. Nếu muốn post-train RoboTwin nghiêm túc, hãy chuẩn bị multi-GPU. Nếu muốn pretrain full mixture, đây là bài toán cluster.
Cài từ đầu:
git clone [email protected]:hetolin/PoseVLA.git
cd PoseVLA
conda create -n vla python==3.10.12
conda activate vla
pip install torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 \
--index-url https://download.pytorch.org/whl/cu126
Repo pin LeRobot ở một commit cụ thể và cần sửa nhẹ dependency pyav sang av, bỏ rerun-sdk để tránh xung đột NumPy:
git clone https://github.com/huggingface/lerobot.git third_party/lerobot
cd third_party/lerobot
git checkout 638d411cd3acf32c28d8c2120f3c41bda8bb15d4
sed -i 's/pyav/av/' pyproject.toml
sed -i '/rerun-sdk/d' pyproject.toml
pip install -e .
cd ../..
pip install -r requirements.txt
Nếu dùng BOP cho 3D pretraining:
git clone https://github.com/thodan/bop_toolkit.git third_party/bop_toolkit
cd third_party/bop_toolkit
pip install -e .
cd ../..
Sau đó tạo thư mục pretrain/ và đặt các weight cần dùng:
pretrain/
├── paligemma-3b-pt-224/
├── lerobot_pi0/
└── pi05_base/
Các link tương ứng trong README là PaliGemma-3B trên Hugging Face, hetolin/lerobot_pi0 và hetolin/pi05_base. Nếu bạn muốn thử nhánh π0.5, pi05_base là checkpoint action expert cần chú ý. Cuối cùng đặt biến môi trường:
export DEV_PATH="/path/to/parent/of/PoseVLA"
export HYDRA_FULL_ERROR=1
Một lỗi beginner hay gặp là cài đúng Python nhưng sai CUDA wheel. Hãy kiểm tra trước:
nvidia-smi
python - <<'PY'
import torch
print(torch.__version__)
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else "no cuda")
PY
Nếu CUDA chưa lên, đừng chạy training vội. Hãy sửa driver, container runtime hoặc PyTorch wheel trước.
Pre-training: học 3D pose trước khi học robot action
File hướng dẫn chính là docs/PRETRAIN.md, entry script là train_pretrain.py, config là config/base.yaml. PoseVLA hỗ trợ ba chế độ:
| Mode | Switch chính | Khi nào dùng |
|---|---|---|
| VLM training | co_training.vlm_training=True, action_training=False, data_3d=True |
Học 3D grounding/pose token từ Omni3D, Omni6D, BOP, GraspClutter6D |
| Action training | vlm_training=False, action_training=True |
Train action expert từ robot dataset |
| Co-training | Bật cả VLM và action | Muốn giữ geometry và action alignment trong cùng run |
Lệnh debug multi-GPU một node:
accelerate launch \
--multi_gpu --num_machines 1 --num_processes 8 \
--mixed_precision=bf16 \
--main_process_ip 127.0.0.1 --main_process_port 56789 \
--machine_rank 0 \
train_pretrain.py
Trên cluster, repo dùng:
bash scripts/launch/pretrain.sh False
Script này đọc RANK, MASTER_ADDR, MASTER_PORT, WORLD_SIZE, GPU_NUM từ môi trường cluster rồi gọi accelerate launch. Khi resume:
python train_pretrain.py resume_ckpt=/path/to/exp/29999
Checkpoint có layout:
ckpt/<exp_name>/<step>/
├── model/
└── state/training_state.pth/
Nếu muốn dùng LoRA để giảm chi phí fine-tune, bật training.use_lora=True và chỉnh block lora.* trong config. Nếu muốn thử nhánh π0.5 trong framework PoseVLA, xem training.pi05=True. Tuy nhiên cần phân biệt hai thứ: PI0.5 RoboTwin Baseline trong thư mục pi05_baseline/ là baseline isolated dùng qpos 14D; còn PoseVLA với π0.5 branch/action expert là thí nghiệm PoseVLA thật sự khi bạn khởi tạo và train backbone/action expert theo recipe PoseVLA.
Chuẩn bị dữ liệu RoboTwin
Post-training RoboTwin dùng train_posttrain.py, config/base_posttrain.yaml và config/dataset/robotwin.yaml. Dữ liệu raw RoboTwin cần convert sang HDF5 bằng:
python utils/process_data_all.py
Sau đó compute normalization:
python scripts/stats/norm_robotwin.py --mode eep
Kết quả quan trọng là qpos_mean_std_online.pkl. Trong robotwin.yaml, kiểm tra hdf5_dir, mean_std_path, action_type, action_chunk_size, img_history_size, image_size và dataset_list. Với checkpoint PoseVLA RoboTwin release, action mode chính là EEP; eval config dùng left_arm_dim: 8, right_arm_dim: 8, tổng 16D.
Trước khi train, chạy smoke test dataloader:
python data/ds_train/robot/dataset_hdf5_action.py
Script này ghi all_images.png và all_joints.png. Hãy mở chúng ra trước khi tốn GPU. Nếu camera bị đảo, instruction sai, action curve nhảy bất thường hoặc normalization lệch, training loss vẫn có thể giảm nhưng policy sẽ thất bại trong simulator.
Post-training trên RoboTwin
Post-training trong docs/POSTTRAIN.md là action-only:
| Field | Giá trị cần chú ý |
|---|---|
defaults.dataset |
robotwin |
model.pretrained_model_path |
checkpoint PoseVLA sau pre-training |
model.action_expert_path |
action expert π0 hoặc π0.5 |
co_training.vlm_training |
False |
co_training.action_training |
True |
data_3d |
False |
training.pi05 |
True nếu dùng nhánh π0.5 |
training.max_training_steps |
default repo là 200k cho post-train |
Debug một GPU:
python train_posttrain.py
Một node 8 GPU:
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
accelerate launch --main_process_port 29504 --num_processes=8 train_posttrain.py
Cluster:
bash scripts/launch/posttrain.sh
Resume:
python train_posttrain.py resume_ckpt=/path/to/exp/29999
Với beginner, cách đọc đúng là: pre-training tạo VLM/action representation có prior 3D tốt; post-training căn chỉnh representation đó với robot/action contract. Nếu bỏ pretraining 3D, bạn có thể vẫn train được action model, nhưng paper ablation cho thấy baseline PaliGemma + Action Expert chỉ đạt khoảng 35.4% Easy và 33.4% Hard trên RoboTwin, trong khi thêm 3D data nhảy lên khoảng 70.2% Easy và 69.1% Hard. Đây là bằng chứng chính cho giá trị của pose-centric pretraining.
Inference 3D grounding
Repo có infer_grounding3d.py cho real-world RGB-D hoặc HDF5. Chạy mặc định:
python infer_grounding3d.py
Script dùng ảnh ví dụ trong assets/ và yêu cầu bạn sửa vài biến:
| Biến | Ý nghĩa |
|---|---|
ckpt_path |
checkpoint PoseVLA pretrained |
img_path |
RGB input |
depth_path |
depth input |
cam_K |
camera intrinsic matrix |
task_text |
query open-vocabulary, ví dụ detect the bottle |
Output gồm predicted 3D scene text, structured result sau decode, infer_rgb.png, infer_depth_raw.png và visualization 2D/3D detection. Đây là cách tốt để kiểm tra mô hình có hiểu geometry scene của bạn không trước khi đưa vào policy điều khiển.
Đánh giá trong RoboTwin

Để evaluate policy PoseVLA trong RoboTwin, bạn thường cần hai môi trường: môi trường posevla để train/tạo checkpoint, và môi trường RoboTwin để chạy simulation. Symlink repo vào RoboTwin/policy/PoseVLA:
ln -s /path/to/PoseVLA /path/to/RoboTwin/policy/PoseVLA
Copy eval entry tương thích:
cp /path/to/RoboTwin/policy/PoseVLA/robotwin/PoseVLA/eval_policy.py \
/path/to/RoboTwin/script/eval_policy.py
Tải checkpoint release:
pip install modelscope
export MODELSCOPE_DOMAIN=www.modelscope.ai
cd /path/to/PoseVLA
mkdir -p ckpt_robotwin/model
modelscope download hanyangyu1021/PoseVLA-robotwin \
config.json model.safetensors \
--local_dir ckpt_robotwin/model
Trong robotwin/PoseVLA/deploy_policy.yml, đặt:
checkpoint_path: policy/PoseVLA/ckpt_robotwin/model
action_type: eep
norm_path: policy/PoseVLA/robotwin/PoseVLA/norm_stats/qpos_mean_std_online.pkl
left_arm_dim: 8
right_arm_dim: 8
Chạy eval:
cd /path/to/RoboTwin
conda activate RoboTwin
python script/eval_policy.py --config policy/PoseVLA/robotwin/PoseVLA/deploy_policy.yml
Để chạy song song nhiều task, chỉnh GPU_IDS, TASK_CONFIG, SEED, TASKS trong run_auto_eval_posevla.sh, rồi chạy từ RoboTwin root:
bash run_auto_eval_posevla.sh
Log nằm dưới RoboTwin/eval_result/auto_eval_YYYYMMDD_HHMMSS/, mỗi task có file riêng và summary cuối nằm ở evaluation_summary.txt.
π0.5 baseline trong repo dùng thế nào?
Repo tháng 8/2026 release thêm pi05_baseline/, một entry độc lập cho PI0.5 RoboTwin Baseline. Nó không thay đổi config PoseVLA mặc định. Baseline này dùng qpos/action contract 14D, action horizon 48, normalization riêng và checkpoint ModelScope hanyangyu1021/PoseVLA-pi05-robotwin.
Chuẩn bị:
export DEV_PATH=/path/to/parent/of/PoseVLA
export ROBOTWIN_HDF5_DIR=/path/to/robotwin/hdf5/root
export HYDRA_FULL_ERROR=1
Dataset root cần có:
robotwin_processed/
robotwin_processed_random/
Tạo stats:
python pi05_baseline/prepare_stats.py \
--dataset-root "$ROBOTWIN_HDF5_DIR" \
--output /path/to/pi05_stats/qpos_hybrid_stats.pkl
export PI05_NORM_PATH=/path/to/pi05_stats/qpos_hybrid_stats.pkl
Smoke test training:
python -m pi05_baseline.train \
debug=True \
training.max_training_steps=10 \
training.max_evaluation_steps=1
Training 8 GPU:
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
accelerate launch \
--main_process_port 29504 \
--num_processes 8 \
pi05_baseline/train.py
Config baseline cố định các contract quan trọng:
training.pi05=true
training.add_extra_token=false
training.add_prior=false
dataset.action_type=qpos
dataset.action_chunk_size=48
Để evaluate checkpoint release:
pip install modelscope
cd /path/to/PoseVLA
modelscope download \
--model hanyangyu1021/PoseVLA-pi05-robotwin \
--local_dir ckpt_robotwin/pi05_baseline
Chạy một task:
cd /path/to/RoboTwin
bash policy/PoseVLA/pi05_baseline/eval.sh \
beat_block_hammer demo_clean 0
Randomized:
bash policy/PoseVLA/pi05_baseline/eval.sh \
beat_block_hammer demo_randomized 0
Tên gọi nên cẩn thận. Theo README, hãy gọi checkpoint lịch sử này là PI0.5 RoboTwin Baseline hoặc reproduction baseline. Chỉ dùng tên PoseVLA-PI0.5 khi thí nghiệm thật sự khởi tạo và train PoseVLA backbone như một phần của method.
Kết quả và cách diễn giải

Các số chính nên nhớ:
| Benchmark | Kết quả |
|---|---|
| RoboTwin 2.0 paper checkpoint | 79.91% Easy, 79.10% Hard |
| RoboTwin 2.0 release/scaled checkpoint | 89.40% Clean, 88.60% Random |
| LIBERO average | 96.0% |
| Objectron 3D grounding | 87.3 AP15 |
| SUN RGB-D 3D grounding | 45.5 AP15 |
| Real-world average trong paper | 81.25% |
So với π0 và π0.5 trong bảng paper, Pose-VLA không chỉ thắng bằng model lớn hơn. Ablation cho thấy thêm 3D data giúp success rate Hard tăng từ khoảng 33.4% lên 69.1%; thêm robot data và đổi post-train từ joint sang EE pose tiếp tục nâng lên 79.1%. Orthogonal ablation cũng cho thấy Qwen3PI, dù dùng Qwen3-VL mạnh, vẫn thua PoseVLA hơn 20 điểm nếu chỉ post-training mà thiếu pose-centric pretraining.
Ý nghĩa thực tế là: nếu lab của bạn có ít robot demo, hãy ưu tiên kiểm tra representation và data contract trước khi tăng số step. PoseVLA gợi ý một recipe rõ: dùng 3D dataset không nhất thiết là robot dataset để dạy geometry, sau đó dùng robot demo ít hơn để học action alignment. Real-world experiment trong paper chỉ dùng trung bình 100 demo mỗi task trên dual-arm Xtrainer với RealSense D455 head camera và D405 wrist camera, nhưng vẫn đạt kết quả tốt trên stacking, hanging mug, drawer interaction và towel folding.
Checklist cho lab muốn thử
Nếu bạn mới bắt đầu, đi theo thứ tự này:
- Cài repo và pass kiểm tra CUDA.
- Tải Stage-1 hoặc RoboTwin checkpoint thay vì tự pretrain ngay.
- Chạy
infer_grounding3d.pyvới ảnh ví dụ. - Thay ảnh RGB-D của lab vào, chỉnh
cam_Kvàtask_text. - Convert một subset nhỏ RoboTwin sang HDF5.
- Chạy dataloader smoke test và xem
all_images.png,all_joints.png. - Chạy post-train debug 10-100 step để kiểm tra pipeline.
- Evaluate một task RoboTwin trước, sau đó mới chạy 50 task.
- Nếu dùng π0.5 baseline, giữ nó trong
pi05_baseline/và không trộn normalization EEP với qpos. - Khi chuyển sang robot thật, khóa camera mapping, action frame, normalization và safety limit trước khi chạy policy tốc độ cao.
Sai lầm phổ biến nhất là nhầm lẫn giữa camera frame, robot base frame và end-effector frame. PoseVLA học camera-centric pose, RoboTwin PoseVLA release dùng EEP action 16D, còn PI0.5 baseline dùng qpos 14D. Ba contract này không thay thế lẫn nhau. Nếu bạn dùng sai normalization hoặc sai action adapter, policy sẽ trông như "không học được" dù checkpoint đúng.
Nguồn tham khảo
- Paper:
arXiv:2602.19710, Universal Pose Pretraining for Generalizable Vision-Language-Action Policies. - Project page:
https://hetolin.github.io/PoseVLA/. - Code:
https://github.com/hetolin/PoseVLA. - Checkpoints:
hetolin/PoseVLA-stage1,hanyangyu1021/PoseVLA-robotwin,hanyangyu1021/PoseVLA-pi05-robotwin.



