# ROBOMETER

ROBOMETER est un **modèle de récompense robotique vidéo-langage à usage général**. Il prédit la progression de la tâche et le succès au niveau des images à partir d'une vidéo de trajectoire et d'une description de la tâche.

**Article** : [ROBOMETER: Scaling General-Purpose Robotic Reward Models via Trajectory Comparisons](https://arxiv.org/abs/2603.02115) **Projet** : [robometer.github.io](https://robometer.github.io/) **Code original** : [github.com/robometer/robometer](https://github.com/robometer/robometer) **Point de contrôle** : [lerobot/Robometer-4B](https://huggingface.co/lerobot/Robometer-4B)

## Aperçu

ROBOMETER s'appuie sur `Qwen/Qwen3-VL-4B-Instruct` et ajoute trois têtes de prédiction légères :

- **En-tête de progression** : prédit la progression de la tâche par image dans `[0, 1]`.
- **Tête de succès** : prédit la probabilité de succès de la tâche pour chaque image.
- **Tête de préférence** : prédit laquelle des deux trajectoires complète le mieux la tâche pendant l'entraînement.

L'article entraîne ROBOMETER avec un objectif composite :

```text
L = L_pref + L_prog + L_succ
```

L'intégration LeRobot est actuellement **limitée à l'inférence**. Elle conserve la tête de préférence afin que le point de contrôle `Robometer-4B` publié se charge sans remappage, mais `compute_reward()` interroge uniquement la tête de progression ou de succès.

## Ce que couvre l'intégration LeRobot

- Configuration standard `reward_model.type=robometer` via LeRobot.
- Prétraitement des images et du texte de Qwen3-VL via `RobometerEncoderProcessorStep`.
- APIs de sauvegarde/chargement des modèles de récompense LeRobot via `PreTrainedRewardModel`.
- Prédictions internes de progression et de succès au niveau des images, denses.
- Une récompense scalaire via `compute_reward()` pour l'utilisation en aval du modèle de récompense LeRobot.

Cette page se concentre sur l'utilisation du point de contrôle ROBOMETER publié comme modèle de récompense en zéro tirage. L'entraînement de ROBOMETER à partir de zéro est hors du périmètre de l'intégration LeRobot actuelle.

## Prérequis d'installation

1. Installez LeRobot en suivant le [Guide d'installation](./installation).
2. Installer les dépendances de ROBOMETER :

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

Si vous utilisez `uv` directement depuis un checkout source :

```bash
uv sync --extra robometer
```

ROBOMETER utilise un backbone Qwen3-VL-4B, l'inférence sur GPU est donc fortement recommandée.

## Entrées et sorties du modèle

ROBOMETER s'attend à :

- Une vidéo de trajectoire ou une séquence d'images.
- Description de la tâche en langage naturel.

Dans les jeux de données LeRobot, le préprocesseur lit :

| Champ de configuration              | Par défaut                  | Signification                                               |
| ------------------------- | ------------------------ | ----------------------------------------------------- |
| `reward_model.image_key`  | `observation.images.top` | Observation caméra/vidéo utilisée par ROBOMETER            |
| `reward_model.task_key`   | `task`                   | Saisissez des données complémentaires qui stockent la chaîne de caractères de la tâche |
| `reward_model.max_frames` | `8`                      | Nombre maximal de frames passées à ROBOMETER          |

Le modèle prédit en interne la progression et le succès par image. L'API de récompense de LeRobot renvoie un scalaire par échantillon :

- `reward_output="progress"` (par défaut) : renvoie la progression de la dernière image, bornée à `[0, 1]`.
- `reward_output="success"` : renvoie `1.0` si la probabilité de succès de la dernière image est supérieure à `success_threshold`, sinon `0.0`.

## Utilisation

### Charger le modèle de récompense directement

```python
from lerobot.rewards.robometer import RobometerConfig, RobometerRewardModel

cfg = RobometerConfig(
    pretrained_path="lerobot/Robometer-4B",
    device="cuda",
    reward_output="progress",
)
reward_model = RobometerRewardModel.from_pretrained(cfg.pretrained_path, config=cfg)
```

### Encoder les images et calculer une récompense

Pour un appel Python direct, fournissez les images sous forme de tableaux `uint8` de forme `(T, H, W, C)` et une chaîne de caractères de tâche :

```python
from lerobot.rewards.robometer.modeling_robometer import ROBOMETER_FEATURE_PREFIX
from lerobot.rewards.robometer.processor_robometer import RobometerEncoderProcessorStep

# frames: np.ndarray, shape (T, H, W, C), dtype uint8
# task: str
encoder = RobometerEncoderProcessorStep(
    base_model_id=cfg.base_model_id,
    use_multi_image=cfg.use_multi_image,
    use_per_frame_progress_token=cfg.use_per_frame_progress_token,
    max_frames=cfg.max_frames,
)

encoded = encoder.encode_samples([(frames, task)])
batch = {f"{ROBOMETER_FEATURE_PREFIX}{key}": value for key, value in encoded.items()}

reward = reward_model.compute_reward(batch)
```

`reward` est un tenseur de forme `(batch_size,)`.

### Utiliser la Reward Factory

Vous pouvez également instancier ROBOMETER via la fabrique de récompenses :

```python
from lerobot.rewards import make_reward_model, make_reward_model_config, make_reward_pre_post_processors

cfg = make_reward_model_config(
    "robometer",
    pretrained_path="lerobot/Robometer-4B",
    device="cuda",
    image_key="observation.images.top",
)
reward_model = make_reward_model(cfg)
preprocessor, postprocessor = make_reward_pre_post_processors(cfg)
```

Le préprocesseur écrit les tenseurs Qwen-VL sous l'espace de noms `observation.robometer.*`, et `compute_reward()` lit ces tenseurs encodés.

## Notes de configuration

### Backbone et Vocabulaire

Le point de contrôle publié utilise un squelette Qwen3-VL-4B. ROBOMETER ajoute cinq jetons spéciaux au tokeniseur dans un ordre fixe :

```text
<|split_token|>
<|reward_token|>
<|pref_token|>
<|sim_token|>
<|prog_token|>
```

`<|prog_token|>` est inséré après chaque image et correspond à la position d’état caché utilisée pour la prédiction du progrès et de la réussite par image. `<|split_token|>` et `<|pref_token|>` sont utilisés par l’objectif de préférence de trajectoires par paires de l’article. `<|reward_token|>` et `<|sim_token|>` sont conservés pour la compatibilité des points de contrôle.

La configuration LeRobot stocke un `vlm_config` sérialisé avec le vocabulaire après redimensionnement, afin que le modèle puisse se recharger depuis `config.json` sans avoir à télécharger d’abord les poids de base de Qwen. Pour `Qwen/Qwen3-VL-4B-Instruct`, la longueur du tokenizer est de `151669`, et les cinq jetons ROBOMETER produisent la taille de vocabulaire du point de contrôle `151674`.

### Prévision de progression

Dans le point de contrôle publié, la progression est discrète. La tête de progression émet des logits sur `progress_discrete_bins=10` centres de classes uniformément espacés dans `[0, 1]`. LeRobot convertit ces logits en une valeur continue en appliquant un softmax et en prenant l'espérance sur les centres de classes, conformément à l'implémentation amont de ROBOMETER.

### Prédiction de succès

La tête de succès émet des logits bruts par image. LeRobot les convertit en probabilités à l'aide de `sigmoid`. Lorsque `reward_output="success"`, `compute_reward()` applique un seuil à la probabilité de succès de la dernière image en utilisant `success_threshold`.

## Limites

- L'intégration LeRobot actuelle est limitée à l'inférence ; elle n'implémente pas l'entraînement ROBOMETER ni l'entraînement par paires de préférences.
- `compute_reward()` renvoie un scalaire par échantillon pour l’API du modèle de récompense LeRobot, bien que ROBOMETER prédise le progrès et la réussite par image en interne.
- ROBOMETER est basé sur la vidéo et le langage ; il n'utilise pas d'état robotique privilégié tel que les forces de contact ou les poses des objets.

## Références

- [projet ROBOMETER](https://robometer.github.io/)
- [article ROBOMETER](https://arxiv.org/abs/2603.02115)
- [Code original de ROBOMETER](https://github.com/robometer/robometer)
- [Point de contrôle ROBOMETER-4B publié](https://huggingface.co/lerobot/Robometer-4B)
- [Qwen3-VL-4B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct)

## Citation

```bibtex
@inproceedings{liang2026robometer,
title = {Robometer: Scaling General-Purpose Robotic Reward Models via Trajectory Comparisons},
author={Anthony Liang and Yigit Korkmaz and Jiahui Zhang and Minyoung Hwang and Abrar Anwar and Sidhant Kaushik and Aditya Shah and Alex S. Huang and Luke Zettlemoyer and Dieter Fox and Yu Xiang and Anqi Li and Andreea Bobu and Abhishek Gupta and Stephen Tu and Erdem Biyik and Jesse Zhang},
year={2026},
booktitle={Robotics: Science and Systems 2026},
}
```

## Licence

Cette intégration LeRobot suit la **licence Apache 2.0** utilisée par LeRobot. Consultez le code ROBOMETER en amont et les pages de modèles pour les licences de l'implémentation originale et des points de contrôle publiés.

