GO-3 Preview 的动作是当场生成的吗 / 延迟和任务粒度怎么权衡

文章导读
先给判断:GO-3 Preview 这类策略模型在每一拍推理时通常只生成“一段”动作,而不是把整条任务一次性算完再执行。所谓“当场生成”,指的是当拍这一段动作在现场算出;任务剩下的部分要等下一拍再推理。因此延迟是三段叠加的结果:采一帧、推一次、把动作写下去并等执行器动起来。粒度权衡的本质是:段切得越粗,重新决策越少、动作越连贯,但中途偏了纠不回来;段切得越细,纠偏越快,但每段都要重付一次推理延迟,
📋 目录
  1. 壹 列出从输入到动作要经过的环节
  2. 贰 用打点方式测一次端到端间隔
  3. 叁 同一任务分别按粗粒度和细粒度各跑一遍
  4. 肆 判断自己的节拍该落在哪一档
A A

先给判断:GO-3 Preview 这类策略模型在每一拍推理时通常只生成“一段”动作,而不是把整条任务一次性算完再执行。所谓“当场生成”,指的是当拍这一段动作在现场算出;任务剩下的部分要等下一拍再推理。因此延迟是三段叠加的结果:采一帧、推一次、把动作写下去并等执行器动起来。粒度权衡的本质是:段切得越粗,重新决策越少、动作越连贯,但中途偏了纠不回来;段切得越细,纠偏越快,但每段都要重付一次推理延迟,甚至出现排队。

判断 GO-3 Preview 的动作是否当场生成,先看它在一次推理里输出的是单个动作还是一段动作序列:若是序列,则当场生成的是这一段,后续动作靠下一次推理接续。处理方向是把延迟拆成采集、推理、下发三段分别打点,再在同一任务上分别用粗粒度(整段)和细粒度(拆四段)各跑一遍,看失败落在第几步。适用场景是有相机触发与执行器反馈可打点的环境;边界是测量结论只在同一套硬件和同一批任务下成立,换设备需重测。

列出从输入到动作要经过的环节

把“延迟”当成一个整体去猜,通常猜不准,因为三段里任何一段的抖动都会被误算到模型头上。建议先按下面这张表,在自己的链路上标出可观测时间点,再决定优化哪一段。

环节可观测的起止时间点常见延迟来源
感知采集相机触发或曝光开始 → 帧数据进入主机缓冲(帧回调入口)曝光与传输、解码、取帧队列积压、多路相机不同步
模型推理推理请求入队 → 动作序列返回(推理出口)图像预处理、前向计算、后处理与平滑、批处理等待、显存与线程竞争
动作下发指令写入 → 执行器反馈出现对应变化总线/控制器周期、插补与限速、通信重传、控制柜内部队列

三段的观测点必须能被同一个 frame_id 或 step_id 串起来,否则事后对不上账。如果某段的起止点在你的接入方式里拿不到(例如控制器不暴露内部周期),就把它和相邻可观测点合并成一个“黑盒段”来测,仍然比整体猜要好。

用打点方式测一次端到端间隔

下面是通用打点骨架,字段名和调用位置按你的实际接入替换,重点是把同一拍的四类事件写进同一份日志。

import time, json

def tick(tag, **kw):
    # 用单调时钟,避免系统时间跳变污染间隔
    print(json.dumps({"t": time.perf_counter(), "tag": tag, **kw}, ensure_ascii=False))

# 帧回调里
tick("frame_in", frame_id=fid)

tick("infer_start", frame_id=fid)
actions = policy.infer(obs)   # 替换为你的推理调用
tick("infer_end", frame_id=fid, n=len(actions))

tick("cmd_write", frame_id=fid)   # 指令写入总线/控制器
tick("fb_change", frame_id=fid)   # 执行器反馈出现变化时打
  1. 统一时钟:同一进程用单调时钟;相机与控制器不在同一主机时,先做一次时钟对齐,或都换算到同一台主机的接收时刻。
  2. 对齐方法:下发一个方向明确、幅度足够大的单步动作,避开随机波动,然后在执行器反馈里找同向变化的第一个采样点,作为“动作生效”时刻。
  3. 相机侧对齐:让一个可见标记进入视野,以标记首次出现在帧里的那一帧作为“采集完成”的参照,而不是按调用时间反推。
  4. 重复多次看分布:记录端到端间隔的最小值、常见值和最差值。选粒度时看最差值和抖动,只看均值容易在偶发卡顿上翻车。

做完这一步,你会得到三个分项间隔和一条端到端间隔。分项之和与端到端之间的差额,通常就是队列等待和同步开销,不要忽略它。

同一任务分别按粗粒度和细粒度各跑一遍

把同一个任务写成固定的步骤序列,先整段下发跑一遍,再拆成四段、每段单独推理下发跑一遍,其他条件(初始位姿、物体位置、光照)尽量保持一致,然后记录失败发生在第几步。

GO-3 Preview 的动作是当场生成的吗 / 延迟和任务粒度怎么权衡
# 任务分解的可替换示例:steps 数量直接决定重新决策的频率
task: "把物体放进容器"
steps:
  - id: 1
    goal: "移动到物体上方"
  - id: 2
    goal: "下降到抓取位"
  - id: 3
    goal: "闭合夹爪并抬起"
  - id: 4
    goal: "移动到容器口并释放"
粒度决策次数观察到的现象失败发生在第几步
一段(整段下发)1动作连贯,但起始偏差会一路带到末尾填写:如“第 3 步抓空”
四段(每段一次推理)4每步可纠偏,但段间衔接处可能出现停顿或抖动填写:如“第 2 步下发后等待下一拍”

失败位置比成功次数更有信息量:粗粒度失败集中在后段,说明误差累积;细粒度失败集中在段间,说明推理间隔跟不上执行节奏。两种现象对应完全不同的调法,前者加反馈或缩段长,后者减少每段的重决策开销。

判断自己的节拍该落在哪一档

把测到的端到端间隔和你场景能容忍的响应间隔放在一起比,结论才有依据。判断顺序建议是:先算容忍间隔,再看单次推理间隔占容忍间隔的比例,最后看单段执行时长是否短于端到端间隔。

选择细粒度(每步一次推理下发),通常满足这几条:场景容忍的响应间隔接近你测到的单次推理间隔;失败代价高、需要频繁纠偏;物体位置或环境在执行过程中会变化。排除条件:如果每段执行时长比端到端间隔还短,指令会排队堆积,此时细粒度反而更差,应先降推理开销或合并步骤。

选择粗粒度(整段动作一次生成),通常满足这几条:容忍间隔明显大于端到端间隔;动作连续性要求高,停顿会被视为失败;环境在执行期间基本稳定。排除条件:如果末端反馈无法在中途纠正偏差,且偏差会累积到任务后段,就不要用粗粒度,或者至少把最后接近目标的那一段拆细。

介于两者之间时,可以先做非均匀切分:靠近目标的阶段切细,长距离移动阶段保持粗粒度。改完后仍用上面那套打点和对比表复测,确认失败位置发生了移动,再决定是否定型。