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.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add ADu2021/skillXiv --skill x-vla-embodiment --agent claude-codeInstalls 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 automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/adu2021-x-vla-embodiment)More formats (shields.io, HTML) on the badges page.
---
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
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!