aiai-perceptionvladeploymentsimulationpsi0

Ψ₀ Hands-On (5): Inference & Evaluation

Hướng dẫn deploy model Ψ₀, chạy inference trong SIMPLE simulator, và đánh giá kết quả với Real-Time Chunking.

Nguyễn Anh Tuấn9 tháng 4, 202614 phút đọc
Ψ₀ Hands-On (5): Inference & Evaluation

Sau 4 bài xây dựng nền tảng — từ kiến trúc 3 hệ thống, cách huấn luyện staged training, đến thiết kế MM-DiT — giờ là lúc chúng ta chạy thực tế. Bài này sẽ đưa bạn từ checkpoint model đến inference trên simulator, với toàn bộ pipeline: serve model, kết nối SIMPLE simulator, và đánh giá kết quả. Quan trọng nhất, chúng ta sẽ đào sâu vào Real-Time Chunking (RTC) — kỹ thuật giúp Ψ₀ vượt qua rào cản latency mà hầu hết VLA model đều gặp phải.

Hai chế độ inference: Open-loop vs Closed-loop

Trước khi chạy bất kỳ dòng lệnh nào, bạn cần hiểu hai chế độ evaluation hoàn toàn khác nhau mà Ψ₀ hỗ trợ.

Open-loop evaluation (offline)

Ở chế độ này, bạn có sẵn một tập dữ liệu gồm các cặp (observation, ground-truth action). Model nhận observation và dự đoán action, sau đó bạn so sánh action dự đoán với ground-truth. Đây là cách đánh giá nhanh nhất — không cần simulator, không cần GPU mạnh cho rendering.

Tuy nhiên, open-loop có một hạn chế nghiêm trọng: compounding error. Trong thực tế, mỗi action của robot thay đổi trạng thái môi trường, và observation tiếp theo phụ thuộc vào action trước đó. Open-loop bỏ qua điều này — nó giả định mọi observation đều "hoàn hảo" như trong dataset. Kết quả là model có thể đạt loss thấp trên open-loop nhưng thất bại thảm hại khi deploy thực tế.

Hãy nghĩ thế này: open-loop giống như kiểm tra một đầu bếp bằng cách đưa ảnh món ăn hoàn chỉnh và hỏi "bước tiếp theo là gì?" — trong khi closed-loop bắt đầu bếp thực sự nấu từ đầu, và mỗi sai lầm nhỏ sẽ tích lũy.

Closed-loop evaluation (online)

Closed-loop chạy model trong simulator, tạo vòng lặp hoàn chỉnh: observation → model → action → simulator cập nhật trạng thái → observation mới. Đây là cách đánh giá chính xác nhất, gần nhất với real-world deployment.

Ψ₀ sử dụng SIMPLE simulator cho closed-loop evaluation — chúng ta sẽ nói chi tiết ở phần sau.

Minh họa pipeline inference từ camera đến hành động robot

Inference flow: Từ pixel đến chuyển động

Hãy cùng trace toàn bộ đường đi của dữ liệu qua 3 hệ thống của Ψ₀, từ khi camera chụp ảnh đến khi motor quay.

Bước 1: System-2 (VLM) — Nhận diện và lập kế hoạch

Ảnh RGB từ camera egocentric (gắn trên đầu robot) được đưa vào Qwen3-VL-2B cùng với task instruction bằng ngôn ngữ tự nhiên (ví dụ: "Pick up the red cup and place it on the tray"). VLM xử lý và trích xuất visual features — các vector đặc trưng mô tả ngữ cảnh cần thiết cho hành động.

Bước 2: System-1 (MM-DiT Action Expert) — Sinh hành động

Visual features từ System-2 được ghép nối (concatenate) với action noise tokens và đưa vào MM-DiT 500M tham số. Tại đây, quá trình Flow Matching denoising diễn ra:

# Pseudocode: Flow Matching inference step
def inference_step(model, visual_features, task_embedding, num_steps=10):
    # Bắt đầu từ noise thuần túy
    x_t = torch.randn(batch_size, action_horizon, action_dim)  # Gaussian noise
    
    # Lặp qua các bước denoising
    dt = 1.0 / num_steps
    for t in torch.linspace(1.0, 0.0, num_steps):
        # Model dự đoán velocity field v(x_t, t)
        v_t = model(
            x_t,                    # noisy actions hiện tại
            t,                      # timestep
            visual_features,        # từ VLM
            task_embedding          # task instruction
        )
        # Euler step: đi theo velocity field
        x_t = x_t - v_t * dt
    
    # x_t bây giờ là predicted actions (denoised)
    return x_t  # shape: [batch, horizon, action_dim]

Điểm khác biệt so với Diffusion Policy truyền thống: Flow Matching chỉ cần 10 bước denoising thay vì 100 bước của DDPM, giảm inference time đáng kể. Actions được tokenize bằng FAST tokenizer — biến continuous actions thành discrete tokens — rồi decode ngược lại thành joint positions.

Bước 3: System-0 (RL Controller) — Thực thi

Actions từ System-1 là target joint positions cho 15 bậc tự do phần trên cơ thể (hai tay + thân). System-0 — một RL locomotion controller huấn luyện riêng trong Isaac Lab — nhận target này cùng với trạng thái proprioceptive (vận tốc, góc nghiêng, vị trí khớp) và sinh ra torque commands cho toàn bộ 43 DoF của Unitree G1, bao gồm cả chân để giữ thăng bằng.

Hệ thống server phục vụ inference model AI theo thời gian thực

Serve model: Từ checkpoint đến HTTP endpoint

Ψ₀ cung cấp script serve_psi0-rtc.sh để khởi động model inference server. Dưới đây là cách hoạt động:

Chuẩn bị môi trường

# Clone repository
git clone https://github.com/physical-superintelligence-lab/Psi0.git
cd Psi0

# Cài đặt dependencies với uv (Python package manager)
pip install uv
uv sync

# Download checkpoint (khoảng 4GB)
# Checkpoint chứa cả VLM + MM-DiT weights
huggingface-cli download psi-lab/psi0-checkpoints --local-dir checkpoints/

Khởi động inference server

# Cách đơn giản nhất — dùng script có sẵn
bash scripts/serve_psi0-rtc.sh

# Hoặc chạy trực tiếp với uv để tùy chỉnh tham số
uv run serve \
    --host 0.0.0.0 \
    --port 8000 \
    --checkpoint checkpoints/psi0-rtc \
    --action_exec_horizon 10 \
    --rtc true

Các tham số quan trọng:

Tham số Mô tả Giá trị mặc định
--host Địa chỉ bind 0.0.0.0
--port Port lắng nghe 8000
--checkpoint Đường dẫn checkpoint model Bắt buộc
--action_exec_horizon Số actions thực thi trước khi re-query 10
--rtc Bật Real-Time Chunking true

Server khởi động xong sẽ expose HTTP endpoint tại http://localhost:8000/predict. Client gửi POST request chứa observation (ảnh + proprioception), server trả về predicted actions dạng JSON.

SIMPLE Simulator: Môi trường đánh giá chuẩn

SIMPLE (SIMulation Platform for Learning Embodied tasks) là framework evaluation được xây dựng trên MuJoCoIsaac Sim, cung cấp môi trường 3D với vật lý chính xác để đánh giá robot manipulation.

Docker setup

SIMPLE được đóng gói trong Docker container để đảm bảo reproducibility:

# Pull SIMPLE Docker image
docker pull psi-lab/simple-eval:latest

# Chạy evaluation
docker run --gpus all \
    --network host \
    -v $(pwd)/results:/results \
    psi-lab/simple-eval:latest \
    python eval.py \
        --task fill_water \
        --policy-url http://localhost:8000/predict \
        --num-episodes 10 \
        --max-episode-steps 360 \
        --save-video /results/

Các tham số evaluation

  • --num-episodes: Số episode chạy cho mỗi task. Paper dùng 10 episodes — đủ để có statistical significance cho binary success/fail.
  • --max-episode-steps: Giới hạn bước tối đa mỗi episode. Với control frequency 60Hz và 360 steps, mỗi episode kéo dài tối đa 6 giây thời gian robot. Tuy nhiên, do inference latency, wall-clock time thực tế khoảng 6-10 phút/episode trên GPU A100.
  • --task: Tên task evaluation — một trong 8 task được định nghĩa sẵn: fill_water, wipe_bowl, pour_bottle, handoff, place_lunch, pull_tray, stack_cups, arrange_objects.

Tổng thời gian chạy full evaluation (8 tasks × 10 episodes): khoảng 8-12 giờ trên single A100 GPU.

Real-Time Chunking: Giải pháp cho bài toán latency

Đây là phần quan trọng nhất của bài viết. Real-Time Chunking (RTC) là kỹ thuật giúp Ψ₀ deploy được trong real-time mặc dù model inference chậm. Nếu bạn chỉ đọc một phần, hãy đọc phần này.

Vấn đề: 160ms latency vs 30Hz control

Với MM-DiT 500M tham số + VLM 2B tham số, mỗi inference step của Ψ₀ mất khoảng 160ms trên GPU A100. Nhưng robot cần hành động ở 30Hz (33ms/step) hoặc thậm chí 60Hz (16.7ms/step) để chuyển động mượt mà và an toàn.

Nếu robot "đứng chờ" model suy nghĩ xong rồi mới hành động, nó sẽ giật cục — đứng yên 160ms, hành động 33ms, lại đứng yên. Trong các task manipulation phức tạp như rót nước, sự giật cục này gây ra đổ nước, va chạm, hoặc rơi vật.

Hầu hết các VLA model khác giải quyết bằng cách giảm model size (hy sinh accuracy) hoặc giảm control frequency (hy sinh smoothness). Ψ₀ chọn con đường thứ ba.

Giải pháp: Hai luồng bất đồng bộ

RTC chia inference thành 2 thread chạy song song:

Policy thread (chạy ở ~6Hz, mỗi 160ms):

  • Nhận observation mới nhất
  • Chạy full VLM + MM-DiT inference
  • Xuất ra chunk gồm 10 actions tương lai (action_exec_horizon = 10)
  • Cập nhật action buffer

Control thread (chạy ở 30-60Hz, mỗi 16-33ms):

  • Đọc action tiếp theo từ buffer
  • Gửi xuống System-0 (RL controller)
  • Nếu buffer hết action → dùng action cuối cùng (hold)

Hình dung thế này: policy thread như một đầu bếp chuẩn bị sẵn 10 đĩa món ăn mỗi lần vào bếp, còn control thread như người phục vụ mang từng đĩa ra liên tục. Khách hàng (robot) luôn có đồ ăn (action) để thưởng thức, dù đầu bếp cần thời gian nấu.

Timeline minh họa

Thời gian (ms):  0    33   66   99  132  165  198  231  264  297  330
                 |    |    |    |    |    |    |    |    |    |    |
Policy thread:   [====== Inference 1 =========]
                 → Xuất actions a1..a10
                                               [====== Inference 2 =========]
                                               → Xuất actions a11..a20

Control thread:  a1   a2   a3   a4   a5   a6   a7   a8   a9   a10  a11
                 ↑ Lấy từ buffer liên tục ở 30Hz ↑

Nhờ overlap, robot không bao giờ phải chờ. Khi inference 1 đang chạy, control thread vẫn thực thi các actions từ inference trước. Khi inference 1 xong, buffer được bổ sung 10 actions mới.

Training-time RTC: Dạy model chấp nhận "lệch pha"

Có một vấn đề tinh tế: trong training, mỗi observation luôn khớp chính xác với action tại cùng thời điểm. Nhưng trong deployment với RTC, observation có thể cũ hơn action đang thực thi vài bước — vì policy thread mất 160ms để xử lý, trong khi robot đã di chuyển tiếp.

Ψ₀ giải quyết bằng training-time masking: trong quá trình huấn luyện, với mỗi training sample, random mask đi d tokens đầu tiên của action sequence, với d ~ Uniform(0, d_max) và d_max = 6. Điều này dạy model "đừng quá phụ thuộc vào d actions đầu tiên — chúng có thể đã bị thực thi rồi khi bạn nhận được observation".

# Training-time RTC masking
d = random.randint(0, d_max)  # d_max = 6
action_sequence = action_sequence[d:]  # Bỏ d tokens đầu
# Model học predict actions bắt đầu từ vị trí d

Kết quả: model Ψ₀ với RTC đạt success rate cao hơn 3-5% so với không RTC, và quan trọng hơn — giảm collision rate đáng kể vì robot phản ứng mượt hơn.

Biểu đồ phân tích dữ liệu kết quả đánh giá mô hình

Phân tích kết quả: Ψ₀ thực sự làm được gì?

Bảng kết quả trên 8 task thực tế (Unitree G1)

Task Success Rate Ghi chú
Handoff object 9/10 Ổn định nhất — ít subtask
Place lunch box 9/10 Navigation + placement chính xác
Pour from bottle 8/10 Cần tilt angle chính xác
Wipe bowl 7/10 Lỗi chủ yếu do trượt khăn
Fill water 6/10 Khó nhất — cần coordination hai tay
Pull tray 5/10 Lực kéo không đều → tray xoay
Stack cups Chưa report đủ data
Arrange objects Chưa report đủ data

Phân tích failure modes

Qua 80 episodes (8 tasks × 10 episodes), các nguyên nhân thất bại phổ biến nhất:

  1. Grasp failure (35%): Robot không nắm chính xác vật — ngón tay trượt hoặc không đóng đủ lực. Đây là hạn chế của Dex3-1 gripper với 3 ngón, không phải lỗi model.

  2. Navigation error (25%): Robot di chuyển đến vị trí sai, đặc biệt khi bàn làm việc không ở vị trí chuẩn. System-0 locomotion controller đôi khi drift.

  3. Timing mismatch (20%): Robot thả vật quá sớm hoặc quá muộn — action timing không khớp với trạng thái thực tế. Đây là vấn đề của open-loop action chunking.

  4. Perception failure (20%): VLM nhận diện sai vật thể, đặc biệt với vật trong suốt (cốc thủy tinh, chai nước) hoặc ánh sáng phản chiếu mạnh.

So sánh với baselines

Model Avg Success Rate Inference Time Ghi chú
Ψ₀ (RTC) 73% 160ms Foundation model, staged training
Pi0.5 65% 200ms Co-training, larger model
GR00T N1.6 58% 180ms Naive DiT, NVIDIA
Diffusion Policy 52% 500ms DDPM 100 steps, chậm
H-RDT 48% 150ms Không có VLM
EgoVLA 45% 250ms Egocentric nhưng không staged
InternVLA-M1 42% 300ms General VLA, không robot-specific
ACT 38% 80ms Nhanh nhưng kém chính xác

Ψ₀ dẫn đầu nhờ sự kết hợp của staged training (tránh negative transfer) và EgoDex pre-training (dữ liệu egocentric video chất lượng cao). Đáng chú ý, ACT tuy nhanh nhất nhưng accuracy thấp — cho thấy model capacity quan trọng hơn inference speed khi đã có RTC.

Open-loop evaluation: Nhanh nhưng không đủ

Nếu bạn muốn kiểm tra nhanh model mà không cần simulator, open-loop evaluation vẫn hữu ích cho debugging:

# Open-loop evaluation pseudocode
for obs, gt_actions in test_dataset:
    pred_actions = model.predict(obs)
    
    # So sánh predicted vs ground-truth
    l2_error = torch.norm(pred_actions - gt_actions, dim=-1).mean()
    
    # Cosine similarity cho hướng chuyển động
    cos_sim = F.cosine_similarity(pred_actions, gt_actions, dim=-1).mean()
    
    print(f"L2 error: {l2_error:.4f}, Cosine sim: {cos_sim:.4f}")

Tuy nhiên, luôn nhớ: open-loop L2 error thấp không đảm bảo closed-loop success rate cao. Trong paper Ψ₀, một số baselines có open-loop error thấp hơn Ψ₀ nhưng lại thất bại nhiều hơn trong simulator — vì chúng không robust với compounding error.

Bài học quan trọng cho bất kỳ ai làm VLA models: luôn đánh giá bằng closed-loop, open-loop chỉ để sanity check.

Checklist trước khi chạy inference

Dưới đây là danh sách kiểm tra để đảm bảo bạn không gặp lỗi phổ biến:

  • GPU: Cần ít nhất 1 GPU với 24GB VRAM (A5000/A100/H100). RTX 4090 cũng hoạt động nhưng chậm hơn.
  • Docker: Đã cài Docker với NVIDIA Container Toolkit cho SIMPLE simulator.
  • Checkpoint: Đã download đầy đủ (~4GB) và verify checksum.
  • Port: Port 8000 không bị chiếm bởi service khác.
  • Network: Server và SIMPLE container cùng network (dùng --network host).
  • Disk space: Ít nhất 50GB trống cho Docker images + video recordings.

Tổng kết

Trong bài này, chúng ta đã đi qua toàn bộ pipeline inference của Ψ₀: từ serve model qua HTTP, kết nối SIMPLE simulator cho closed-loop evaluation, đến phân tích kết quả chi tiết. Quan trọng nhất, Real-Time Chunking giải quyết bài toán latency một cách tinh tế — không hy sinh model capacity, không giảm control frequency, mà dùng 2 thread bất đồng bộ + training-time masking để robot phản ứng mượt mà.

Bài tiếp theo — bài cuối của series — chúng ta sẽ phân tích ablation studies và rút ra 5 bài học quan trọng nhất từ Ψ₀ cho bất kỳ ai muốn xây dựng foundation model cho robot.


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.

Bài viết liên quan

NEWTutorial
Hướng dẫn GigaBrain-0: VLA + World Model + RL
vlaworld-modelreinforcement-learninggigabrainroboticsmanipulation

Hướng dẫn GigaBrain-0: VLA + World Model + RL

Hướng dẫn chi tiết huấn luyện VLA bằng World Model và Reinforcement Learning với framework RAMP từ GigaBrain — open-source, 3.5B params.

12/4/202611 phút đọc
NEWTutorial
StarVLA: Xây dựng VLA Model mô-đun
vlastarvlarobot-manipulationaideep-learningqwen-vlflow-matchingiclr-2026

StarVLA: Xây dựng VLA Model mô-đun

Hướng dẫn chi tiết xây dựng Vision-Language-Action model với StarVLA — framework mô-đun kiểu Lego từ ICLR 2026, hỗ trợ 4 kiến trúc action head.

12/4/202611 phút đọc
NEWTutorial
Hướng dẫn fine-tune NVIDIA GR00T N1
vlahumanoidnvidiaisaac-labfine-tuningdeep-learninggrootsim2real

Hướng dẫn fine-tune NVIDIA GR00T N1

Hướng dẫn chi tiết fine-tune VLA model GR00T N1 cho humanoid robot với Isaac Lab và dữ liệu AGIBOT World — từ cài đặt đến inference.

12/4/202612 phút đọc