改进版视频标注 API 使用说明
主要改进
1. 动态任务描述(已实现 ✓)
- 自动读取 metadata JSON:根据视频路径自动查找对应的
metadata_*.json文件 - 提取任务描述:从 JSON 中提取
current_task字段 - 动态插入 prompt:将任务描述动态插入到 GPT prompt 中
示例:
视频路径: PennPAL/failure/2023-10-01/Sun_Oct__1_16:56:53_2023/recordings/MP4/14436910.mp4
Metadata: PennPAL/failure/2023-10-01/Sun_Oct__1_16:56:53_2023/metadata_PennPAL+c5f808b7+2023-10-01-16h-56m-53s.json
任务: "Open or close hinged object (ex: hinged door, microwave, oven, book, dryer, toilet, box)"
2. 视频序列帧分析(已实现 ✓)
提供两种处理模式:
模式 A:基础模式(USE_SLIDING_WINDOW = False)
- 一次性发送所有帧给 GPT
- 适合短视频(< 20 帧)
- 成本较低,处理速度快
模式 B:滑动窗口模式(USE_SLIDING_WINDOW = True)⭐ 推荐
- 连续帧分析:每次发送 WINDOW_SIZE 个连续帧
- 捕捉动态关系:GPT 可以看到连续的动作序列,判断:
- 运动是否平滑还是抖动
- 物体是否稳定还是摇晃
- 进度是前进、停滞还是倒退
- 上下文传递:前一个窗口的分析结果作为上下文传递给下一个窗口
- 参数配置:
WINDOW_SIZE = 5:每个窗口包含 5 个连续帧WINDOW_STRIDE = 3:窗口每次滑动 3 帧(允许重叠)
滑动窗口示例:
视频帧: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
窗口 1: [0, 1, 2, 3, 4] → 分析 + 上下文A
窗口 2: [3, 4, 5, 6, 7] → 分析 + 上下文B(基于窗口1)
窗口 3: [6, 7, 8, 9, 10] → 分析 + 上下文C(基于窗口2)
窗口 4: [9, 10, 11, 12] → 分析 + 上下文D(基于窗口3)
3. 对齐仿真奖励指标(已实现 ✓)
新增字段(与仿真数据对齐)
{
"stage": 0, // 阶段索引 (0-5)
"stage_name": "reach", // 阶段名称
// 奖励组件(与仿真对齐)
"reachout": 0.8, // 接近物体的进度 (0.0-1.0)
"grasp": 0.0, // 抓取质量 (0.0-1.0)
"collision": 0.0, // 碰撞惩罚 (0.0-1.0)
"fall": 0.0, // 掉落惩罚 (0.0-1.0)
"smooth": 0.9, // 运动平滑度 (0.0-1.0)
// 综合指标
"reward": 0.85, // 总奖励
"delta": 0.05, // 奖励变化
"success_prob": 0.7, // 成功概率
"failure": 0, // 是否失败 (0/1)
"explanation": "..." // 解释
}
阶段定义
0: reach - 伸手接近物体
1: grasp - 抓取物体
2: lift - 抬起物体
3: move - 移动物体
4: place - 放置物体
5: retract - 收回手臂
奖励组件说明
reachout(接近)
- 0.0: 机器人远离目标
- 0.5: 正在接近
- 1.0: 已接触或达到目标位置
grasp(抓取)
- 0.0: 无接触
- 0.5: 接触但不稳定
- 1.0: 稳固抓取
collision(碰撞惩罚)
- 0.0: 无碰撞
- 0.5: 轻微碰撞
- 1.0: 严重碰撞
fall(掉落惩罚)
- 0.0: 物体稳定
- 1.0: 物体掉落/滚落
smooth(平滑度)
- 0.0-0.3: 抖动、突然运动
- 0.8-1.0: 平滑、稳定运动
配置参数
# 基础配置
ROOT = Path("/playpen-ssd/dataset/droid_raw/1.0.1/AUTOLab/failure")
TARGET_NAME = "22008760.mp4"
OUTPUT_FILE = "./output/labels_batch_improved.jsonl"
FPS_SAMPLE = 2
MODEL_NAME = "gpt-4o" # 推荐使用 gpt-4o
MAX_VIDEOS = 10
START_INDEX = 0
# 滑动窗口配置
USE_SLIDING_WINDOW = True # 推荐设为 True
WINDOW_SIZE = 5 # 每个窗口的帧数
WINDOW_STRIDE = 3 # 窗口滑动步长
输出格式
输出 JSONL 文件,每行一个时间步的标注:
{
"video_path": "/playpen-ssd/dataset/.../22008760.mp4",
"video_id": "22008760",
"task": "Move object into or out of container",
"t": 0,
"frame_index": 0,
"total_frames": 229,
"native_fps": 60.0,
"window_idx": 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 toward the container..."
}
使用方法
1. 安装依赖
pip install openai decord pillow python-dotenv tqdm
2. 设置 API Key
创建 .env 文件:
OPENAI_API_KEY=your_api_key_here
3. 运行脚本
cd /home/jqliu/projects/RewardModel
python api_batch_improved.py
4. 查看结果
# 查看输出文件
cat output/labels_batch_improved.jsonl | jq .
# 统计不同阶段的分布
cat output/labels_batch_improved.jsonl | jq -r '.stage_name' | sort | uniq -c
# 查看失败案例
cat output/labels_batch_improved.jsonl | jq 'select(.failure == 1)'
成本估算
使用 GPT-4o 的成本(2024年价格):
- 输入: $2.50 / 1M tokens
- 输出: $10.00 / 1M tokens
示例视频(2秒,60fps,采样2fps):
- 帧数: ~4 帧
- 每帧图片 token: ~1000 tokens
- 每视频成本: ~$0.01-0.02
对比原版本的改进
| 特性 | 原版本 | 改进版本 |
|---|---|---|
| 任务描述 | 固定 | ✓ 从 metadata 动态提取 |
| 帧分析方式 | 单次所有帧 | ✓ 滑动窗口 + 上下文传递 |
| 动态关系分析 | 有限 | ✓ 连续帧序列,捕捉运动平滑度 |
| 奖励指标 | 基础 | ✓ 对齐仿真(reachout, grasp, collision, fall, smooth) |
| 阶段定义 | 字符串 | ✓ 数值索引 + 名称(与仿真对齐) |
| 上下文传递 | 无 | ✓ 前一窗口结果作为上下文 |
建议
- 首次测试:先设置
MAX_VIDEOS = 1测试单个视频 - 模型选择:推荐使用
gpt-4o,性能最佳且成本较低 - 窗口大小:
- 短视频(<3秒):WINDOW_SIZE = 3-5
- 长视频(>5秒):WINDOW_SIZE = 5-7
- 质量检查:定期检查输出,确保标注质量
- 批处理:可以使用多进程并行处理多个视频
故障排除
问题1:找不到 metadata 文件
- 检查视频路径结构是否正确
- 确认 metadata JSON 文件存在于轨迹根目录
问题2:API 超时
- 减小 WINDOW_SIZE
- 增加重试机制
- 检查网络连接
问题3:输出格式错误
- 检查 GPT 返回的 JSON 是否有效
- 可能需要调整 prompt 或增加输出格式验证
后续扩展
可以进一步添加:
- 多视角融合(同时分析多个摄像头)
- 失败检测器(专门识别失败模式)
- 质量评分(评估标注的可信度)
- 人工审核界面(可视化标注结果)