# LIBERO-plus

LIBERO-plus est un **benchmark de robustesse** pour les modèles Vision-Language-Action (VLA) construit sur la base de [LIBERO](./libero). Il met systématiquement les politiques à l'épreuve en appliquant **sept dimensions de perturbation indépendantes** à l'ensemble de tâches original de LIBERO, révélant ainsi des modes d'échec que les benchmarks standards manquent.

- Article : [Analyse approfondie de la robustesse des modèles Vision-Language-Action](https://arxiv.org/abs/2510.13626)
- GitHub : [sylvestf/LIBERO-plus](https://github.com/sylvestf/LIBERO-plus)
- Jeu de données : [lerobot/libero_plus](https://huggingface.co/datasets/lerobot/libero_plus)

![An overview of the LIBERO-plus benchmark perturbation dimensions](https://github.com/sylvestf/LIBERO-plus/raw/main/static/images/libero-plus.jpg)

## Dimensions de perturbation

LIBERO-plus crée environ 10 000 variantes de tâches en perturbant chaque tâche LIBERO originale selon ces axes :

| Dimension             | Quelles sont les modifications                                          |
| --------------------- | ----------------------------------------------------- |
| Disposition des objets        | Position cible, présence d'objets de confusion      |
| Points de vue de la caméra     | Position, orientation et champ de vision de la caméra           |
| États initiaux du robot  | Pose de départ du manipulateur                                |
| Instructions de langue | Description de la tâche réécrite par un LLM (paraphrase / synonyme) |
| Conditions d'éclairage      | Intensité, direction, couleur, ombre                   |
| Textures d'arrière-plan   | Surface de la scène et apparence des objets                   |
| Bruit du capteur          | Distorsions photométriques et dégradation d'image         |

## Suites de tâches disponibles

LIBERO-plus perturbe les 40 tâches originales des suites Spatial, Object, Goal et Long. Chaque tâche enregistrée dans ces quatre suites est une variante perturbée, plutôt qu'une des tâches originales. Le fork conserve également les 90 tâches non perturbées de LIBERO-90.

| Suite          | Nom de la CLI         | Tâches d'origine | Tâches enregistrées | Étapes maximales | Description                                       |
| -------------- | ---------------- | -------------- | ---------------- | --------- | ------------------------------------------------- |
| LIBERO-Spatial | `libero_spatial` | 10             | 2,402            | 280       | Tâches nécessitant un raisonnement sur les relations spatiales |
| LIBERO-Object  | `libero_object`  | 10             | 2,518            | 280       | Tâches centrées sur la manipulation d'objets différents  |
| LIBERO-Goal    | `libero_goal`    | 10             | 2,591            | 300       | Tâches conditionnées par un objectif avec des cibles changeantes      |
| LIBERO-90      | `libero_90`      | 90             | 90               | 400       | Tâches LIBERO à horizon court non perturbées            |
| LIBERO-Long    | `libero_10`      | 10             | 2,519            | 520       | Tâches à long horizon de la collection LIBERO-100 |

Ces compteurs proviennent du [registre de tâches](https://github.com/sylvestf/LIBERO-plus/blob/4976dc30028e805ff8094b55501d532c48fec182/libero/libero/benchmark/libero_suite_task_map.py) amont. Les quatre suites perturbées contiennent au total **10 030 variantes de tâches** ; LIBERO-90 n’est pas inclus dans ce total. Les compteurs et les indices de tâches dépendent de la révision du fork installé.

  L’installation de LIBERO-plus **remplace** LIBERO standard — elle désinstalle `hf-libero` afin que `import libero` pointe vers le fork LIBERO-plus. Il est impossible d’avoir les deux installés simultanément. Pour revenir à LIBERO standard, désinstallez le fork et réinstallez-le avec `pip install -e ".[libero]"`.

## Installation

### Dépendances système (Linux uniquement)

```bash
sudo apt install libexpat1 libfontconfig1-dev libmagickwand-dev
```

### Paquet Python

```bash
pip install -e ".[libero]" "robosuite==1.4.1" bddl easydict mujoco wand scikit-image gym
git clone https://github.com/sylvestf/LIBERO-plus.git
cd LIBERO-plus && pip install --no-deps -e .
pip uninstall -y hf-libero  # so `import libero` resolves to the fork
```

LIBERO-plus est installé depuis son fork GitHub plutôt que depuis un extra pyproject — le fork est fourni en tant que package d’espace de noms que pip ne peut pas gérer, il doit donc être cloné et ajouté à `PYTHONPATH`. Consultez `docker/Dockerfile.benchmark.libero_plus` pour l’installation canonique. MuJoCo est requis, seul Linux est donc pris en charge.

Définissez le backend de rendu MuJoCo avant d’exécuter l’évaluation :

```bash
export MUJOCO_GL=egl   # headless / HPC / cloud
```

### Télécharger les ressources de LIBERO-plus

LIBERO-plus distribue son pack d’actifs étendu séparément. Téléchargez `assets.zip` depuis le [jeu de données Hugging Face](https://huggingface.co/datasets/Sylvest/LIBERO-plus/tree/main) et extrayez-le dans le répertoire du package LIBERO-plus :

```bash
# After installing the package, find where it was installed:
python -c "import libero; print(libero.__file__)"
# Then extract assets.zip into <package_root>/libero/assets/
```

## Évaluation

### Évaluation par défaut (recommandée)

Évaluez chaque variante enregistrée sur les quatre suites perturbées, en utilisant un épisode par variante comme recommandé par le [guide d’évaluation en amont](https://github.com/sylvestf/LIBERO-plus#-evaluation) :

```bash
lerobot-eval \
  --policy.path="your-policy-id" \
  --env.type=libero_plus \
  --env.task=libero_spatial,libero_object,libero_goal,libero_10 \
  --eval.batch_size=1 \
  --eval.n_episodes=1 \
  --env.max_parallel_tasks=1
```

Cela exécute **10 030 épisodes** pour le registre ci-dessus. Avec `--eval.n_episodes=10`, la même commande exécute **100 300 épisodes**, et non 400.

### Test de fumée

Avant de lancer une évaluation complète, vérifiez votre configuration avec une variante enregistrée et un épisode :

```bash
lerobot-eval \
  --policy.path="your-policy-id" \
  --env.type=libero_plus \
  --env.task=libero_spatial \
  --env.task_ids='[0]' \
  --eval.batch_size=1 \
  --eval.n_episodes=1
```

Il s'agit d'une vérification de configuration, et non d'une évaluation représentative de la robustesse.

### Évaluation sur une seule suite

Évaluer sur une seule suite LIBERO-plus :

```bash
lerobot-eval \
  --policy.path="your-policy-id" \
  --env.type=libero_plus \
  --env.task=libero_spatial \
  --eval.batch_size=1 \
  --eval.n_episodes=1
```

- `--env.task` sélectionne la suite (`libero_spatial`, `libero_object`, etc.).
- `--env.task_ids` restreint l’exécution aux indices de tâches enregistrés (`[0]`, `[1,2,3]`, etc.), qui identifient les variantes au sein des quatre suites perturbées. Omettez ce paramètre pour exécuter toutes les tâches enregistrées. Lors de l’évaluation de plusieurs suites, la même liste d’indices est appliquée indépendamment à chaque suite.
- `--eval.batch_size` contrôle le nombre d'environnements exécutés en parallèle.
- `--eval.n_episodes` définit le nombre d'épisodes à exécuter pour chaque tâche enregistrée. L'augmenter répète l'évaluation des variantes sélectionnées ; il ne sélectionne pas de variantes distinctes supplémentaires.

### Évaluation multi-suite

Évaluez une politique sur plusieurs suites à la fois en passant une liste séparée par des virgules :

```bash
lerobot-eval \
  --policy.path="your-policy-id" \
  --env.type=libero_plus \
  --env.task=libero_spatial,libero_object \
  --eval.batch_size=1 \
  --eval.n_episodes=1
```

### Mode de contrôle

LIBERO-plus prend en charge deux modes de contrôle — `relative` (par défaut) et `absolute`. Les différents points de contrôle VLA sont entraînés avec des paramétrisations d’actions différentes, assurez-vous donc que le mode correspond à votre politique :

```bash
--env.control_mode=relative   # or "absolute"
```

### Réinitialiser les performances

Par défaut, LeRobot conserve le comportement de réinitialisation dure de LIBERO. Avec les états initiaux fixes activés, vous pouvez opter pour des réinitialisations douces afin d'éviter de reconstruire le modèle du simulateur et le moteur de rendu à chaque épisode :

```bash
--env.init_states=true --env.hard_reset=false
```

Les réinitialisations douces sont plus rapides, mais elles ne sont pas identiques au bit près aux réinitialisations dures après les étapes de stabilisation de l'environnement, de sorte que les observations de la caméra et les résultats de la politique peuvent différer légèrement. Utilisez des réinitialisations dures pour reproduire les résultats des benchmarks.

### Entrées et sorties de la politique

**Observations :**

- `observation.state` — 8 caractéristiques proprioceptives (position de l'effecteur, orientation en axe-angle, qpos de la pince)
- `observation.images.image` — vue de la caméra principale (`agentview_image`), HWC uint8
- `observation.images.image2` — vue de la caméra au poignet (`robot0_eye_in_hand_image`), HWC uint8

**Actions :**

- Contrôle continu dans `Box(-1, 1, shape=(7,))` — delta de l'effecteur final 6D + pince 1D

### Charge de travail d'évaluation et reproductibilité

Le nombre total d'épisodes d'évaluation est **le nombre de tâches enregistrées sélectionnées dans toutes les suites × `--eval.n_episodes`**. Par exemple, toutes les variantes Spatial avec un épisode chacune donnent 2 402 épisodes ; sélectionner `--env.task_ids='[0,1,2]'` dans Spatial et Object avec un épisode chacune donne six épisodes.

Le calcul de 400 épisodes (40 tâches d'origine × 10 épisodes) s'applique à LIBERO vanilla, et non à une évaluation complète de LIBERO-plus. Pour LIBERO-plus, commencez par un épisode par variante enregistrée. Des épisodes répétés d'une variante ne sont pas équivalents à l'échantillonnage de variantes distinctes d'une tâche d'origine.

Pour un sous-ensemble personnalisé, utilisez la [classification des tâches](https://github.com/sylvestf/LIBERO-plus/blob/4976dc30028e805ff8094b55501d532c48fec182/libero/libero/benchmark/task_classification.json) du fork pour identifier les catégories de perturbation et les niveaux de difficulté. Ne supposez pas que chaque tâche originale dispose de dix variantes distinctes dans chaque catégorie de perturbation. Lors de la publication des résultats, notez la révision du fork, les noms des suites sélectionnées et les indices des tâches, le nombre d'épisodes par variante, la graine (seed) et les paramètres de réinitialisation. Pour comparer avec des résultats publiés, suivez le protocole d'échantillonnage et d'agrégation du benchmark plutôt que de considérer un sous-ensemble arbitraire comme équivalent.

## Entraînement

### Jeu de données

Un jeu de données d'entraînement au format LeRobot pour LIBERO-plus est disponible à l'adresse suivante :

- [lerobot/libero_plus](https://huggingface.co/datasets/lerobot/libero_plus)

### Exemple de commande d'entraînement

```bash
lerobot-train \
    --policy.type=smolvla \
    --policy.repo_id=${HF_USER}/smolvla_libero_plus \
    --policy.load_vlm_weights=true \
    --dataset.repo_id=lerobot/libero_plus \
    --env.type=libero_plus \
    --env.task=libero_spatial \
    --output_dir=./outputs/ \
    --steps=100000 \
    --batch_size=4 \
    --eval.batch_size=1 \
    --eval.n_episodes=1 \
    --env_eval_freq=1000
```

## Relation avec LIBERO

LIBERO-plus est une extension intégrable de LIBERO :

- Même interface Python gym (`LiberoEnv`, `LiberoProcessorStep`)
- Mêmes noms de caméras et même format d'observation/action
- Noms de suites de tâches identiques
- S'installe sous le même nom de package Python `libero` (dépôt GitHub différent)

Pour utiliser le benchmark LIBERO original, consultez [LIBERO](./libero) et utilisez `--env.type=libero`.

