VLA-0: Train VLA Đỉnh Cao Không Cần Sửa Kiến Trúc
Cộng đồng robot learning đang chạy đua xây dựng Vision-Language-Action (VLA) model ngày càng phức tạp hơn: custom action head, diffusion decoder, flow matching, discrete tokenizer riêng, pipeline đặc biệt cho continuous action space... Mỗi paper mới lại thêm một tầng kỹ thuật, mỗi codebase lại dài thêm hàng nghìn dòng.
Nhưng NVIDIA NVlabs vừa đặt ra một câu hỏi ngược chiều:
"Điều gì xảy ra nếu ta không sửa gì hết?"
Câu trả lời là VLA-0 — một VLA đạt state-of-the-art trên benchmark LIBERO với 94.7% success rate, vượt qua pi_0, GR00T-N1, OpenVLA-OFT và SmolVLA. Không có action head tùy chỉnh. Không có diffusion decoder. Chỉ là Qwen2.5-VL-3B fine-tuned để predict action như văn bản thông thường. Toàn bộ codebase chỉ khoảng 1,200 dòng — so với hơn 10,000 dòng của các VLA phức tạp khác.
Paper gốc: VLA-0: Building State-of-the-Art VLAs with Zero Modification (Goyal, Hadfield, Yang, Blukis, Ramos — NVIDIA NVlabs). GitHub: NVlabs/vla0.
Vấn Đề Với VLA Hiện Tại
Để hiểu tại sao VLA-0 quan trọng, hãy nhìn vào giả định nền tảng của các VLA trước đó.
Robot action vốn là tín hiệu liên tục (continuous): tọa độ end-effector, góc khớp, lực tác động, vận tốc... Giá trị này không phải là ngôn ngữ — không phải word token nào trong vocabulary của LLM. Vì vậy cộng đồng đã đi theo hai hướng chính:
Hướng 1 — Discrete tokenization: OpenVLA tokenize action thành bin cố định và thêm vào vocabulary của LLM. Vấn đề: phải resize embedding layer, mất resolution nếu số bin ít, thêm phức tạp training.
Hướng 2 — Continuous action head: pi_0, GR00T-N1 thêm flow matching hoặc diffusion head ở output của VLM, xử lý riêng phần continuous action. Vấn đề: kiến trúc phức tạp, training khó, codebase cồng kềnh.
Cả hai hướng đều xuất phát từ cùng giả định: "VLM gốc không thể xử lý continuous action, cần thêm component đặc biệt."
VLA-0 thách thức chính giả định này.
Ý Tưởng Cốt Lõi: Action As Text
VLA-0 đặt câu hỏi: Nếu ta chỉ yêu cầu VLM predict action như một chuỗi số nguyên thông thường thì sao?
Quá trình biểu diễn action dưới dạng text diễn ra như sau:
- Normalize: Mỗi chiều của action vector được chuẩn hóa về khoảng
[0, 1000](số nguyên). - Serialize: Các giá trị được viết thành chuỗi text, ví dụ
"524 341 892 127 650 200". - Predict: VLM được fine-tune để predict chuỗi này như bất kỳ đoạn text nào khác.
- Decode: Số nguyên được parse và denormalize về action space thực tế.
Ví dụ thực tế:
Input: [Camera frame] + "Pick up the red cup and place it on the plate"
Output: "524 341 892 127 483 671 201 890 ..."
↓ parse & denormalize ↓
Action: [0.524, 0.341, 0.892, 0.127, 0.483, ...] (joint targets)
Action as text: thay vì thêm custom head phức tạp, VLA-0 chỉ yêu cầu VLM predict chuỗi số nguyên — đơn giản nhưng đạt SOTA
Tại sao hoạt động được? VLM đã được pretrain trên lượng data khổng lồ bao gồm code, toán học, chuỗi số. Khả năng mô hình hóa pattern của chuỗi số nguyên đã ăn sâu vào weights từ pretraining. Robot manipulation chỉ cần fine-tune mapping (image, instruction) → action sequence.
Điểm khác biệt then chốt so với OpenVLA: VLA-0 không thêm token mới vào vocabulary, không thay đổi embedding layer. Số "524" là chuỗi ký tự bình thường trong vocabulary đã có sẵn của Qwen2.5-VL. Resolution cũng có thể tùy chỉnh dễ dàng bằng cách đổi max range — [0, 100] cho độ phân giải thấp, [0, 10000] cho độ phân giải cao — mà không cần sửa architecture.
Kiến Trúc: Qwen2.5-VL-3B Nguyên Vẹn
VLA-0 dùng Qwen2.5-VL-3B-Instruct làm backbone — một VLM 3 tỷ tham số từ Alibaba với khả năng xử lý ảnh và text rất tốt.
Qwen2.5-VL-3B có kiến trúc gồm:
- Vision Encoder: ViT-based, xử lý ảnh từ camera robot
- Language Model: Qwen2.5-3B transformer decoder, predict tokens
- Visual-Language Bridge: Cross-attention đưa visual features vào language stream
Và VLA-0 không thay đổi bất cứ thứ gì trong kiến trúc này:
- ❌ Không có action head riêng
- ❌ Không có diffusion module
- ❌ Không có flow matching
- ❌ Không có custom tokenizer
- ❌ Không resize embedding layer
Training là standard supervised fine-tuning với causal language modeling loss — hoàn toàn giống fine-tune LLM thông thường, chỉ là "text" target giờ là chuỗi action integers. Loss function vẫn là cross-entropy trên next-token prediction như thường.
Action Chunking và Temporal Ensembling
Một kỹ thuật quan trọng VLA-0 kế thừa là action chunking — thay vì predict 1 action cho timestep hiện tại, model predict một "chunk" gồm n action liên tiếp trong tương lai.
Kỹ thuật này xuất phát từ ACT (Action Chunking Transformer) và được nhiều VLA khác như OpenVLA-OFT adopt. Ưu điểm rõ ràng:
- Temporal consistency: Các action trong chunk nhất quán với nhau, tránh jerky motion
- Long-horizon awareness: Model thấy "tương lai" và đưa ra decision tốt hơn
- Temporal ensembling: Nhiều prediction chồng lấp được combine bằng weighted average (exponential decay), tăng ổn định
Cụ thể: tại timestep t, model predict chunk [a_t, a_{t+1}, ..., a_{t+n-1}]. Chunk tiếp theo dự đoán từ t+1 sẽ chồng lấp với chunk trước. Weighted average của các predictions chồng lấp cho action cuối cùng tại t.
LIBERO Benchmark: Sân Kiểm Tra
LIBERO là benchmark chuẩn để đánh giá VLA models trên robot manipulation, gồm 4 suites kiểm tra các khả năng khác nhau:
| Suite | Nội dung đánh giá | Đặc trưng |
|---|---|---|
| LIBERO-Spatial | Hiểu vị trí không gian | "Put the bowl to the left of the mug" |
| LIBERO-Object | Nhận dạng và thao tác object | "Pick up the black bowl" |
| LIBERO-Goal | Đạt trạng thái mục tiêu | "Stack the red block on the blue block" |
| LIBERO-Long | Chuỗi task dài nhiều bước | Thực hiện 3-4 sub-task liên tiếp |
Mỗi suite có 10 tasks, mỗi task đánh giá 50 episodes. Tổng cộng 2,000 evaluation episodes.
VLA-0 đạt 94.7% average success rate trên toàn bộ LIBERO, vượt tất cả các model sau:
- SmolVLA: được pretrain trên large-scale real robot data
- OpenVLA-OFT: VLA với discrete action tokenizer
- pi_0 và pi_0.5-KI: flow matching VLA từ Physical Intelligence
- GR00T-N1: VLA từ NVIDIA với diffusion action head
- MolmoAct: VLA từ Allen AI
Đặc biệt ấn tượng: VLA-0 không được pretrain trên large-scale robotics data như pi_0 hay SmolVLA, chỉ fine-tune trên dataset LIBERO — nhưng vẫn thắng.
Cài Đặt Môi Trường
Yêu Cầu Phần Cứng
| Thành phần | Tối thiểu | Khuyến nghị |
|---|---|---|
| GPU | RTX 3090 (24GB) | 2× A100 (80GB) |
| RAM | 32GB | 64GB |
| Storage | 50GB | 100GB |
| CUDA | 11.8+ | 12.1+ |
Bước 1: Clone Repository
# Clone kèm submodules (bắt buộc — RoboVerse là submodule)
git clone --recurse-submodules [email protected]:NVlabs/vla0.git
cd vla0
Flag --recurse-submodules là bắt buộc vì VLA-0 dùng RoboVerse như git submodule để quản lý dataset pipeline.
Bước 2: Tạo Môi Trường
conda create -n vla0 python=3.10 -y
conda activate vla0
# Cài lerobot với LIBERO extras
pip install -e "libs/lerobot[libero]"
# Cài các dependencies còn lại
pip install -e .
Bước 3: Tải LIBERO Dataset
LIBERO dataset có thể download qua HuggingFace Hub thông qua lerobot:
# Download cả 4 LIBERO suites (~20GB)
python scripts/download_libero.py --all
# Hoặc từng suite riêng lẻ
python scripts/download_libero.py --suite spatial
python scripts/download_libero.py --suite object
python scripts/download_libero.py --suite goal
python scripts/download_libero.py --suite long
Bước 4: Kiểm Tra Cài Đặt
# Verify dataset và model download đúng
python scripts/verify_setup.py
Cấu Hình Training
VLA-0 dùng file YAML cho cấu hình. Tạo configs/my_vla0.yaml:
MODEL:
name: "Qwen/Qwen2.5-VL-3B-Instruct" # HuggingFace model ID
freeze_vision_encoder: false # Fine-tune toàn bộ
TRAINING:
batch_size: 8 # Điều chỉnh theo VRAM
learning_rate: 2.0e-5
num_epochs: 50
warmup_ratio: 0.05
weight_decay: 0.01
fp16: true # Mixed precision training
gradient_checkpointing: true # Tiết kiệm VRAM
ACTION:
chunk_size: 16 # Predict 16 actions mỗi step
action_bins: 1000 # Normalize về [0, 1000]
ensemble_k: 5 # Temporal ensembling: average 5 overlapping chunks
DATALOADER:
ROBOVERSE:
cfg_path: "libs/RoboVerse/roboverse/configs/img_libero_aug.yaml"
num_workers: 4
LOGGING:
output_dir: "checkpoints/my_vla0"
save_every_n_epochs: 5
eval_every_n_epochs: 10
Giải thích các tham số quan trọng:
action_bins: 1000— normalize action về[0, 1000]. Tăng lên 10000 nếu cần độ phân giải cao hơn.chunk_size: 16— predict 16 action liên tiếp. Tăng nếu task cần long-horizon planning.ensemble_k: 5— average 5 overlapping chunks. Giảm xuống 1 để tắt ensembling (inference nhanh hơn nhưng kém ổn định).gradient_checkpointing: true— cần thiết để fit model 3B vào RTX 3090 24GB.
Chạy Training
# Train trên toàn bộ LIBERO (4 suites)
python train.py --config configs/my_vla0.yaml
# Train chỉ 1 suite (nhanh hơn để thử nghiệm)
python train.py --config configs/my_vla0.yaml \
DATALOADER.ROBOVERSE.suite=spatial
# Multi-GPU với torchrun (khuyến nghị cho A100)
torchrun --nproc_per_node=4 \
train.py --config configs/my_vla0.yaml
Ước tính thời gian training:
| Phần cứng | Dataset | Thời gian |
|---|---|---|
| 1× RTX 3090 | LIBERO-Spatial | ~8 giờ |
| 1× A100 80GB | Toàn bộ LIBERO | ~6 giờ |
| 4× A100 80GB | Toàn bộ LIBERO | ~2 giờ |
Theo dõi training progress:
# TensorBoard
tensorboard --logdir checkpoints/my_vla0/logs --port 6006
# Hoặc Weights & Biases
wandb login
python train.py --config configs/my_vla0.yaml LOGGING.wandb=true
Chạy Evaluation Trên LIBERO
Sau khi training xong, evaluate trên LIBERO simulator:
# Evaluate tất cả 4 suites, mỗi task 50 episodes
python eval_libero.py \
--checkpoint checkpoints/my_vla0/best.pt \
--suite all \
--num_episodes 50 \
--render # Hiển thị visualization (tùy chọn)
# Evaluate nhanh — 1 suite, 10 episodes
python eval_libero.py \
--checkpoint checkpoints/my_vla0/best.pt \
--suite spatial \
--num_episodes 10
Output ví dụ:
LIBERO-Spatial: Success 46/50 = 92.0%
LIBERO-Object: Success 48/50 = 96.0%
LIBERO-Goal: Success 44/50 = 88.0%
LIBERO-Long: Success 49/50 = 98.0%
Average: Success 187/200 = 93.5%
Inference Trên Robot Thực
Để tích hợp VLA-0 vào robot pipeline của bạn:
import torch
import numpy as np
from vla0 import VLA0
# Load model đã train
model = VLA0.from_pretrained(
"checkpoints/my_vla0/best.pt",
device="cuda"
)
model.eval()
# Vòng lặp điều khiển robot
instruction = "Stack the red block on the blue block"
chunk_buffer = [] # Buffer cho temporal ensembling
for timestep in range(max_steps):
# Lấy ảnh từ camera
image = robot.get_camera_image() # numpy array (H, W, 3)
# Predict chunk action mới
with torch.no_grad():
action_chunk = model.predict(
image=image,
instruction=instruction,
chunk_size=16
) # shape: (16, action_dim)
# Thêm vào buffer và compute ensembled action
chunk_buffer.append(action_chunk)
current_action = model.ensemble_actions(chunk_buffer, k=5)
# Gửi action lên robot
robot.execute_action(current_action)
# Check done
if robot.is_task_complete():
break
VLA-0 chạy được trên robot thực và outperform SmolVLA — model được pretrain trên large-scale real data
Lưu ý quan trọng cho deployment thực tế:
- Camera image cần được resize về resolution mà model đã train (thường 224×224 hoặc 336×336)
- Action space của bạn cần được normalize đúng bằng min/max statistics từ training data
- Tần suất inference phụ thuộc vào
chunk_sizevà robot control frequency. Nếu chunk_size=16 và robot chạy 10Hz, bạn chỉ cần inference mỗi 1.6 giây.
So Sánh Tổng Quan Với Các VLA Khác
| Khía cạnh | VLA-0 | OpenVLA-OFT | pi_0 | GR00T-N1 |
|---|---|---|---|---|
| Action representation | Text integers | Discrete tokens | Flow matching | Diffusion |
| Kiến trúc thay đổi | ❌ Không | ✅ Resize vocab | ✅ Action head | ✅ Diffusion head |
| Codebase (lines) | ~1,200 | 10,000+ | 10,000+ | 10,000+ |
| LIBERO avg | 94.7% | 80.1% | ~86% | ~88% |
| Fine-tuning độ khó | Dễ | Trung bình | Khó | Khó |
| Cần large-scale data | ❌ | ❌ | ✅ | ✅ |
Bài Học Kỹ Thuật Rút Ra
VLA-0 không chỉ là một kết quả benchmark — nó là một bài học về engineering philosophy.
Lesson 1: Kiểm tra giả định trước khi engineer Cả cộng đồng VLA giả định rằng continuous action cần kiến trúc đặc biệt. Không ai thực sự kiểm tra giả định này một cách có hệ thống. VLA-0 làm đúng điều đó và phát hiện giả định là sai.
Lesson 2: Tận dụng capability sẵn có Qwen2.5-VL đã học pattern số từ pretraining. VLA-0 không dạy lại từ đầu — chỉ fine-tune để redirect capability đó sang robot domain. Reuse beats rebuild.
Lesson 3: Complexity không phải virtue Khi một phương pháp đơn giản hơn đánh bại phương pháp phức tạp, đó thường là dấu hiệu của overengineering, không phải innovation. VLA-0 là reminder quan trọng: simple solutions deserve fair comparison before we architect complexity.
Lesson 4: Benchmark honesty VLA-0 được test trên robot thực và vẫn outperform — điều này validate cả benchmark LIBERO lẫn phương pháp. Nhiều nghiên cứu chỉ dừng ở simulation; VLA-0 đi xa hơn.
Hạn Chế Và Hướng Mở Rộng
VLA-0 không phải perfect. Một số hạn chế cần lưu ý:
- Discretization loss: Normalize về [0, 1000] vẫn mất một phần precision so với continuous representation. Với tasks đòi hỏi force control rất chính xác, đây có thể là vấn đề.
- Token sequence length: Mỗi action dimension là một token riêng. Với robot nhiều bậc tự do (7-DOF+), action sequence dài → inference chậm hơn.
- Sim-to-real gap vẫn tồn tại: LIBERO là simulation. Real-world results tốt nhưng chưa được test ở quy mô lớn.
- Camera dependency: VLA-0 cần ảnh RGB từ camera tốt. Với camera cheap hoặc noisy, performance có thể giảm.
Hướng mở rộng tự nhiên:
- Multi-camera input (wrist + overhead)
- Proprioception fusion (joint states + force/torque)
- Language grounding cho novel instructions
- Scaling lên Qwen2.5-VL-7B hoặc 72B
Kết Luận
VLA-0 là bằng chứng mạnh mẽ rằng đôi khi câu trả lời không nằm ở việc xây dựng thêm — mà nằm ở việc bỏ bớt đi. Bằng cách từ chối thêm custom component và thay vào đó biểu diễn action như text, NVIDIA NVlabs đã tạo ra VLA đơn giản nhất và hiệu quả nhất trong lớp của nó.
Nếu bạn đang muốn bắt đầu với VLA cho robot của mình, VLA-0 là điểm khởi đầu lý tưởng — codebase nhỏ, dễ hiểu, dễ debug, và đã được chứng minh trên cả simulation lẫn hardware thực.