LeRobot 文件
X-VLA:首個適用於任何機器人、任何任務的軟提示機器人基礎模型
並獲得增強的文件體驗
開始使用
X-VLA:首個適用於任何機器人、任何任務的軟提示機器人基礎模型
概覽
多年來,機器人技術一直渴望建立能遵循人類自然指令,並能在多種環境與機器人本體間靈活運作的代理程式(agent)。近期大規模語言模型(LLM)與視覺語言模型(VLM)的突破提供了一條前進的路徑:將這些基礎模型架構擴展至具身控制(embodied control),賦予其行動基礎。這促成了視覺-語言-動作(VLA)模型的興起,期望單一通用模型能結合廣泛的語義理解與穩健的操控技能。
但訓練此類模型十分困難。機器人數據分散在不同平台、感測器、本體與採集協議中。異質性無處不在:不同的手臂配置、不同的動作空間、不同的攝像頭設置、不同的視覺領域,以及不同的任務分佈。這些不一致性產生了巨大的分佈偏移,使得預訓練變得不穩定,適應性也變得不可靠。
受到元學習(meta-learning)與提示學習(prompt learning)的啟發,我們自問:「如果 VLA 模型能像 LLM 學習任務一樣,透過『提示(prompts)』來學習每個機器人與數據集的結構呢?」
X-VLA 是一個基於軟提示(soft-prompted)與流匹配(flow-matching)的 VLA 框架,它將每種硬體設置視為一項「任務」,並使用一組小型可學習嵌入(embeddings)對其進行編碼。這些軟提示(Soft Prompts)捕捉了本體與領域特有的變異,從多模態融合的最初階段開始引導 Transformer。透過這種機制,X-VLA 可以在單一統一架構中協調多樣的機器人形態、數據類型與感測器設置。

X-VLA 純粹由 Transformer 編碼器構建,可隨模型大小與數據集多樣性自然擴展。在 6 項模擬基準測試與 3 個真實機器人中,軟提示在處理硬體與領域差異方面一致優於現有方法。在 Phase I 中,於涵蓋七種機器人平台、共 29 萬個回合(episodes)數據上訓練的 X-VLA-0.9B 學習到了與本體無關的通用策略;在 Phase II 中,只需學習一組新的提示並保持骨幹網路凍結,即可高效適應新機器人。

僅調整 1% 的參數(900 萬),X-VLA-0.9B 在 LIBERO 與 Simpler-WidowX 上就達到了接近 π₀ 的性能,儘管使用的可訓練參數少了 300 倍。它還展現了強大的真實世界靈活性,即使只有極少的演示,包括在兩分鐘內完成摺衣服任務。

X-VLA 表明,通用的機器人智慧不需要日益複雜的架構,只需要正確吸收異質性的方法。軟提示為統一多樣化的機器人數據提供了一種簡單、可擴展的機制,為邁向可適應的跨本體機器人基礎模型鋪平了道路。
安裝
安裝 LeRobot 後,請安裝 X-VLA 依賴項目
pip install -e .[xvla]
新版本發佈後,您將能夠進行
pip install lerobot[xvla]
快速入門
基本使用
要在您的 LeRobot 配置中使用 X-VLA,請將策略類型指定為
policy.type=xvla
評估預訓練檢查點
使用 LIBERO 進行評估的範例
lerobot-eval \
--policy.path="lerobot/xvla-libero" \
--env.type=libero \
--env.task=libero_spatial,libero_goal,libero_10 \
--env.control_mode=absolute \
--eval.batch_size=1 \
--eval.n_episodes=1 \
--env.episode_length=800 \
--seed=142可用的檢查點
🎯 基礎模型
X-VLA 的 9 億(0.9B)參數實例,採用精心設計的數據處理與學習方案進行訓練。訓練流程包含兩個階段:
第一階段:預訓練 (Phase I) - 在來自 Droid、Robomind 與 Agibot 的 29 萬個回合中進行預訓練,涵蓋跨越五種類型機械臂(從單臂到雙臂設置)的七個平台。透過利用軟提示來吸收特定本體的變異,模型學習到了與本體無關的通用策略。
第二階段:領域適應 (Phase II) - 適應為目標領域的可部署策略。引入並優化一組新的軟提示以對新領域的硬體配置進行編碼,同時保持預訓練骨幹網路凍結。
模擬環境檢查點
在 LIBERO 基準測試中達到 93% 的成功率。從基礎模型針對模擬任務進行微調而成。
在 BridgeData 上微調,用於精巧型 WidowX 平台的取放實驗。展示了穩健的操控能力。
🤖 真實世界檢查點
這是一個經過微調的靈巧操控模型,在高品質的 Soft-FOLD 摺衣服數據集上訓練。在連續 2 小時的摺衣服過程中達到 100% 的成功率。
針對 AgileX 機器人靈巧操控任務進行了優化。
針對 Google 機器人平台進行了適應調整。
訓練 X-VLA
建議的訓練配置
針對新的本體或任務微調 X-VLA 時,我們建議不要凍結 VLM,並設置 policy.dtype=bfloat16 以避免記憶體不足(OOM)錯誤。
lerobot-train \
--dataset.repo_id=YOUR_DATASET \
--output_dir=./outputs/xvla_training \
--job_name=xvla_training \
--policy.path="lerobot/xvla-base" \
--policy.repo_id="HF_USER/xvla-your-robot" \
--policy.dtype=bfloat16 \
--policy.action_mode=auto \
--steps=20000 \
--policy.device=cuda \
--policy.freeze_vision_encoder=false \
--policy.freeze_language_encoder=false \
--policy.train_policy_transformer=true \
--policy.train_soft_prompts=true \訓練參數說明
| 參數 | 預設 | 說明 |
|---|---|---|
freeze_vision_encoder (凍結視覺編碼器) | false | 不要凍結 VLM 視覺編碼器權重 |
freeze_language_encoder | false | 不要凍結 VLM 語言編碼器權重 |
train_policy_transformer | true | 允許策略 Transformer 層進行訓練 |
train_soft_prompts | true | 允許軟提示進行訓練 |
💡 最佳實踐:對於 Phase II 適應新本體,不要凍結 VLM 編碼器,並且同時訓練策略 Transformer 與軟提示。
範例:在雙臂機器人上訓練
lerobot-train \
--dataset.repo_id=<USER>/bimanual-so100-handover-cube \
--output_dir=./outputs/xvla_bimanual \
--job_name=xvla_so101_training \
--policy.path="lerobot/xvla-base" \
--policy.dtype=bfloat16 \
--policy.repo_id="YOUR_USERNAME/xvla-biso101" \
--steps=3000 \
--policy.device=cuda \
--policy.action_mode=so101_bimanual \
--policy.freeze_vision_encoder=false \
--policy.freeze_language_encoder=false \
--policy.train_policy_transformer=true \
--policy.train_soft_prompts=true💡 最佳效能: 如果您有足夠的運算資源並希望達到最佳的 X-VLA 微調效能,您應該遵循官方微調策略
🔥 使用自定義學習率方案微調所有組件
為了確保優化穩定,視覺語言模型 (VLM) 必須僅以基礎學習率的 1/10 進行訓練,而所有其他組件則使用全額學習率。此學習率比例對於實現強大且穩定的微調性能至關重要。這已經預設為您完成。 ❕注意
要完全達到官方報告的效能,可能需要為軟提示添加額外的預熱學習率排程,這可以帶來微小的改進。我們鼓勵在您自定義的訓練流程中實施此操作以獲得最佳結果。
核心概念
1. 動作模式 (Action Modes)
X-VLA 使用動作註冊系統 (Action Registry) 來處理不同的動作空間與本體。action_mode 參數定義了動作如何被處理、使用哪些損失函數,以及預測結果如何進行後處理。
可用的動作模式
| 動作模式 | 動作維度 | 說明 | 使用案例 |
|---|---|---|---|
ee6d | 20 | 具備 xyz、6D 旋轉與夾爪的末端執行器 | 具備空間控制的雙臂設置 |
joint | 14 | 具備夾爪的關節空間 | 直接關節控制機器人 |
agibot_ee6d | 20 | 使用 MSE 損失函數的 AGI-bot 變體 | AGI-bot 平台 |
so101_bimanual | 20 (模型), 12 (實際) | SO101 雙臂機器人 | 雙臂操控任務 |
auto | 20 (模型), auto (實際) | 從數據集中自動偵測動作維度 | 建議用於新機器人 |
動作模式為何重要
當您有一個像 lerobot/xvla-base 這樣在 action_dim=20 下訓練的預訓練檢查點,且您想在動作維度不同的數據集上訓練(例如:雙臂機器人的 14 維)時,您不能簡單地修剪動作維度。動作模式負責協調:
- 損失計算:為不同動作組件使用不同的損失函數(關節使用 MSE,夾爪使用 BCE 等)
- 預處理:歸零夾爪通道、填充維度
- 後處理:對夾爪對數機率(logits)應用 Sigmoid、修剪填充
範例:BimanualSO101 動作空間
so101_bimanual 動作模式處理模型輸出 (20D) 與實際機器人控制 (12D) 之間的不匹配
# Model outputs 20 dimensions for compatibility
dim_action = 20
# Real robot only needs 12 dimensions
# [left_arm (6), right_arm (6)] = [joints (5) + gripper (1)] × 2
REAL_DIM = 12
# Preprocessing: Pad 12D actions to 20D for training
# Postprocessing: Trim 20D predictions to 12D for deployment詳見 action_hub.py 實作細節。
自動動作模式 (建議使用)
auto 動作模式是在任何機器人上使用 X-VLA 最簡單的方法。它會自動偵測數據集的動作維度並處理填充/修剪:
lerobot-train \
--policy.path="lerobot/xvla-base" \
--policy.action_mode=auto \
--policy.max_action_dim=20 \
...運作方式
- 從您的數據集中讀取
action_feature.shape[-1](例如:Franka 為 7) - 模型輸出
max_action_dim(預設為 20) 以保持預訓練兼容性 - 損失函數僅在實際維度上計算:
MSE(pred[:,:,:real_dim], target[:,:,:real_dim]) - 後處理將輸出修剪回
real_dim以進行機器人控制
這消除了大多數機器人需要創建自定義動作模式的需求。
2. 領域識別碼 (Domain IDs)
領域識別碼是針對不同機器人配置與攝像頭設置的可學習識別碼。它們讓 X-VLA 能夠區分:
- 不同的機器人 (機器人 1 vs 機器人 2)
- 不同的攝像頭配置 (cam1 vs cam2)
- 不同的組合 (Robot1-cam1-cam2 vs Robot1-cam1 vs Robot2-cam1)
設置領域識別碼
訓練期間:預設情況下,domain_id 設為 0 以進行一般訓練。
評估期間:指定與您檢查點訓練配置相符的 domain_id。
# Example: LIBERO checkpoint uses domain_id=3
domain_id = 3domain_id 會透過預處理流程中的 XVLAAddDomainIdProcessorStep 自動添加到觀測值 (observations) 中。
lerobot/xvla-base 模型已在以下領域識別碼上進行訓練。建議選擇最接近您機器人/配置的一個:
微調數據集
| 資料集名稱 | 領域識別碼 (Domain ID) |
|---|---|
| Bridge | 0 |
| RT1 | 1 |
| Calvin | 2 |
| libero | 3 |
| widowx-air | 4 |
| AIR-AGILEX-HQ | 5 |
| robotwin2_abs_ee | 6 |
| robotwin2_clean | 6 |
| robocasa-human | 7 |
| VLABench | 8 |
| AGIBOT-challenge | 9 |
| AIR-AGILEX | 10 |
| AIRBOT | 18 |
3. 處理器步驟 (Processor Steps)
X-VLA 需要特定的預處理與後處理步驟才能正常運作。
必要的預處理步驟
- XVLAImageToFloatProcessorStep:將圖像範圍從 [0, 255] 轉換為 [0, 1]
- XVLAImageNetNormalizeProcessorStep:套用 ImageNet 歸一化(VLM 骨幹網路所需)
- XVLAAddDomainIdProcessorStep:將 domain_id 加到觀測值中
自定義處理器範例
對於 LIBERO 環境,使用自定義處理器來處理特定的觀測格式
from lerobot.policies.xvla.processor_xvla import LiberoProcessorStep
processor = LiberoProcessorStep()
# Handles robot_state dictionary, converts rotation matrices to 6D representation
# Applies 180° image rotation for camera convention4. 配置參數
X-VLA 的關鍵配置參數
# Observation and action
n_obs_steps: int = 1 # Number of observation timesteps
chunk_size: int = 32 # Action sequence length
n_action_steps: int = 32 # Number of action steps to execute
# Model architecture
hidden_size: int = 1024 # Transformer hidden dimension
depth: int = 24 # Number of transformer layers
num_heads: int = 16 # Number of attention heads
num_domains: int = 30 # Maximum number of domain IDs
len_soft_prompts: int = 32 # Length of soft prompt embeddings
# Action space
action_mode: str = "ee6d" # Action space type (use "auto" for auto-detection)
use_proprio: bool = True # Use proprioceptive state
max_state_dim: int = 32 # Maximum state dimension
max_action_dim: int = 20 # Max action dim for padding (used by "auto" mode)
# Vision
num_image_views: int | None # Number of camera views
resize_imgs_with_padding: tuple[int, int] | None # Target image size with padding
# Training
num_denoising_steps: int = 10 # Flow matching denoising steps創建自定義動作模式
如果您的機器人具有獨特的動作空間,您可以創建自定義動作模式
步驟 1:定義您的動作空間
from lerobot.policies.xvla.action_hub import BaseActionSpace, register_action
import torch.nn as nn
@register_action("my_custom_robot")
class MyCustomActionSpace(BaseActionSpace):
"""Custom action space for my robot."""
dim_action = 15 # Your robot's action dimension
gripper_idx = (7, 14) # Gripper channel indices
def __init__(self):
super().__init__()
self.mse = nn.MSELoss()
self.bce = nn.BCEWithLogitsLoss()
def compute_loss(self, pred, target):
"""Define your loss computation."""
# Example: MSE for joints, BCE for grippers
joints_loss = self.mse(pred[:, :, :7], target[:, :, :7])
gripper_loss = self.bce(pred[:, :, self.gripper_idx],
target[:, :, self.gripper_idx])
return {
"joints_loss": joints_loss,
"gripper_loss": gripper_loss,
}
def preprocess(self, proprio, action, mode="train"):
"""Preprocess actions before training."""
# Example: Zero out grippers in proprioception
proprio_m = proprio.clone()
action_m = action.clone() if action is not None else None
proprio_m[..., self.gripper_idx] = 0.0
if action_m is not None:
action_m[..., self.gripper_idx] = 0.0
return proprio_m, action_m
def postprocess(self, action):
"""Post-process predictions for deployment."""
# Example: Apply sigmoid to gripper logits
action[..., self.gripper_idx] = torch.sigmoid(action[..., self.gripper_idx])
return action步驟 2:使用您的自定義動作模式
lerobot-train \
--policy.action_mode=my_custom_robot \
--dataset.repo_id=YOUR_DATASET \
--policy.path="lerobot/xvla-base" \
...進階主題
多攝像頭支援
X-VLA 透過 num_image_views 參數支援多個攝像頭視角
# Configure for 3 camera views
policy.num_image_views=3
# Add empty cameras if you have fewer physical cameras
policy.empty_cameras=1 # Adds 1 zero-padded camera view自定義預處理流程
為您的環境創建自定義預處理流程
from lerobot.processor import PolicyProcessorPipeline
from lerobot.policies.xvla.processor_xvla import (
XVLAImageToFloatProcessorStep,
XVLAImageNetNormalizeProcessorStep,
XVLAAddDomainIdProcessorStep,
)
# Build custom pipeline
preprocessor = PolicyProcessorPipeline(
steps=[
YourCustomProcessorStep(), # Your custom processing
XVLAImageToFloatProcessorStep(), # Required: convert to float
XVLAImageNetNormalizeProcessorStep(), # Required: ImageNet norm
XVLAAddDomainIdProcessorStep(domain_id=5), # Your domain ID
]
)處理不同的動作維度
當您的數據集動作維度少於預訓練模型時
選項 1 (建議):使用 auto 動作模式
# Automatically detects your dataset's action dimension
# Works with any robot without custom code
policy.action_mode=auto
policy.max_action_dim=20 # Match pretrained model選項 2:使用具備內置填充功能的預定義動作模式
# Model expects 20D, dataset has 12D
# Action mode handles padding internally
action_mode = "so101_bimanual" # Pads 12 → 20選項 3:創建一個顯式映射維度的自定義動作模式
@register_action("my_mapped_action")
class MappedActionSpace(BaseActionSpace):
dim_action = 20
REAL_DIM = 12
def _pad_to_model_dim(self, x):
# Custom padding logic
...疑難排解
常見問題
問題:「動作維度不匹配 (Action dimension mismatch)」
- 解決方案:檢查您的
action_mode是否與機器人的動作空間相符。如有需要,請創建自定義動作模式。
問題:「圖像值超出 [0, 1] 範圍」
- 解決方案:確保在歸一化之前,圖像已透過
XVLAImageToFloatProcessorStep進行預處理。
問題:「找不到領域識別碼 (Domain ID not found)」
- 解決方案:確保
XVLAAddDomainIdProcessorStep已在您的預處理流程中,並設置了正確的 domain_id。
問題:「新本體上的成功率低」
- 解決方案:
- 確認您的動作模式 (action_mode) 正確
- 檢查軟提示是否正在接受訓練 (
train_soft_prompts=True) - 確保正確的預處理(ImageNet 歸一化、domain_id)
- 考慮增加訓練步數
問題:「訓練期間記憶體不足 (Out of memory)」
- 解決方案:
- 減少
chunk_size(例如從 32 減至 16) - 啟用梯度檢查點 (gradient checkpointing)
- 減小批次大小 (batch size)
- 凍結更多組件
- 減少
引用
如果您在研究中使用 X-VLA,請引用:
@article{zheng2025x,
title = {X-VLA: Soft-Prompted Transformer as Scalable Cross-Embodiment Vision-Language-Action Model},
author = {Zheng, Jinliang and Li, Jianxiong and Wang, Zhihao and Liu, Dongxiu and Kang, Xirui
and Feng, Yuchun and Zheng, Yinan and Zou, Jiayin and Chen, Yilun and Zeng, Jia and others},
journal = {arXiv preprint arXiv:2510.10274},
year = {2025}
}額外資源
貢獻
我們歡迎貢獻!如果您為機器人實作了新的動作模式或處理器,請考慮提交一個 PR 以幫助社群。
在 GitHub 上更新