Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Important

🌟 Stay up to date at opendrivelab.com!

🌏 UniVLA

📄 Paper | 🚀 Demo Page (Coming Soon)

✒️ Qingwen Bu, Y. Yang, J. Cai, S. Gao, G. Ren, M. Yao, P. Luo, H. Li
📧 Primary Contact: Qingwen Bu (buqingwen@opendrivelab.com)

🔥 Highlights

  • A recipe towards generalist policy by planning in a unified, embodiment-agnostic action space.
  • A novel approach for extracting task-centric latent actions from cross-embodiment videos.
  • A VLA that achieves state-of-the-art results on multiple benchmarks with compute-efficient training.

Table of Contents

🎥 Demo

Real-world robot experiments.

Store the screwdriver (1x speed)Clean the cutting board (1x speed)Fold towel twice (1x speed)
Task1.mp4
Task2.mp4
Task3.mp4
Stack the tower of hanoi (1x speed)
Task4_ours_success_case_1.mp4
Task4_ours_success_case_2.mp4
Task4_ours_success_case_3.mp4

📢 News

  • [2025/05] The code of UniVLA v1.0 is released. Please check it out!

🤗 Model Zoo

Model NameBackboneHF PathNote
lam-stage-1 - univla-latent-action-model The stage-1 latent action model trained on OpenX and Ego4D.
lam-stage-2 - univla-latent-action-model The stage-2 latent action model trained on OpenX and Ego4D. (Generate task-centric latent actions.)
univla-7bTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7bUniVLA pretrained on our full data collection (Manip. + Navi. + Human).
univla-7b-bridge-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-bridge-ptUniVLA pretrained only on BridgeV2 data.
univla-7b-human-ptTRI-ML/prismatic-vlms/prism-dinosiglip-224px+7bunivla-7b-human-ptUniVLA pretrained only on Ego4D human videos.
univla-liberounivla-7bunivla-7b-224-sft-liberoFinetuned on the LIBERO dataset
univla-calvinunivla-7bunivla-7b-224-sft-calvinFinetuned on the CALVIN dataset
univla-r2runivla-7bunivla-7b-224-sft-r2rFinetuned on the R2R dataset
univla-bridgeunivla-7bunivla-7b-224-sft-simpler-bridgeFinetuned on the BridgeV2 (OXE ver.) dataset

🎮 Getting Started

  1. (Optional) We use conda to manage the environment.
conda create -n univla python=3.10 -y
conda activate univla
  1. Install dependencies.
# Install pytorch# Look up https://pytorch.org/get-started/previous-versions/ with your cuda version for a correct command# Our experiments are conducted with 'torch 2.2.0 + cuda 12.1'
pip install torch torchvision
# Clone our repo and pip install to download dependencies
git clone git@github.com:OpenDriveLab/UniVLA.git
cd univla
pip install -e .# Install Flash Attention 2 for training (https://github.com/Dao-AILab/flash-attention)
pip install packaging ninja
ninja --version;echo$?# Verify Ninja --> should return exit code "0"
pip install "flash-attn==2.5.5" --no-build-isolation

🔥 Training Recipe

0️⃣ Data Preparation

Please refer to this script for an example of how to download datasets from OXE

[optional] Please follow this instruction if you'd like to convert Ego4D data into RLDS format for training UniVLA.

1️⃣ Task-centric Latent Action Learning

We hightly recommond directly using our pre-trained latent action model ckeckpoints to save your time and compute.

Note

Our latent action model is trained on a comprehensive data collection, encompassing multiple robotic manipulation and navigation datasets from Open X-Embodiment, along with a curated subset of the Ego4D dataset (detailed data construction procedures are provided in the appendix of our paper).

To adapt the model to additional datasets or custom data sources, users may refer to ./prismatic/vla/datasets/rlds/oxe/mixtures.py to either utilize predefined data mixtures or define new ones. Subsequently, the data_mix parameter in the configuration file should be updated accordingly.

The latent action model is implemented based on VQ-VAE. We train the latent action model on the collection of dataset comprising robot manipulation, navigation and human videos. In stage-1 training, we use an overall batch size of 512 and 100k optimization steps to construct the task-irrelevant latent actions:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-1.yaml \
2>&1| tee lam-stage-1.log

The following stage-2 then focuses on learning task-centric latent actions on the basis of stage-1 results. Please modify the stage_one_ckpt in latent_action_model/config/lam-stage-2.yaml to your local path of stage-1 checkpoint, then run training with:

torchrun --standalone --nnodes 1 --nproc-per-node 8 main.py fit \
--config config/lam-stage-2.yaml \
2>&1| tee lam-stage-2.log

2️⃣ Pretraining of Generalist Policy

  • Latent Action Pseudo-Labeling for Policy Optimization: The trained latent action model is employed to generate pseudo-labels for policy optimization via a next-token prediction objective. Specifically, the indices of inferred latent actions in the VQ-VAE codebook are mapped to dedicated tokens in the LLaMA tokenizer, denoted as {ACT_0, ACT_1, ..., ACT_C}.

  • Cost-effective Pre-Training: The full-scale pre-training procedure, incorporating both OpenX and Ego4D datasets, was performed using a 32-GPU A100 cluster over 20,000 optimization steps. This training regimen required approximately 960 A100 GPU-hours, representing just 5% of the computational resources utilized by OpenVLA. Furthermore, experiments conducted on the 'Bridge' and 'Human' subsets demanded only 200 GPU-hours, demonstrating substantially reduced computational requirements compared to previous vision-language-action models.

  • To initiate pre-training, please refer to the following scipt or simply run bash ./vla-scripts/train.sh:

Note

For pretraining UniVLA only on BridgeV2 or Human (Ego4D) data, please modify vla.type to prism-dinosiglip-224px+mx-bridge(human) correspondingly. Detailed setups can be found in ./prismatic/conf/vla.py.

### Experiment on a 32-GPU cluster
GPUS_PER_NODE=8 NNODES=4
MASTER_PORT=${MASTER_PORT:-28596}
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
RANK=${RANK:-0}# Run your training script with torchrun
torchrun --nproc_per_node ${GPUS_PER_NODE} --nnodes ${NNODES} --node_rank ${RANK} --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} train.py \
--vla.type prism-dinosiglip-224px+mx-oxe-magic-soup-plus \
--run_root_dir "vla_log" \

Once pretraining is complete, convert the UniVLA weights (default 'Prismatic' format) to HuggingFace AutoClasses with:

python vla-scripts/extern/convert_openvla_weights_to_hf.py \
--openvla_model_path_or_id /path/to/your/pretrained_ckpt_path \
--ckpt_name /path/to/your/specific_ckpt_name.pt \
--output_hf_model_local_path /path/to/your/output_model_path

The converted model is then compatible with HF AutoClasses 'AutoModelForVision2Seq'.

3️⃣ Post-training for Deployment & Evaluations

  • With the pretrained generalist policy trained to plan over an embodiment-agnostic action space, we then add embodiment-specific action decoder heads for downstream deployment.
  • Our action decoder is extremely lightwight with only around 12M parameters. Using parameter efficient fine-tuning with LoRA rank 32, the total trainable parameter is around 123M.

🦾 Real-world Experiment

Our guidelines are based on real-device testing conducted on the AgiLex platform. If you have code deployed on other platforms or in different data formats, we welcome pull requests!

We provide a simple guideline to deploy UniVLA on your customized setups.

1) LIBERO

Please first download the LIBERO datasets that we used in experiments

Start training with torchrun:

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local LIBERO dataset path in data_root_dir.
  3. You can choose dataset_name from libero_spatial_no_noops, libero_object_no_noops, libero_goal_no_noops, and libero_10_no_noops

We trained on 'Spatial', 'Object' and 'Goal' for 30k steps and 'Long' for 40k steps. Please first modify the max_steps in training config accordingly for reproduction.

# Start training on LIBERO-10(long) with 8 GPUs
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_libero.py \
--dataset_name "libero_10_no_noops" \
--run_root_dir "libero_log" \

Once you finished training and get the action decoder and UniVLA backbone, you can start evaluation with:

# Start evaluation on LIBERO-10# [Optional] Install LIBERO dependencies
pip install -r experiments/robot/libero/libero_requirements.txt
# By default, we test for 50 rollouts every task, totalling 500 independent trials.
python experiments/robot/libero/run_libero_eval.py \
--task_suite_name libero_10 \ # Choose from [libero_spatial, libero_object, libero_goal, libero_10] 
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/libero_10_finetuned_univla \
--save_video False # Whether to save rollout videos \
--num_trials_per_task 50 \
--seed 7

2) CALVIN

Please first follow CALVIN to install relavent dependencies and prepare your dataset

  1. You should first set the pretrained UniVLA and latent action model path in vla_path and lam_path of the training config.
  2. Set your local CALVIN directory path in calvin_root.
  3. Start training with torchrun:
torchrun --standalone --nnodes 1 --nproc-per-node 8 finetune_calvin.py \
--vla_path /path/to/your/univla-7b \
--lam_path /path/to/your/lam-stage-2.ckpt \
--calvin_root /path/to/yout/calvin_root_path \
--max_steps 100000 \
--batch_size 8 \
--grad_accumulation_steps 2 \
--window_size 12 \ 
--run_root_dir "calvin_log"

Start evaluation on CALVIN:

# Mutli-GPU evaluation is supported
torchrun --standalone --nnodes 1 --nproc-per-node 8 experiments/robot/calvin/run_calvin_eval_ddp.py \
--calvin_root /path/to/yout/calvin_root_path \
--action_decoder_path /path/to/your/action_decoder_path.pt \
--pretrained_checkpoint /path/to/your/calvin_finetuned_univla \
--seed 7

3) Room2Room

Note

Please refer to this documentation for detailed guidelines.

4) SimplerEnv

Our SimplerEnv evlauation is based on the official repo.

  1. Clone and install SimplerEnv dependencies with
# We used the Maniskill3 version
git clone -b maniskill3 https://github.com/simpler-env/SimplerEnv.git
cd SimplerEnv
pip install --upgrade git+https://github.com/haosulab/ManiSkill.git
pip install -e .
  1. Add experiments/robot/simpler-bridge/policies/univla to simpler_env/policies, and replace simpler_env/real2sim_eval_maniskill3.py with experiments/robot/simpler-bridge/real2sim_eval_maniskill3.py.

  2. Run evaluation on SimplerEnv-Bridge "Put Spoon on Table Cloth" task:

Please refer to experiments/robot/simpler-bridge/eval_simpler_bridge_4task.sh for the evaluation on all tasks.

ckpt_path="/path/to/your/univla-7b-224-sft-simpler-bridge"
action_decoder_path="/path/to/your/univla-7b-224-sft-simpler-bridge/action_decoder.pt"
CUDA_VISIBLE_DEVICES=0 XLA_PYTHON_CLIENT_PREALLOCATE=false python real2sim_eval_maniskill3.py \
--model="univla" -e "PutSpoonOnTableClothInScene-v1" -s 0 --num-episodes 24 --num-envs 1 \
--action_decoder_path ${action_decoder_path} \
--ckpt_path ${ckpt_path} \

🚀 UniVLA's Performance

Note

LIBERO Simulation Benchmark Results.

ModelLIBERO-SpatialLIBERO-ObjectLIBERO-GoalLIBERO-LongAverage
SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)SR (↑)Rank (↓)
Diffusion Policy 78.3 ± 1.1% 592.5 ± 0.7%268.3 ± 1.2%550.5 ± 1.3%572.4 ± 0.7%5
Octo78.9 ± 1.0%485.7 ± 0.9%484.6 ± 0.9%251.1 ± 1.3%475.1 ± 0.6%3
OpenVLA84.7 ± 0.9%288.4 ± 0.8%379.2 ± 1.0%353.7 ± 1.3%376.5 ± 0.6%2
TraceVLA84.6 ± 0.2%385.2 ± 0.4%575.1 ± 0.3%454.1 ± 1.0%274.8 ± 0.5%4
UniVLA (Ours)96.5 ± 0.5%196.8 ± 0.5%195.6 ± 0.4%192.0 ± 1.0%195.2 ± 0.3%1

Note

LIBERO Results with Limited Data. (Models are trained with 10%, 20%, 50%, and the full dataset)

ModelLIBERO-GoalLIBERO-Long
10%20%50%100%10%20%50%100%
ATM64.3%77.1%--36.5%39.1%--
OpenVLA61.4%66.0%77.0%79.2%11.6%22.4%36.6%53.7%
OpenVLA-OFT76.8%88.2%91.1%96.2%43.0%62.2%77.8%90.7%
UniVLA (Ours)86.3%90.4%93.1%95.6%62.4%71.4%87.0%92.0%

Note

SimplerEnv evaluation on WidowX Robot tasks. (Averaged across 3 seeds)

We fix a minor bug about input processing, so the UniVLA's results are higher than the numbers reported in our original paper.

ModelPut Spoon on TowelPut Carrot on PlateStack Green Block on Yellow BlockPut Eggplant in Yellow Basket#Overall Average
Grasp SpoonSuccessGrasp CarrotSuccessGrasp Green BlockSuccessGrasp EggplantSuccess
RT-1-X16.7%0.0%20.8%4.2%8.3%0.0%0.0%0.0%1.1%
Octo-Base34.7%12.5%52.8%8.3%31.9%0.0%66.7%43.1%16.0%
Octo-Small77.8%47.2%27.8%9.7%40.3%4.2%87.5%56.9%30.0%
OpenVLA4.1%0.0%33.3%0.0%12.5%0.0%8.3%4.1%1.0%
RoboVLM54.2%29.2%25.0%25.0%45.8%12.5%58.3%58.3%31.3%
UniVLA76.4% ± 4.8%52.8% ± 6.4%79.2% ± 0.0%55.6% ± 2.4%66.7% ± 4.1%2.8% ± 2.4%93.0% ± 4.8%80.6% ± 6.4%47.9% ± 1.0%

Note

Real-world Experiments.

📝 Citation

If you find our code or models useful in your work, please cite our paper:

@article{bu2025univla,
title={Univla: Learning to act anywhere with task-centric latent actions},
author={Bu, Qingwen and Yang, Yanting and Cai, Jisong and Gao, Shenyuan and Ren, Guanghui and Yao, Maoqing and Luo, Ping and Li, Hongyang},
journal={arXiv preprint arXiv:2505.06111},
year={2025}
}

Acknowledgements

We thank OpenVLA for their open-sourced work!

About

[RSS 2025] Learning to Act Anywhere with Task-centric Latent Actions

Topics

Resources

Stars

1.1k stars

Watchers

8 watching

Forks

Sponsor this project

Used by

Contributors

Languages