LeRobot 奖励模型(Reward Model)模型卡指南:从训练发布到 Hub 加载推理的完整实践
【免费下载链接】lerobot🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot
LeRobot 将「奖励模型」作为一类与策略网络并列的一等公民:在真实机器人操作中,任务成功与否往往无法直接观测,需要由奖励模型从观测/轨迹中预测奖励信号,用于离线强化学习、人在环路微调、数据筛选与自动失败检测等下游环节。本文以仓库中的 lerobot_rewardmodel_modelcard_template.md 为核心,系统讲解 LeRobot 奖励模型的四类实现(Reward Classifier、SARM、ROBOMETER、TOPReward)、模型卡模板的渲染机制,以及从零训练、发布到 Hugging Face Hub、再以 Python API 加载并计算奖励的完整实战流程。
一、模板是什么:奖励模型模型卡生成机制
lerobot_rewardmodel_modelcard_template.md是一个Jinja2 渲染模板,它不是直接面向读者的说明文档,而是 LeRobot 在训练完成后自动生成模型卡(Model Card)所用的骨架。模板顶层通过{{ card_data }}注入 YAML front matter,随后用{{ model_name }}、{{ license }}等占位符动态填充内容。
从源码看,模型卡的渲染入口位于 src/lerobot/common/train_utils.py 的generate_model_card函数:当训练的是奖励模型而非策略时,该函数会读取lerobot_rewardmodel_modelcard_template.md模板文件(见 L761),并仅依据card_data渲染——即训练配置中的奖励模型类型、数据集信息与 Hub 元数据最终决定了模型卡上展示的内容。
这意味着模板中的{% if model_name == "..." %}分支(模板 L12-L22)是整个模型卡的「摘要引擎」:当前仓库支持四种已注册的奖励模型类型,分别对应reward_classifier、sarm、robometer、topreward四个分支。若类型未被识别,模板会回退到提示文案"Reward model type not recognized — please update this template."。
四种类型的官方定义(模板原文语义)
| 类型键 | 全称/出处 | 一句话定位 | 是否可训练 |
|---|---|---|---|
reward_classifier | Reward Classifier | 轻量神经网络,为观测或轨迹的成功与否打分,提供学习型奖励信号或离线评估 | 是 |
sarm | Success-Aware Reward Model(SARM) | 从观测预测稠密奖励信号,用于强化学习或人在环路微调 | 是 |
robometer | ROBOMETER | 基于微调 Qwen3-VL-4B 的通用视频-语言奖励模型,输出逐帧稠密任务进度与成功率 | 是 |
topreward | TOPReward | 零样本奖励模型:直接抽取现成 VLM(默认 Qwen3-VL)对指令的 token 对数概率作为奖励,无需微调 | 否(零样本) |
二、四类奖励模型深度剖析
模板的四个分支各有对应的配置类与建模实现,均注册在RewardModelConfig的选择注册表中(见 src/lerobot/rewards/init.py 与 src/lerobot/rewards/factory.py 的get_reward_model_class)。
2.1 Reward Classifier:轻量图像分类器
配置类RewardClassifierConfig位于 src/lerobot/rewards/classifier/configuration_classifier.py,模型实现Classifier位于 src/lerobot/rewards/classifier/modeling_classifier.py。
- 默认以
lerobot/resnet10为图像编码器(model_name),支持model_type切换CNN或Transformer两种骨干; - 编码器参数被冻结(
_freeze_encoder,见 modeling_classifier.py#L159-L162),只训练轻量的SpatialLearnedEmbeddings+ MLP 分类头; - 核心超参数:
num_classes=2(二分类时输出 sigmoid 概率)、hidden_dim=256、latent_dim=256、image_embedding_pooling_dim=8、dropout_rate=0.1、num_cameras=2、learning_rate=1e-4、weight_decay=0.01、grad_clip_norm=1.0; - 推理时
compute_reward对二分类返回(probabilities > 0.5).float(),即成功返回 1.0、失败返回 0.0(见 modeling_classifier.py#L237-L245); - 训练时
forward返回(loss, {"accuracy": ...}),可直接对接训练循环; - 配置校验要求输入特征中必须存在以
observation.image开头的图像特征(validate_features)。
2.2 SARM:面向长程操作的阶段感知奖励建模
SARM(Stage-Aware Reward Modeling for Long Horizon Robot Manipulation)配置类位于 src/lerobot/rewards/sarm/configuration_sarm.py。其核心设计是annotation_mode三档模式:
single_stage(默认):无需任何额外标注,将整条轨迹视为一个阶段(稀疏 head 学习任务完成度);dense_only:使用 VLM 生成的细粒度标注训练稠密 head,同时自动生成覆盖全轨迹的单个稀疏「task」阶段;dual:稀疏(高层)+ 稠密(细粒度)双 head 全量训练。
时序建模上采用双向抽帧:observation_delta_indices以当前帧为中心,向前后各取frame_gap=30(30fps 下约 1 秒)间隔的帧(见 configuration_sarm.py#L217-L236),配合max_rewind_steps=4的时序回退增强(rewind_probability=0.8),训练序列长度为1 + n_obs_steps + max_rewind_steps = 13帧。输出特征包含stage与progress两类奖励头,架构默认hidden_dim=768、num_heads=12、num_layers=8。SARM 预设了 AdamW 优化器(lr=5e-5)与余弦退火调度器(warmup 500 步、decay 50000 步),训练时无需额外配置优化器。
2.3 ROBOMETER:通用视频-语言奖励模型
ROBOMETER 配置类位于 src/lerobot/rewards/robometer/configuration_robometer.py,基于Qwen3-VL-4B(base_model_id="Qwen/Qwen3-VL-4B-Instruct")微调,带progress / preference / success三个头。其关键机制:
- 输入为轨迹视频 + 任务描述,逐帧输出
[0,1]的稠密任务进度与帧级成功率,服务于离线/在线 RL、数据筛选与检索、自动失败检测; reward_output可在"progress"与"success"间切换,success_threshold=0.5控制二值化;frame_pooling支持mean/boundary/attention三种逐帧池化策略;progress_loss_type支持l1/l2/discrete(离散分箱,默认 10 箱);- 与上游权重复原相关的特殊 token 顺序被显式固定为数据契约(见 configuration_robometer.py#L39-L45):
<|split_token|>、<|reward_token|>、<|pref_token|>、<|sim_token|>、<|prog_token|>,任何增删或换序都会导致保存的 embedding 行与 token id 错位; - 配置初始化时会读取 Qwen3-VL 的 config 与 tokenizer,将
vocab_size扩为len(tokenizer) + 5 = 151,674,与发布的Robometer-4B检查点一致; - 默认
pretrained_path="lerobot/Robometer-4B",即开箱即用的官方预训练权重。
2.4 TOPReward:零样本 token 对数概率奖励
TOPReward 配置类位于 src/lerobot/rewards/topreward/configuration_topreward.py,其实现文档(src/lerobot/rewards/topreward/modeling_topreward.py)明确指出它是inference-only、不可训练的模型:forward有意继承基类的NotImplementedError,因此is_trainable恒为False,所谓「检查点」只是单个config.json,VLM 权重(默认Qwen/Qwen3-VL-8B-Instruct)在加载时按 Hub id 现取。
奖励的计算方式是概率化的:处理器把「视频 + 指令 + 后缀」组装成 prompt,默认后缀模板为
{instruction} Decide whether the above statement is True or not. The answer is: True然后只对末尾的"True"标记解除 label 掩码,最终奖励即log P("True" | 视频 + prompt + 指令)(见 modeling_topreward.py#L29-L41)。关键参数:max_frames=16(每样本送入 VLM 的帧数上限)、fps=2.0(Qwen 视频处理器的元数据)、add_chat_template开关、success_threshold(有限值时返回(reward > threshold).float()的二值结果)、max_input_length=32768(超限样本抛ValueError)。
注意:TOPReward 属于「零样本」方案,
get_optimizer_preset返回None;与此对应,基类 src/lerobot/configs/rewards.py 中优化器预设的注释也写明"Nonefor zero-shot models"。
三、从零训练并发布到 Hub
模板中给出的训练命令是发布奖励模型的推荐姿势,本质上是调用 lerobot_train.py 并把reward_model.type指定为上述四种类型之一:
lerobot-train \ --dataset.repo_id=${HF_USER}/<dataset> \ --reward_model.type={{ model_name | default("reward_classifier", true) }} \ --output_dir=outputs/train/<desired_reward_model_repo_id> \ --job_name=lerobot_reward_training \ --reward_model.device=cuda \ --reward_model.repo_id=${HF_USER}/<desired_reward_model_repo_id> \ --wandb.enable=true各参数含义与注意点:
| 参数 | 说明 | 备注 |
|---|---|---|
--dataset.repo_id | 训练用数据集的 HF repo id | 需替换${HF_USER}/<dataset>占位符 |
--reward_model.type | 奖励模型类型:reward_classifier/sarm/robometer/topreward | 模板默认渲染为reward_classifier;topreward为零样本模型,实际上没有可训练权重 |
--output_dir | 本地输出目录 | 检查点写入outputs/train/<desired_reward_model_repo_id>/checkpoints/ |
--job_name | 训练任务名 | 同时用于 WandB 等日志分组 |
--reward_model.device | 训练设备,如cuda | 基类 RewardModelConfig 会自动校验设备可用性,不可用时会回退到自动选择 |
--reward_model.repo_id | 目标 Hub 仓库 id,训练完成推送的地址 | 与--reward_model.push_to_hub配合使用 |
--wandb.enable | 是否启用 WandB 日志 | 训练奖励模型默认可开启 |
从 src/lerobot/configs/train.py 可见,TrainPipelineConfig中reward_model与policy二选一;当配置了--reward_model.path时(train.py#L200-L214),训练器会从该路径加载已有奖励模型的配置并应用 CLI 覆盖项,实现断点续训。训练入口在 lerobot_train.py#L454-L459 通过make_reward_model实例化模型,并在训练完成后将配置、模型权重(safetensors 单文件)、前后处理器一起推送至reward_model.repo_id。
训练产物:检查点目录包含config.json(含奖励模型配置与 Hub 元数据)与model.safetensors。序列化逻辑在 src/lerobot/rewards/pretrained.py:_save_pretrained由主进程写入,分布式场景下副本权重一致,因此无需集体通信。
四、在 Python 中加载与推理
模板提供了最小可用的加载与推理片段:
from lerobot.rewards import make_reward_model reward_model = make_reward_model(pretrained_path="<hf_user>/<reward_model_repo_id>") reward = reward_model.compute_reward(batch)4.1make_reward_model工厂的工作方式
工厂函数位于 src/lerobot/rewards/factory.py#L107-L135。其逻辑为:
- 通过
get_reward_model_class(cfg.type)动态导入对应类(使用懒加载,避免一次性加载全部模型依赖,见 factory.py#L33-L70); - 若配置中设置了
pretrained_path,则调用from_pretrained从本地目录或 HF Hub 下载权重;否则从零初始化; - 统一将模型
to(cfg.device)。
from_pretrained的完整签名(src/lerobot/rewards/pretrained.py#L83-L142)支持revision(指定 Hub commit/branch/tag 固定版本)、token(私有仓库鉴权)、cache_dir、local_files_only、strict(严格检查权重键名)等参数。注意:加载完成后模型默认处于eval()模式——若需继续训练,必须显式调用reward.train()。
4.2compute_reward:统一的奖励接口
基类 PreTrainedRewardModel 定义了抽象方法compute_reward(batch) -> Tensor(pretrained.py#L165-L176),输入为包含至少观测张量的 batch 字典,输出形状为(batch_size,)的奖励张量。各类型的输出语义:
- Reward Classifier:
{0.0, 1.0}二值(成功/失败),或argmax多类索引; - SARM:逐帧稀疏/稠密 stage 分类与 progress 稠密进度;
- ROBOMETER:
reward_output="progress"时为[0,1]稠密进度,"success"时为阈值二值化成功率; - TOPReward:默认返回原始 token 对数概率,配置
success_threshold后返回二值成功判定。
训练与推理的区分由is_trainable属性承担(pretrained.py#L184-L191):可训练模型重写了forward,零样本模型(如 TOPReward)继承基类实现并抛出NotImplementedError。这一契约在 tests/rewards/test_reward_model_base.py 中有对应测试覆盖("A reward model that only implementscompute_rewardis zero-shot")。
4.3 预处理与后处理管线
奖励模型同样走处理器管线。make_reward_pre_post_processors(factory.py#L138-L205)按配置类型分派到各子包的 processor 工厂。以 Reward Classifier 为例(src/lerobot/rewards/classifier/processor_classifier.py#L32-L80):预处理器依次执行输入/输出特征的NormalizerProcessorStep(依据dataset_stats与normalization_mapping)与DeviceProcessorStep;后处理器将输出移回 CPU 并施加恒等步骤。SARM 的处理器还会注入数据集元数据(dataset_meta),用于阶段标注对齐;ROBOMETER/TOPReward 的处理器则负责把视频帧、指令与 prompt 组装成 VLM 所需的编码张量。
测试方面,tests/rewards/test_modeling_topreward.py 与 tests/rewards/test_modeling_robometer.py 分别验证了compute_reward返回(B,)形状、success_threshold二值化、以及缺失输入键时报错的契约行为。
五、模型卡元数据(Model Details)
模板末尾的Model Details区块要求填充license字段,其默认值为占位符[More Information Needed]。在实际训练中,该字段来源于奖励模型配置基类 RewardModelConfig 的 Hub 元数据字段:
| 字段 | 类型 | 说明 |
|---|---|---|
license | str | 开源协议标识,如 ROBOMETER 默认apache-2.0、TOPReward 默认mit |
tags | list[str] | 检索标签,如["reward-model", "vision-language", "qwen3-vl", "zero-shot"] |
private | bool | 推送时是否创建私有仓库 |
push_to_hub | bool | 训练结束是否自动推送 |
repo_id | str | 目标 Hub 仓库 id |
各具体配置类已为license/tags提供合理默认值(见 configuration_robometer.py#L62-L65、configuration_topreward.py#L100-L103),训练时可通过 CLI 覆盖。这些元数据随config.json一起保存,是模型卡渲染与 Hub 检索的关键依据。
六、端到端工作流小结
- 选型:根据任务确定奖励模型类型——轻量图像级成败判断选
reward_classifier,长程操作需要阶段感知稠密奖励选sarm,视频-语言通用奖励选robometer,希望零成本、零微调地复用现成 VLM 选topreward; - 训练:
lerobot-train指定--reward_model.type与数据集,检查点落盘到outputs/train/<repo_id>/checkpoints/; - 发布:训练完成后推送
config.json+model.safetensors(TOPReward 仅推送config.json)至--reward_model.repo_id,Hub 元数据驱动模型卡渲染; - 推理:
make_reward_model(pretrained_path=...)一行加载,compute_reward(batch)得到(batch_size,)奖励向量,作为 RL 奖励信号、数据筛选分数或失败检测器使用。
更多细节可继续研读:src/lerobot/rewards/factory.py、src/lerobot/rewards/pretrained.py、src/lerobot/configs/rewards.py,以及测试目录 tests/rewards 中各类模型的契约测试。
【免费下载链接】lerobot🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning项目地址: https://gitcode.com/GitHub_Trending/le/lerobot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考