Một VLA policy có thể cần rất nhiều lần thử để học cách mở ngăn kéo, nhấc vật và đặt đúng vị trí. Tuy nhiên, thời gian thuê GPU không chỉ dành cho việc học: GPU còn chờ simulator trả observation, chờ gom đủ batch, rồi chờ chuyển từ inference sang cập nhật trọng số. RL-VLA³ giải quyết phần thời gian chờ trong hệ thống reinforcement learning cho VLA, bằng cách cho các thành phần tiến triển bất đồng bộ.
Bài hướng dẫn này đi từ ý tưởng đến một quy trình thực hành trên LIBERO với GR00T N1.5. Bạn sẽ hiểu ba nhóm worker, chuẩn bị môi trường, kiểm tra cấu hình, chạy PPO và đánh giá policy. Các lệnh là hướng dẫn được đối chiếu với mã nguồn công khai; chúng chưa được chạy training trên GPU trong quá trình biên soạn bài.
Nguồn gốc gồm repo chính thức Haoran0301/RL-VLA3, paper bản v3 và tài liệu dependency của repo. Repo hiện giới thiệu công trình tại COLM 2026. Bài dùng bản paper v3 để đọc kết quả, tránh trộn số liệu với preprint đầu.
1. Những khái niệm cần biết trước khi chạy
Vision-Language-Action, hay VLA, nhận ảnh, instruction và thông tin trạng thái robot để dự đoán action. Ví dụ, ảnh cho thấy một chiếc bát trên bàn; instruction yêu cầu đặt vật vào bát; proprioception cho biết trạng thái hiện tại của tay máy. Output thường là một action chunk, tức nhiều action liên tiếp, thay vì chỉ một lệnh đơn.
Supervised fine-tuning, hay SFT, dạy policy bắt chước demonstration. Reinforcement learning, hay RL, cho policy tương tác với môi trường, nhận reward rồi cập nhật để tăng khả năng thành công. Với người mới, hãy hình dung SFT là học từ video hướng dẫn, còn RL là tự làm bài tập có phản hồi.
Rollout là quá trình thu dữ liệu tương tác. Một trajectory chứa observation, action, reward và trạng thái kết thúc. Inference là lúc model dự đoán action. Training là lúc gradient cập nhật model. Trong distributed RL, inference và training thường dùng những bản trọng số được đồng bộ theo lịch, vì vậy chúng không nhất thiết xảy ra trên cùng worker.
LIBERO cung cấp các task manipulation trong simulation. Ở đây, chúng ta dùng suite libero_10, được cấu hình trực tiếp trong repo. Thành công trong suite này là kết quả simulation; muốn chuyển sang robot thật còn phải xử lý camera, action convention, độ trễ và đặc tính phần cứng.
2. Ý tưởng: giảm barrier giữa ba công đoạn
Trong vòng lặp đồng bộ, các worker thường phải đi cùng nhau. Nếu một môi trường render chậm hoặc một episode kéo dài, phần còn lại có thể phải chờ trước khi model inference hay learner bắt đầu bước tiếp theo. Càng nhiều môi trường, khả năng gặp một worker chậm càng đáng chú ý.
RL-VLA³ tổ chức pipeline thành ba vai trò. Simulator chạy môi trường và sinh observation. Generator giữ policy để tạo action. Trainer nhận dữ liệu và cập nhật policy. Các vai trò được tách về logic, còn việc chúng dùng chung hay riêng GPU phụ thuộc placement.
Simulator: observation -> request queue -> Generator
Simulator: env.step <- action <- Generator
Simulator: trajectory ------------------> Trainer
Generator: policy weights <------------- Trainer
Ví dụ minh họa: Simulator A đã có ảnh mới, nhưng Simulator B vẫn đang stepping. Generator có thể xử lý request từ A thay vì chờ B. Khi một batch trajectory sẵn sàng, Trainer có thể bắt đầu công việc trong lúc những rollout khác tiếp tục. Đây là cách chồng lấp công việc; một môi trường riêng lẻ vẫn phải nhận action trước khi thực hiện bước phụ thuộc action đó.
Trong mã nguồn, các đường dẫn quan trọng nằm ở rlinf/workers/env/per_env_async/, rlinf/workers/rollout/hf/ và rlinf/workers/per_env_flex_plan.py. README chỉ rõ chúng là các phần mở rộng trên nền RLinf.
Dynamic batching và fine-grained sharding
Nếu Generator inference ngay mỗi lần có một request nhỏ, GPU có thể không được sử dụng hiệu quả. Dynamic batching gom request theo hai giới hạn: kích thước batch tối đa và thời gian chờ tối đa. Batch đủ lớn thì chạy; request cũ chờ quá lâu cũng kích hoạt chạy. Hai tham số tương ứng là max_batch_size và batch_timeout_ms trong cấu hình rollout.
Đừng tăng hai giá trị này một cách máy móc. Batch lớn có thể tăng hiệu suất tính toán nhưng cần nhiều VRAM; timeout lớn có thể khiến Simulator đứng chờ. Điểm phù hợp phải được đo trên đúng model, simulator và số môi trường của bạn.
Fine-grained sharding chia môi trường thành các slot nhỏ để điều phối request linh hoạt hơn. Hãy tưởng tượng một quầy phục vụ có nhiều hàng nhỏ: người đã sẵn sàng không phải đợi toàn bộ một nhóm lớn. Trong cấu hình thực tế, số lượng môi trường trong từng slot phải khớp tổng môi trường và bản đồ routing.
3. Chuẩn bị môi trường cài đặt
Các cấu hình benchmark đi kèm dùng một node tám GPU. Đây là mốc cấu hình đã công bố, không phải tuyên bố rằng mọi máy đều cần tám GPU để hiểu framework. Một máy ít GPU hơn cần sửa đồng thời placement, environment count, routing và batch training; chỉ đặt CUDA_VISIBLE_DEVICES=0 sẽ không tự biến recipe tám GPU thành recipe một GPU.
Chuẩn bị Linux, NVIDIA driver phù hợp, dung lượng cho checkpoint và dependency, cùng CPU/RAM đủ cho nhiều MuJoCo environment. Dùng hướng dẫn RLinf installation làm tài liệu nền, nhưng giữ dependency tương thích với fork RL-VLA³. Tài liệu upstream mới hơn có thể đã thay đổi CLI hoặc model version.
Tải source archive nếu chưa có repo:
curl -fL https://github.com/Haoran0301/RL-VLA3/archive/refs/heads/main.zip \
-o RL-VLA3-main.zip
unzip RL-VLA3-main.zip
cd RL-VLA3-main
python3 -m pip install --upgrade uv
bash requirements/install.sh embodied --model gr00t --env maniskill_libero
source .venv/bin/activate
Đây là cú pháp được hỗ trợ bởi installer của fork. Script có thể tải thêm source và asset, cài các dependency native và cần quyền phù hợp ở bước system dependency. Đọc script trước khi chạy trên máy dùng chung. Lưu lại phiên bản archive hoặc commit tương ứng với lần tải để người khác tái lập được môi trường.
Kiểm tra interpreter và CUDA trước khi tải workload lớn:
python -c "import sys; print(sys.executable)"
python -c "import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.device_count())"
python -c "import rlinf, libero; print('imports OK')"
Nếu import thất bại, kiểm tra virtualenv, thư mục đang đứng và dependency log. Đừng tiếp tục sửa PPO hyperparameter để chữa lỗi cài đặt. Với headless rendering, wrapper LIBERO dùng MUJOCO_GL=egl và PYOPENGL_PLATFORM=egl; lỗi EGL cần được xử lý ở driver, thư viện và container GPU access trước.
4. Chuẩn bị checkpoint và đọc cấu hình thật
Recipe LIBERO hiện dùng GR00T, không tự chuyển sang OpenVLA hay π₀ chỉ vì dependency đã được cài. Checkpoint khởi đầu phải khớp task và observation/action converter. RLinf-Gr00t-SFT-Long là checkpoint được đường dẫn trong YAML nhắc đến.
python -m pip install huggingface_hub
hf download RLinf/RLinf-Gr00t-SFT-Long \
--local-dir models/RLinf-Gr00t-SFT-Long
export EMBODIED_PATH="$PWD/examples/embodiment"
export PYTHONPATH="$PWD:${PYTHONPATH:-}"
export LIBERO_REPO_PATH="$PWD/.venv/libero"
export MUJOCO_GL=egl
export PYOPENGL_PLATFORM=egl
export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
Nếu bạn dùng LIBERO checkout có sẵn khi cài, đổi LIBERO_REPO_PATH theo vị trí thật. Cần kiểm tra asset và init-state của suite có thể được đọc, vì import thành công chưa đảm bảo environment reset được.
Đọc YAML full async trước khi chạy. Có ba điểm dễ gây hiểu nhầm:
- Tên file chứa
env256, nhưng nội dung hiện đặtenv.train.total_num_envs: 384. Routing có tám hàng, mỗi hàng bốn slot 12 môi trường:8 × 4 × 12 = 384. - Checkpoint path mặc định nằm dưới
/ufs/models/, là đường dẫn máy của tác giả. Cần thay cảactor.model.model_pathvàrollout.model.model_path. - Recipe đặt
runner.max_epochs: 5vàsave_interval: 100. Không nên kỳ vọng một run ngắn tự lưu checkpoint phục vụ đánh giá dài hạn.
Ngoài ra, action chunk và micro batch trong YAML hiện tại khác bảng benchmark paper. Vì vậy, chạy file có tên tương tự bảng không đủ để tuyên bố tái lập chính xác số liệu công bố.
5. Chạy thử, rồi mới chạy training dài
Lệnh quick start của repo là:
bash scripts/run_libero.sh libero_col_aa_env256_pipe4
Tuy nhiên, wrapper hiện chỉ lấy tên config, không chuyển tiếp những đối số override phía sau. Với nhu cầu thay checkpoint, hãy gọi Python entrypoint trực tiếp như dưới đây. Ví dụ này giữ nguyên topology 384 môi trường của YAML và giảm thời lượng để kiểm tra pipeline; nó vẫn là workload tám GPU, không phải bài thử nhẹ trên laptop.
python examples/embodiment/train_embodied_agent.py \
--config-path "$EMBODIED_PATH/config/libero" \
--config-name libero_col_aa_env256_pipe4 \
actor.model.model_path="$PWD/models/RLinf-Gr00t-SFT-Long" \
rollout.model.model_path="$PWD/models/RLinf-Gr00t-SFT-Long" \
runner.logger.log_path="$PWD/logs/libero-aa-smoke" \
runner.max_epochs=1 \
runner.save_interval=1 \
env.train.video_cfg.save_video=false
Quan sát ba mốc: model load xong, environment reset và tạo rollout, rồi Trainer hoàn thành update. Nếu chỉ thấy model load và GPU im lặng kéo dài, hãy kiểm tra environment worker, asset path và routing. Log có gradient update mới chứng minh pipeline đã đi qua training; việc process chưa crash chưa đủ.
Recipe dùng actor-critic với GAE, discount gamma=0.99, gae_lambda=0.95 và PPO clipping. Cấu hình có value head trong actor; critic.use_critic_model: false không đồng nghĩa thuật toán không có value estimation. Xem model config GR00T để hiểu cách value head được nối vào policy.
Với beginner, advantage có thể hiểu là đánh giá action tốt hơn hay kém hơn mức policy đang kỳ vọng. PPO dùng thông tin đó để tăng xác suất action có ích, đồng thời giới hạn độ lớn cập nhật. Trong full async, còn cần theo dõi độ cũ của dữ liệu: trajectory có thể được tạo bằng policy version trước bản Trainer đang cập nhật. Chạy bất đồng bộ không loại bỏ yêu cầu kiểm soát sự chênh lệch này.
Khi smoke run thành công, tăng số epoch theo ngân sách, chọn tần suất save/eval và thư mục log riêng. Đo cả throughput lẫn success rate, thời gian tới một mức thành công mục tiêu, VRAM và queue delay. Có thể mất thêm wall-clock do checkpoint hoặc rendering video; hãy dùng cùng chính sách logging khi so sánh hai mode.
6. Thiết kế phép so sánh công bằng
Quy ước tên config dùng ss cho rollout đồng bộ và training đồng bộ, as cho rollout bất đồng bộ nhưng training đồng bộ, aa cho cả hai bất đồng bộ. col là colocated, nghĩa là các vai trò cùng chia sẻ nhóm GPU.
Một thí nghiệm dễ đọc là so sánh libero_col_ss_env256_pipe4, libero_col_as_env256_pipe4 và libero_col_aa_env256_pipe4. Đối chiếu nội dung cả ba file: cùng tên chưa đảm bảo cùng tổng môi trường, action chunk hoặc batch size. Giữ checkpoint, seed, suite, số GPU và lượng dữ liệu bằng nhau; thay đúng cơ chế muốn đo.
Nếu muốn dùng 256 môi trường như bảng paper, cần sửa cả tổng env và slot layout tương ứng, đồng thời kiểm tra constraint trong code. Chỉ override total_num_envs=256 trong khi routing vẫn cộng thành 384 là một cấu hình không nhất quán.
Một lưu ý vận hành: YAML full async hiện có batch_timeout_ms: 1000000. Giá trị rất lớn này không phải gợi ý timeout chung cho mọi workload. Nếu request không đạt batch threshold, nó có thể dẫn tới chờ dài; cần đọc cách worker áp dụng scheduler và đo hành vi thực tế trước khi tuning.
7. Inference và evaluation sau training
Inference trong quá trình RL dùng policy để lấy action, còn evaluation chạy policy đã cố định để đo kết quả. Bạn nên đánh giá checkpoint SFT ban đầu trước, sau đó dùng cùng tập reset state cho checkpoint sau RL. Như vậy, thay đổi success rate mới có ý nghĩa so sánh.
Repo có eval_embodied_agent.py. Evaluation runner đọc runner.eval_policy_path để nạp state dict bổ sung. Khi giá trị này là null, nó dùng checkpoint ở rollout.model.model_path. Ví dụ đánh giá SFT trên topology tám worker:
python examples/embodiment/eval_embodied_agent.py \
--config-path "$EMBODIED_PATH/config/libero" \
--config-name libero_col_ss_env256_pipe1 \
actor.model.model_path="$PWD/models/RLinf-Gr00t-SFT-Long" \
rollout.model.model_path="$PWD/models/RLinf-Gr00t-SFT-Long" \
+runner.eval_policy_path=null \
env.eval.total_num_envs=80 \
env.eval.video_cfg.save_video=true \
runner.logger.log_path="$PWD/logs/libero-sft-eval"
Ở snapshot được đọc, YAML chưa khai báo eval_policy_path, nên cú pháp Hydra dùng dấu + để thêm key. Chọn 80 để chia hết cho tám environment worker; đây là ví dụ smoke evaluation, không phải protocol benchmark đầy đủ. Nếu snapshot mới đã có key, bỏ dấu + khi override.
Để đánh giá policy sau RL, thay +runner.eval_policy_path=null bằng đường dẫn file state dict tương thích. Đọc định dạng checkpoint mà training backend xuất trước khi dùng: thư mục FSDP shard không tự động là file mà torch.load và load_state_dict ở rollout worker có thể nạp. Không suy đoán tên file từ ví dụ của framework khác.
Xem video để phân loại lỗi grasp, trượt vật, va chạm hoặc task dài bị bỏ dở. Đồng thời kiểm tra action normalization và observation converter vẫn khớp checkpoint. Evaluation trong simulation là bước cần thiết trước khi nghĩ tới export model hoặc tích hợp controller thật.
8. Kết quả và cách đọc mức tăng tốc
Table 4 của paper v3, Appendix A báo LIBERO + GR00T N1.5 + PPO, tám GPU, 256 môi trường:
| Chế độ | Batch môi trường/GPU | Throughput |
|---|---|---|
| Sync | 1 | 217,27 |
| Sync | 2 | 242,30 |
| Async rollout | 4 | 344,47 |
| Full async | 4 | 423,39 |
Baseline sync bốn batch đạt 240,13: so cùng cấu hình này, 423,39 tương ứng tăng khoảng 76,3%. So với baseline sync tốt nhất 242,30, mức tăng khoảng 74,7%. Đây là throughput, không phải tăng 76,3 điểm phần trăm success rate. Kết quả scaling được khảo sát từ 8 đến 256 GPU; đường success theo số bước tương đương baseline trong các trường hợp đánh giá.
Để diễn giải thực dụng, nếu throughput tăng 1,763 lần và lượng công việc giữ nguyên, phần thời gian lý tưởng tương ứng còn khoảng 1 / 1,763 = 56,7%. Đây là phép tính suy ra, không phải cam kết thời gian training end-to-end: khởi tạo, I/O, evaluation và communication vẫn tốn thời gian.
9. Checklist trước khi dùng kết quả cho dự án
Trước hết, xác nhận bạn đã cố định source version, checkpoint, suite và seed. Sau đó kiểm tra tổng số slot khớp environment count và batch training hợp lệ với world size. Tiếp theo, chạy một vòng reset–rollout–update–save–eval để phát hiện lỗi tích hợp trước khi thuê tài nguyên lâu hơn.
Khi báo cáo, ghi rõ baseline, placement, action chunk, số GPU, throughput và success protocol. Nếu phải giảm micro batch do thiếu VRAM, ghi lại thay đổi; nếu dùng 384 môi trường của YAML hiện tại, không gọi đó là tái lập nguyên vẹn thí nghiệm 256 môi trường. Phần giá trị nhất của RL-VLA³ là một thiết kế có thể đo và điều chỉnh theo bottleneck của bạn.


