LeRobot documentation

Compatibilité ascendante

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Compatibilité ascendante

Migration de la normalisation de politique (PR #1452)

Changement majeur : les politiques LeRobot ne disposent plus de couches de normalisation intégrées dans leurs poids. La normalisation est désormais gérée par des composants externes PolicyProcessorPipeline.

Qu'est-ce qui a changé ?

Avant la PR #1452Après la PR #1452
Emplacement de la normalisationIntégré dans les poids du modèle (normalize_inputs.*)Composants externes de PolicyProcessorPipeline
Dict d'état du modèleContient les statistiques de normalisationPoids propres uniquement - pas de paramètres de normalisation
Utilisationpolicy(batch) gère toutpreprocessor(batch) → policy(...) → postprocessor(...)

Impact sur les modèles existants

  • Les modèles entraînés avant la PR #1452 ont la normalisation intégrée dans leurs poids
  • Ces modèles nécessitent une migration pour fonctionner avec le nouveau système PolicyProcessorPipeline
  • La migration extrait les statistiques de normalisation et crée des pipelines de processeur distincts

Migration des anciens modèles

Utilisez le script de migration pour convertir les modèles avec normalisation intégrée :

python src/lerobot/processor/migrate_policy_normalization.py \
    --pretrained-path lerobot/act_aloha_sim_transfer_cube_human \
    --push-to-hub \
    --branch migrated

Le script :

  1. Extracts les statistiques de normalisation à partir des poids du modèle
  2. Crée des pipelines de préprocesseur et de postprocesseur externes
  3. Supprime les couches de normalisation des poids du modèle
  4. Sauvegarde des pipelines de modèle et de processeur propres
  5. Pushes vers le Hub avec création automatique de PR

Utilisation de modèles migrés

# New usage pattern (after migration)
from lerobot.policies import make_policy, make_pre_post_processors

# Load model and processors separately
policy = make_policy(config, ds_meta=dataset.meta)
preprocessor, postprocessor = make_pre_post_processors(
    policy_cfg=config,
    dataset_stats=dataset.meta.stats
)

# Process data through pipeline
processed_batch = preprocessor(raw_batch)
action = policy.select_action(processed_batch)
final_action = postprocessor(action)

Refonte de l'API matériel

La PR #777 améliore la calibration de LeRobot mais n'est pas rétrocompatible. Voici un aperçu des modifications apportées et de la manière de continuer à travailler avec les jeux de données créés avant cette pull request.

Qu'est-ce qui a changé ?

Avant la PR #777Après la PR #777
Plage conjointeDegrés -180...180°Plage normalisée Articulations : –100...100 Pince : 0...100
Position zéro (SO100 / SO101)Bras entièrement déployé horizontalementAu milieu de la plage pour chaque articulation
Gestion des limitesMesures logicielles pour détecter les retours à ±180 °Aucune logique de retour à zéro n'est nécessaire en raison du zéro à mi-échelle

Impact sur les jeux de données existants

  • Les trajectoires enregistrées créées avant la PR #777 seront rejouées de manière incorrecte si elles sont chargées directement :
    • Les angles articulaires sont décalés et normalisés de manière incorrecte.
  • Tous les modèles directement affinés ou entraînés sur les anciennes données devront avoir leurs entrées et sorties converties.

Utilisation de jeux de données créés avec l'ancien système de calibration

Nous fournissons un script d’exemple de migration pour rejouer un épisode enregistré avec l’étalonnage précédent, ici : examples/backward_compatibility/replay.py. Ci-dessous, nous vous guidons à travers les modifications apportées dans le script d’exemple pour faire fonctionner les jeux de données d’étalonnage précédents.

+   key = f"{name.removeprefix('main_')}.pos"
    action[key] = action_array[i].item()
+   action["shoulder_lift.pos"] = -(action["shoulder_lift.pos"] - 90)
+   action["elbow_flex.pos"] -= 90

Décomposons cela. La nouvelle base de code utilise le suffixe .pos pour les observations de position et nous avons supprimé le préfixe main_ :

key = f"{name.removeprefix('main_')}.pos"

Pour "shoulder_lift" (id = 2), la position 0 est modifiée de -90 degrés et le sens est inversé par rapport à l’ancienne calibration/code.

action["shoulder_lift.pos"] = -(action["shoulder_lift.pos"] - 90)

Pour "elbow_flex" (id = 3), la position 0 est modifiée de -90 degrés par rapport à l’ancienne calibration/code.

action["elbow_flex.pos"] -= 90

Pour utiliser la normalisation en degrés, nous définissons ensuite l'option --robot.use_degrees sur true.

python examples/backward_compatibility/replay.py \
    --robot.type=so101_follower \
    --robot.port=/dev/tty.usbmodem5A460814411 \
    --robot.id=blue \
+   --robot.use_degrees=true \
    --dataset.repo_id=my_dataset_id \
    --dataset.episode=0

Utilisation de politiques entraînées avec le système de calibration précédent

Les politiques produisent des actions dans le même format que les jeux de données (torch.Tensors). Par conséquent, les mêmes transformations doivent être appliquées.

Pour trouver ces transformations, nous recommandons de rejouer d'abord un épisode du jeu de données sur lequel votre politique a été entraînée, en utilisant la section ci-dessus. Ensuite, ajoutez ces mêmes transformations à votre script d'inférence (illustré ici pour un script qui appelle predict_action, comme les exemples de evaluate.py dans examples/) :

action_values = predict_action(
    observation_frame,
    policy,
    get_safe_torch_device(policy.config.device),
    preprocessor,
    postprocessor,
    policy.config.use_amp,
    task=single_task,
    robot_type=robot.robot_type,
    )
    action = {key: action_values[i].item() for i, key in enumerate(robot.action_features)}

+   action["shoulder_lift.pos"] = -(action["shoulder_lift.pos"] - 90)
+   action["elbow_flex.pos"] -= 90
    robot.send_action(action)

Si vous avez des questions ou rencontrez des problèmes de migration, n'hésitez pas à les poser sur Discord

Update on GitHub