向后兼容性

policy 归一化迁移(PR #1452)

破坏性变更:LeRobot policy 不再在权重中内嵌归一化层。归一化现在由外部的 PolicyProcessorPipeline 组件处理。

有什么变化?

PR #1452 之前PR #1452 之后
归一化位置嵌入在模型权重中(normalize_inputs.*外部的 PolicyProcessorPipeline 组件
模型 state 字典包含归一化统计仅含干净权重 - 无归一化参数
用法policy(batch) 处理一切preprocessor(batch)policy(...)postprocessor(...)

对现有模型的影响

  • 在 PR #1452 之前训练的模型,其权重中嵌入了归一化
  • 这些模型需要迁移才能与新的 PolicyProcessorPipeline 系统配合使用
  • 迁移会提取归一化统计并创建独立的处理器流水线

迁移旧模型

使用迁移脚本转换带有内嵌归一化的模型:

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

该脚本:

  1. 提取模型权重中的归一化统计
  2. 创建外部预处理和后处理流水线
  3. 移除模型权重中的归一化层
  4. 保存干净模型 + 处理器流水线
  5. 推送到 Hub 并自动创建 PR

使用迁移后的模型

# 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)

硬件 API 重新设计

PR #777 改进了 LeRobot 的 calibration,但不向后兼容。下面概述了有哪些变化,以及你如何继续使用在此拉取请求之前创建的 dataset。

有什么变化?

PR #777 之前PR #777 之后
关节范围度数 -180...180°归一化范围 关节:–100...100 gripper:0...100
零位(SO100 / SO101)机械臂水平完全伸展位于每个关节范围的中部
边界处理用于检测 ±180 ° 回绕的软件保护由于零位在范围中部,无需回绕逻辑

对现有 dataset 的影响

  • 在 PR #777 之前录制的轨迹,如果直接加载将无法正确回放:
    • 关节角度存在偏移且归一化不正确。
  • 任何直接在旧数据上 fine-tune 或训练的模型,其输入和输出都需要进行转换。

使用旧 calibration 系统制作的 dataset

我们在这里提供了一个迁移示例脚本,用于回放使用旧 calibration 录制的 episode:examples/backward_compatibility/replay.py。 下面我们带你了解示例脚本中所做的修改,以使旧的 calibration dataset 能够正常使用。

+   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

我们来逐项分析。 新代码库对位置 observation 使用 .pos 后缀,并且我们已移除 main_ 前缀:

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

对于 "shoulder_lift"(id = 2),与旧 calibration/代码相比,0 位置偏移了 -90 度,且方向反转。

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

对于 "elbow_flex"(id = 3),与旧 calibration/代码相比,0 位置偏移了 -90 度。

action["elbow_flex.pos"] -= 90

要使用度数归一化,我们将 --robot.use_degrees 选项设置为 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

使用旧 calibration 系统训练的 policy

policy 输出的 action 与 dataset(torch.Tensors)格式相同。因此,应应用相同的变换。

要找到这些变换,我们建议先用上面一节的方法,回放你的 policy 所训练 dataset 中的一个 episode。 然后,在 inference 脚本中(如 record.py 脚本所示)添加这些相同的变换:

action_values = predict_action(
    observation_frame,
    policy,
    get_safe_torch_device(policy.config.device),
    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)

如果你有疑问或遇到迁移问题,欢迎在 Discord 上提问

在 GitHub 上更新