# X-VLA: O primeiro modelo de fundação para robôs com soft prompts para qualquer robô, qualquer tarefa

## Visão geral

Por anos, a robótica aspirou a construir agentes capazes de seguir instruções humanas naturais e operar com destreza em diversos ambientes e corpos robóticos. Avanços recentes em LLMs e VLMs sugerem um caminho a seguir: estender essas arquiteturas de modelos de fundação para o controle corporificado, ancorando-as em ações. Isso levou ao surgimento de modelos Vision-Language-Action (VLA), com a esperança de que um único modelo generalista pudesse combinar uma compreensão semântica ampla com habilidades robustas de manipulação.

Mas treinar esses modelos é difícil. Os dados de robôs estão fragmentados entre plataformas, sensores, corpos robóticos e protocolos de coleta. A heterogeneidade aparece em todos os lugares: diferentes configurações de braços, diferentes espaços de ação, diferentes configurações de câmeras, diferentes domínios visuais e diferentes distribuições de tarefas. Essas inconsistências criam grandes deslocamentos de distribuição que tornam o pré-treinamento instável e a adaptação não confiável.

Inspirados pelo meta-aprendizado e pelo aprendizado de prompts, nos perguntamos: **"E se um modelo VLA pudesse aprender a estrutura de cada robô e conjunto de dados da mesma forma que os LLMs aprendem tarefas, por meio de prompts?"**

**X-VLA** é um framework VLA com soft prompts e flow matching que trata cada configuração de hardware como uma "tarefa" e a codifica usando um pequeno conjunto de embeddings aprendíveis. Esses **Soft Prompts** capturam variações de embodiment e específicas do domínio, orientando o Transformer desde os estágios iniciais da fusão multimodal. Com esse mecanismo, o X-VLA pode conciliar morfologias de robôs, tipos de dados e configurações de sensores diversos dentro de uma única arquitetura unificada.

  <img
    src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/xvla-architecture.png"
    alt="XVLA Architecture"
    style="max-width: 100%; height: auto; width: 800px;"
  />

Construído a partir de codificadores Transformer puros, o X-VLA escala naturalmente com o tamanho do modelo e a diversidade do conjunto de dados. Em 6 benchmarks de simulação e 3 robôs reais, os Soft Prompts superam consistentemente os métodos existentes no tratamento de diferenças de hardware e de domínio. O X-VLA-0.9B, treinado em 290 mil episódios abrangendo sete plataformas robóticas, aprende uma política generalista agnóstica ao corpo (embodiment) na Fase I e se adapta eficientemente a novos robôs na Fase II simplesmente aprendendo um novo conjunto de prompts, mantendo o backbone congelado.

  <img
    src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/xvla-architecture2.png"
    alt="XVLA Architecture 2"
    style="width: 60%; height: auto;"
  />

Com apenas 1% dos parâmetros ajustados (9M), o X-VLA-0.9B atinge um desempenho próximo ao do π₀ em LIBERO e Simpler-WidowX, apesar de usar **300× menos parâmetros treináveis**. Ele também demonstra uma forte destreza no mundo real com demonstrações mínimas, incluindo dobrar tecidos em menos de dois minutos.

  <img
    src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/xvla-fold.png"
    alt="XVLA fold visualization"
    style="width: 95%; max-width: 1100px; height: auto;"
  />

X-VLA mostra que a inteligência robótica generalista não requer arquiteturas cada vez mais complexas, apenas a maneira certa de absorver a heterogeneidade. Soft Prompts oferecem um mecanismo simples e escalável para unificar dados robóticos diversos, abrindo caminho para modelos de fundação robótica adaptáveis e cross-embodiment.

## Instalação

Após instalar o LeRobot, instale as dependências do X-VLA:

```bash
pip install -e ".[xvla]"
```

Se você instalou o LeRobot a partir do PyPI:

```bash
pip install 'lerobot[xvla]'
```

## Início rápido

### Uso Básico

Para usar o X-VLA na sua configuração do LeRobot, especifique o tipo de política como:

```bash
policy.type=xvla
```

### Avaliando checkpoints pré-treinados

Exemplo de avaliação com LIBERO:

```bash
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
```

## Checkpoints Disponíveis

### 🎯 Modelo Base

**[lerobot/xvla-base](https://huggingface.co/lerobot/xvla-base)**

Uma instanciação de 0,9B parâmetros do X-VLA, treinada com um cuidadosamente projetado processamento de dados e receita de aprendizado. O pipeline de treinamento consiste em duas fases:

- **Fase I: Pré-treinamento** - Pré-treinado em 290 mil episódios de Droid, Robomind e Agibot, abrangendo sete plataformas em cinco tipos de braços robóticos (de configuração de braço único a bi-manual). Ao aproveitar soft prompts para absorver variações específicas de cada encarnação, o modelo aprende uma política generalista agnóstica em relação à encarnação.

- **Fase II: Adaptação de Domínio** - Adaptado para políticas implantáveis em domínios-alvo. Um novo conjunto de prompts suaves é introduzido e otimizado para codificar a configuração de hardware do novo domínio, enquanto o backbone pré-treinado permanece congelado.

### Pontos de verificação de simulação

**[lerobot/xvla-libero](https://huggingface.co/lerobot/xvla-libero)**

Alcança uma taxa de sucesso de 93% nos benchmarks LIBERO. Ajustado a partir do modelo base para tarefas de simulação.

**[lerobot/xvla-widowx](https://huggingface.co/lerobot/xvla-widowx)**

Ajustado fino no BridgeData para experimentos de pick-and-place em plataformas compactas WidowX. Demonstra capacidades robustas de manipulação.

### 🤖 Pontos de verificação do mundo real

**[lerobot/xvla-folding](https://huggingface.co/lerobot/xvla-folding)**

Um modelo de manipulação ágil ajustado, treinado no conjunto de dados de alta qualidade Soft-FOLD para dobrar tecidos. Alcança uma taxa de sucesso de 100% em 2 horas de dobramento contínuo de tecidos.

**[lerobot/xvla-agibot-world](https://huggingface.co/lerobot/xvla-agibot-world)**

Otimizado para tarefas de manipulação ágil do robô AgileX.

**[lerobot/xvla-google-robot](https://huggingface.co/lerobot/xvla-google-robot)**

Adaptado para as plataformas de robôs da Google.

## Treinando X-VLA

### Configuração de Treinamento Recomendada

Ao fazer o fine-tuning do X-VLA para um novo embodiment ou tarefa, recomendamos não congelar o VLM e também definir `policy.dtype=bfloat16` para evitar erros de OOM.

```bash
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
```

### Parâmetros de Treinamento Explicados

| Parâmetro                  | Padrão | Descrição                                    |
| -------------------------- | ------- | ---------------------------------------------- |
| `freeze_vision_encoder`    | `false` | Não congele os pesos do codificador de visão do VLM   |
| `freeze_language_encoder`  | `false` | Não congele os pesos do codificador de linguagem do VLM |
| `train_policy_transformer` | `true`  | Permitir que as camadas do transformador de política sejam treinadas       |
| `train_soft_prompts`       | `true`  | Permitir que prompts suaves sejam treinados                    |

**💡 Melhor prática**: Para a adaptação da Fase II a novas incorporações, não congele os codificadores do VLM e treine também o transformer de política e os soft prompts.

### Exemplo: Treinamento em Robô Bimanual

```bash
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
```

💡 **Desempenho ideal:** Se você tiver recursos computacionais suficientes e quiser alcançar o melhor desempenho no ajuste fino do X-VLA, você deve seguir a estratégia oficial de ajuste fino:

**🔥 Ajuste fino completo de todos os componentes com um esquema de taxa de aprendizado personalizado**

Para garantir uma otimização estável, o Vision-Language Model (VLM) deve ser treinado com apenas 1/10 da taxa de aprendizado base, enquanto todos os outros componentes usam a taxa de aprendizado completa. Essa proporção de taxa de aprendizado é crucial para alcançar um desempenho de finetuning forte e estável. Isso já é feito por padrão para você. ❕Nota

Conseguir um desempenho totalmente alinhado ao reportado oficialmente pode exigir um agendamento adicional de aquecimento (warm-up) da taxa de aprendizado para soft-prompts, o que pode trazer melhorias menores. Recomendamos implementar isso no seu pipeline de treinamento personalizado para obter os melhores resultados.

## Conceitos Fundamentais

### 1. Modos de Ação

O X-VLA utiliza um sistema de **Action Registry** para lidar com diferentes espaços de ação e encarnações. O parâmetro `action_mode` define como as ações são processadas, quais funções de perda são utilizadas e como as previsões são pós-processadas.

#### Modos de Ação Disponíveis

| Modo de Ação      | Dimensão da Ação              | Descrição                                 | Caso de Uso                             |
| ---------------- | ----------------------- | ------------------------------------------- | ------------------------------------ |
| `ee6d`           | 20                      | Efetor final com xyz, rotação 6D, garra | Configurações de braço duplo com controle espacial |
| `joint`          | 14                      | Espaço conjunto com garra                    | Robôs de controle conjunto direto          |
| `agibot_ee6d`    | 20                      | Variante do AGI-bot com perda MSE               | Plataformas de bots de AGI                    |
| `so101_bimanual` | 20 (modelo), 12 (real)   | Robô bimanual SO101                        | Tarefas de manipulação bimanual          |
| `auto`           | 20 (modelo), auto (real) | Detecta automaticamente a dimensão da ação a partir do conjunto de dados        | **Recomendado** para novos robôs       |

#### Por que os Modos de Ação Importam

Quando você tem um checkpoint pré-treinado como `lerobot/xvla-base` treinado com `action_dim=20` e deseja treinar em um conjunto de dados com uma dimensão de ação diferente (por exemplo, 14 para braços bimanuais), você não pode simplesmente reduzir a dimensão da ação. O modo de ação orquestra:

1. **Cálculo da perda**: diferentes funções de perda para diferentes componentes de ação (MSE para articulações, BCE para garfos, etc.)
2. **Pré-processamento**: zerar os canais do garfo, preencher as dimensões
3. **Pós-processamento**: Aplicar sigmoid aos logits do garfo, remover padding

#### Exemplo: Espaço de Ações BimanualSO101

O modo de ação `so101_bimanual` trata a incompatibilidade entre a saída do modelo (20D) e o controle do robô real (12D):

```python
# 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
```

Veja a implementação de [action_hub.py](https://github.com/huggingface/lerobot/blob/main/src/lerobot/policies/xvla/action_hub.py) para mais detalhes.

#### Modo de Ação Automática (Recomendado)

O modo de ação `auto` é a maneira mais fácil de usar o X-VLA com qualquer robô. Ele detecta automaticamente a dimensão de ação do seu conjunto de dados e trata o preenchimento/corte:

```bash
lerobot-train \
  --policy.path="lerobot/xvla-base" \
  --policy.action_mode=auto \
  --policy.max_action_dim=20 \
  ...
```

**Como funciona:**

- Lê `action_feature.shape[-1]` do seu conjunto de dados (por exemplo, 7 para Franka)
- As saídas do modelo `max_action_dim` (padrão 20) para compatibilidade com pré-treinamento
- A perda é calculada **apenas nas dimensões reais**: `MSE(pred[:,:,:real_dim], target[:,:,:real_dim])`
- O pós-processamento reduz a saída de volta para `real_dim` para controle de robô

Isso elimina a necessidade de criar modos de ação personalizados para a maioria dos robôs.

### 2. IDs de domínio

IDs de domínio são identificadores aprendíveis para diferentes configurações de robôs e configurações de câmeras. Eles permitem que o X-VLA distinga entre:

- Robôs diferentes (Robô 1 vs Robô 2)
- Diferentes configurações de câmera (cam1 vs cam2)
- Diferentes combinações (Robot1-cam1-cam2 vs Robot1-cam1 vs Robot2-cam1)

#### Definindo IDs de Domínio

**Durante o treinamento**: Por padrão, domain_id é definido como 0 para o treinamento geral.

**Durante a avaliação**: especifique o domain_id que corresponde à configuração de treinamento do seu checkpoint.

```python
# Example: LIBERO checkpoint uses domain_id=3
domain_id = 3
```

O domain_id é adicionado automaticamente às observações pelo `XVLAAddDomainIdProcessorStep` no pipeline de pré-processamento.

O modelo `lerobot/xvla-base` foi treinado nos seguintes IDs de domínio. É recomendado escolher aquele que mais se assemelha ao seu robô/configuração:

#### Conjuntos de dados para ajuste fino

| Nome do Conjunto de Dados     | ID do domínio |
| ---------------- | --------- |
| 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. Etapas do Processador

O X-VLA requer etapas específicas de pré-processamento e pós-processamento para um funcionamento adequado.

#### Etapas de Pré-processamento Necessárias

1. **XVLAImageToFloatProcessorStep**: Converte imagens do intervalo [0, 255] para o intervalo [0, 1]
2. **XVLAImageNetNormalizeProcessorStep**: Aplica a normalização do ImageNet (necessária para o backbone do VLM)
3. **XVLAAddDomainIdProcessorStep**: Adiciona domain_id às observações

#### Exemplo de Processador Personalizado

Para os ambientes LIBERO, um processador personalizado converte a observação canônica no formato de entrada no qual o X-VLA foi treinado:

```python
from lerobot.policies.xvla.processor_xvla import LiberoProcessorStep

processor = LiberoProcessorStep()
# Builds the 9D state from the canonical 8D state, with the end-effector rotation in 6D
# Rotates the wrist camera back, since the LIBERO integration rotates every camera by 180°
```

### 4. Parâmetros de Configuração

Principais parâmetros de configuração para X-VLA:

```python
# 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
```

## Criando Modos de Ação Personalizados

Se o seu robô possui um espaço de ações exclusivo, você pode criar um modo de ação personalizado:

### Etapa 1: Defina seu espaço de ações

```python
from lerobot.policies.xvla.action_hub import BaseActionSpace, register_action
import torch
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
```

### Etapa 2: Use o Modo de Ação Personalizado

```bash
lerobot-train \
  --policy.action_mode=my_custom_robot \
  --dataset.repo_id=YOUR_DATASET \
  --policy.path="lerobot/xvla-base" \
  ...
```

## Tópicos Avançados

### Suporte a múltiplas câmeras

O X-VLA suporta múltiplas visões de câmera por meio do parâmetro `num_image_views`:

```python
# 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
```

### Pipeline de Pré-processamento Personalizado

Crie um pipeline de pré-processamento personalizado para o seu ambiente:

```python
from lerobot.processor import PolicyProcessorPipeline
from lerobot.policies.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
    ]
)
```

### Lidando com diferentes dimensões de ação

Quando o seu conjunto de dados tem menos dimensões de ação do que o modelo pré-treinado:

**Opção 1 (Recomendada)**: Use o modo de ação `auto`

```bash
# 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
```

**Opção 2**: Use um modo de ação predefinido com padding embutido

```python
# Model expects 20D, dataset has 12D
# Action mode handles padding internally
action_mode = "so101_bimanual"  # Pads 12 → 20
```

**Opção 2**: Crie um modo de ação personalizado que mapeia as dimensões explicitamente

```python
@register_action("my_mapped_action")
class MappedActionSpace(BaseActionSpace):
    dim_action = 20
    REAL_DIM = 12

    def _pad_to_model_dim(self, x):
        # Custom padding logic
        ...
```

## Solução de problemas

### Problemas comuns

**Problema**: "Divergência na dimensão da ação"

- **Solução**: Verifique se o seu `action_mode` corresponde ao espaço de ações do seu robô. Crie um modo de ação personalizado, se necessário.

**Problema**: "Valores de imagem fora da faixa [0, 1]"

- **Solução**: Certifique-se de que as imagens sejam pré-processadas com `XVLAImageToFloatProcessorStep` antes da normalização.

**Problema**: "Domain ID não encontrado"

- **Solução**: Verifique se `XVLAAddDomainIdProcessorStep` está presente no seu pipeline de pré-processamento com o domain_id correto.

**Problema**: "Baixa taxa de sucesso em nova incorporação"

- **Solução**:
  1. Verifique se o seu action_mode está correto
  2. Verifique se os soft prompts estão sendo treinados (`train_soft_prompts=True`)
  3. Garanta o pré-processamento adequado (normalização do ImageNet, domain_id)
  4. Considere aumentar as etapas de treinamento

**Problema**: "Falta de memória durante o treinamento"

- **Solução**:
  1. Reduza `chunk_size` (por exemplo, de 32 para 16)
  2. Ativar o checkpointing de gradientes
  3. Reduzir o tamanho do lote
  4. Congelar mais componentes

## Citação

Se você usa X-VLA em sua pesquisa, por favor, cite:

```bibtex
@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}
}
```

## Recursos adicionais

- [Artigo X-VLA](https://arxiv.org/pdf/2510.10274)
- [Documentação do LeRobot](https://github.com/huggingface/lerobot)
- [Implementação do Registro de Ações](https://github.com/huggingface/lerobot/blob/main/src/lerobot/policies/xvla/action_hub.py)
- [Implementação do Processador](https://github.com/huggingface/lerobot/blob/main/src/lerobot/policies/xvla/processor_xvla.py)
- [Configuração do Modelo](https://github.com/huggingface/lerobot/blob/main/src/lerobot/policies/xvla/configuration_xvla.py)

## Contribuindo

Acolhemos contribuições! Se você implementou um novo modo de ação ou processador para seu robô, considere enviar um PR para ajudar a comunidade.

