Evo-1: Lightweight Vision-Language-Action Model with Preserved Semantic Alignment [CVPR 2026]
August 5, 2026 Β· View on GitHub
π° News
- ποΈ 2026-08-05 β Evo-1 is now supported in the official RLinf framework π₯: full-parameter SFT and GRPO fine-tuning on the LIBERO simulator (doc).
- ποΈ 2026-07-21 β Released RoboTwin evaluation (Evo-1 policy plugin + 50 bimanual tasks). See RoboTwin benchmark part.
- ποΈ 2026-07-20 β Release LIBERO-plus benchmark evaluation scripts and results. See LIBERO-plus benchmark part.
- ποΈ 2026-07-05 β Evo-1 has been added to the official LeRobot framework ππ.
- ποΈ 2026-06-07 β Evo-1 received the ποΈ Efficient CVPR Badge ποΈ.
- ποΈ 2026-04-10 β Updated the
evo1-flashbranch: faster training with reduced GPU memory usage. - ποΈ 2026-04-10 β Updated the
evo1-lerobotbranch: Evo-1 is now fully integrated into the LeRobot framework. - ποΈ 2026-04-08 β Evo-1 is now fully integrated into the LeRobot framework!
- ποΈ 2026-04-08 β We released Evo-1 Docker support for Jetson (https://huggingface.co/datasets/MINT-SJTU/Evo-1_JetsonOrin).
- ποΈ 2026-02-20 β Evo-1 is accepted by CVPR 2026 ππ
- ποΈ 2025-12-15 β Added Evo-1 inference code in Aloha dual arm (Implemented by community user @meijie-jesse)
- ποΈ 2025-11-15 β Added Evo-1 inference in the LeRobot framework for SO100/SO101
- ποΈ 2025-11-10 β Released inference script in xarm6
- ποΈ 2025-11-06 β Released Meta-World & LIBERO evaluation scripts
- ποΈ 2025-11-06 β Uploaded model weights to HuggingFace
- ποΈ 2025-11-06 β Released official code
β To-Do List
- β Release inference script in xarm6
- β
Update
evo1-flashbranch (faster training + reduced GPU memory usage) - β
Update
evo1-lerobotbranch (fully integrated Evo-1 into the LeRobot framework) - β Release instructions for deploying Evo-1 on Jetson Orin (https://huggingface.co/datasets/MINT-SJTU/Evo-1_JetsonOrin)
- β Release RoboTwin evaluation script
- β Release results of all 50 RoboTwin tasks
βοΈ Installation
Prepare the environment for Evo-1
# Clone this repo
git clone https://github.com/MINT-SJTU/Evo-1.git
cd Evo-1/
# Create a Conda environment
conda create -n Evo1 python=3.10 -y
conda activate Evo1
# Install requirements
cd Evo_1
pip install -r requirements.txt
# You may need to reduce MAX_JOBS to suit your computer
# (!!! This is a critical step β skipping it may cause lower success rate or unstable robot motion !!!)
MAX_JOBS=64 pip install -v flash-attn --no-build-isolation
π§ͺ Simulation Benchmark
π‘ Tips
In downstream tasks, the client script needs to be processed according to different task configurations. Because the client executes states or actions in the absolute/original action space, while the actions sent by the server are in the relative action space. Therefore, if the benchmark evaluation uses absolute actions, an additional logic is required in the client script: convert the relative actions returned by the model back to absolute actions through accumulation. If the evaluation uses relative actions, no modification is needed.
π§ͺ Meta-World Benchmark
1οΈβ£ Prepare the environment for Meta-World
conda create -n metaworld python=3.10 -y
conda activate metaworld
pip install mujoco
pip install metaworld
pip install websockets
pip install opencv-python
pip install packaging
pip install huggingface_hub
2οΈβ£ Model Preparation
π₯ 2.1 Download Model Weight
hf download MINT-SJTU/Evo1_MetaWorld --local-dir /path/to/save/checkpoint/
βοΈ 2.2 Modify config
- Modify checkpoint dir: Evo1_server.py
- Modify arm key and dataset key: The arm_key and dataset_key used during server inference must completely match the corresponding arm-dataset keys in the norm_stats.json in checkpoint. Located in Evo1_server.py
arm_key = "metaworld_robot"
dataset_key = "metaworld_dataset"
Tips: When using the old version model checkpoints, you only need to change the
arm_keyto the key name of thenorm_stats.jsonfile in the model checkpoint. For the new model checkpoints trained by the new version, you need to modify botharm_keyanddataset_key.
- (Optional) Modify server port: Evo1_server.py
- (Optional) Modify client port: mt50_evo1_client_prompt.py
3οΈβ£ Run Meta-World Evaluation
# Terminal 1
conda activate Evo1
cd Evo_1
python scripts/Evo1_server.py
# Terminal 2
conda activate metaworld
cd MetaWorld_evaluation
python mt50_evo1_client_prompt.py
π§ͺ LIBERO Benchmark
1οΈβ£ Prepare the environment for LIBERO
conda create -n libero python=3.8.13 -y
conda activate libero
cd LIBERO_evaluation/
git clone https://github.com/Lifelong-Robot-Learning/LIBERO.git
cd LIBERO
pip install -r requirements.txt
pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio==0.11.0 --extra-index-url https://download.pytorch.org/whl/cu113
pip install -e .
pip install websockets
pip install huggingface_hub
2οΈβ£ Model Preparation
π₯ 2.1 Download Model Weight
hf download MINT-SJTU/Evo1_LIBERO --local-dir /path/to/save/checkpoint/
βοΈ 2.2 Modify config
- Modify checkpoint dir: Evo1_server.py
- Modify ckpt name: libero_client_4tasks.py
- Modify arm key and dataset key: The arm_key and dataset_key used during server inference must completely match the corresponding arm-dataset keys in the norm_stats.json in checkpoint. Located in Evo1_server.py
# Specialized for different downstream tasks.
# Old version checkpointοΌ
arm_key = "libero_robot"
dataset_key = "libero_4_datasets"
# New version trained checkpoint:
# Keep the same name as in your norm_stats.json, which is usually the same as the arm name in config.yaml
arm_key = "franka_ee_pose_delta"
dataset_key = "libero_10_no_noops_lerobot"
Tips: When using the old version model checkpoints, you only need to change the
arm_keyto the key name of thenorm_stats.jsonfile in the model checkpoint. For the new model checkpoints trained by the new version, you need to modify botharm_keyanddataset_key.
- (Optional) Modify server port: Evo1_server.py
- (Optional) Modify client port: libero_client_4tasks.py
3οΈβ£ Run LIBERO Evaluation
# Terminal 1
conda activate Evo1
cd Evo_1
python scripts/Evo1_server.py
# Terminal 2
conda activate libero
cd LIBERO_evaluation
python libero_client_4tasks.py
π§ͺ LIBERO-plus Benchmark
1οΈβ£ Prepare the environment for LIBERO-plus
Prepare LIBERO-plus evaluation environment, detailed instructions can be found in libero-plus-eval/README.md. Follow Step 1 to Step 6 to set up the environment and download the necessary assets.
2οΈβ£ Model Preparation
π₯ 2.1 Download Model Weight
LIBERO-plus model use the same Evo-1 model weight as LIBERO, you can download it from HuggingFace:
hf download MINT-SJTU/Evo1_LIBERO --local-dir /path/to/save/checkpoint/
βοΈ 2.2 Modify server config
- Modify checkpoint dir: Evo1_server.py
- Modify arm key and dataset key to match your LIBERO checkpoint's
norm_stats.json, same as step 2.2 of the LIBERO Benchmark: Evo1_server.py - (Optional) Modify server port: Evo1_server.py
3οΈβ£ Run LIBERO-plus Evaluation
# Terminal 1
conda activate Evo1
cd Evo_1
python scripts/Evo1_server.py
Open another terminal and run the evaluation script for LIBERO-plus, more specific instructions can be found in libero-plus-eval/README.md Step 7. Following is an simple example of running the evaluation for the libero_spatial suite:
# Terminal 2
conda activate libero_plus
export LIBERO_CONFIG_PATH="$HOME/.libero-plus"
cd /path/to/libero-plus-eval
bash test_libero_plus.sh libero_spatial
π§ͺ RoboTwin Benchmark
RoboTwin (50 bimanual manipulation tasks in SAPIEN) uses a policy-plugin architecture: start the Evo-1 server, drop the Evo-1 policy adapter into a RoboTwin checkout, and launch RoboTwin's evaluator as the client.
1οΈβ£ Prepare the environment for RoboTwin
RoboTwin is not bundled in this repo. Clone and install it separately (SAPIEN + CuRobo are required):
conda create -n RoboTwin python=3.10 -y
conda activate RoboTwin
git clone https://github.com/TianxingChen/RoboTwin.git
cd RoboTwin
pip install -r script/requirements.txt
pip install websockets
# CuRobo is REQUIRED β expert solvability check and scene setup use its motion planner
cd envs && git clone https://github.com/NVlabs/curobo.git
cd curobo && python -m pip install -e . --no-build-isolation && cd ../..
See the RoboTwin README for full setup (assets, SAPIEN, mplib).
2οΈβ£ Model Preparation
π₯ 2.1 Download Model Weight
hf download MINT-SJTU/Evo1_RoboTwin --local-dir /path/to/save/checkpoint/
βοΈ 2.2 Modify config
- Modify checkpoint dir: Evo1_server.py
arm_key/dataset_key: no server edit needed for RoboTwin. The client sends them per request (arm_key=aloha_joint, per-taskdataset_key=robotwin_<task>) and the server reads them from the payload. RoboTwinnorm_stats.jsonis keyed per task (50 keys underaloha_joint), so a single fixeddataset_keywould be wrong for 49/50 tasks β the per-request key is required.- (Optional) Modify server port: Evo1_server.py
π 2.3 Install the Evo-1 policy plugin into RoboTwin
cp -r RoboTwin_evaluation/policy/Evo1 /path/to/RoboTwin/policy/Evo1
3οΈβ£ Run RoboTwin Evaluation
# Terminal 1 β Evo-1 server (PYTHONPATH=. lets the server import scripts.* and config)
conda activate Evo1
cd Evo_1
PYTHONPATH=. python scripts/Evo1_server.py
# Terminal 2 β RoboTwin client, one task
conda activate RoboTwin
cd /path/to/RoboTwin/policy/Evo1
# Usage: bash eval.sh <task_name> [task_config] [ckpt_setting] [seed] [gpu_id] [server_url] [horizon]
bash eval.sh place_burger_fries demo_clean step_20000 0 0 ws://0.0.0.0:9000 37
Each task runs 100 episodes with expert solvability check; results are written under RoboTwin/eval_result/.
π§ Training on Your Own Dataset
We support lerobot v2.1 format, please convert your data to this format.
Below we will demonstrate how to prepare the dataset, modify configurations, and start the two-stage pretraining along with standard VLA finetuning.
ποΈ 1. Data Preparation
First, you need to download the dataset for pretraining. Taking the Libero dataset as an example, assuming you are located in the project root directory, run the following commands to download the dataset:
mkdir -p Evo1_training_dataset/libero_standard
cd Evo1_training_dataset/libero_standard
# 1) spatial
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/datasets/IPEC-COMMUNITY/libero_spatial_no_noops_1.0.0_lerobot
cd libero_spatial_no_noops_1.0.0_lerobot
git lfs pull
cd ..
# 2) object
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/datasets/IPEC-COMMUNITY/libero_object_no_noops_1.0.0_lerobot
cd libero_object_no_noops_1.0.0_lerobot
git lfs pull
cd ..
# 3) goal
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/datasets/IPEC-COMMUNITY/libero_goal_no_noops_1.0.0_lerobot
cd libero_goal_no_noops_1.0.0_lerobot
git lfs pull
cd ..
# 4) libero_10
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/datasets/IPEC-COMMUNITY/libero_10_no_noops_1.0.0_lerobot
cd libero_10_no_noops_1.0.0_lerobot
git lfs pull
cd ../../..
βοΈ 2. Data Configuration & Norm Stats
βοΈ 2.1 Modify config.yaml
You need to modify the detailed config. For detailed dataset configuration (how to define suite, modify config.yaml, configure cache_dir, etc.), please refer to: Detailed Tutorial for Dataset Configuration.
βοΈ 2.2 Compute Norm Stats
After configuring the config.yaml, it is necessary to calculate the statistical values (norm_stats) of each feature in the dataset:
cd Evo_1/
python -m dataset.compute_normstats dataset/config.yaml --action_horizon 50
Run the command above to compute the statistical characteristics for the datasets included in the config, which consist of max, min, q01, q99, mean, and std.
If an OOM error occurs while running the above code, you can run the streaming version instead:
cd Evo_1/
python -m dataset.compute_normstats_streaming dataset/config.yaml --action_horizon 50
π 3. Start Training
We use the two-stage training paradigm.
π 3.1 Setup deepspeed
accelerate config
You can check this setup guide
π 3.2 Training Stage 1
We only train the integration module and action expert in stage 1.
If you are training with multiple GPU, set --num_processes to the GPU number.
You need to change the --wandb_project, --run_name, --save_dir, and --cache_dir base on your own config. You may also change other options based on your need.
conda activate Evo1
cd Evo_1/
accelerate launch --num_processes 1 --num_machines 1 --deepspeed_config_file ds_config.json scripts/train.py --wandb_project your_project_name --run_name Evo1_flash_libero4_stage1 --action_head flowmatching --use_augmentation --lr 1e-5 --dropout 0.2 --weight_decay 1e-3 --batch_size 16 --image_size 448 --max_steps 20000 --log_interval 10 --ckpt_interval 5000 --warmup_steps 1000 --grad_clip_norm 1.0 --num_layers 8 --horizon 50 --finetune_action_head --disable_wandb --prefetch_factor 2 --video_backend av --cache_dir /your/path/to/dataset_cache/evo1_libero_4_cache --vlm_name OpenGVLab/InternVL3-1B --dataset_config_path dataset/config.yaml --per_action_dim 24 --state_dim 24 --save_dir /your/path/checkpoints/stage1
π 3.3 Training Stage 2
We perform Full-scale training in stage 2. You need to change the --wandb_project, --run_name, --save_dir, --resume_path and --cache_dir base on your own config. You may also change other options based on your need.
conda activate Evo1
cd Evo_1/
accelerate launch --num_processes 1 --num_machines 1 --deepspeed_config_file ds_config.json scripts/train.py --wandb_project your_project_name --run_name Evo1_libero_stage2 --action_head flowmatching --use_augmentation --lr 1e-5 --dropout 0.2 --weight_decay 1e-3 --batch_size 16 --image_size 448 --max_steps 80000 --log_interval 10 --ckpt_interval 5000 --warmup_steps 1000 --grad_clip_norm 1.0 --num_layers 8 --horizon 50 --finetune_vlm --finetune_action_head --disable_wandb --prefetch_factor 2 --video_backend av --cache_dir /your/path/to/dataset_cache/evo1_libero_4_seg_cache --vlm_name OpenGVLab/InternVL3-1B --dataset_config_path dataset/config.yaml --per_action_dim 24 --state_dim 24 --save_dir /your/path/checkpoints/stage2 --resume --resume_pretrain --resume_path /your/path/checkpoints/stage1/step_10000
π 3.4 (Optional) Resume Training
If you want to resume the training process, you can use the following command (we use stage 2 as an example):
accelerate launch --num_processes 1 --num_machines 1 --deepspeed_config_file ds_config.json scripts/train.py --wandb_project your_project_name --run_name Evo1_la2vla_libero_stage2 --action_head flowmatching --use_augmentation --lr 1e-5 --dropout 0.2 --weight_decay 1e-3 --batch_size 16 --image_size 448 --max_steps 80000 --log_interval 10 --ckpt_interval 5000 --warmup_steps 1000 --grad_clip_norm 1.0 --num_layers 8 --horizon 50 --finetune_vlm --finetune_action_head --disable_wandb --prefetch_factor 2 --video_backend av --cache_dir /your/path/to/dataset_cache/evo1_libero_4_seg_cache --vlm_name OpenGVLab/InternVL3-1B --dataset_config_path dataset/config.yaml --per_action_dim 24 --state_dim 24 --save_dir /your/path/checkpoints/stage2 --resume --resume_path /the/checkpoint/path/you/want/to/resume/from/step_20000
π¦Ύ 4. Inference in Your Own Embodiment
We provide an example of inference client script Evo1_client_xarm6 for xArm6.
The key is to construct an observation dict and pass it to the server.
obs = {
# You need to change the image size to 448x448 before send in obs
"image": [base_proc.tolist(), wrist_proc.tolist(), dummy_proc.tolist()],
# This shows which image is valid.
"image_mask": [int(i) for i in [1, 1, 0]],
# This is the state of the robot.
"state": state.astype(float).tolist(),
# This is the action mask that shows which action is valid.
"action_mask": [[int(i) for i in action_mask[0]]],
# This is the instruction of the task
"prompt": task_instruction
}
try:
# Send the observation to the server
await ws.send(json.dumps(obs))
result = await ws.recv()
# Get the action chunk
action_chunk = torch.tensor(json.loads(result))
except Exception as e:
print(f"β Inference Error: {e}")
await asyncio.sleep(0.5)
continue
π€ 5.Inference in Lerobot SO100/SO101
For detailed instructions, please check out the evo1-lerobot branch.
π Citation
@article{lin2025evo,
title={Evo-1: Lightweight Vision-Language-Action Model with Preserved Semantic Alignment},
author={Lin, Tao and Zhong, Yilei and Du, Yuxin and Zhang, Jingjing and Liu, Jiting and Chen, Yinxinyu and Gu, Encheng and Liu, Ziyan and Cai, Hongyi and Zou, Yanwen and others},
journal={arXiv preprint arXiv:2511.04555},
year={2025}
}
π¬ Contact
If you encounter any issues or have suggestions,
please open an issue or start a discussion on GitHub.
We sincerely welcome your feedback and contributions.
You can also scan the QR code below to connect with me or join chatting group on WeChat: