errm / docs /PROJECT_OVERVIEW.md
yuffish's picture
Add files using upload-large-folder tool
a741a7c verified

Reward Model for Robotics - 项目概述

项目目标

训练一个**奖励模型 (Reward Model)**,用于为后续 Robotics VLA (Vision-Language-Action) 模型的 Policy 训练提供奖励信号。

核心理念

通过视觉观察机器人操作视频,评估每一帧/每一步的:

  • **阶段识别 (Stage)**:reach → grasp → lift → move → place → retract
  • 奖励组件:reachout, grasp, collision, fall, smooth
  • 综合指标:reward, delta, success_prob, failure

数据来源

1. 真机数据 (Real Robot Data)

数据源 位置 说明
DROID 数据集 /playpen-ssd/dataset/droid_raw/1.0.1/ 主要数据源,包含多个机构的机器人操作数据
PennPAL 同上 包含 failure/success 标注
AUTOLab 同上 包含多种任务类型

数据统计

  • 总轨迹数:15,157 条 (failure 数据)
  • 涵盖任务类型:300+ 种
  • 主要数据源:AUTOLab (3618), ILIAD (1303), IPRL (1298), 等

2. 仿真数据 (Simulation Data)

数据源 位置 说明
fangyu 仿真数据 /playpen-ssd/yufang/projects/reward/cokecan-50 ~800-900 条轨迹
yangyue 失败数据 /playpen-ssd/dataset/libero_failures/dec_29_2025_v1 Libero 环境失败案例
本地仿真数据 ./data/cokecan-50/ 包含 fall, collision, grasp, smooth, success 分类

仿真数据格式

{
  "joint_poss": [[...], [...], ...],  // 关节位置序列
  "stages": [0, 0, 1, 1, 2, ...],      // 阶段标签
  "rewards": {
    "reachout": [...],
    "grasp": [...],
    "collision": [...],
    "fall": [...],
    "smooth": [...]
  }
}

项目架构

RewardModel/
├── api_batch_improved.py      # GPT-4 视频标注(滑动窗口模式)
├── api_batch_hf_dataset.py    # 处理 HuggingFace 数据集
├── video_process.py           # 从 DROID TFDS 提取视频
├── extract_frames_to_images.py # 从视频提取帧图片
├── convert_to_sft.py          # 转换为 SFT 训练格式
│
├── caption/                   # 视频描述生成
│   ├── infer_caption.py       # 单视频推理
│   └── infer_caption_batch.py # 批量推理(Qwen VL)
│
├── data_sta/                  # 数据统计与上传
│   ├── count_failure_trajectories.py
│   ├── prepare_hf_dataset.py  # 准备 HuggingFace 数据集
│   └── upload_to_huggingface.py
│
├── data/                      # 本地数据
│   ├── cokecan-50/            # 仿真数据(按类型分类)
│   ├── frames/                # 提取的帧图片
│   └── sft_*.json             # SFT 训练数据集
│
├── droid_processed/           # 处理后的 DROID 数据
│   └── episode_*.json         # 每个 episode 的元数据
│
├── weights_reward_sft*/       # 训练权重
│   └── checkpoint-*/          # LoRA/Full 检查点
│
└── output/                    # 标注输出
    └── labels_*.jsonl         # GPT/模型标注结果

数据处理流程

流程图

原始视频数据
    ↓
[video_process.py] 从 TFDS 提取视频和元数据
    ↓
[extract_frames_to_images.py] 抽帧保存为图片
    ↓
[api_batch_improved.py] 发送给 GPT-4 打分
    ↓
标注 JSONL 文件
    ↓
[convert_to_sft.py] 转换为 SFT 格式
    ↓
SFT 训练数据集 (.json)
    ↓
[训练脚本] LoRA/Full SFT 微调
    ↓
Reward Model 权重

1. 视频预处理

从 TFDS 提取

# video_process.py
ds = tfds.load("droid_100", data_dir="/playpen-ssd/dataset/", split="train")
# 提取 wrist_image_left + exterior_image_1_left
# 保存为 MP4 视频 + JSON 元数据

从原始视频抽帧

# extract_frames_to_images.py
# 根据标注的 frame_index 提取对应帧
# 支持 mirror/flat_hash 两种保存模式

2. GPT 标注

改进版特性

  • 动态任务描述(从 metadata JSON 提取)
  • 滑动窗口分析(WINDOW_SIZE=5, STRIDE=3)
  • 上下文传递(前一窗口结果作为上下文)
  • 对齐仿真奖励指标

输出格式

{
  "video_id": "22008760",
  "task": "Move object into container",
  "t": 0,
  "frame_index": 0,
  "stage": 0,
  "stage_name": "reach",
  "reachout": 0.3,
  "grasp": 0.0,
  "collision": 0.0,
  "fall": 0.0,
  "smooth": 0.8,
  "reward": 0.55,
  "delta": 0.0,
  "success_prob": 0.5,
  "failure": 0,
  "explanation": "Robot arm is reaching..."
}

3. SFT 数据格式

训练格式

{
  "conversation": [
    {
      "from": "human",
      "value": "<Image: path/to/frame.jpg>\nPlease output the execution stage and reward..."
    },
    {
      "from": "assistant",
      "value": "{\"stage\": \"reach\", \"reward\": 0.5, ...}"
    }
  ]
}

已完成工作

数据处理 ✓

  • DROID 数据集统计和分析
  • 视频帧提取脚本
  • GPT-4 批量标注脚本(基础版 + 改进版)
  • 滑动窗口分析模式
  • SFT 数据格式转换

标注系统 ✓

  • 与仿真奖励指标对齐
  • 6 阶段定义(reach, grasp, lift, move, place, retract)
  • 5 奖励组件(reachout, grasp, collision, fall, smooth)
  • 动态任务描述提取

数据管理 ✓

  • HuggingFace 数据集准备脚本
  • 采样策略支持(balanced, random, proportional)
  • 上传指南文档

模型训练 ✓

  • LoRA SFT 训练配置
  • 特殊 token 版本实验
  • 多个训练检查点

阶段与奖励定义

操作阶段 (Stage)

索引 名称 描述
0 reach 机器人向目标物体伸手
1 grasp 机器人尝试抓取物体
2 lift 机器人抬起物体
3 move 机器人携带物体移动
4 place 机器人放置物体
5 retract 机器人收回到中性位置

奖励组件 (Reward Components)

组件 范围 描述
reachout 0.0-1.0 接近目标的进度
grasp 0.0-1.0 抓取质量(0=无接触, 1=稳固)
collision 0.0-1.0 碰撞惩罚(0=无碰撞, 1=严重)
fall 0.0-1.0 掉落惩罚(0=稳定, 1=掉落)
smooth 0.0-1.0 运动平滑度(0=抖动, 1=平滑)

综合指标

  • reward: 综合奖励值 ≈ (reachout + grasp + smooth - collision - fall) / 3
  • delta: 相对上一步的奖励变化(-1.0 到 1.0)
  • success_prob: 最终成功概率估计(0.0 到 1.0)
  • failure: 是否已失败(0 或 1)

模型训练权重

已保存检查点

版本 路径 说明
v0 weights_reward_sft/v0-20251105-171242/ 初始版本
v1 weights_reward_sft/v1-20251110-230134/ 改进版本
v0 (special token) weights_reward_sft_special_token/v0-20251110-232149/ 特殊 token 版本
v1 (special token) weights_reward_sft_special_token/v1-20251110-234131/ 特殊 token v1
v2 (special token) weights_reward_sft_special_token/v2-20251110-235126/ 完整 merge 版本

关键配置

GPT 标注配置

MODEL_NAME = "gpt-4o"  # 推荐模型
FPS_SAMPLE = 2         # 帧采样率
USE_SLIDING_WINDOW = True
WINDOW_SIZE = 5        # 窗口大小
WINDOW_STRIDE = 3      # 滑动步长

数据筛选规则

PROCESS_TYPE = "failure"     # failure/success/both
VIDEO_NAME_PATTERN = "2*.mp4"  # 以 2 开头
EXCLUDE_STEREO = True        # 排除 stereo 视频

快速开始

1. 环境配置

pip install openai decord pillow python-dotenv tqdm tensorflow_datasets

2. 设置 API Key

export OPENAI_API_KEY="your-key-here"
# 或创建 .env 文件

3. 运行标注

cd /home/jqliu/projects/RewardModel

# GPT 标注
python api_batch_improved.py

# 或 Qwen VL 标注
cd caption && python infer_caption_batch.py

4. 转换训练数据

python extract_frames_to_images.py
python convert_to_sft.py

参考文档