VnRoboVnRobo
Về chúng tôiBảng giáBlogLiên hệ
🇺🇸ENĐăng nhậpDùng thử miễn phí
🇺🇸EN
VnRobo logoVnRobo logo

Hạ tầng AI cho robot công nghiệp thế hệ mới.

Sản phẩm

  • Tính năng
  • Bảng giá
  • Kiến thức
  • Dịch vụ

Công ty

  • Về chúng tôi
  • Blog
  • Liên hệ

Pháp lý

  • Chính sách bảo mật
  • Điều khoản sử dụng

© 2026 VnRobo. Bảo lưu mọi quyền.

Được tạo với♥tại Việt Nam
VnRoboVnRobo
Về chúng tôiBảng giáBlogLiên hệ
🇺🇸ENĐăng nhậpDùng thử miễn phí
🇺🇸EN
  1. Trang chủ
  2. Blog
  3. unifolm-vla + G1 (Bài 4): fine-tune Qwen2.5-VL-7B, LoRA
humanoidhumanoidvlafine-tuningqwen2.5-vlloradeepspeedunitree-g1tutorial

unifolm-vla + G1 (Bài 4): fine-tune Qwen2.5-VL-7B, LoRA

Fine-tune unifolm-vla từ checkpoint Qwen2.5-VL-7B-Instruct (vì Unifolm-VLM-0 chưa public) — approach chính thức 8-GPU DeepSpeed và workaround single-GPU QLoRA.

Nguyễn Anh Tuấn6 tháng 6, 20268 phút đọcCập nhật: 15 thg 9, 2026
unifolm-vla + G1 (Bài 4): fine-tune Qwen2.5-VL-7B, LoRA

unifolm-vla + Unitree G1 (Bài 4): fine-tune từ Qwen2.5-VL-7B — 8-GPU và single-GPU LoRA

Đây là bài 4 của series unifolm-vla + Unitree G1. Bài trước đã chuẩn bị dataset ở RLDS format. Bài này: fine-tune mô hình VLA.

Vấn đề: Unifolm-VLM-0 chưa công khai

unifolm-vla có 2 thành phần:

  • VLM backbone: Qwen/Qwen2.5-VL-7B-Instruct — công khai trên HuggingFace ✅
  • Action head: weight đặc biệt để predict robot actions
  • Unifolm-VLM-0: checkpoint sau khi Unitree đã continued-pretrain trên robot data — chưa công khai ❌ (thời điểm viết bài)

Repo chính thức tham chiếu đến Unifolm-VLM-0 nhưng path là placeholder, không tải được. Giải pháp: fine-tune trực tiếp từ Qwen2.5-VL-7B-Instruct — VLM đã biết nói chuyện về thế giới, chỉ cần học thêm cách điều khiển robot.

Trade-off khi dùng Qwen2.5-VL-7B-Instruct thay Unifolm-VLM-0:

Metric Unifolm-VLM-0 Qwen2.5-VL-7B-Instruct
Robot knowledge prior Cao (đã pretrain trên robot) Thấp (chỉ có visual knowledge)
Số demo cần thiết ~30-50 demos ~80-150 demos
Convergence speed Nhanh (~30 epochs) Chậm hơn (~80-120 epochs)
Final performance Tốt hơn Thấp hơn ~15-20%
Availability ❌ Not public ✅ Public

Kết luận thực tế: với 100-150 demos và ~120 epochs, Qwen2.5-VL-7B-Instruct đạt ~80% performance của Unifolm-VLM-0 trên task đơn giản. Đủ để test và học.

Approach A: 8-GPU Full Fine-tune (Official)

Đây là cách chính thức trong repo — cần 8× GPU NVIDIA.

GPU requirements

Setup VRAM tổng Training time (100 demos)
8× RTX 4090 192GB ~6 giờ
8× A100 40GB 320GB ~3 giờ
4× A100 80GB 320GB ~4 giờ

Modify config để dùng checkpoint công khai

Tìm file config training và sửa pretrained_model_path:

bash
cd ~/unifolm_ws/unifolm-vla

# Tìm file config
find . -name "*.yaml" -path "*/config/*" | head -10

# Sửa path checkpoint
# Thay:  pretrained_model_path: "/path/to/Unifolm-VLM-0"
# Thành: pretrained_model_path: "$HOME/models/Qwen2.5-VL-7B-Instruct"
yaml
# src/unifolm_vla/config/train_config.yaml (ví dụ)

model:
  # THAY ĐỔI: dùng Qwen2.5-VL-7B-Instruct thay Unifolm-VLM-0
  pretrained_model_path: "/home/user/models/Qwen2.5-VL-7B-Instruct"
  
dataset:
  rlds_data_dir: "/home/user/datasets/g1_pickplace_rlds"
  dataset_name: "g1_pickplace"
  robot_type: "g1_dex3"
  
training:
  num_epochs: 120          # tăng từ ~80 lên 120 vì bắt đầu từ checkpoint không chuyên
  batch_size: 4            # per GPU
  learning_rate: 1e-4
  warmup_steps: 200        # tăng warmup vì model cần adapt nhiều hơn
  save_every_n_epochs: 10
  
  # DeepSpeed settings (do NOT change)
  gradient_checkpointing: true
  bf16: true

Chạy training

bash
conda activate unifolm
cd ~/unifolm_ws/unifolm-vla

accelerate launch \
  --config_file src/unifolm_vla/config/deepseeds/deepspeed_zero2.yaml \
  --num_processes 8 \
  src/unifolm_vla/training/train_unifolm_vla.py

Terminal output mong đợi:

code
[DeepSpeed] Using ZeRO Optimization Stage 2
Epoch 1/120 | Step 25 | Loss: 2.847 | LR: 5.0e-5
Epoch 1/120 | Step 50 | Loss: 2.341 | LR: 1.0e-4
...
Epoch 10/120 | Val Loss: 1.234 | Saved checkpoint: ./checkpoints/epoch_10/
...
Epoch 120/120 | Val Loss: 0.487 | Best checkpoint: epoch_110

Loss target: bắt đầu ~2.5-3.0, sau 120 epochs nên xuống ~0.4-0.6 cho task đơn giản.

Approach B: Single-GPU QLoRA (Workaround cho beginner)

Nếu chỉ có 1× RTX 4090 (24GB), đây là cách fine-tune Qwen2.5-VL-7B với LoRA qua thư viện PEFT. Lưu ý: đây là custom script, không có trong repo chính thức. Bạn cần tích hợp thủ công với unifolm-vla action head.

Setup

bash
conda activate unifolm
pip install peft bitsandbytes transformers accelerate

# Verify
python -c "import peft; print('peft version:', peft.__version__)"

Custom LoRA training script

Tạo file train_lora_single_gpu.py:

python
"""
Custom single-GPU LoRA fine-tuning for unifolm-vla.
Trains Qwen2.5-VL-7B-Instruct with QLoRA on G1 robot data.
NOTE: This is a workaround — not official unifolm-vla API.
"""

import torch
import json
import numpy as np
from pathlib import Path
from transformers import (
    Qwen2VLForConditionalGeneration,
    AutoProcessor,
    BitsAndBytesConfig,
)
from peft import LoraConfig, get_peft_model, TaskType
import h5py
import glob
from torch.utils.data import Dataset, DataLoader

# ── 1. Model setup với QLoRA ──────────────────────────────────────────────────

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True,
)

model = Qwen2VLForConditionalGeneration.from_pretrained(
    "/home/user/models/Qwen2.5-VL-7B-Instruct",
    quantization_config=bnb_config,
    device_map="auto",
    torch_dtype=torch.bfloat16,
)

processor = AutoProcessor.from_pretrained(
    "/home/user/models/Qwen2.5-VL-7B-Instruct"
)

# ── 2. LoRA config ────────────────────────────────────────────────────────────

lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=16,                    # LoRA rank — tăng lên 32 nếu có đủ VRAM
    lora_alpha=32,
    target_modules=[
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj",
    ],
    lora_dropout=0.05,
    bias="none",
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Kết quả mong đợi: trainable params: ~40M / 7B (0.6%) — rất nhỏ, fit single GPU

# ── 3. Dataset ────────────────────────────────────────────────────────────────

class G1RobotDataset(Dataset):
    """Load G1 robot demos từ HDF5 format."""
    
    def __init__(self, hdf5_dir: str, instruction: str = "pick up the red cup"):
        self.files = glob.glob(f"{hdf5_dir}/train/*.hdf5")
        self.instruction = instruction
    
    def __len__(self):
        return len(self.files)
    
    def __getitem__(self, idx):
        with h5py.File(self.files[idx], 'r') as f:
            # Load first frame as observation image
            frames = f['obs/left_wrist_rgb'][:]     # shape: (T, H, W, 3)
            actions = f['action'][:]                 # shape: (T, 28)
            instruction = f['language_instruction'][()].decode()
            
        # Dùng frame giữa episode làm example
        mid_frame = frames[len(frames) // 2]  # (H, W, 3), uint8
        mid_action = actions[len(actions) // 2]  # (28,)
        
        return {
            "image": mid_frame,
            "instruction": instruction or self.instruction,
            "action": torch.tensor(mid_action, dtype=torch.float32),
        }

dataset = G1RobotDataset(
    hdf5_dir="/home/user/datasets/g1_pickplace_hdf5",
    instruction="pick up the red cup"
)
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)

# ── 4. Training loop ──────────────────────────────────────────────────────────

optimizer = torch.optim.AdamW(
    filter(lambda p: p.requires_grad, model.parameters()),
    lr=2e-4,
    weight_decay=0.01,
)

# Simple regression head để predict actions từ hidden states
action_head = torch.nn.Linear(3584, 28).to("cuda")  # 3584 = Qwen2.5-VL-7B hidden dim
head_optimizer = torch.optim.AdamW(action_head.parameters(), lr=2e-4)

num_epochs = 50  # cần nhiều hơn full fine-tune, nhưng nhanh hơn nhiều mỗi epoch

for epoch in range(num_epochs):
    total_loss = 0
    for batch in dataloader:
        # Prepare input cho VLM
        messages = [{
            "role": "user",
            "content": [
                {"type": "image", "image": batch["image"][0].numpy()},
                {"type": "text", "text": f"Robot task: {batch['instruction'][0]}. Predict action."}
            ]
        }]
        
        text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
        inputs = processor(
            text=[text],
            images=[batch["image"][0].numpy()],
            return_tensors="pt",
            padding=True
        ).to("cuda")
        
        # Forward pass — lấy hidden states
        with torch.amp.autocast("cuda", dtype=torch.bfloat16):
            outputs = model(**inputs, output_hidden_states=True)
            hidden = outputs.hidden_states[-1][:, -1, :]  # last token hidden state
            
            # Predict action
            predicted_action = action_head(hidden.float())
            target_action = batch["action"].to("cuda")
            
            loss = torch.nn.functional.mse_loss(predicted_action, target_action)
        
        optimizer.zero_grad()
        head_optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        head_optimizer.step()
        
        total_loss += loss.item()
    
    if (epoch + 1) % 10 == 0:
        print(f"Epoch {epoch+1}/{num_epochs} | Loss: {total_loss/len(dataloader):.4f}")

# ── 5. Save checkpoint ────────────────────────────────────────────────────────

save_dir = Path("./checkpoints/lora_g1_pickplace")
model.save_pretrained(save_dir / "lora_weights")
torch.save(action_head.state_dict(), save_dir / "action_head.pt")
processor.save_pretrained(save_dir / "processor")
print(f"Saved to {save_dir}")

Chạy LoRA training

bash
conda activate unifolm
python train_lora_single_gpu.py

# VRAM usage:
# Qwen2.5-VL-7B 4-bit quantized: ~6GB
# LoRA adapter: ~0.5GB
# Action head: negligible
# Activations + optimizer: ~8GB
# TỔNG: ~14-15GB → fit RTX 4090 (24GB) tốt

Kết quả mong đợi

code
trainable params: 41,943,040 || all params: 7,615,832,064 || trainable%: 0.55
Epoch 10/50 | Loss: 0.8341
Epoch 20/50 | Loss: 0.4123
Epoch 30/50 | Loss: 0.2847
Epoch 40/50 | Loss: 0.2156
Epoch 50/50 | Loss: 0.1934
Saved to ./checkpoints/lora_g1_pickplace

So sánh 2 approaches

Approach A (8-GPU) Approach B (LoRA single-GPU)
GPU cần 8× RTX 4090 1× RTX 4090
Training time ~6 giờ ~1.5 giờ
Performance Tốt hơn ~70-80% của A
Chính thức ✅ Official ❌ Custom workaround
Khó triển khai Cần multi-GPU setup Chạy ngay trên laptop

Khuyến nghị:

  • Beginner, 1 GPU: dùng Approach B để học pipeline. Performance đủ để verify end-to-end hoạt động.
  • Research / production: Approach A, hoặc thuê cloud GPU (Lambda Labs, RunPod, Vast.ai có 8× A100 ~$5-10/giờ).

Cloud GPU cho Approach A

Nếu không có 8 GPU nhưng cần chất lượng tốt:

bash
# RunPod: 8× A100 SXM4 80GB, khoảng $8/giờ
# Training 100 demos ≈ 3 giờ = $24

# Sau khi thuê:
rsync -avz $HOME/datasets/g1_pickplace_rlds/ runpod:/workspace/datasets/
rsync -avz ~/unifolm_ws/unifolm-vla/ runpod:/workspace/unifolm-vla/

# Chạy training trên cloud
accelerate launch \
  --config_file src/unifolm_vla/config/deepseeds/deepspeed_zero2.yaml \
  --num_processes 8 \
  src/unifolm_vla/training/train_unifolm_vla.py

# Download checkpoint về local
rsync -avz runpod:/workspace/unifolm-vla/checkpoints/ $HOME/checkpoints/

Monitoring training

Theo dõi loss bằng TensorBoard (nếu được log):

bash
tensorboard --logdir ./runs/

# Nếu không có TensorBoard, theo dõi qua terminal output
# Loss hội tụ tốt:
# Epoch 10: 2.1 → Epoch 50: 1.2 → Epoch 100: 0.7 → Epoch 120: 0.5

Early stopping heuristic:

  • Nếu val loss tăng 3 lần liên tiếp → dùng checkpoint tốt nhất trước đó
  • Nếu train loss giảm nhưng val loss đứng yên → đang overfit → thêm data, giảm epochs

Bài tiếp theo: Deploy inference server + kết nối G1 thật + chạy locomotion song song.


References

  • unifolm-vla GitHub
  • Qwen2.5-VL-7B-Instruct (HuggingFace)
  • PEFT / LoRA documentation
  • BitsAndBytes QLoRA
  • DeepSpeed Zero Redundancy Optimizer

Khuyến nghị công cụ

Stack train/deploy cho VLA

Train trên cloud/workstation, deploy bản tối ưu xuống Jetson hoặc robot computer.

Cloud GPU for VLA / policy training Dùng cho imitation learning, diffusion policy, RL và fine-tuning model robotics. Xem cloud GPU → NVIDIA Jetson Orin NX / Orin Nano Máy deploy edge cho perception, logging và inference đã tối ưu. Xem Jetson → Hugging Face / robotics dataset hosting Lưu dataset, checkpoint và model card để workflow LeRobot/VLA dễ chia sẻ hơn. Xem platform →

Bài viết liên quan

  • Bài 3: Data pipeline JSON → RLDS
  • Bài 5: Deploy inference server + G1 locomotion
  • GR00T N1 + G1: Fine-tuning với Isaac Lab data
NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Fleet MonitoringROS 2 IntegrationAMR Solutions
unifolm-vla-g1-series — Phần 4/5
← unifolm-vla + G1 (Bài 3): pipeline JSON → LeRobot → RLDSunifolm-vla + G1 (Bài 5): inference server và SSH tunnel →

Bài viết liên quan

Tutorial
unifolm-vla + G1 (Bài 5): inference server và SSH tunnel
humanoidvladeployPhần 5
humanoid

unifolm-vla + G1 (Bài 5): inference server và SSH tunnel

Bài cuối series: khởi động FastAPI inference server, kết nối G1 qua SSH tunnel, chạy arm VLA và locomotion đồng thời — kèm safety checklist, debug guide.

7/6/20269 phút đọc
NT
Tutorial
unifolm-vla + G1 (Bài 3): pipeline JSON → LeRobot → RLDS
humanoidvladata-pipelinePhần 3
humanoid

unifolm-vla + G1 (Bài 3): pipeline JSON → LeRobot → RLDS

Chuyển đổi dữ liệu teleoperation 3 bước: JSON (xr_teleoperate) sang LeRobot V2.1, sang HDF5, sang RLDS chuẩn cho training unifolm-vla — kèm cách verify dataset.

4/6/20266 phút đọc
NT
Tutorial
unifolm-vla + G1 (Bài 2): thu dữ liệu với xr_teleoperate
humanoidvladata-collectionPhần 2
humanoid

unifolm-vla + G1 (Bài 2): thu dữ liệu với xr_teleoperate

Hướng dẫn setup xr_teleoperate với Meta Quest 3, kết nối G1, record demo, và mẹo thu dữ liệu chất lượng cao để VLA học hành vi chính xác trên phần cứng thật.

2/6/20268 phút đọc
NT
VnRobo logoVnRobo logo

Hạ tầng AI cho robot công nghiệp thế hệ mới.

Sản phẩm

  • Tính năng
  • Bảng giá
  • Kiến thức
  • Dịch vụ

Công ty

  • Về chúng tôi
  • Blog
  • Liên hệ

Pháp lý

  • Chính sách bảo mật
  • Điều khoản sử dụng

© 2026 VnRobo. Bảo lưu mọi quyền.

Được tạo với♥tại Việt Nam