# LingBot-VA

LingBot-VA adalah **kebijakan model dunia video-aksi autoregresif** yang dibangun di atas tumpukan video-difusi **Wan2.2**. Model ini menyisipkan prediksi **laten video** masa depan dan **aksi robot** ("VA" = Video-Action) ke dalam satu urutan autoregresif. Integrasi LeRobot menghubungkan LingBot-VA ke antarmuka pelatihan, evaluasi, dan pemroses standar.

## Ringkasan Model

LingBot-VA adalah **"mixture-of-transformers" dual-stream**: stream video/laten (`patch_embedding_mlp → blocks → proj_out`) dan stream aksi (`action_embedder → blocks → action_proj_out`) berbagi 30 blok transformer yang sama serta kondisioning teks.

| Komponen                | Kelas                   | Peran                                                        |
| ------------------------ | ----------------------- | ----------------------------------------------------------- |
| DiT backbone (dapat dilatih) | `WanTransformer3DModel` | transformer dual-stream dengan ~5B parameter.                          |
| VAE (beku)             | `AutoencoderKLWan`      | Wan2.2 VAE, `z_dim=48`. Diambil secara lazy dari repo sumber.   |
| Penkode teks (beku)    | `UMT5EncoderModel`      | UMT5-XXL, `d_model=4096`. Diambil secara lazy dari repo sumber. |

Saat inferensi, kebijakan menjalankan loop autoregresif per chunk: ia mendenois stream video-latent (CFG, ~20 langkah) dan stream aksi (~50 langkah) dengan dua scheduler flow-matching independen, sambil mempertahankan KV cache antar chunk. Keyframe yang diamati secara nyata dimasukkan kembali ke dalam KV cache saat chunk dieksekusi (pemodelan dunia closed-loop).

### Cakupan Integrasi LeRobot

- Konfigurasi standar `policy.type=lingbot_va` melalui LeRobot.
- Checkpoint format LeRobot siap pakai di Hub (dikonversi dari yang dirilis hulu).
- Inferensi dual-stream autoregressive di balik antarmuka `select_action` standar (evaluasi lingkungan tunggal, `--eval.batch_size=1`).
- Penyimpanan opsional (opt-in) **video yang diprediksi (dibayangkan)** oleh kebijakan selama evaluasi / pelatihan.
- Evaluasi dengan `lerobot-eval` pada LIBERO dan RoboTwin.
- Pelatihan / penyesuaian halus melalui kerugian flow-matching dual-stream (`policy.forward`), lihat di bawah.

## Instalasi

1. Install LeRobot dengan mengikuti [Panduan Instalasi](./installation).
2. Instal tambahan LingBot-VA:

```bash
pip install -e ".[lingbot_va]"
```

## Checkpoint

Checkpoint upstream yang dirilis telah dikonversi ke format LeRobot dan diunggah ke Hub:

| Varian                | Checkpoint LeRobot               |
| ---------------------- | -------------------------------- |
| LIBERO-Long pasca-pelatihan | `lerobot/lingbot_va_libero_long` |
| Post-train RoboTwin    | `lerobot/lingbot_va_robotwin`    |
| Dasar pra-terlatih        | `lerobot/lingbot_va_base`        |

Hanya transformer yang dapat dilatih ~5B yang disimpan dalam `model.safetensors` LeRobot. VAE + UMT5 + tokenizer yang dibekukan (~20 GB) diambil dari `config.wan_pretrained_path` saat dimuat (defaultnya adalah repo sumber `robbyant/*`). Encoder teks UMT5-XXL berjalan di CPU secara default (`config.text_encoder_device`) sehingga transformer 5B + VAE muat di satu GPU 24–32 GB.

## Evaluation (LIBERO)

```bash
lerobot-eval \
    --policy.path=lerobot/lingbot_va_libero_long \
    --policy.device=cuda \
    --env.type=libero --env.task=libero_10 \
    --env.observation_height=128 --env.observation_width=128 \
    --eval.n_episodes=50 --eval.batch_size=1 \
    --output_dir=outputs/eval/lingbot_va_libero
```

Inferensi streaming LingBot-VA (KV cache + umpan balik keyframe yang diamati) diimplementasikan untuk evaluasi lingkungan tunggal; gunakan `--eval.batch_size=1`.

## Evaluation (RoboTwin)

RoboTwin 2.0 membutuhkan stack simulator SAPIEN + CuRobo; tahap `robotwin_native` dari `docker/Dockerfile.sim` adalah instalasi referensi (LingBot-VA juga membutuhkan `warp-lang==1.3.1` dan `pytorch3d` yang dipin, serta CuRobo yang dibangun dengan compute capability GPU di `TORCH_CUDA_ARCH_LIST`). Konfigurasi RoboTwin pada server simulator menggunakan kontrol sendi, sehingga mode end-effector di bawah ini dijalankan secara lokal. RoboTwin menggunakan **kontrol pose end-effector**, jadi jalankan dengan `--env.action_mode=ee`: kebijakan memprediksi delta `xyz+quaternion+gripper` per lengan (layout laten `robotwin_tshape`) yang dikomposisikan ke pose eef awal episode dan dieksekusi melalui IK CuRobo.

```bash
lerobot-eval \
    --policy.path=lerobot/lingbot_va_robotwin \
    --policy.device=cuda \
    --env.type=robotwin --env.task=beat_block_hammer --env.action_mode=ee \
    --eval.n_episodes=10 --eval.batch_size=1 \
    --output_dir=outputs/eval/lingbot_va_robotwin
```

### Menyimpan video yang diprediksi (dibayangkan)

Set `--policy.save_predicted_video=true` untuk juga melakukan VAE-decode pada latens video prediksi dan menulis `pred_episode_*.mp4` di samping video `eval_episode_*.mp4` yang dirender oleh env. Flag yang sama juga berfungsi untuk eval periodik selama `lerobot-train`.

### Menonton video yang dibayangkan secara langsung

Set `--policy.return_predicted_video=true` saat `lerobot-rollout --display_data=true` untuk mendekode video prediksi dari setiap chunk dan menampilkan, saat setiap aksi dieksekusi, frame kamera yang dibayangkan yang terkait dengannya (`prediction.images.<camera>`, berdampingan dengan setiap kamera asli). Hal ini memerlukan satu dekoding VAE per chunk.

## Pelatihan / penyesuaian halus

`LingBotVAPolicy.forward(batch)` mengimplementasikan loss **flow-matching** dual-stream (`latent_loss + action_loss`, berbobot timestep, bermasker aksi) dari makalah tersebut: metode ini meng-encode klip kamera menjadi latens video menggunakan VAE, meng-encode tugas menggunakan UMT5, menambahkan noise pada kedua stream, menjalankan jalur pelatihan block-causal dari transformer, dan mengembalikan `(loss, metrics)`. Preset optimizer adalah AdamW dengan jadwal linear-warmup-then-constant (sesuai dengan upstream).

Persyaratan:

- Masker kausal blok menggunakan **flex-attention** PyTorch, sehingga bangun kebijakan dengan `--policy.attn_mode=flex` untuk pelatihan (SDPA `torch` bawaan hanya untuk inferensi).
- DiT 5B penuh tidak muat di satu GPU 24–32 GB dengan AdamW; lakukan fine-tune dengan **LoRA** (`--peft.method_type=LORA`) dan/atau optimizer offload. `get_optim_params` hanya mengembalikan parameter yang dapat dilatih (misalnya adapter); VAE + UMT5 text encoder tetap beku. Instal extra `lerobot[peft]` untuk mengaktifkan dukungan PEFT (lihat [panduan pelatihan PEFT](./peft_training)).

```bash
lerobot-train \
  --policy.path=lerobot/lingbot_va_libero_long --policy.attn_mode=flex \
  --peft.method_type=LORA --peft.r=32 --peft.lora_alpha=32 \
  --peft.target_modules='transformer\.blocks\.\d+\.attn[12]\.(to_q|to_v)' \
  --dataset.repo_id=<your LeRobot-format dataset> \
  --batch_size=1 --steps=... --output_dir=outputs/train/lingbot_va
```

Berbeda dengan SmolVLA / π₀, LingBot-VA tidak menyertakan target LoRA bawaan, sehingga Anda harus meneruskan `--peft.target_modules` secara eksplisit. Hanya `self.transformer` (transformer dual-stream Wan) yang dapat dilatih; contoh di atas mengadaptasi proyeksi query/value dari kedua blok self-attention (`attn1`) dan cross-attention (`attn2`)-nya, yaitu set target LoRA standar. Perluas target tersebut (misalnya tambahkan `to_k`/`to_out`, atau lapisan `ffn`) jika Anda membutuhkan adapter dengan kapasitas lebih tinggi. Meneruskan `--peft.method_type` mengimplikasikan penggunaan PEFT, sehingga `--policy.use_peft=true` tidak diperlukan.

Dataset harus menyediakan klip kamera (jendela temporal per kamera, di-encode VAE menjadi `frame_chunk_size` frame laten) dan `frame_chunk_size * action_per_frame` langkah aksi per item.

## Format data (saluran aksi & urutan kamera)

LingBot-VA adalah kebijakan **pose ujung-efektor (Cartesian)**, yang memprediksi pose EEF + gripper, bukan posisi sendi. Aksi berada dalam tata letak **30-dim** multi-embodiment yang tetap; petakan dimensi aksi robot Anda ke saluran-saluran ini dan isi sisanya dengan `0` (`used_action_channel_ids` memilih saluran yang benar-benar digunakan oleh checkpoint tertentu):

| channels | makna                                               |
| -------- | ----------------------------------------------------- |
| 0–6      | Pose ujung efektor lengan kiri                            |
| 7–13     | Pose ujung efektor lengan kanan                           |
| 14–20    | Sendi lengan kiri (tidak digunakan oleh checkpoint yang dirilis)  |
| 21–27    | Sendi lengan kanan (tidak digunakan oleh checkpoint yang dirilis) |
| 28       | Gripper kiri                                          |
| 29       | Gripper kanan                                         |

- **LIBERO** menggunakan saluran `0–6`: delta EEF 6-DoF (xyz + rotasi) + gripper (satu lengan).
- **RoboTwin** menggunakan kanal `[0–6, 28, 7–13, 29]`: EEF kiri (xyz + kuaternion) + gripper kiri + EEF kanan + gripper kanan (16 dimensi). Env mengonversi pose ini menjadi trajektori sendi melalui CuRobo IK — sendi tidak pernah diprediksi.

Dataset ruang bersama (atau konvensi EEF yang berbeda) harus dipetakan ulang ke skema ini sebelum melakukan fine-tuning pada checkpoint ini.

**Urutan kamera bersifat tetap dan sensitif terhadap urutan**, latents per kamera digabungkan secara spasial sesuai urutan `obs_cam_keys`, sehingga pemetaan kamera fisik→slot harus sesuai dengan pelatihan:

| benchmark | `obs_cam_keys` (berurutan)                                                                             | `camera_layout`                                                     |
| --------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| LIBERO    | `observation.images.image` (tampilan agen / sudut pandang orang ketiga), `observation.images.image2` (pergelangan tangan eye-in-hand)  | `width_concat` (laten yang digabungkan pada lebar)                      |
| RoboTwin  | `observation.images.head_camera`, `observation.images.left_camera`, `observation.images.right_camera` | `robotwin_tshape` (kepala resolusi penuh di bawah, dua pergelangan tangan resolusi setengah di atas) |

Kamera pertama adalah tampilan eksterior/kepala dan sisanya adalah tampilan pergelangan tangan.

## Hyperparameter Inferensi (LIBERO)

| Kunci                                    | Nilai                                                                             |
| -------------------------------------- | --------------------------------------------------------------------------------- |
| tinggi × lebar                         | 128 × 128                                                                         |
| kamera                                | `observation.images.image` (agentview), `observation.images.image2` (eye-in-hand) |
| kanal aksi yang digunakan                   | 0–6 (lengan 7-DoF + gripper)                                                         |
| action_per_frame / frame_chunk_size    | 4 / 4                                                                             |
| attn_window                            | 30                                                                                |
| langkah denoising video / aksi         | 20 / 50                                                                           |
| guidance_scale / action_guidance_scale | 5 / 1                                                                             |
| snr_shift / action_snr_shift           | 5.0 / 0.05                                                                        |

Ini adalah nilai bawaan dari `LingBotVAConfig`; timpa salah satunya melalui `--policy.<name>=...`.

## Catatan

- **Backend perhatian:** inferensi menggunakan backend SDPA `torch` (selalu tersedia). Backend `flashattn` dan `flex` bersifat opsional; `flex` hanya diperlukan untuk pelatihan.
- **Ukuran model:** DiT memiliki sekitar 5 miliar parameter, dan VAE+UMT5 yang dibekukan menambah sekitar 20 GB; inferensi membutuhkan sekitar 18–24 GB VRAM.

## Lisensi

LingBot-VA dirilis di bawah lisensi Apache-2.0. Lihat [repo upstream](https://github.com/Robbyant/lingbot-va).

