真机回流数据标注
真机回流轨迹如何做人标、半自动和全自动标注,以及和 VLA / WAM 训练怎么接。
真机回流数据里,动作、状态、多相机画面已经有了,不要再标一遍。 标注的真正工作是给这些轨迹补上「这段在干什么、成没成、切在哪、对着哪个物体」。业界现在基本按三档做:人标金标、半自动扩量、全自动铺底再抽检。
先定标什么#
按投入产出排优先级。回流一批数据,通常只需要做到 L2;要训 \(\pi_{0.5}\) 式高层策略或 grounding,再加 L3;L4 是可选项。
| 层级 | 标什么 | 训练里干什么 | 建议方式 |
|---|---|---|---|
| L0 质量 | 成功 / 失败、失败类型、idle 段、丢弃原因 | 过滤脏数据,几乎立刻涨成功率 | 规则全自动 + 人抽检 |
| L1 任务句 | episode 级指令,可加 8–10 条改写 | VLA 的 task 条件 | 采集时写好;没有就 VLM 生成 + 人审 |
| L2 子任务 | [start, end] + 原子指令(how, not what) | 长程任务、分层策略 | 半自动为主 |
| L3 空间中间表示 | 目标物体框、夹爪框、接触帧、放置区 | \(\pi_{0.5}\) 先预测 bbox 再预测子任务 | SAM2 半自动 |
| L4 交互 / 认知 | 口头纠正、VQA、memory、plan | 可打断、可问答的 VLA | 全自动生成,人只审金标集 |
Physical Intelligence 在 \(\pi_{0.5}\) 里对长程数据是人手标子任务 + 相关 bbox;Hugging Face 现在把同类东西做成了 LeRobot 标注管线;InternRobotics 的 RoboInter 则是「人切段 + SAM2 跟物体」的半自动套件。
回流数据建议写成两列,和 LeRobot 对齐,后面换模型不用重标:
language_persistent:整段都成立的状态(当前子任务、plan、memory)language_events:只落在某一帧上的事件(夹爪闭合、口头纠正、VQA)
一批真机数据的总流程#
原始回流 episode
│
├─ 1. 机器闸门(全自动,不经过人)
│ 同步检查 → 去 idle → 过短 / 过长丢掉
│ 夹爪 / 速度突变 → 候选切点
│
├─ 2. 成功判定(半自动)
│ 规则 / VLM 预打标签 → 人只审不确定的
│
├─ 3. 语言(半自动 / 全自动)
│ VLM:先描述画面,再切子任务
│ 人改边界和措辞(金标 + 抽检)
│
├─ 4. 空间(半自动,按需)
│ 人点一下目标物体 → SAM2 跟踪整段
│ 接触帧 / 放置区由规则从动作导出
│
└─ 5. 金标冻结 + 抽检
5–10% 人复核,不一致的回写规则 / prompt不要一上来全员手标每一帧。先标 50–100 条金标,把词表、切分粒度、成功定义钉死,再放大。
L0:质量标注#
回流数据最脏的不是语言,是「人在想下一句、夹爪空合、失败还接着录」。
全自动:机器闸门怎么界定#
阈值跟控制频率挂钩。下面默认 15 Hz(DROID);20 Hz 把「帧数」乘 20/15,50 Hz 乘 50/15。先在 100 条回流上画直方图,再用百分位微调,不要直接抄死数字。
同步检查(整段丢弃或截断)#
查的是「这一帧的图、状态、动作是不是同一时刻」,不是任务成不成。任一条件不满足就打 sync_fail,默认整段丢掉:
| 检查 | 通过条件(起步值) | 不通过时 |
|---|---|---|
| 长度一致 | 各相机帧数、state、action 条数相差 ≤ 1 | 丢弃 |
| 时间戳单调 | t[i+1] - t[i] > 0,无回跳 | 丢弃 |
| 帧间隔 | 中位 dt 在标称周期 ±20% 内;单帧 dt > 3 个周期算掉帧 | 掉帧超过 5% 丢弃,否则从掉帧处截断 |
| 数值合法 | 无 NaN / Inf;关节、夹爪在限位内 | 丢弃 |
| 维数 | 与该本体 schema 一致 | 丢弃 |
| 多路时钟 | 腕部 / 第三人称 / 关节状态最大偏移 < 1 个控制周期 | 超过则该相机不用,或整段丢 |
去 idle(切掉静止,保留有效段)#
定义来自 Physical Intelligence 的 DROID idle filter,不要用「看起来没动」:
- 单帧是否 idle。 相邻两步关节速度差的绝对值,所有关节都
< 1e-3,则后一帧为 idle。若有纯夹爪动作,把夹爪开合变化也并进「非 idle」,否则拧瓶盖会被误删。 - 连续 idle 段。 连续 idle ≥ 7 帧(约 0.5 s) 整段删掉。短于 7 帧的停顿保留——那是接触、对准,不是人在发呆。7 这个数对应他们 chunk 策略每次真正执行的前 8 步:训练里不能出现「接下来一整块都是零动作」。
- 有效段够不够长。 删完 idle 后,剩下的连续运动段必须 ≥ 16 帧(约 1 s),更短的整段丢掉。
- 段尾再裁一截。 每个保留段再丢掉最后 10 帧。段尾动作 chunk 里后半截往往已经是停住,不裁的话模型仍会学到「快结束就输出静止」。
一条 episode 删完可能裂成多段:开头对准、中间思考、结尾松手都会被切掉,中间几段运动分别保留。全部被切光 → 整条丢弃。
若不用关节速度、只用末端位姿:把「速度差 < 1e-3 rad/s」换成末端线速度低于任务噪声,例如桌面操作 < 5 mm/s 且角速度很小,连续仍按 0.5 s / 1 s / 一段 chunk 这三档时间来,不要死盯 7/16/10 帧。
过短 / 过长(idle 切完之后再量)#
量的是切完 idle 后剩下的时长,不是原始录像墙钟时间。过短直接丢;过长不要丢,进「待拆分」。
| 短技能桌面(抓放、插拔) | 长程(收拾桌面、开关柜) | |
|---|---|---|
| 过短 → 丢弃 | < 2 s(或不够 1 个 action chunk + 1 帧观测) | < 10 s |
| 正常 | 约 3–40 s | 约 1–8 min |
| 过长 → 待拆分 | > 90 s | > 10–15 min |
过短通常是误触开始、对了一下就停、或 idle 切完什么都不剩。过长通常是一次录像里塞了多次尝试、中途聊天、或整段家务还没按失败点切开。
不要用绝对分钟一刀切全库。更稳的做法:
- 画出切完 idle 后的时长直方图。
- 过短取
max(2 s, 第 5 百分位),且不得短于 1 个训练 chunk。 - 过长取第 95 百分位,或「明显是多任务粘在一起」的拐点。
- 过长段按失败点、夹爪开合、或人按的 episode 边界拆开,拆完再走一遍闸门。
半自动:成功 / 失败#
不要只靠「操作员按了成功键」。回流里常见:人按了成功但物体没放到位。
- 规则:任务结束时目标物体是否进入放置区(若有检测)、夹爪是否按预期开合
- VLM:抽最后 4–8 帧 + 任务句,问「任务是否完成」
- 人只看:规则和 VLM 不一致的,以及随机 5%
失败用小词表,不要自由文本:grasp_fail / drop / collision / timeout / wrong_object / human_abort。失败段可以留作负样本或世界模型数据,但默认不要进 VLA 正样本。
L1–L2:语言标注#
这是回流数据最该补的一层。短技能(「抓杯子放到盘子」)有 episode 级 task 就够;长程(收拾桌面、开关柜门多步)必须有子任务时间轴。
人标(金标,不是全量)#
工具:时间轴打点即可。每人看第三人称 + 腕部,在切点打标。约束必须事先写死,否则三个人标出来对不齐:
- 粒度: 一条子任务对应一次「接触状态变化」。LeRobot 的定义:物体被拿起 / 被放下 / 到达新位置 / 盖子开合 / 容器内容物变化,才开新段。
- 写法: \(\pi_{0.7}\) / LeRobot 强调 how, not what。写
pick up the blue cup from the left of the sink,不要写do the next step或复述整句任务。 - 覆盖: 每一帧有且仅有一条当前子任务,中间不能有空洞。
- 最短时长: 建议 ≥ 1.5 秒,避免把接近、对准拆成十几段。
- 词表: 物体名、方位词、技能动词先冻结一份。同物多名会把策略训散。
人标只覆盖:金标集、难例、以及后面抽检打回的。
半自动(主路径)#
边界尽量用动作信号切,文案用 VLM 写,人只改错的。
切边界(规则,比纯 VLM 稳):
- 夹爪开 ↔ 合
- 末端速度由高变低后保持(接触 / 放置)
- 基座开始 / 停止移动(移动操作)
- 力 / 电流超过阈值(若有)
仿真或状态可观测的任务,还可以像 LIBERO 那样用「环境状态跳变」切子任务。真机没有物体位姿时,夹爪 + 速度是最稳的先验。
写文案(VLM): 不要让模型对着任务句直接幻想子任务。LeRobot 现在的标准是两步:
- Describe: 只叙述选定相机里实际看到的事,禁止猜任务
- Segment: 把叙述再喂回去,切成连续原子子任务
可选第三步 seeded-relabel: 边界锁死,只改措辞。生产上建议:金标和难例开,全量先关以省成本。