向后兼容性
策略归一化迁移(PR #1452)
破坏性变更:LeRobot 策略不再在其权重中嵌入归一化层。归一化现在由外部 PolicyProcessorPipeline 组件处理。
发生了什么变化?
| PR #1452 之前 | PR #1452 之后 | |
|---|---|---|
| 归一化位置 | 嵌入在模型权重中(normalize_inputs.*) |
外部 PolicyProcessorPipeline 组件 |
| 模型状态字典 | 包含归一化统计信息 | 仅包含干净的权重 - 没有归一化参数 |
| 使用方法 | 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
该脚本:
- 提取模型权重中的归一化统计信息
- 创建外部预处理器和后处理器管道
- 移除模型权重中的归一化层
- 保存干净的模型 + 处理器管道
- 推送到 Hub 并自动创建 PR
使用迁移后的模型
# 新的使用模式(迁移后)
from lerobot.policies import make_policy, make_pre_post_processors
# 分别加载模型和处理器
policy = make_policy(config, ds_meta=dataset.meta)
preprocessor, postprocessor = make_pre_post_processors(
policy_cfg=config,
dataset_stats=dataset.meta.stats
)
# 通过管道处理数据
processed_batch = preprocessor(raw_batch)
action = policy.select_action(processed_batch)
final_action = postprocessor(action)
硬件 API 重新设计
PR #777 改进了 LeRobot 校准,但不向后兼容。以下是发生了什么变化以及如何继续使用在此拉取请求之前创建的数据集的概述。
发生了什么变化?
| PR #777 之前 | PR #777 之后 | |
|---|---|---|
| 关节范围 | 度数 -180...180° |
归一化范围 关节:–100...100 夹爪:0...100 |
| 零位置(SO100 / SO101) | 手臂完全水平伸展 | 每个关节范围的中间 |
| 边界处理 | 软件保护措施检测 ±180° 环绕 | 由于中间范围零位,不需要环绕逻辑 |
对现有数据集的影响
- 在 PR #777 之前创建的记录轨迹如果直接加载将无法正确重放:
- 关节角度偏移且归一化不正确。
- 任何直接在旧数据上微调或训练的模型都需要转换其输入和输出。
使用以前校准系统制作的数据集
我们提供了一个迁移示例脚本,用于重放使用以前校准记录的片段:examples/backward_compatibility/replay.py。
下面我们将带你了解示例脚本中所做的修改,以使以前的校准数据集工作。
+ 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
让我们分解一下。
新代码库对位置观测使用 .pos 后缀,我们已删除 main_ 前缀:
key = f"{name.removeprefix('main_')}.pos"
对于 "shoulder_lift"(id = 2),与旧校准/代码相比,0 位置改变了 -90 度,方向相反。
action["shoulder_lift.pos"] = -(action["shoulder_lift.pos"] - 90)
对于 "elbow_flex"(id = 3),与旧校准/代码相比,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
使用以前校准系统训练的策略
策略以与数据集相同的格式输出动作(torch.Tensors)。因此,应应用相同的转换。
要找到这些转换,我们建议首先尝试使用上面的部分重放你的策略训练所用数据集的片段。
然后,在你的推理脚本上添加这些相同的转换(此处显示在 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 上提问。