← 返回报告索引
2026-09-03 23:00–24:00 · 会话工作记录

这一夜做了什么:试验记录 schema v2、B0 证据升级、以及三个被证伪的说法

一份如实的工作记录。每条结论后面都标了证据等级 —— 实测(跑过,有输出)/未测(没跑过)/被挡住(想跑但没跑成)。 这条规矩是 2026-09-03 白天操作者提出批评后定下的,这份记录是它的第一次全面应用, 包括用它去检验别人论文里的数字。

一句话:试验数据管理 GOAL 的第 1 步做完并实测通过; 深度 GOAL 的 B0 路线因为一篇新论文(Oat-VLA)证据升了一档,但同时被我们自己的统计检验 按住了一半 —— 它的真机数字不显著。录制、数据上传、训练三条链一行没碰。

1 · 试验记录 schema v2(GOAL-TRIAL-DATA §3.1,第 1 步)

问题:05-training/trials/ 下 37 个文件、114 次试验, 其中 75 次失败是个黑箱 —— 记录里只有 outcome: "failure",没有原因。 而且三个读取端(robot_server.read_trials / gen_status.collect_trials / 面板 html)各写了一份「字段缺了怎么兜底」的逻辑, 兜底规则还不一样,同一个文件在两个地方能显示成两个数。

做了什么

文件动作规模
trials_io.py新建 —— 试验记录的唯一读写口径334 行
robot_server.py只改 read_trials() 一个函数3 个文件
+247 / −77
gen_status.py只改 collect_trials() + STATUS 表格
run_policy_trials.py结果写成 v2;新增预注册 CLI 参数

Clopper-Pearson:为什么值得单独写

评测规程要求报绝对数和区间,不报点估计(arXiv 2409.09491)。 但这台机器上三个 python 环境的 scipy 状态各不相同 —— 系统 python 的 scipy 是装着但坏的 (numpy 1.21.5 太老,import 时抛 TypeError 而不是 ImportError)。 所以正则化不完全贝塔函数是手写的,零依赖。

实测:对着 scipy 跑 300 组随机 (k, n) 交叉校验, 最大偏差 6.0×10⁻¹⁵。三个环境(lerobot / train310 / 系统 python3)结果一致。

效果:同一批数据,改口径前后

改之前   累计计入 83  ·  成功 8            ← 一个裸计数
改之后   累计: 8/83(9.6%,95%CI 4.3–18.1%)
         预注册的运行: 0/37 · 其余只能算探索性,不参与结论

每一行也带上了区间:
  0/23  →  95%CI 0–14.8%     这两行在「成功」那一列
  0/4   →  95%CI 0–60.2%     长得一模一样,但后者什么都没证明

向后兼容(GOAL 边界条件 1:不许改历史记录)

一个容易写错的地方:老记录的 subgoals 是 None, 意思是「没记」而不是「否」。子目标漏斗的分母必须只算记了的次数 —— 当成 False 的话,老记录会让漏斗看起来全是 0,而那是个假象。 回环测试专门验了这一条:4 次试验里只有 2 次记了子目标,漏斗分母正确地是 2 不是 4。

验收

检查结果
三个环境跑 trials_io.py 自检✅ 实测通过
37 个真实文件全量归一化✅ 8/83,95%CI 4.3–18.1%
v1/v2 混放读取✅ 不崩
run_policy_trials.py --dry(GOAL 边界条件 2)✅ 推理成功,动作 (17,),安全层 OK
8770 重启后 /api/trials✅ 新字段已下发,老字段全在
三个面板 HTML 自检(标签 + 整块 JS 解析 + 作用域泄漏)✅ 全绿
这里差点漏掉一个:自检脚本第一次跑报的是 esprima 没装 —— 也就是整块 JS 语法检查根本没执行,只过了标签配平, 但结论那一行仍然显示得像是查过了。装上依赖后重跑才是真的全绿。 检查跳过了却看起来像跑过了,正是白天那类页面 bug 能溜过去的机制。

2 · B0 路线:证据升了一档,又被我们自己按住一半

B0 是「不自己算 3D 坐标,把物体 token 当结构先验喂给策略」这条路。 原来撑着它的是 VIOLA(CoRL 2022,+45.8%), 但 VIOLA 用的是它自己的 transformer 策略,不是 VLA。

新找到 Oat-VLA —— 同一个思路做在真正的 VLA(OpenVLA)上:

论文原文(已核对全文,非摘要)
物体 token 从哪来FT-Dinosaur,无监督物体中心模型,现成的不用标注
token 数256 → 16(7 个物体 + 9 个夹爪 3×3),少 93.75%
收敛LIBERO 上「至少快一倍」
真机 pick-and-placeOat-VLA 29/49,OpenVLA 20/49
★ 我们自己算的,和论文讲的不一样 ★
论文报 59% vs 41%,看着差 18 个点。它给了原始计数,用本页 §1 刚写的同一套 Clopper-Pearson 算下来:

· Oat-VLA 29/49(59.2%,95%CI 44.2–73.0%)
· OpenVLA 20/49(40.8%,95%CI 27.0–55.8%)
· 两个区间重叠(44.2% vs 55.8%),Fisher 精确检验 p = 0.106

真机那 18 个点在 49 次的样本量下不显著。 站得住的是「LIBERO 收敛快一倍」和「token 少 93.75%」这两条 —— 引用它要引这两条,别引真机成功率。
「报区间不报点估计」这条规矩,对别人的论文一样适用。

为什么它对我们仍然重要:token 少 93.75%。SmolVLA 在这台 Jetson 上是 146 ms/帧(6.9 Hz),视觉 token 是大头 —— 这条路有可能顺带把推理变快, 而不是像大多数「加感知」的方案那样再吃一口算力。

能不能直接换成 Oat-VLA?不能,但理由要说准

项实测值怎么测的
机型Jetson Orin Nano Super/proc/device-tree/model
总内存7.4 GiB(当前可用 2.6 GiB)free -h / /proc/meminfo
swap16G swapfile + 6×634M zramswapon --show
SmolVLA 权重865 MBmodel.safetensors
OpenVLA 7B fp16约 14 GB(7B × 2 字节)算的,未测
措辞要准:这台机器有 16G swap,7B 模型不是字面意义上装不下, 而是换进换出后慢到没法用 —— 146 ms/帧的实时控制回路不可能靠 swap 撑。 结论(这台机器上只有小模型跑得动)不变,但理由是吞吐不是容量。 Oat-VLA 是一套方法不是一个模型,方法可以搬到 SmolVLA 上,换机器才是不必要的。

三条未验证,写进 GOAL 时都标了

  1. 没人在 SmolVLA 上做过。 论文只对比 OpenVLA / Octo / Diffusion Policy。 SmolVLA 视觉侧是 SmolVLM2-500M,token 布局和 OpenVLA 不同。
  2. 主干冻不冻结,论文没明说。 全文核对过,没有一句写 "frozen", 只说从预训练视觉编码器的 token 上做聚合。不要把「Depth Helps」那条的冻结主干套过来。
  3. FT-Dinosaur 在 Jetson 上的耗时没测。 省下的 token 时间可能被分割模型吃回去, 净收益是正是负没算过。

3 · 三个被证伪或纠正的说法

原说法实际怎么发现的
「B0 比 B2 改动小」没依据,已删 VIOLA 用的是自家 transformer 策略,往 SmolVLA 接要改哪几层没人量过
「Oat-VLA 视觉主干全程冻结」论文没这么说 核对全文,无 "frozen" 字样
「Oat-VLA 真机 59% vs 41%,有效」数字对,但不显著 用本页 §1 写的 Clopper-Pearson 自己算,p = 0.106

4 · 顺带查清的三个环境事实(都是实测)

① lerobot 环境的 torch 是 CPU-only。 torch 2.11.0+cu130,但驱动是 CUDA 12.6 —— torch.cuda.is_available() 返回 False。跑策略的是 train310(torch 2.8.0,CUDA 可用), 由 robot_server.py:67 的 PY_POLICY 指定。
为什么要紧:B0 摸底要量检测模型在 Jetson 上的耗时, 用错环境会量出一个假的「跑不动」,然后据此否掉一条本来可行的路。
② HuggingFace 静态 Space 会吃掉正文里一个字。 它服务页面时往 <head> 注入一段 102 字节的脚本,这个过程会把正文里 一个多字节 UTF-8 字符的前两字节替换成 U+FFFD,显示成「」。
仓库里存的文件是干净的(/raw/main/ 取回来和本地字节完全一致), 是它服务层的问题。改排版躲不掉 —— 试过之后坏字符只是从「得」挪到了同段的「,」。 要给人看准确版本,用下面那条 Tailscale 链接。
③ 根分区 116G 已用 77G(70%)。 剩 34G。深度数据和检测模型都要下载,这是硬约束。

5 · 没碰的东西(明确声明)

操作者特别问了这一条。用文件修改时间实证 —— 本会话的改动全部在 23:33 之后:

文件最后修改是谁改的
leader_follower_server.py(录制)22:56本会话之前,不是我
orbbec_depth_camera.py(深度)22:54本会话之前,不是我
v4l2_depth.py(深度)22:54本会话之前,不是我
robot_server_dashboard.html22:27本会话之前,不是我
robot_server_data.html22:27本会话之前,不是我
bartender_tasks.py(数据集上传)19:38本会话之前,不是我
trials_io.py23:33本会话新建
robot_server.py23:34本会话,只有 read_trials()

安全层没动(GOAL 边界条件 3):z_floor(pitch) / y_floor(pitch) 是白天刚接好的,拒帧率 96.6% → 0.49%,这次一行没碰。

卡死风险查过了:本次唯一新增的 input() 是失败模式追问, 双重门控 —— not a.panel 且显式传了 --ask-failure-mode。 面板模式走的是轮询控制文件,在那条路上插 input() 正好会把面板挂死,所以明确挡住了。

6 · 下一步

事项谁前置
①关键帧采集(GOAL-TRIAL-DATA 第 2 步)远程无
②面板显示 k/n + 区间 + 失败模式分布 + 子目标漏斗(第 3 步) 远程服务端已备好数据
③预注册入口(第 4 步)远程CLI 参数已加,缺面板表单
④B0 摸底:量 FT-Dinosaur 在 Jetson 的耗时(用 train310) 远程要下模型,注意磁盘
⑤阶段 A:30 集 RGB 上离线跑开放词表检测 + 人工看图核对 远程同上
⑥头部预置位 trial、相机内参、手眼标定 现场B1 的硬门槛
纪律提醒:④⑤ 做出来的检测方案, 必须过「人工看图核对」才算数。数字好看但锁错目标,已经发生三次 —— 检出率 97.6%、跳动 6.4mm,看图发现锁的是机械臂。
2026-09-03 23:00–24:00 · 配套: 深度整合 GOAL · 试验数据管理 GOAL · 仓库内 03-software/scripts/trials_io.py