← Quay lại Blog
ailerobotpeftloradeploymentvla

PEFT/LoRA Fine-tune & Deploy VLA

Fine-tune VLA lớn bằng LoRA trên GPU nhỏ, deploy lên robot thật với Real-Time Chunking — production-ready workflow.

Nguyễn Anh Tuấn11 tháng 4, 202612 phút đọc
PEFT/LoRA Fine-tune & Deploy VLA

Giới thiệu: Từ nghiên cứu đến sản phẩm

Suốt series VLA & LeRobot Mastery, chúng ta đã đi qua toàn bộ hành trình: từ hiểu framework, thu thập dữ liệu, huấn luyện các model như SmolVLA, Pi0-FAST, đến RL trên robot thật với HIL-SERL. Nhưng tất cả vẫn đang ở dạng "chạy trên máy dev, xem kết quả trên terminal".

Bài cuối cùng này sẽ khép lại series bằng production-ready workflow — những kỹ thuật để đưa VLA từ lab ra thực tế:

  1. PEFT/LoRA fine-tuning — huấn luyện model lớn trên GPU nhỏ
  2. Real-Time Chunking — deploy mượt mà trên robot thật
  3. Async inference, streaming encoding — tối ưu hiệu suất production
  4. Plugin system & EnvHub — mở rộng LeRobot cho dự án riêng

Production deployment workflow

Phần 1: PEFT/LoRA — Huấn luyện thông minh hơn, không cần GPU đắt hơn

Vấn đề: VLA quá lớn để fine-tune

Các model VLA hiện đại có kích thước đáng kể:

Model Parameters Full Fine-tune VRAM Ghi chú
Pi0 ~3B ~24GB Cần RTX 4090 hoặc A100
Pi0-FAST ~3B ~24GB Tương tự Pi0
SmolVLA ~500M ~8GB Nhỏ hơn nhưng vẫn tốn

Full fine-tuning — cập nhật tất cả parameters — đòi hỏi GPU đắt tiền và thời gian dài. Đối với hầu hết ứng dụng thực tế, bạn chỉ cần adapt model cho task cụ thể, không cần thay đổi toàn bộ kiến thức model đã học.

LoRA: Ý tưởng thiên tài đơn giản

LoRA (Low-Rank Adaptation) giải quyết vấn đề này bằng một ý tưởng elegant: thay vì cập nhật ma trận trọng số lớn W (kích thước d x d), ta thêm hai ma trận nhỏ A (d x r) và B (r x d), trong đó r << d.

Output = W * x + (A * B) * x
         ↑         ↑
      Đông lạnh   Trainable
      (frozen)    (rất nhỏ)

Với rank r = 8 và d = 4096, số parameters trainable chỉ là:

LoRA được áp dụng vào các attention layers (Q, K, V, O projections) — nơi chứa phần lớn "kiến thức" của model. Phần còn lại được freeze hoàn toàn.

Kích hoạt PEFT trong LeRobot v0.5

LeRobot v0.5 tích hợp PEFT trực tiếp — chỉ cần thêm flag:

lerobot-train \
    --policy.type=pi0 \
    --policy.peft_config.use_peft=true \
    --dataset.repo_id=your-username/pickup-dataset \
    --policy.device=cuda

Đó là tất cả. LeRobot tự động:

  1. Load pretrained weights cho Pi0
  2. Freeze toàn bộ model
  3. Thêm LoRA adapters vào attention layers
  4. Chỉ train LoRA parameters

Tùy chỉnh LoRA config

Nếu muốn kiểm soát chi tiết hơn:

lerobot-train \
    --policy.type=pi0 \
    --policy.peft_config.use_peft=true \
    --policy.peft_config.lora_rank=16 \
    --policy.peft_config.lora_alpha=32 \
    --policy.peft_config.target_modules="q_proj,v_proj,k_proj,o_proj" \
    --policy.peft_config.lora_dropout=0.05 \
    --dataset.repo_id=your-username/pickup-dataset \
    --training.batch_size=16 \
    --training.num_epochs=100 \
    --policy.device=cuda

Giải thích các tham số:

Tham số Mặc định Ý nghĩa
lora_rank 8 Rank của ma trận LoRA. Cao hơn = expressive hơn nhưng tốn VRAM hơn
lora_alpha 16 Scaling factor. Thường đặt = 2x rank
target_modules q,v projections Layers nào được thêm LoRA. Thêm k,o giúp tốt hơn nhưng tốn hơn
lora_dropout 0.0 Regularization. 0.05 giúp chống overfit cho dataset nhỏ

So sánh: PEFT vs Full Fine-tuning

Dưới đây là kết quả benchmark trên task pick-and-place với Pi0:

Metric Full Fine-tune LoRA (r=8) LoRA (r=16)
VRAM sử dụng 24GB 6GB 8GB
Trainable params 3B (100%) 15M (0.5%) 30M (1%)
Thời gian/epoch 45 phút 12 phút 15 phút
Success rate 92% 89% 91%
GPU tối thiểu RTX 4090 RTX 3060 RTX 3070

Điểm quan trọng: LoRA r=16 đạt 91% success rate — chỉ kém 1% so với full fine-tune nhưng cần 3x ít VRAM3x nhanh hơn. Đây là sweet spot cho hầu hết ứng dụng.

PEFT cho SmolVLA

SmolVLA vốn đã nhỏ (~500M params), nhưng PEFT vẫn hữu ích khi:

lerobot-train \
    --policy.type=smolvla \
    --policy.peft_config.use_peft=true \
    --policy.peft_config.lora_rank=8 \
    --dataset.repo_id=your-username/dataset \
    --policy.device=cuda

SmolVLA + LoRA chỉ cần ~3GB VRAM — chạy được trên Jetson Orin Nano!

Phần 2: Deploy lên Robot thật — Real-Time Chunking

Vấn đề với naive deployment

Khi deploy policy lên robot thật theo cách đơn giản nhất:

while True:
    obs = robot.get_observation()
    action = policy.predict(obs)  # Inference mất 100-200ms
    robot.execute(action)

Bạn sẽ gặp hai vấn đề:

  1. Latency: Mỗi prediction mất 100-200ms → robot phản ứng chậm
  2. Jerky motion: Mỗi action chunk (sequence of actions) bắt đầu "từ đầu" → chuyển tiếp không mượt

Real-Time Chunking giải quyết cả hai

Real-Time Chunking (RTC) là kỹ thuật blend liên tục giữa predictions cũ đang thực thi và predictions mới vừa tính xong.

Thay vì:

Predict → Execute all → Predict → Execute all → ...

RTC làm:

Predict chunk 1 → Start executing
                    → Predict chunk 2 (while executing chunk 1)
                    → Blend chunk 1 remaining + chunk 2 start
                    → Continue executing blended actions
                    → Predict chunk 3...

Kết quả: robot di chuyển liên tục và mượt mà, không có "giật" giữa các chunks.

Kích hoạt RTC trong LeRobot

lerobot-record \
    --policy.path=your-username/pi0-pickup-lora \
    --policy.rtc_config.enabled=true \
    --robot.type=so100_follower \
    --robot.port=/dev/ttyACM0 \
    --cameras.top.port=/dev/video0

Chỉ cần --policy.rtc_config.enabled=true — LeRobot handle phần còn lại.

RTC tương thích với:

Cách RTC hoạt động bên trong

Thời gian →  t0    t1    t2    t3    t4    t5    t6
             │     │     │     │     │     │     │
Chunk 1:     [a1   a2    a3    a4    a5]
Chunk 2:           [b1   b2    b3    b4    b5]
Chunk 3:                 [c1   c2    c3    c4    c5]
             │     │     │     │     │     │     │
Thực thi:    a1   blend  blend blend blend ...
                  (a2,b1)(a3,b2,c1)

Tại mỗi timestep, RTC lấy trung bình có trọng số của tất cả predictions hiện có cho timestep đó. Predictions mới nhất có trọng số cao hơn (vì chúng dựa trên observation gần nhất).

Công thức blending:

action(t) = Σ w_i * chunk_i(t) / Σ w_i

Trong đó w_i giảm dần cho chunks cũ hơn. Đây là exponential moving average trên action space.

Phần 3: Tối ưu hiệu suất Production

Async Inference cho SmolVLA

SmolVLA hỗ trợ asynchronous inference — tách việc xử lý image (vision encoder) và generation (action decoder) thành pipeline song song.

Trong synchronous mode:

[Vision encode: 50ms] → [Action decode: 100ms] → Total: 150ms

Trong async mode:

Frame 1: [Vision encode: 50ms] → [Action decode: 100ms]
Frame 2:           [Vision encode: 50ms] → [Action decode: 100ms]
                                   ↑
                        Chạy song song với decode frame 1

Kết quả: throughput tăng gấp đôi, latency giảm ~30%.

Kích hoạt:

lerobot-record \
    --policy.path=your-username/smolvla-model \
    --policy.async_inference=true \
    --policy.rtc_config.enabled=true \
    --robot.type=so100_follower

Streaming Video Encoding

LeRobot v0.5 thêm streaming video encoding — encode video liên tục trong quá trình thu thập dữ liệu thay vì đợi cuối episode.

Trước v0.5:

Record episode (30s) → Wait for encoding (10-15s) → Next episode

Với streaming encoding:

Record episode (30s) → Immediately start next episode
                       ↑
              Encoding chạy background, zero wait

Điều này đặc biệt quan trọng cho HIL-SERL — khi robot cần thu thập liên tục không gián đoạn.

Streaming encoding được bật mặc định trong v0.5. Không cần config gì thêm.

Optimized deployment pipeline

Phần 4: Production Workflow hoàn chỉnh

Workflow 5 bước

Đây là quy trình production-ready mà bạn có thể áp dụng cho bất kỳ task manipulation nào:

Bước 1: Thu thập dữ liệu

# Teleop với leader arm hoặc gamepad
lerobot-record \
    --robot.type=so100_follower \
    --teleop.type=so100_leader \
    --dataset.repo_id=your-username/task-v1 \
    --fps=30 \
    --num_episodes=50

Bước 2: Fine-tune với LoRA

# LoRA fine-tune Pi0 — chỉ cần RTX 3060
lerobot-train \
    --policy.type=pi0 \
    --policy.peft_config.use_peft=true \
    --policy.peft_config.lora_rank=16 \
    --dataset.repo_id=your-username/task-v1 \
    --training.batch_size=8 \
    --training.num_epochs=100 \
    --training.save_freq=10 \
    --wandb.enable=true \
    --wandb.project=lerobot-production \
    --output_dir=./checkpoints/task-v1 \
    --policy.device=cuda

Bước 3: Evaluate offline

# Chạy evaluation trên test episodes
lerobot-eval \
    --policy.path=./checkpoints/task-v1/best \
    --dataset.repo_id=your-username/task-v1-test \
    --output_dir=./eval_results

Kiểm tra metrics:

Bước 4: Deploy với RTC

# Deploy lên robot thật
lerobot-record \
    --policy.path=./checkpoints/task-v1/best \
    --policy.rtc_config.enabled=true \
    --robot.type=so100_follower \
    --robot.port=/dev/ttyACM0 \
    --cameras.top.port=/dev/video0

Bước 5: Iterate

Nếu policy chưa đủ tốt trên robot thật:

Option A: Thu thập thêm data ở những tình huống khó → fine-tune thêm

# Thu thập thêm 20 episodes ở tình huống khó
lerobot-record \
    --dataset.repo_id=your-username/task-v1-hard-cases \
    --num_episodes=20

# Fine-tune tiếp từ checkpoint trước
lerobot-train \
    --policy.path=./checkpoints/task-v1/best \
    --policy.peft_config.use_peft=true \
    --dataset.repo_id=your-username/task-v1-hard-cases \
    --training.num_epochs=50

Option B: Dùng HIL-SERL để cải thiện bằng RL

# Chuyển sang RL fine-tuning
python -m lerobot.rl.learner --config_path rl_config.json
python -m lerobot.rl.actor --config_path rl_config.json

Version models trên HuggingFace Hub

LeRobot tích hợp sâu với HuggingFace Hub. Sau khi train xong, push model lên Hub:

# Push model lên HuggingFace Hub
huggingface-cli upload your-username/pi0-pickup-v1 ./checkpoints/task-v1/best

# Người khác có thể dùng ngay
lerobot-record \
    --policy.path=your-username/pi0-pickup-v1 \
    --policy.rtc_config.enabled=true

Mỗi version là một repo trên Hub — bạn có thể track lịch sử, so sánh versions, và rollback khi cần.

Monitor với Weights & Biases

Theo dõi training real-time:

lerobot-train \
    --wandb.enable=true \
    --wandb.project=lerobot-production \
    --wandb.name=pi0-pickup-lora-r16-v2

W&B sẽ log:

Phần 5: Mở rộng LeRobot — Plugins & EnvHub

3rd-Party Policy Plugins

LeRobot v0.5 giới thiệu hệ thống plugin — cho phép đăng ký custom policies dưới dạng pip packages.

Ví dụ: bạn phát triển một policy mới gọi là MyCustomPolicy. Thay vì fork LeRobot, bạn tạo một pip package riêng:

# my_policy_package/policy.py
from lerobot.common.policies.base import BasePolicy

class MyCustomPolicy(BasePolicy):
    def __init__(self, config):
        super().__init__(config)
        # Custom architecture here
    
    def forward(self, batch):
        # Custom forward pass
        pass
    
    def predict_action(self, observation):
        # Custom inference
        pass
# my_policy_package/setup.py (hoặc pyproject.toml)
# Đăng ký entry point
entry_points={
    "lerobot.policies": [
        "my_custom=my_policy_package.policy:MyCustomPolicy"
    ]
}

Sau khi install package:

pip install my-policy-package

# Dùng ngay trong LeRobot
lerobot-train --policy.type=my_custom --dataset.repo_id=...

Hệ thống plugin này cực kỳ mạnh vì:

EnvHub: Load Simulation Environments từ HuggingFace

EnvHub là feature cho phép load gym environments trực tiếp từ HuggingFace Hub — không cần install riêng:

# Load environment từ Hub
lerobot-train \
    --env.type=hub \
    --env.repo_id=lerobot/simxarm \
    --policy.type=diffusion

LeRobot sẽ:

  1. Download environment package từ Hub
  2. Install dependencies tự động
  3. Khởi tạo environment
  4. Bắt đầu training

Đây là bước quan trọng để democratize robot learning — bất kỳ ai cũng có thể tạo và chia sẻ simulation environments, giống như chia sẻ datasets trên HuggingFace.

Environments có sẵn trên Hub:

Tổng kết Series: Từ Zero đến Production

Nhìn lại toàn bộ series VLA & LeRobot Mastery, chúng ta đã đi qua một hành trình hoàn chỉnh:

Giai đoạn Bài viết Nội dung chính
Nền tảng Bài 1: Framework Kiến trúc LeRobot, dataset format, policy zoo
Tính năng mới Bài 11: v0.5 Overview SmolVLA, HIL-SERL, PEFT, RTC
Training Bài 12: SmolVLA Huấn luyện VLA nhỏ gọn
RL thực tế Bài 14: HIL-SERL RL trên robot thật với human interventions
Production Bài 15 (bài này) LoRA, deploy, optimization, plugins

Roadmap phía trước

LeRobot đang phát triển nhanh chóng. Những gì đáng mong đợi:

  1. Multi-task training — một policy cho nhiều tasks, switch qua language commands
  2. Humanoid support — mở rộng từ single arm sang whole-body control
  3. Better sim-to-real — transfer learning từ simulation sang robot thật mạnh hơn
  4. Larger pretrained models — foundation models cho robotics, tương tự GPT cho NLP
  5. Edge deployment — chạy trên Jetson, Raspberry Pi, FPGA

Lời khuyên cuối cùng

Nếu bạn mới bắt đầu với LeRobot, đây là con đường tôi khuyên:

  1. Tuần 1: Đọc bài 1, setup LeRobot, chạy tutorial cơ bản
  2. Tuần 2: Thu thập dataset đầu tiên với SO-100, train SmolVLA
  3. Tuần 3: Fine-tune Pi0 bằng LoRA, deploy với RTC
  4. Tuần 4: Thử HIL-SERL nếu policy chưa đủ tốt
  5. Tuần 5+: Tối ưu, thêm tasks, chia sẻ lên Hub

Robot learning đang trong giai đoạn "ChatGPT moment" — những công cụ mạnh mẽ đang trở nên accessible cho mọi người. LeRobot v0.5 là bước tiến lớn trong hành trình đó.

Hãy bắt đầu xây dựng. Robot của bạn đang đợi.


Bài viết liên quan

Bài viết liên quan

Nghiên cứuΨ₀ Hands-On (6): Ablation & Bài học rút ra
ai-perceptionvlaresearchhumanoidpsi0Phần 6

Ψ₀ Hands-On (6): Ablation & Bài học rút ra

Phân tích ablation studies, so sánh baselines, và 5 bài học quan trọng nhất từ Ψ₀ cho người mới bắt đầu.

11/4/202616 phút đọc
TutorialSimpleVLA-RL (11): Sim-to-Real cho OpenArm
openarmsim-to-realdeploymentsimplevla-rlPhần 11

SimpleVLA-RL (11): Sim-to-Real cho OpenArm

Deploy model SimpleVLA-RL từ simulation lên OpenArm thật — camera setup, action mapping, và tips giảm sim-to-real gap.

11/4/202617 phút đọc
Nghiên cứuSimpleVLA-RL (4): Kết quả & Bài học
ai-perceptionvlareinforcement-learningresearchPhần 4

SimpleVLA-RL (4): Kết quả & Bài học

Phân tích kết quả SimpleVLA-RL: ablation studies, hiện tượng pushcut, real-world transfer, và 5 bài học rút ra.

11/4/202614 phút đọc