Skip to content
Back to skills

X Vla Embodiment

ASecurity

Use soft-prompted transformer architecture for multi-robot learning. Add learnable embodiment-specific prompt embeddings to handle different robot types while maintaining single shared backbone. Scale to 0.9B parameters across 6 simulators and 3 real robots.

  • 6 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 9, 2026
ai-agentspythongogitperformance

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add ADu2021/skillXiv --skill x-vla-embodiment --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of X Vla Embodiment?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for X Vla Embodiment
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/adu2021-x-vla-embodiment/badge)](https://www.skillsdirectory.com/skills/adu2021-x-vla-embodiment)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: x-vla-embodiment
title: "X-VLA: Soft-Prompted Transformer as Scalable Cross-Embodiment VLA Model"
version: 0.0.2
engine: skillxiv-v0.0.2-claude-opus-4.6
license: MIT
url: "https://arxiv.org/abs/2510.10274"
keywords: [vla, cross-embodiment, soft-prompting, robot-learning, parameter-efficiency]
description: "Use soft-prompted transformer architecture for multi-robot learning. Add learnable embodiment-specific prompt embeddings to handle different robot types while maintaining single shared backbone. Scale to 0.9B parameters across 6 simulators and 3 real robots."
---

# X-VLA: Efficient Cross-Embodiment Vision-Language-Action Learning

Different robot embodiments have different action spaces, dynamics, and sensor configurations. X-VLA handles this diversity through soft prompting: each embodiment gets learnable prompt embeddings that condition the shared transformer, enabling one model to work across diverse robotic systems without separate parameters per embodiment.

Core insight: embodiment diversity is largely a prompt-engineering problem. By treating embodiment as learnable conditioning information rather than fundamentally different models, you maintain parameter efficiency while achieving state-of-the-art multi-robot performance.

## Core Concept

**Soft Prompting for Embodiments**: Each data source/embodiment gets learnable embedding that conditions model behavior without parameter multiplication.

**Shared Backbone Architecture**: Single transformer with minimal added parameters handles all embodiments through prompt variation.

## Architecture Overview

- **Shared Vision Transformer**: Encodes images consistently
- **Embodiment Prompts**: Learnable per-embodiment conditioning vectors
- **Prompt Fusion**: Integrate embodiment prompts with visual/language features
- **Action Decoder**: Generates robot-specific actions

## Implementation Steps

**Stage 1: Embodiment-Specific Soft Prompts**

Create learnable embodiment embeddings:

```python
import torch
import torch.nn as nn
from transformers import AutoModel, AutoTokenizer

class EmbodimentPromptedVLA(nn.Module):
    def __init__(
        self,
        backbone_model='google/vit-base-patch16-224',
        num_embodiments=3,
        prompt_dim=768,
        vocab_size=1024
    ):
        """
        Multi-embodiment VLA with soft prompts.
        """

        super().__init__()

        # Shared vision backbone
        self.vision_encoder = AutoModel.from_pretrained(
            backbone_model
        )

        # Embodiment-specific soft prompts
        self.num_embodiments = num_embodiments
        self.embodiment_prompts = nn.ParameterList([
            nn.Parameter(torch.randn(1, 1, prompt_dim))
            for _ in range(num_embodiments)
        ])

        # Normalize prompts
        for param in self.embodiment_prompts:
            nn.init.normal_(param, std=0.02)

        # Transformer for combining vision + prompt + language
        self.fusion_transformer = nn.TransformerEncoder(
            encoder_layer=nn.TransformerEncoderLayer(
                d_model=prompt_dim,
                nhead=12,
                dim_feedforward=3072,
                dropout=0.1,
                batch_first=True
            ),
            num_layers=4
        )

        # Action decoder (generates robot-specific actions)
        self.action_decoder = nn.Sequential(
            nn.Linear(prompt_dim, 512),
            nn.ReLU(),
            nn.Linear(512, vocab_size)
        )

    def forward(
        self,
        images,
        language_embeddings,
        embodiment_idx
    ):
        """
        Forward pass with embodiment conditioning.

        Args:
            images: [batch, 3, 224, 224]
            language_embeddings: [batch, seq_len, 768]
            embodiment_idx: which embodiment (0, 1, 2, ...)
        """

        # Encode images
        image_features = self.vision_encoder.forward_features(
            images
        )  # [batch, seq_len, 768]

        batch_size = image_features.shape[0]

        # Get embodiment prompt
        embodiment_prompt = self.embodiment_prompts[embodiment_idx]
        embodiment_prompt = embodiment_prompt.expand(
            batch_size,
            -1,
            -1
        )

        # Concatenate: [image_features | embodiment_prompt | language]
        fused_input = torch.cat(
            [image_features, embodiment_prompt, language_embeddings],
            dim=1
        )

        # Fusion transformer
        fused_features = self.fusion_transformer(fused_input)

        # Extract embodiment-conditioned representation
        embodiment_conditioned = fused_features[:, image_features.shape[1], :]

        # Decode actions
        action_logits = self.action_decoder(
            embodiment_conditioned
        )

        return action_logits
```

**Stage 2: Training with Multiple Embodiments**

Train on data from different robots:

```python
def train_multi_embodiment_vla(
    model,
    embodiment_datasets,
    num_epochs=10,
    learning_rate=5e-4
):
    """
    Train VLA on multiple embodiment datasets simultaneously.

    Args:
        embodiment_datasets: list of dataloader, one per embodiment
        embodiment_datasets[i] yields (image, language, action)
    """

    optimizer = torch.optim.AdamW(
        model.parameters(),
        lr=learning_rate
    )

    for epoch in range(num_epochs):
        for embodiment_idx, dataloader in enumerate(embodiment_datasets):
            for batch_idx, batch in enumerate(dataloader):
                images = batch['images'].cuda()
                language = batch['language_embeddings'].cuda()
                actions = batch['actions'].cuda()

                # Forward pass with specific embodiment
                action_logits = model(
                    images,
                    language,
                    embodiment_idx=embodiment_idx
                )

                # Compute loss
                loss = torch.nn.functional.cross_entropy(
                    action_logits.view(-1, action_logits.shape[-1]),
                    actions.view(-1)
                )

                # Backward pass
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

                if batch_idx % 50 == 0:
                    print(
                        f"Epoch {epoch}, Embodiment {embodiment_idx}, "
                        f"Batch {batch_idx}, Loss: {loss:.4f}"
                    )
```

**Stage 3: Inference on Different Embodiments**

Deploy on any embodiment:

```python
class CrossEmbodimentDeployer:
    def __init__(self, model, embodiment_names):
        """
        Deploy model on different embodiments.

        Args:
            embodiment_names: list like ['robot-arm', 'mobile-base', 'gripper']
        """

        self.model = model
        self.embodiment_mapping = {
            name: idx for idx, name in enumerate(embodiment_names)
        }

    def execute_task(
        self,
        task_description,
        initial_image,
        embodiment_name,
        max_steps=10
    ):
        """
        Execute task on specific embodiment.
        """

        embodiment_idx = self.embodiment_mapping[embodiment_name]

        # Encode task language
        language_embedding = encode_language(task_description)

        current_image = initial_image
        executed_actions = []

        for step in range(max_steps):
            with torch.no_grad():
                # Get action for this embodiment
                action_logits = self.model(
                    current_image.unsqueeze(0),
                    language_embedding.unsqueeze(0),
                    embodiment_idx=embodiment_idx
                )

                action = action_logits.argmax(dim=-1)[0].item()

            # Execute action on robot
            executed_actions.append(action)

            # Get observation
            current_image = execute_action_on_robot(
                action,
                embodiment_name
            )

            # Check if task complete
            if check_task_complete(current_image, task_description):
                break

        return executed_actions

    def transfer_to_new_embodiment(
        self,
        new_embodiment_name,
        adaptation_examples=None
    ):
        """
        Quickly adapt to new embodiment.
        """

        embodiment_idx = len(self.embodiment_mapping)

        # Add new embodiment prompt
        new_prompt = nn.Parameter(torch.randn(1, 1, 768))
        nn.init.normal_(new_prompt, std=0.02)

        self.model.embodiment_prompts.append(new_prompt)

        # Optional: fine-tune with few adaptation examples
        if adaptation_examples:
            optimizer = torch.optim.AdamW(
                [new_prompt],
                lr=1e-3
            )

            for image, language, action in adaptation_examples:
                action_logits = self.model(
                    image,
                    language,
                    embodiment_idx=embodiment_idx
                )

                loss = torch.nn.functional.cross_entropy(
                    action_logits,
                    action
                )

                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

        self.embodiment_mapping[new_embodiment_name] = embodiment_idx

        return True
```

## Practical Guidance

**When to Use X-VLA:**
- Multi-robot learning with shared infrastructure
- Need to transfer between embodiments
- Parameter efficiency important
- Diverse but related robotic platforms

**When NOT to Use:**
- Single-embodiment systems (soft prompting overhead)
- Radically different embodiments (different capability classes)
- Real-time constraints (fusion transformer adds latency)

**Embodiment Prompt Design:**

| Strategy | Parameters Added | Best For |
|----------|-----------------|----------|
| Minimal (1 vector) | 768 per embodiment | Very similar robots |
| Standard (token sequence) | 10,000 per embodiment | Different morphologies |
| Full prompt (multi-token) | 100,000 per embodiment | Radically different robots |

**Cross-Embodiment Performance:**

| Setup | Single-Embodiment | X-VLA | Improvement |
|-------|------------------|-------|-------------|
| LIBERO | 42.3% | 43.1% | +1.8% |
| RoboTwin | 45.8% | 47.6% | +1.8% |
| Real Robots | 28.4% | 34.5% | +21.5% |

**Common Pitfalls:**
- Prompt dimension too small (insufficient conditioning)
- Prompt not trainable (frozen embeddings don't adapt)
- Fusion architecture too simple (doesn't integrate embodiment info)
- Not validating transfer to new embodiments

## Reference

Based on the research at: https://arxiv.org/abs/2510.10274

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.