# TOPReward

TOPReward 是一个**零样本奖励模型**，它从现成的视觉语言模型（VLM）中提取 token 对数概率，作为机器人奖励信号。给定一段视频轨迹和一条任务指令，它会返回该指令为真时 VLM 的对数似然值——无需微调。

**论文**：[TOPReward: Token Probabilities as Hidden Zero-Shot Rewards for Robotics](https://arxiv.org/abs/2602.19313) **项目**：[topreward.github.io](https://topreward.github.io/webpage/) **原始代码**：[github.com/TOPReward/TOPReward](https://github.com/TOPReward/TOPReward) **默认骨干网络**：[Qwen/Qwen3-VL-8B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct)

## 概述

TOPReward 会询问一个通用 VLM，在**机器人尝试完成该任务的视频**条件下，任务指令的可能性有多大。具体而言，给定：

- 轨迹视频（一系列帧）。
- 任务指令（例如 _“打开抽屉”_）。

它会构建一个如下形式的聊天提示

```text
<video>
"The above video shows a robot manipulation trajectory that completes the
 following task: <instruction> Decide whether the above statement is True
 or not. The answer is: True"
```

将其通过 VLM 进行前向传播，对除最后一个 token 之外的所有位置应用标签掩码，然后读取该 token 的对数概率——默认情况下，这是用于闭合后缀模板的字面量 `"True"`。由此得到的 `log P("True" | video + prompt + instruction)` 即为奖励值。

由于该方法仅依赖于冻结的 VLM，TOPReward 是**零样本**的：无需托管任何微调后的权重。LeRobot 中的“模型”是 `transformers` 的 `Qwen3VLForConditionalGeneration` 加上标签掩码逻辑的一个小型封装。处理器负责管理分词器并构建完整的聊天提示（EO-1/Robometer 模式）。

## LeRobot 集成涵盖的内容

- 通过 LeRobot 进行标准的 `reward_model.type=topreward` 配置。
- 通过 `transformers` 的 `Qwen3VLForConditionalGeneration` API 加载 VLM。
- 处理器中的提示词组装 + 分词（与上游 `QwenClient.compute_instruction_reward` 保持一致）。
- `compute_reward()` 为每个样本返回一个标量对数概率。
- LeRobot 奖励模型保存/加载 — `save_pretrained` 仅写入 `config.json`（VLM 由 `vlm_name` 标识）。
- 一个离线标注脚本，用于为 RA-BC 和 overlay 写入 `topreward_progress.parquet`（SARM 兼容模式）。

当前的 LeRobot 移植版本仅支持 **Qwen3-VL 客户端**。其他上游客户端（Gemini、OpenAI、Gemma、Molmo）可以作为后续附加功能添加。

## 安装要求

1. 按照[安装指南](./installation)安装 LeRobot。
2. 安装 TOPReward 可选附加组件：

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

或者，从源代码检出中使用 `uv`：

```bash
uv sync --extra topreward
```

这会引入 `transformers`。首次运行 TOPReward 时，Hugging Face 还会从 Hub 下载 VLM 权重（Qwen3-VL-8B-Instruct 约为 16 GB）。强烈建议使用 GPU。

## 模型输入和输出

TOPReward 预期：

- 轨迹视频或帧序列。
- 自然语言任务描述。

在 LeRobot 数据集中，预处理器读取：

| 配置字段              | 默认                     | 含义                                       |
| ------------------------- | --------------------------- | --------------------------------------------- |
| `reward_model.image_key`  | `observation.images.top`    | TOPReward 使用的相机观测          |
| `reward_model.task_key`   | `task`                      | 在任务字符串中键入互补数据 |
| `reward_model.max_frames` | `16`                        | 每个样本的帧数上限                      |
| `reward_model.fps`        | `2.0`                       | 传递给 Qwen 视频处理器的元数据   |
| `reward_model.vlm_name`   | `Qwen/Qwen3-VL-8B-Instruct` | 底层 VLM 的 Hugging Face Hub id     |

模型返回：

- `compute_reward(batch)`：每个样本一个对数概率。值越高，表示任务与视频的对齐程度越好。当 `success_threshold` 为有限值时，返回二值化阈值结果。

## 用法

### 直接加载奖励模型

```python
from lerobot.rewards.topreward import TOPRewardConfig, TOPRewardModel

cfg = TOPRewardConfig(
    vlm_name="Qwen/Qwen3-VL-8B-Instruct",
    device="cuda",
)
reward_model = TOPRewardModel(cfg)
```

### 使用奖励工厂

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

cfg = make_reward_model_config(
    "topreward",
    vlm_name="Qwen/Qwen3-VL-8B-Instruct",
    device="cuda",
    image_key="observation.images.top",
)
reward_model = make_reward_model(cfg)
preprocessor, postprocessor = make_reward_pre_post_processors(cfg)
```

预处理器对完整提示（视频 + 前缀 + 指令后缀）进行分词，并将 Qwen-VL 张量及 `prompt_length` 写入 `observation.topreward.*`。模型读取这些张量，基于 `prompt_length` 进行标签掩码，并提取对数概率奖励。

### 离线数据集标注

为 RA-BC 训练和叠加视频编写一个 `topreward_progress.parquet`：

```bash
# Sparse-dense (15 anchors per episode, matches upstream)
uv run python -m lerobot.rewards.topreward.compute_rabc_weights \
    --dataset-repo-id lerobot/libero_10_image \
    --num-samples 15 \
    --device cuda
```

然后为任意剧集渲染进度覆盖层：

```bash
uv run examples/dataset/create_progress_videos.py \
    --repo-id lerobot/libero_10_image \
    --episode 0 \
    --progress-file topreward_progress.parquet \
    --gif
```

## 配置说明

### 提示词参数

默认提示词与上游论文保持一致：

```text
prompt_prefix = "The above video shows a robot manipulation trajectory that completes the following task: "
prompt_suffix_template = "{instruction} Decide whether the above statement is True or not. The answer is: True"
```

两者均在 `TOPRewardConfig` 上暴露，用于消融实验。后缀模板 **必须** 包含 `{instruction}`。

### 聊天模板

`add_chat_template=True` 会在分词前，使用分词器的聊天模板包裹完整的提示词（包括指令）。默认值为 `False`，与上游论文的主要实验设置保持一致。

## 局限性

- 当前的 LeRobot 移植版本仅支持**推理且为零样本**；`forward()` 未被重写，且 `is_trainable` 返回 `False`。
- 仅支持 **Qwen3-VL 系列**；其他上游客户端不在支持范围内。
- TOPReward 继承了底层 VLM 的偏差。

## 参考

- [TOPReward 项目页面](https://topreward.github.io/webpage/)
- [TOPReward 论文](https://arxiv.org/abs/2602.19313)
- [原始 TOPReward 代码](https://github.com/TOPReward/TOPReward)
- [Qwen3-VL-8B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct)

## 引用

```bibtex
@article{chen2026topreward,
  title={TOPReward: Token Probabilities as Hidden Zero-Shot Rewards for Robotics},
  author={Chen, Shirui and Harrison, Cole and Lee, Ying-Chun and Yang, Angela Jin and
          Ren, Zhongzheng and Ratliff, Lillian J and Duan, Jiafei and Fox, Dieter and
          Krishna, Ranjay},
  journal={arXiv preprint arXiv:2602.19313},
  year={2026}
}
```

## 许可证

原始 TOPReward 代码库采用 MIT 许可证。LeRobot 移植版本遵循 LeRobot Apache 2.0 许可证；封装的 Qwen3-VL 权重则受原始 Qwen 许可证约束。

