# EVO1

EVO1 adalah kebijakan Vision-Language-Action untuk pengendalian robot yang dibangun di sekitar tulang punggung InternVL3 dan kepala aksi flow-matching kontinu. Integrasi LeRobot ini mengekspos EVO1 sebagai jenis kebijakan standar sehingga dapat dilatih dan dievaluasi dengan API dataset, checkpoint, dan processor LeRobot yang biasa digunakan.

## Ringkasan Model

Kebijakan ini menyematkan satu atau lebih gambar kamera dan prompt tugas bahasa dengan InternVL3, mengisi vektor status/aksi robot hingga dimensi maksimum tetap, dan memprediksi chunk aksi masa depan dengan kepala aksi flow-matching. Selama inferensi, kebijakan ini mengambil sampel chunk aksi dan mengembalikan `n_action_steps` aksi dari chunk tersebut sebelum mengambil sampel lagi.

### Cakupan Integrasi LeRobot

- Konfigurasi standar `policy.type=evo1` melalui LeRobot
- Embedding gambar/teks InternVL3 dengan fallback FlashAttention opsional
- Kontrol finetuning berbasis tahap untuk eksekusi finetuning hanya action-head dan VLM
- Prediksi aksi flow-matching kontinu
- Menyimpan/memuat checkpoint melalui API kebijakan LeRobot
- Pelatihan dengan `lerobot-train` dan evaluasi dengan API inferensi kebijakan standar

Proyek EVO1 yang lebih luas mungkin mencakup skrip pelatihan dan alat dataset tambahan. Halaman ini berfokus pada jalur kebijakan kontrol robot LeRobot.

## Persyaratan Instalasi

1. Install LeRobot dengan mengikuti [Panduan Instalasi](./installation).
2. Instal dependensi EVO1:

   ```bash
   pip install -e ".[training,evo1]"
   ```

   Untuk pelatihan dan evaluasi LIBERO, instal juga ekstra LIBERO:

   ```bash
   pip install -e ".[training,evo1,libero]"
   ```

3. Instal wheel `flash-attn` hanya jika kompatibel dengan stack Python, PyTorch, CUDA, dan GPU Anda. EVO1 akan kembali ke perhatian standar ketika `flash_attn` tidak tersedia.

EVO1 menggunakan implementasi InternVL `transformers` Hugging Face native, sehingga `policy.vlm_model_name` harus menunjuk ke checkpoint yang dikonversi secara native seperti `OpenGVLab/InternVL3-1B-hf` (perhatikan akhiran `-hf`). Eksekusi pertama akan mengunduh checkpoint VLM yang dikonfigurasi, dan eksekusi selanjutnya akan memakainya kembali dari cache Hugging Face.

## Kebutuhan Data

EVO1 mengharapkan dataset LeRobot dengan:

- Satu hingga `policy.max_views` pengamatan visual, misalnya `observation.images.image`
- `observation.state`
- `action`
- Instruksi tugas bahasa di dataset pada field `task`, atau field lain yang dikonfigurasi dengan `policy.task_field`

Vektor state dan action di-pad hingga `policy.max_state_dim` dan `policy.max_action_dim`. Prediksi dipangkas kembali ke dimensi action dataset sebelum dikembalikan.

## Penggunaan

Untuk menggunakan EVO1 dalam konfigurasi LeRobot, tentukan:

```python
policy.type=evo1
```

Secara default, kebijakan EVO1 baru menginisialisasi VLM-nya dari:

```python
policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf
```

Setelah checkpoint EVO1 dalam format LeRobot tersedia, muat dengan:

```python
policy.path=your-org/your-evo1-checkpoint
```

## Pelatihan

### Tahap 1

Stage 1 membekukan VLM dan melatih action head:

```bash
lerobot-train \
  --dataset.repo_id=your_org/your_dataset \
  --policy.type=evo1 \
  --policy.training_stage=stage1 \
  --policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \
  --policy.device=cuda \
  --policy.chunk_size=50 \
  --policy.n_action_steps=50 \
  --policy.max_state_dim=24 \
  --policy.max_action_dim=24 \
  --policy.optimizer_lr=1e-5 \
  --batch_size=4 \
  --steps=5000 \
  --output_dir=./outputs/evo1_stage1
```

### Tahap 2

Stage 2 memuat kebijakan Stage 1, tetapi memulai optimizer dan scheduler baru:

```bash
lerobot-train \
  --dataset.repo_id=your_org/your_dataset \
  --policy.path=./outputs/evo1_stage1/checkpoints/005000/pretrained_model \
  --policy.training_stage=stage2 \
  --policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \
  --policy.device=cuda \
  --policy.chunk_size=50 \
  --policy.n_action_steps=50 \
  --policy.max_state_dim=24 \
  --policy.max_action_dim=24 \
  --policy.optimizer_lr=1e-5 \
  --batch_size=4 \
  --steps=80000 \
  --output_dir=./outputs/evo1_stage2
```

Secara default, `policy.training_stage` menerapkan ulang nilai default finetuning untuk tahap tersebut. Hal ini penting saat memulai Stage 2 dari checkpoint Stage 1, karena konfigurasi checkpoint Stage 1 menyimpan flag finetuning VLM sebagai nonaktif. Nilai default tahap ini memiliki prioritas lebih tinggi daripada flag `policy.finetune_*` yang disimpan atau diberikan secara manual, kecuali jika `policy.apply_training_stage_defaults=false`, sehingga setel flag tersebut hanya jika Anda mengontrol setiap flag finetuning secara manual.

### Parameter Pelatihan Utama

| Parameter                                     | Default                     | Deskripsi                                                       |
| --------------------------------------------- | --------------------------- | ----------------------------------------------------------------- |
| `policy.vlm_model_name`                       | `OpenGVLab/InternVL3-1B-hf` | Checkpoint InternVL3 yang dikonversi secara native atau direktori model lokal  |
| `policy.training_stage`                       | `stage1`                    | `stage1` melatih kepala aksi; `stage2` melakukan penyesuaian halus pada cabang VLM  |
| `policy.apply_training_stage_defaults`        | `true`                      | Menerapkan kembali nilai default penyesuaian tahap setelah memuat checkpoint    |
| `policy.vlm_num_layers`                       | `14`                        | Jumlah lapisan bahasa InternVL3 yang dipertahankan untuk kebijakan           |
| `policy.dtype`                                | `bfloat16`                  | dtype VLM yang diminta                                               |
| `policy.use_flash_attn`                       | `true`                      | Meminta FlashAttention saat terinstal; jika tidak, kembali ke      |
| `policy.enable_gradient_checkpointing`        | `true`                      | Mengaktifkan checkpointing pada modul InternVL3 yang didukung              |
| `policy.gradient_checkpointing_use_reentrant` | `false`                     | Pengaturan reentrant yang diteruskan ke gradient checkpointing saat didukung |
| `policy.chunk_size`                           | `50`                        | Jumlah aksi masa depan yang diprediksi per chunk                      |
| `policy.n_action_steps`                       | `50`                        | Jumlah aksi yang dikonsumsi dari chunk yang disampel                   |
| `policy.max_state_dim`                        | `24`                        | Dimensi padding State                                           |
| `policy.max_action_dim`                       | `24`                        | Dimensi padding aksi                                          |
| `policy.postprocess_action_dim`               | `null`                      | Dimensi aksi opsional yang dikembalikan setelah pascapemrosesan EVO1      |
| `policy.binarize_gripper`                     | `false`                     | Membuat biner saluran gripper yang telah diproses pascaproses untuk evaluasi gaya LIBERO |
| `policy.task_field`                           | `task`                      | Batch field yang digunakan sebagai prompt bahasa                           |

## Inferensi

Coba dengan checkpoint EVO1 yang sudah dilatih:

```bash
# --inference.type=rtc is optional
lerobot-rollout \
  --policy.path=your-org/your-evo1-checkpoint \
  --inference.type=rtc \
  ...
```

## Hasil

### Evaluasi LIBERO

#### Hasil referensi

> [!NOTE]
> Checkpoint Stage-2 yang dirilis lulus verifikasi unduhan bersih dan rollout: [`zuoxingdong/evo1_libero`](https://huggingface.co/zuoxingdong/evo1_libero), revisi [`515921f4a2c1d3f3ad523721eafa26fdf2af315b`](https://huggingface.co/zuoxingdong/evo1_libero/commit/515921f4a2c1d3f3ad523721eafa26fdf2af315b). Evaluasi unduhan bersih menggunakan revisi LeRobot [`e40b58a8dfa9e7b86918c374791599d070518d11`](https://github.com/huggingface/lerobot/commit/e40b58a8dfa9e7b86918c374791599d070518d11).

Checkpoint Stage-2 dari satu kali eksekusi pada langkah 70.000 menghasilkan:

| Suite          | Episode yang berhasil |  Episode | Tingkat keberhasilan |
| -------------- | ------------------: | --------: | -----------: |
| LIBERO Spatial |                 485 |       500 |        97.0% |
| LIBERO Object  |                 496 |       500 |        99.2% |
| Tujuan LIBERO    |                 483 |       500 |        96.6% |
| LIBERO-10      |                 469 |       500 |        93.8% |
| **Seluruhnya**    |           **1,933** | **2,000** |   **96.65%** |

Hasil ini menggunakan satu checkpoint terlatih dan seed evaluasi `1000`; ini bukan rata-rata multi-seed atau estimasi kepercayaan.

#### Resep pelatihan referensi

Checkpoint yang dirilis merekam konfigurasi Stage-2 yang telah diselesaikan secara lengkap di [`train_config.json`](https://huggingface.co/zuoxingdong/evo1_libero/blob/515921f4a2c1d3f3ad523721eafa26fdf2af315b/train_config.json). Eksekusi yang diukur menggunakan dua GPU H100 dengan dua proses DDP dan batch 64 per proses, sehingga menghasilkan global batch 128. Kedua tahap menggunakan topologi yang sama. VLM dasar berasal dari revisi `014c0583a0d4bedf29fbe2dbff4f865eb998e171` dari `OpenGVLab/InternVL3-1B-hf`. Artefak yang dirilis tidak merekam commit pelatihan LeRobot yang tepat atau kunci dependensi aslinya, sehingga perintah di bawah ini mereproduksi konfigurasi dan topologi yang tercatat dari checkout saat ini, bukan merekonstruksi lingkungan perangkat lunak secara bit per bit.

Dari checkout sumber LeRobot, instal dependensi terkunci dan unduh revisi VLM yang persis tersebut:

```bash
uv sync --locked --extra training --extra evo1 --extra libero
VLM_DIR=$(uv run hf download OpenGVLab/InternVL3-1B-hf \
  --revision=014c0583a0d4bedf29fbe2dbff4f865eb998e171)
```

Stage 1 membekukan VLM dan melatih action head selama 5.000 langkah:

```bash
uv run accelerate launch --num_processes=2 -m lerobot.scripts.lerobot_train \
  --dataset.repo_id=lerobot/libero \
  --dataset.revision=a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4 \
  --dataset.video_backend=torchcodec \
  --dataset.return_uint8=true \
  --dataset.image_transforms.enable=true \
  --dataset.use_imagenet_stats=true \
  --dataset.eval_split=0.0 \
  --policy.type=evo1 \
  --policy.training_stage=stage1 \
  --policy.apply_training_stage_defaults=true \
  --policy.vlm_model_name="${VLM_DIR}" \
  --policy.vlm_num_layers=14 \
  --policy.dtype=bfloat16 \
  --policy.device=cuda \
  --policy.use_amp=true \
  --policy.use_flash_attn=true \
  --policy.enable_gradient_checkpointing=true \
  --policy.gradient_checkpointing_use_reentrant=false \
  --policy.image_resolution='[448,448]' \
  --policy.chunk_size=50 \
  --policy.n_action_steps=50 \
  --policy.max_state_dim=24 \
  --policy.max_action_dim=24 \
  --policy.dropout=0.2 \
  --policy.optimizer_lr=1e-5 \
  --policy.optimizer_weight_decay=1e-3 \
  --policy.optimizer_grad_clip_norm=1.0 \
  --policy.scheduler_warmup_steps=1000 \
  --policy.push_to_hub=false \
  --use_policy_training_preset=true \
  --batch_size=64 \
  --steps=5000 \
  --save_checkpoint=true \
  --save_checkpoint_to_hub=false \
  --save_freq=2500 \
  --log_freq=10 \
  --env_eval_freq=0 \
  --num_workers=4 \
  --prefetch_factor=2 \
  --persistent_workers=true \
  --seed=1000 \
  --trackio.enable=false \
  --output_dir=./outputs/evo1-libero-stage1-g128-5k
```

Stage 2 memuat kebijakan Stage-1 tetapi memulai optimizer dan scheduler baru. Pelatihan dilakukan selama 80.000 langkah; checkpoint yang dilaporkan adalah penyimpanan pada langkah 70.000:

```bash
uv run accelerate launch --num_processes=2 -m lerobot.scripts.lerobot_train \
  --dataset.repo_id=lerobot/libero \
  --dataset.revision=a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4 \
  --dataset.video_backend=torchcodec \
  --dataset.return_uint8=true \
  --dataset.image_transforms.enable=true \
  --dataset.use_imagenet_stats=true \
  --dataset.eval_split=0.0 \
  --policy.path=./outputs/evo1-libero-stage1-g128-5k/checkpoints/005000/pretrained_model \
  --policy.training_stage=stage2 \
  --policy.apply_training_stage_defaults=true \
  --policy.vlm_model_name="${VLM_DIR}" \
  --policy.vlm_num_layers=14 \
  --policy.dtype=float32 \
  --policy.device=cuda \
  --policy.use_amp=true \
  --policy.use_flash_attn=true \
  --policy.enable_gradient_checkpointing=true \
  --policy.gradient_checkpointing_use_reentrant=false \
  --policy.image_resolution='[448,448]' \
  --policy.chunk_size=50 \
  --policy.n_action_steps=50 \
  --policy.max_state_dim=24 \
  --policy.max_action_dim=24 \
  --policy.dropout=0.2 \
  --policy.optimizer_lr=1e-5 \
  --policy.optimizer_weight_decay=1e-3 \
  --policy.optimizer_grad_clip_norm=1.0 \
  --policy.scheduler_warmup_steps=1000 \
  --policy.push_to_hub=false \
  --use_policy_training_preset=true \
  --batch_size=64 \
  --steps=80000 \
  --resume=false \
  --save_checkpoint=true \
  --save_checkpoint_to_hub=false \
  --save_freq=10000 \
  --log_freq=10 \
  --env_eval_freq=0 \
  --num_workers=4 \
  --prefetch_factor=2 \
  --persistent_workers=true \
  --seed=1000 \
  --trackio.enable=false \
  --output_dir=./outputs/evo1-libero-stage2-g128-80k
```

#### Profil evaluasi format penulis

Profil EVO1 LIBERO format penulis menggunakan nama fitur kamera mentah LIBERO (`observation.images.agentview_image` dan `observation.images.robot0_eye_in_hand_image`), merencanakan ulang setiap 14 aksi, dan membinerisasi perintah gripper sebelum melangkah simulator. Postprocessor kebijakan EVO1 dapat memotong aksi 24D yang di-pad kembali ke ruang aksi 7D LIBERO dan menerapkan binerisasi gripper tersebut. Untuk mengevaluasi checkpoint format penulis di bawah pengaturan satu episode per tugas yang sama, pertahankan nama kamera mentah alih-alih pemetaan default `image`/`image2` dan set bendera postprocessing aksi LIBERO:

```bash
lerobot-eval \
  --policy.path=your-org/your-evo1-libero-checkpoint \
  --policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \
  --policy.device=cuda \
  --policy.use_flash_attn=true \
  --policy.n_action_steps=14 \
  --policy.postprocess_action_dim=7 \
  --policy.binarize_gripper=true \
  --env.type=libero \
  --env.task=libero_object \
  --env.camera_name_mapping="{agentview_image: agentview_image, robot0_eye_in_hand_image: robot0_eye_in_hand_image}" \
  --env.observation_height=448 \
  --env.observation_width=448 \
  --eval.batch_size=1 \
  --eval.n_episodes=1
```

#### Profil `lerobot/libero` v3 native

Revisi `a1aaacb7f6cd6ee5fb43120f673cebb0cfea7dd4` menyimpan fitur kamera sebagai `image` dan `image2`. Contoh ini mengevaluasi semua sepuluh tugas LIBERO Object, dengan meluncurkan setiap tugas dalam proses baru:

```bash
export MUJOCO_GL=egl
export PYOPENGL_PLATFORM=egl

suite=libero_object
horizon=280
for task_id in {0..9}; do
  lerobot-eval \
    --policy.path=zuoxingdong/evo1_libero \
    --policy.pretrained_revision=515921f4a2c1d3f3ad523721eafa26fdf2af315b \
    --policy.vlm_model_name=OpenGVLab/InternVL3-1B-hf \
    --policy.device=cuda \
    --policy.use_amp=true \
    --policy.dtype=bfloat16 \
    --policy.use_flash_attn=false \
    --policy.enable_gradient_checkpointing=false \
    --policy.vlm_num_layers=14 \
    --policy.image_resolution='[448,448]' \
    --policy.max_text_length=1024 \
    --policy.chunk_size=50 \
    --policy.n_action_steps=14 \
    --policy.max_state_dim=24 \
    --policy.max_action_dim=24 \
    --policy.num_inference_timesteps=32 \
    --policy.postprocess_action_dim=7 \
    --policy.binarize_gripper=true \
    --policy.gripper_threshold=0.0 \
    --policy.gripper_below_threshold_value=-1.0 \
    --policy.gripper_above_threshold_value=1.0 \
    --env.type=libero \
    --env.task="${suite}" \
    --env.task_ids="[${task_id}]" \
    --env.camera_name=agentview_image,robot0_eye_in_hand_image \
    --env.camera_name_mapping="{agentview_image: image, robot0_eye_in_hand_image: image2}" \
    --env.control_mode=relative \
    --env.obs_type=pixels_agent_pos \
    --env.observation_width=448 \
    --env.observation_height=448 \
    --env.init_states=true \
    --env.episode_length="${horizon}" \
    --env.render_mode=rgb_array \
    --env.max_parallel_tasks=1 \
    --eval.n_episodes=50 \
    --eval.batch_size=1 \
    --eval.use_async_envs=false \
    --eval.recording=false \
    --seed=1000 \
    --output_dir="./outputs/evo1-libero-stage2-70k-eval/${suite}/task-${task_id}" \
    --job_name="evo1-libero-stage2-70k-${suite}-task-${task_id}"
done
```

Jalankan semua sepuluh ID tugas untuk setiap suite dengan horizon berikut:

| `env.task`       | `env.episode_length` |
| ---------------- | -------------------: |
| `libero_spatial` |                `280` |
| `libero_object`  |                `280` |
| `libero_goal`    |                `300` |
| `libero_10`      |                `520` |

Set `suite` dan `horizon` untuk setiap baris. Ini menghasilkan 500 episode per suite dan 2.000 episode secara keseluruhan, sementara proses baru per tugas dalam loop sesuai dengan topologi reset RNG yang diukur.

## Referensi

- [repo EVO1](https://github.com/MINT-SJTU/Evo-1)
- [InternVL3-1B-hf](https://huggingface.co/OpenGVLab/InternVL3-1B-hf)

## Lisensi

Integrasi LeRobot ini mengikuti Lisensi Apache 2.0 yang digunakan oleh LeRobot. Periksa halaman model EVO1 dan InternVL3 upstream untuk lisensi checkpoint dan data yang dirilis.

