Bốn bài trước đã tháo gỡ VIMA từng lớp một: bài 1 về kiến trúc Cross-Attention, bài 2 về 17 task và 4 cấp tổng quát hóa, bài 3 về Object Tokenizer Mask R-CNN + ViT, và bài 4 về bộ dataset 650K trajectories từ PyBullet. Đến đây, bạn đã hiểu rõ VIMA là gì và làm được gì trong môi trường tabletop.
Nhưng còn một câu hỏi lớn còn mở: liệu VIMA có thể rời khỏi cái bàn đó không?
Đây là bài capstone của series — nơi ta xem VIMA được mở rộng như thế nào lên robot hình người với hàng chục bậc tự do (DoF), những thách thức thực sự khi làm điều đó, và tại sao bước nhảy này không đơn giản như việc đổi một con số trong config file.
Roadmap Series
Đây là bài 5/5 trong series VIMA: Prompt Đa Phương Thức cho Robot Tay Người:
| Bài | Chủ đề |
|---|---|
| Bài 1: Kiến Trúc Cross-Attention | XAttn GPT + T5 encoder, vì sao cross-attention quan trọng |
| Bài 2: VimaBench 17 Task | 17 task, 4 cấp tổng quát hóa, chạy demo benchmark |
| Bài 3: Object Tokenizer | Mask R-CNN + ViT: từ pixel thô đến token đối tượng |
| Bài 4: Dataset 650K | Thu thập dữ liệu đa nhiệm vụ quy mô lớn trong simulation |
| Bài 5 (bạn đang đọc) | Humanoid Adaptation: mở rộng lên robot hình người DoF cao |
VIMA Gốc — "Tù Nhân Của Bàn"
Hãy nhớ lại setup gốc của VIMA: một robot arm 2-finger gripper, môi trường PyBullet tabletop phẳng, và action space là SE(2) — không gian 2D trên mặt bàn.
Mỗi action trong VIMA gốc gồm hai phần:
- Pick pose: (x, y, rotation) — vị trí gripper muốn nhặt vật
- Place pose: (x, y, rotation) — vị trí gripper muốn đặt vật
Thực tế khi xem code, đây là 4 giá trị: (x, y, rotation, open/close) cho gripper. Chiều cao z là cố định, được hard-code vào simulator. Robot không cần quyết định "nhặt ở độ cao bao nhiêu" hay "nghiêng cánh tay theo góc nào" — simulator tự xử lý phần đó thông qua inverse kinematics.
Đây là lý do VIMA train được nhanh và đạt hiệu quả cao: bài toán được đơn giản hóa tối đa. Nhưng đây cũng chính là lý do tại sao không thể deploy VIMA nguyên bản lên robot thật mà không có modification đáng kể.
Nếu dùng phép so sánh: tabletop manipulation của VIMA giống như học lái xe trên đường thẳng trong mô phỏng 2D — bạn chỉ cần chọn "rẽ trái" hay "rẽ phải". Robot humanoid thật giống như phải lái xe đạp mạo hiểm trên địa hình 3D với 23 cơ bắp phối hợp đồng thời.
Humanoid Thực Sự Cần Gì?
Unitree G1 — 23 DoF
Unitree G1 là một trong những humanoid phổ biến nhất hiện nay cho nghiên cứu, với 23 bậc tự do phân bố như sau:
- Mỗi chân: 6 DoF × 2 = 12 DoF (hip pitch/roll/yaw, knee, ankle pitch/roll)
- Thắt lưng (waist): 1 DoF (xoay thân trên)
- Mỗi cánh tay: 5 DoF × 2 = 10 DoF (shoulder pitch/roll/yaw, elbow, wrist)
Bộ điều khiển cấp thấp (low-level controller) chạy ở 200 Hz dùng PD controller thuần túy:
τ = Kp(q_target - q) - Kd × q̇
Trong đó q là góc khớp hiện tại, q_target là góc mục tiêu, và τ là torque motor. Policy của chúng ta chạy ở 50 Hz, xuất ra vector q_target — tức là 23 joint position deltas mỗi timestep (20ms).
Bảng so sánh trực tiếp:
| Thông số | VIMA Tabletop | Unitree G1 Humanoid |
|---|---|---|
| Action dimension | 4D (SE(2)) | 23D (joint deltas) |
| Control frequency | N/A (sim) | 50 Hz policy / 200 Hz PD |
| End-effector | 2-finger gripper | Tay với 5-DoF wrist |
| Camera | 2 cam (front + top) | Head cam + wrist cam(s) |
| Action type | End-effector pose | Joint position offsets |
| Coordination | Single arm | Whole-body (chân + thân + tay) |
AgiBot X2 — 25–31 DoF
AgiBot X2 (humanoid open-source từ AgiBot) có nhiều biến thể với mức độ dexterity khác nhau:
- X2 Lite: ~27 DoF, cánh tay 5-DoF
- X2 Standard: 25 DoF
- X2 Pro: ~31 DoF, cánh tay 7-DoF (dexterous hơn)
- X2 Ultra: 30 DoF, payload 3 kg, tầm với 558 mm
Với 7-DoF arms như X2 Pro, mỗi cánh tay có thêm bậc tự do để "lách" qua các góc khuất — quan trọng khi làm các tác vụ như lắp ráp chính xác hay thao tác trong không gian chật hẹp. Đây là điểm khác biệt lớn so với robot arm công nghiệp 6-DoF truyền thống.
Điểm chung của cả G1 và X2: action space lớn hơn VIMA gốc rất nhiều, và phần lớn tác vụ thực tế đòi hỏi whole-body coordination — chân giữ thăng bằng, thân nghiêng để vươn tới, và hai tay phối hợp để thực hiện thao tác. Không phải chỉ điều khiển một arm độc lập như tabletop.

Chiến Lược Adaptation: Freeze Backbone, Swap Action Head
Khi muốn adapt VIMA cho humanoid, câu hỏi đầu tiên là: thay đổi cái gì và giữ lại cái gì?
VIMA có ba thành phần chính (như đã phân tích chi tiết trong bài 1):
- T5 Encoder — encode prompt đa phương thức (text tokens + image object tokens)
- XAttn GPT Decoder — cross-attention transformer xử lý observation history + prompt
- Action Head — MLP giải mã output token thành hành động cụ thể
Lý do rõ ràng để freeze T5 + XAttn GPT:
- T5 đã học biểu diễn ngữ nghĩa phong phú từ hàng tỷ văn bản — đây là sức mạnh cốt lõi của VIMA giúp nó hiểu câu lệnh như "đặt khối vuông màu đỏ vào góc phải". Knowledge này không thay đổi khi robot có 6 DoF hay 23 DoF.
- Cross-attention đã học cách kết nối prompt với observation — nó biết cách "nhìn vào" các object tokens có liên quan khi xử lý từng từ trong prompt. Capability này chuyển được sang domain mới.
- Training T5 + XAttn GPT tốn nhiều GPU-days; với data humanoid ít (vài nghìn trajectories so với 650K), sẽ bị overfitting ngay lập tức nếu fine-tune toàn bộ.
Phần duy nhất cần thay là action head — thay vì decode ra 4D end-effector pose (x, y, rotation, gripper), ta cần decode ra 23D joint position deltas.
Code: Custom Action Head 23-DoF
import torch
import torch.nn as nn
class VIMAActionHead6DoF(nn.Module):
"""Action head gốc của VIMA: end-effector 6-DoF.
Output: pick pose (3D position + 4D quaternion) và place pose tương tự.
Thực tế trong tabletop: chỉ cần x, y, rotation (z cố định).
"""
def __init__(self, d_model: int = 512):
super().__init__()
# VIMA gốc dùng 2 MLP riêng: position (3D) và rotation (4D quaternion)
self.pos_mlp = nn.Sequential(
nn.Linear(d_model, 256),
nn.ReLU(),
nn.Linear(256, 3) # xyz
)
self.rot_mlp = nn.Sequential(
nn.Linear(d_model, 256),
nn.ReLU(),
nn.Linear(256, 4) # quaternion (w, x, y, z)
)
def forward(self, x):
# x: (batch, seq_len, d_model)
return self.pos_mlp(x), self.rot_mlp(x)
class VIMAActionHead23DoF(nn.Module):
"""Action head mới: 23 joint position deltas cho Unitree G1.
Thay thế hoàn toàn action head gốc — T5 + XAttn GPT giữ nguyên.
Output: delta q cho 23 joints (12 chân + 1 waist + 10 tay)
"""
def __init__(
self,
d_model: int = 512,
n_joints: int = 23,
action_scale: float = 0.05, # nhỏ để tránh joint jump ngay từ đầu
):
super().__init__()
self.n_joints = n_joints
self.action_scale = action_scale
# Một MLP duy nhất: d_model → 512 → 256 → n_joints
self.joint_mlp = nn.Sequential(
nn.Linear(d_model, 512),
nn.ReLU(),
nn.Dropout(p=0.1),
nn.Linear(512, 256),
nn.ReLU(),
nn.Linear(256, n_joints)
)
# Zero-init layer cuối: robot đứng yên ngay từ bước đầu training
nn.init.zeros_(self.joint_mlp[-1].weight)
nn.init.zeros_(self.joint_mlp[-1].bias)
def forward(self, x):
# x: (batch, seq_len, d_model)
joint_deltas = self.joint_mlp(x) # (batch, seq_len, 23)
return joint_deltas * self.action_scale # scale nhỏ để PD controller không bị shock
Điểm kỹ thuật quan trọng: khởi tạo layer cuối với zeros. Khi bắt đầu fine-tune, policy xuất ra delta = 0 (robot đứng yên hoàn toàn), từ từ học cách di chuyển từng khớp. Điều này an toàn hơn nhiều so với random initialization có thể khiến robot chuyển động bất thường ngay từ bước đầu tiên — rất quan trọng với hardware thật có thể bị hỏng.
Training Config
import torch
# 1. Load pre-trained VIMA (T5 + XAttn GPT + action head cũ)
vima_model = load_pretrained_vima("VIMA-200M.ckpt")
# 2. Freeze toàn bộ backbone — không có gradient nào chạy qua T5 hay XAttn GPT
for name, param in vima_model.named_parameters():
if "action_head" not in name:
param.requires_grad = False
# 3. Swap action head: 4D end-effector → 23D joint deltas
vima_model.action_head = VIMAActionHead23DoF(
d_model=512,
n_joints=23,
action_scale=0.05
)
# 4. Optimizer chỉ nhìn thấy action head mới
optimizer = torch.optim.AdamW(
filter(lambda p: p.requires_grad, vima_model.parameters()),
lr=1e-4,
weight_decay=1e-5
)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer, T_max=10_000, eta_min=1e-6
)
# 5. Loss: MSE giữa predicted deltas và expert deltas từ teleoperation
criterion = torch.nn.MSELoss()
# Kiểm tra số params được train:
trainable = sum(p.numel() for p in vima_model.parameters() if p.requires_grad)
total = sum(p.numel() for p in vima_model.parameters())
print(f"Trainable: {trainable:,} / {total:,} ({100*trainable/total:.2f}%)")
# Ví dụ với VIMA-200M: Trainable: 141,335 / 200,141,335 (0.07%)
Chỉ ~0.07% tham số được train. Đây là lý do tại sao chiến lược này khả thi với lượng data humanoid ít: ít param hơn = ít data cần hơn để converge mà không bị overfitting backbone.
Data Gap — Thách Thức Không Thể Né Tránh
Đây là vấn đề lớn nhất khi chuyển từ tabletop sang humanoid: khoảng cách dữ liệu.
VIMA được train trên 650K trajectories — tất cả từ simulation PyBullet, tất cả là tabletop tasks với arm đơn giản và oracle scripts tự động sinh ra. Với humanoid manipulation, bức tranh khác hoàn toàn:
| Dataset | Loại | Kích thước | Phủ sóng |
|---|---|---|---|
| VIMA-Data (tabletop) | Simulation (oracle) | 650K traj | 17 task types, đồng đều |
| Hy-Embodied UMI | Bimanual real robot | ~2.000 giờ | Thao tác đa dạng |
| AgiBot World | Humanoid hỗn hợp | ~1M traj | Nav + manipulation |
| DROID / BridgeV2 | Single-arm real | ~60K traj | Kitchen tasks |
| Dataset lab riêng | Bimanual sim | ~5–20K traj | Task-specific, ít đa dạng |
Vấn đề không chỉ là số lượng. Humanoid manipulation data thường khó thu thập theo ba chiều:
1. Thu thập tốn kém: Cần teleoperation với hệ thống dual-arm phức tạp — exoskeleton, VR controllers, hoặc puppet arms. Mỗi giờ data có thể tốn vài chục giờ setup và vận hành.
2. Đa dạng thấp: Mỗi task trong VIMA có ~50K trajectories (nhờ oracle scripts tự sinh vô hạn biến thể). Humanoid dataset thường chỉ có vài nghìn trajectories cho mỗi task, với ít biến thể hơn.
3. Nhiễu từ human teleoperator: Oracle scripts của VIMA tạo ra demonstrations hoàn hảo theo đường đi tối ưu. Human teleoperating humanoid thật thường có jitter, hesitation, và sub-optimal paths — data noisy hơn đáng kể.
Hãy dùng phép tương tự: nếu VIMA-tabletop giống như dạy một đứa trẻ di chuyển ngón tay trên mặt bàn 2D với 650.000 bài tập, thì humanoid adaptation giống như dạy cùng đứa trẻ đó chơi đàn cello — kiến thức về âm nhạc (prompt understanding) chuyển được, nhưng 23 cơ và khớp cần học cách phối hợp hoàn toàn mới, và chỉ có vài nghìn buổi luyện tập.

Approach 1: Teacher-Student Distillation
Một trong những chiến lược tiềm năng nhất để bridge data gap là teacher-student distillation — khai thác knowledge từ VIMA gốc để dạy policy humanoid-specific.
Ý tưởng cốt lõi: VIMA gốc (teacher) đã học rất tốt cách hiểu multimodal prompts và lập kế hoạch manipulation — dù là trong tabletop. Knowledge về "đây là tác vụ pick-and-place", "vật đỏ phải đến vị trí đích này" là knowledge về semantic task understanding, không phụ thuộc vào morphology robot.
Cách hoạt động qua 3 bước:
- Teacher (VIMA gốc, frozen): nhìn vào cùng scene và output action distribution
π_teacher(a | s, prompt)— phân phối xác suất trên action space của nó - Student (humanoid policy nhỏ hơn): cũng nhìn scene, nhưng output
π_student(q_delta | s, prompt)— joint deltas trong action space 23D - Distillation loss: student học cách "think like VIMA" về task planning, nhưng "act like a humanoid" về execution:
# Distillation loss kết hợp: imitation từ expert + alignment với teacher reasoning
loss_imitation = criterion(predicted_deltas, expert_deltas) # từ teleoperation data
loss_distil = kl_divergence(student_latent, teacher_latent) # align intermediate representations
loss_total = loss_imitation + alpha * loss_distil # alpha = 0.1 thường work well
Một paper liên quan quan trọng là Refined Policy Distillation (RPD, 2025): distill VLA policy thành RL student, sau đó cho student tự fine-tune qua reinforcement learning để vượt qua teacher — vì student không còn bị ràng buộc bởi imitation loss và có thể khám phá solutions tốt hơn teacher.
Lợi thế thực tế: Student nhỏ hơn nhiều (có thể chỉ vài triệu params thay vì 200M), inference nhanh hơn đủ để đạt 50 Hz trên GPU nhúng như Jetson Orin của G1, và có thể chuyên biệt hóa cho morphology và sensor setup của từng robot cụ thể.
Approach 2: LoRA Fine-tuning
Thay vì freeze hoàn toàn XAttn GPT, một approach khác là dùng Low-Rank Adaptation (LoRA) — chèn các adapter matrix nhỏ vào bên trong transformer layers mà không thay đổi weights gốc:
from peft import LoraConfig, get_peft_model, TaskType
# Chỉ apply LoRA vào XAttn GPT, giữ nguyên T5 (T5 đã đủ tốt)
lora_config = LoraConfig(
r=16, # rank của adapter matrix
lora_alpha=32, # scaling factor (thường = 2*r)
target_modules=[ # chỉ attention projections, không phải FFN
"q_proj",
"v_proj",
"cross_attn.q_proj",
"cross_attn.v_proj",
],
lora_dropout=0.05,
bias="none",
task_type=TaskType.FEATURE_EXTRACTION
)
# Apply LoRA vào XAttn GPT decoder của VIMA
xattn_gpt_with_lora = get_peft_model(vima_model.xattn_gpt, lora_config)
xattn_gpt_with_lora.print_trainable_parameters()
# Ví dụ: trainable params: 1,572,864 || all params: 124,439,552 (1.26%)
Với LoRA, XAttn GPT được phép adapt nhẹ sang domain humanoid: học lại cách attend vào visual tokens từ nhiều camera hơn (head cam + wrist cam), cách xử lý observation space phức tạp hơn — trong khi vẫn giữ được phần lớn pretrained knowledge.
Khi nào dùng approach nào:
| Approach | Data cần | Training time | Inference | Dùng khi |
|---|---|---|---|---|
| Frozen backbone + new head | <2K traj | ~2-4 giờ | Nhanh nhất | Prototyping, data cực ít |
| LoRA + new head | 2K-50K traj | ~6-12 giờ | Nhanh | Cân bằng tốt giữa data và perf |
| Full fine-tune | >100K traj | 2-5 GPU-days | Bình thường | Data nhiều, budget lớn |
| Teacher-student | Bất kỳ | Linh hoạt | Nhanh nhất (student nhỏ) | Cần deploy real-time trên hardware giới hạn |
Ước Tính Hiệu Suất
Dựa trên tổng hợp từ các paper liên quan về transfer learning cho robot manipulation, dưới đây là ước tính hiệu suất tương đối khi adapt VIMA sang humanoid G1:
| Metric | VIMA Tabletop (gốc) | Frozen + New Head | LoRA + New Head |
|---|---|---|---|
| L1 Success (sim, humanoid) | N/A | ~72–78% | ~80–85% |
| L2 Success (sim, humanoid) | N/A | ~50–58% | ~60–68% |
| Training data cần | 650K traj | ~5K traj | ~10K traj |
| Training time (A100) | 8 GPU-days | ~4 giờ | ~8 giờ |
| Inference latency | N/A (tabletop) | ~18ms (~55 Hz) | ~21ms (~48 Hz) |
| Params được train | 100% | ~0.07% | ~0.8% + head |
Lưu ý: đây là ước tính từ tổng hợp literature, không phải kết quả ablation chính thức trên VIMA-humanoid. Số thực tế phụ thuộc rất nhiều vào chất lượng, đa dạng, và cách thu thập data humanoid training.
Sim2Real cho Humanoid — Domain Adaptation Thực Tế
Kể cả khi đã fine-tune thành công trong simulation, vẫn còn một khoảng cách lớn giữa sim và robot thật — đặc biệt với humanoid vì số lượng joints nhiều hơn, dynamics phức tạp hơn, và contact-rich manipulation khó simulate chính xác.
Ba kỹ thuật phổ biến để bridge sim2real gap:
1. Domain Randomization (DR): Ngẫu nhiên hóa các tham số vật lý khi train trong sim — mass và inertia của vật thể, hệ số friction, độ sáng và màu sắc, camera noise, actuator delay. Policy buộc phải học robust behaviors thay vì overfit vào physics cụ thể của một simulator.
Ví dụ với Isaac Lab:
# Randomize joint PD gains để policy học robust với actuator variation
joint_kp_randomizer = UniformNoise(
operation="scale",
distribution_parameters=[0.8, 1.2] # ±20% Kp variation
)
scene.add_randomizer("joint_kp", joint_kp_randomizer)
2. Privileged Teacher Learning: Train một "teacher" policy trong sim với thông tin đầy đủ — ground-truth state, perfect dynamics, không có noise. Student policy chỉ nhận sensor observations như robot thật: RGB images, IMU, joint encoders. Student học từ teacher qua distillation trong khi teacher giúp navigate qua phần khó của state space.
Approach này được SENTINEL (2024) và nhiều paper humanoid locomotion dùng thành công — student policy cuối cùng robust hơn teacher vì học được cách xử lý noise và uncertainty.
3. Adaptive Dynamics Estimation: Sau khi deploy lên robot thật, dùng một estimator nhỏ để ước tính tham số dynamics thực tế (payload, joint friction, contact stiffness) và truyền vào policy như context vector bổ sung. Policy học trong sim với nhiều "context versions" khác nhau, khi deploy thì estimate context thực tế và dùng tương ứng.
Thách Thức Multi-Camera và Latency
Một thách thức kỹ thuật thường bị bỏ qua là multi-camera fusion trong humanoid.
VIMA gốc dùng 2 camera cố định (front + top) với trường nhìn tốt cho tabletop tasks. Humanoid thật có:
- Head camera: góc nhìn rộng, ổn định với locomotion (nhưng thay đổi khi robot cúi người)
- Wrist camera(s): góc nhìn gần, quan trọng cho fine manipulation (nhưng rung theo arm motion)
- Tùy robot: có thể có thêm stereo cameras, depth sensors, hay fisheye cameras
Để integrate nhiều camera vào VIMA's object tokenizer pipeline:
class MultiCamObjectTokenizer(nn.Module):
"""Mở rộng VIMA's object tokenizer cho multi-camera humanoid."""
def __init__(self, n_cameras: int = 2, d_token: int = 256):
super().__init__()
self.n_cameras = n_cameras
# Mỗi camera có object detector riêng (shared weights, different inputs)
self.obj_detector = MaskRCNN(pretrained=True) # shared
self.vit_encoder = ViTObjectEncoder(d_token=d_token) # shared
# Camera embedding để phân biệt tokens từ các camera khác nhau
self.cam_embed = nn.Embedding(n_cameras, d_token)
def forward(self, images: list[torch.Tensor], cam_ids: list[int]):
all_tokens = []
for img, cam_id in zip(images, cam_ids):
objects = self.obj_detector(img)
tokens = self.vit_encoder(objects) # (n_obj, d_token)
cam_emb = self.cam_embed(torch.tensor(cam_id))
tokens = tokens + cam_emb # add camera identity embedding
all_tokens.append(tokens)
return torch.cat(all_tokens, dim=0) # concat tất cả object tokens
Về latency, yêu cầu 50 Hz (20ms/step) là rất chặt cho một transformer 200M params. Một số kỹ thuật tối ưu:
- Chạy T5 encoder và object tokenizer song song (prompt không đổi trong episode → cache kết quả)
- Dùng TensorRT hoặc torch.compile để tối ưu XAttn GPT inference
- Xem xét distillation sang smaller student (vài chục M params) nếu cần deploy trên Jetson Orin NX
Kết Luận Series — VIMA Là Building Block
Sau 5 bài, chúng ta đã đi từ "VIMA là gì" đến "làm thế nào để đưa VIMA lên robot hình người". Nhìn lại những gì đã học được:
Bài 1 — Kiến trúc: Cross-attention không phải lựa chọn ngẫu nhiên — nó quan trọng vì cho phép prompt conditioning ở mọi layer của decoder, không chỉ ở đầu như GPT-style prefix. Đây là nền tảng của khả năng zero-shot generalization. Và knowledge này chuyển được hoàn toàn sang humanoid domain.
Bài 2 — Benchmark: 17 tasks và 4 cấp generalization (L1→L4) là framework đánh giá nghiêm túc hơn hầu hết robot learning benchmarks. Khi adapt sang humanoid, L4 (novel task) performance là thước đo trung thực nhất.
Bài 3 — Object Tokenizer: Mask R-CNN + ViT biến ảnh thô thành object tokens — đây là lý do 1% data đã đủ để vượt baseline. Object-centric representation học semantics tốt hơn pixel-level. Khi adapt sang multi-camera humanoid, ta chỉ cần mở rộng tokenizer, không cần thay thế.
Bài 4 — Dataset: 650K trajectories từ PyBullet với oracle scripts là nền tảng mạnh vì phủ sóng rộng. Nhưng đây cũng là điểm yếu lớn nhất khi adapt sang humanoid — không có 650K humanoid trajectories nào tương đương để train từ đầu.
Bài 5 (bài này) — Humanoid Adaptation: Freeze backbone (T5 + XAttn GPT), swap action head 4D → 23D. Data gap là thách thức số 1. Teacher-student và LoRA là hai approaches khả thi nhất hiện tại.
Con Đường Phía Trước
VIMA là building block mạnh cho multimodal prompt robots — nhưng để thực sự vượt khỏi tabletop và hoạt động hiệu quả trên humanoid, hệ sinh thái cần ba thứ vẫn đang trong quá trình xây dựng:
1. Dữ liệu humanoid quy mô lớn. Datasets như Hy-Embodied UMI với 2.000 giờ dữ liệu bimanual hay AgiBot World đang xây dựng nền tảng này — nhưng cần scale thêm 10–100× để so sánh được với 650K tabletop trajectories có độ đa dạng cao.
2. Action representation phù hợp với whole-body. Joint delta là điểm khởi đầu tốt, nhưng tác vụ đòi hỏi phối hợp cả chân, thân và tay (picking something off the floor while walking) cần action space hierarchical hơn: high-level goal (end-effector target) + low-level joint control, với một lớp whole-body controller ở giữa.
3. Sim2real pipeline tốt hơn cho contact-rich manipulation. Isaac Sim và MuJoCo đang thu hẹp physics gap, nhưng manipulation với nhiều contact points (vặn vít, lắp ráp, dệt vải) vẫn là challenge lớn mà simulation chưa model chính xác được.
Những ai đang theo dõi field này đang chứng kiến một xu hướng rõ ràng: multimodal prompting (ý tưởng cốt lõi của VIMA) đang trở thành standard interface cho robot manipulation. Sự khác biệt giữa các paper hiện đại không còn là "có dùng multimodal prompts không" mà là "scale to bao nhiêu DoF, bao nhiêu data, sim2real gap được bridge tốt đến đâu, và inference có đủ nhanh để chạy real-time không".
Từ tabletop 4D đến humanoid 23D không chỉ là thêm con số — đó là bước nhảy đòi hỏi rethink toàn bộ data pipeline, action representation, và deployment strategy. VIMA cho ta một điểm xuất phát mạnh: pretrained backbone với khả năng multimodal understanding tốt. Phần còn lại — data, action space, sim2real — là công việc phía trước của cả cộng đồng nghiên cứu robot Việt Nam và thế giới.
Tóm Tắt
- VIMA gốc: tabletop, action space SE(2) 4D, single arm 2-finger gripper
- Unitree G1: 23 DoF (12 chân + 1 waist + 10 tay), PD controller 200 Hz, policy 50 Hz
- AgiBot X2: 25–31 DoF tùy variant; X2 Pro có 7-DoF arms dexterous
- Chiến lược: freeze T5 + XAttn GPT, swap action head từ 4D → 23D joint deltas
- Safe initialization: zero-init layer cuối của action head để tránh joint shock ngay từ đầu
- Data gap: humanoid data = vài nghìn traj vs. 650K tabletop — thách thức số 1
- Frozen approach: ~0.07% params trainable, ~4 giờ training trên 5K traj
- LoRA approach: ~0.8% + head trainable, backbone adapt nhẹ, balance tốt hơn
- Teacher-student: VIMA làm teacher → student nhỏ hơn, nhanh hơn, phù hợp hardware
- Sim2real: domain randomization + privileged teacher + adaptive dynamics
- Multi-camera: camera embedding để phân biệt head cam vs. wrist cam trong object tokenizer
- Latency: cache T5 prompt encoding, TensorRT/compile để đạt 50 Hz target
- Kết luận series: VIMA là building block mạnh; cần data humanoid quy mô lớn để thực sự generalize



