Files
blackbird/docs/reviews/pybot_actpred_AUDIT_20260814_v3.md
T
qing 9179281420 fix(pybot×actpred): v3 审计 P2 清零——验收链 fixed_range + 导出断言 + overrun 节流
- v3-P2-1: _npu_test/_onnx_validate 按 normalize_mode 分支(fixed_range 免 stats,
  HailoPredictor 透传模式,torch 参考同口径反归一化)
- v3-P2-2: export_deploy/export_onnx 一致性 diff 超 1e-4 即 sys.exit(P2-f 闭环)
- v3-P2-3: run_loop overrun 告警节流(第1次+每100次),降 hz 建议仅 >10% 输出
- P2-a1: default_column_weights 扩展列(action_dim>18)默认 1.0
- P2-c: 补 predictor 异常清理路径测试(异常传播 + finally 落盘)
- P2-d/P2-e: Resize 口径与 resume scheduler T_max 语义文档化
- R2-4: _set.sh 安装后断言 CPU 版 torch,误装 CUDA 即拦截
测试: pybot 89 passed (+1)、actpred 148 passed/18 skipped
2026-08-14 23:01:56 +08:00

11 KiB
Raw Blame History

pybot & actpred 审计报告(第三版 —— v2 修复批次落地后)

审查日期:2026-08-14 (Asia/Shanghai) 审查人:AI Assistant(SOLO Coder) 审查范围:pybot/(机器人运行时)与 actpred/(动作预测)两模块 代码基线:v2 审计修复批次后(commit 85bf68f,工作区干净) 测试状态:pybot 88 passed;actpred 148 passed / 18 skipped(Windows 开发机,全绿; ONNX 类 18 项因本机无 onnxruntime/onnxscript 跳过,在 Pi 上运行)

本报告对照 v2 报告逐项核对修复状态,并给出本轮新发现。

2026-08-14 更新:P0-2(方案 B)、两个新 P1、P2-a 残余、P2-a3 已修复; 3 项新 P2(验收脚本 fixed_range / diff 断言 / overrun 节流)与 5 项遗留 P2 (P2-a1/P2-c 残余/P2-d/P2-e/P2-f/R2-4)亦全部闭环,附回归测试(pybot +2 / actpred +7)。 P0/P1/P2 全部清零,仅剩 2 项 P3(边缘/环境便利)。


一、审计结论摘要

级别 新发现 历史遗留(v2 未修复) 说明
P0(崩溃/数据损坏) 0 1 0(P0-2 已按方案 B 修复) 见 §三
P1(功能风险) 2 0(均已修复) 1 0(P2-a 已闭环) 见 §四
P2(代码质量) 3 0(均已修复) 5 0(全部闭环) 见 §五/§六
P3(边缘/环境) 2 0 见 §五

重点:P0-2 曾随 85bf68f 未修复提交,本轮已按方案 B 闭环;两个新 P1、P2-a 残余与全部 P2 已于本轮回合修复。


二、v2 修复项回归核对(13 项)

# v2 级别 状态 验证
P0-1 HailoPredictor 缺 normalize_mode P0 ✅ 已修复 main.py:163-193 从 companion checkpoint 读取并传入
R2-1 NaN val_loss 阻断 best P1 ✅ 已修复 train.py:270-274、pretrain_mt.py:361-364 isfinite 守卫,NaN 走 patience 早停
P2-a 后端检测大小写敏感 P1 ✅ 已修复 main.py:144-146 已 .lower();v3 补齐 .onnx → OnnxPredictor 分支(归一化模式经元数据自动识别,zscore 缺 stats 时告警)
P1-3 mt_parser BOM P1 ✅ 已修复 mt_parser.py:33 utf-8-sig
R1-1 pretrain data_dir 覆盖 P1 ✅ 已修复 pretrain_mt.py 不再赋值 cfg.data.data_dir
R2-7 _run.sh 静默回退 P1 ✅ 已修复 _run.sh:17-20 未知子命令报错退出
P2-a2 init-from 误报警告 P2 ✅ 已修复 config.py:232 仅在双方归一化开启时比较 normalize_mode
R2-9 predict.py --action-dim 陷阱 P2 ✅ 已修复 predict.py 已移除该参数,统一用 predictor.action_dim
R1-2 parse_action_history 三处重复 P2 ✅ 已修复 三推理文件均从 utils.py 导入
R2-3 空验证集无 best.pt P2 ✅ 已修复 train.py:309-324 保底保存最终权重
P2-c 闭环测试覆盖 P2 ✅ 已修复 test_loop.py 含 recorder 集成 + 异常清理路径用例(test_predictor_exception_still_flushes_recorder)
P2-b numpy 三处 lazy import P2 ✅ 已修复 顶层导入曾破坏零依赖(v3-P1-1),已恢复函数级 lazy import 并加守卫测试
P0-2 normalize_actions 默认值 P0 ✅ 已修复 README.md:170 更正为 True 并注明行为变更(方案 B,见 §三)

三、P0 遗留

P0-2 DataConfig normalize_actions 默认值与 README 不一致 —— ✅ 已修复(2026-08-14,方案 B)

修复:README.md:170 默认值更正为 True, 并注明"2026-08-14 起默认开启——复现旧行为需显式 --no-normalize-actions"。 代码(config.py:14 True)、测试、训练实践此前均已按 True 落地,文档对齐即闭环。


四、P1 新发现

v3-P1-1 pybot 零第三方依赖承诺被打破(85bf68f 修 P2-b 的副作用)—— ✅ 已修复(2026-08-14)

修复:robot.py 顶层 import numpy 移除,7 个 numpy 使用函数(run_loop / _loop_cold_start / _execute_action_vec / _read_imus / _pad_imu / _build_action_vec / _grab_frame)恢复函数内 lazy import,并在导入块处 注明约定禁止恢复顶层导入。新增回归测试 test_loop.py::test_robot_importable_without_numpy(子进程屏蔽 numpy 验证模块可导入)。纯脚本路径零依赖承诺恢复,README 无需变更。

原问题:main.py 无条件 from .robot import RobotStruct,numpy 成为硬依赖。

v3-P1-2 OnnxPredictor 不支持 predict_delta,ONNX 无训练配置元数据 —— ✅ 已修复(2026-08-14)

修复:

  • export_onnx.py:46-63 导出后写入 metadata_props(normalize_mode / predict_delta / imu_dim / action_dim; 未归一化训练记 normalize_mode="none");
  • onnx_infer.py:75-87 构造时从元数据 自动识别两参数(显式传参优先),predict():174-176 在归一化空间加回 history 末步(与 predict.py/hailo_infer 同语义);
  • CLI --normalize-mode 缺省自动识别、新增 --predict-delta;
  • README 部署注意已更正(含旧版无元数据 ONNX 的回退说明);
  • 新增 TestOnnxMetadata 7 用例(元数据写入/回读/覆盖/残差加回数值), 本机无 onnxruntime 跳过,随 Pi 环境运行。

原问题:残差训练模型经 export_onnx.py 导出后,ONNX 推理输出被当作绝对动作——静默错误。


五、P2/P3 新发现

v3-P2-1 验收脚本链未适配 fixed_range —— ✅ 已修复(2026-08-14)

_npu_test.py:65-76、_onnx_validate.py:28-42 均改为按 checkpoint config 的 normalize_mode 分支:zscore 照旧加载 action_stats.npy;fixed_range 走 action_norm min-max 且免 stats 文件; _npu_test 另向 HailoPredictor 透传 normalize_mode、torch 参考输出按同 模式反归一化后再对比。

v3-P2-2 导出一致性校验只打印不拦截 —— ✅ 已修复(2026-08-14)

export_deploy.py:288-292,303-307 与 export_onnx.py:82-85 新增 MAX_TOLERATED_DIFF = 1e-4 阈值断言,超限 sys.exit 拦截(P2-f 的 ManualAttnBlock 布局约定风险一并闭环)。

v3-P2-3 run_loop overrun 逐步告警日志噪音 + 建议阈值偏离约束 —— ✅ 已修复(2026-08-14)

robot.py:310-317 逐步告警节流为 第 1 次 + 每 100 次汇总;robot.py:324-332 最终建议仅在 overrun 比例 >10% 时输出(否则 info 级汇总),对齐工程约束。

v3-P3-1 dfc_compile.py --output 无 .hef 后缀时产物互相覆盖

位置:dfc_compile.py:172-173

args.output.replace(".hef", "_optimized.har") 在无后缀时返回原路径,shutil.copy(har_opt, ...) 把 HAR 写到刚复制的 HEF 同路径,静默损坏产物。建议校验 --output 必须以 .hef 结尾。

v3-P3-2 pybot Windows 测试依赖命令行 fcntl mock

位置:pybot/hd/i2c.py:14

顶层 import fcntl(Unix-only),Windows 下 conftest 自身 import i2c 即失败,需命令行注入 sys.modules['fcntl'] mock 才能跑测试(87 passed 即以此方式验证)。建议在 conftest.py 内置同等 mock(一行,先于 i2c import),消除外部依赖。


六、v2 遗留 P2(已全部修复,2026-08-14)

# 位置 问题 处理
P2-a1 action_norm.py:55-66 default_column_weights 对 action_dim>18 的超出列权重恒 0 ✅ 扩展列默认 1.0(新执行器须参与训练),补 20 列断言
P2-a3 README.md:172 column_weights 始终生效(含不归一化训练)未在文档注明 ✅ 已随 P0-2 一并修复
P2-c 残余 test_loop.py predictor 异常清理路径无用例 ✅ 新增 test_predictor_exception_still_flushes_recorder(异常传播 + finally 落盘 1 步)
P2-d dataset.py:46-49 Resize 不保持宽高比 ✅ 注明有意为之(训练/推理同口径,变更须同步重训),不改行为
P2-e train.py:248-251 resume 时 scheduler T_max 恢复旧值 ✅ 语义已在代码注释 + README --resume 行明确
P2-f export_deploy.py ManualAttnBlock 依赖 PyTorch in_proj 内部布局 ✅ 随 v3-P2-2 阈值断言闭环(布局失效即拦截退出)
R2-4 _set.sh:19-28 CUDA 版 torch 误装风险 ✅ 安装后断言 torch.version.cuda is None,误装即拦截并给出修复命令

七、修复优先级

优先级 项 状态
P0 P0-2 README 与默认值对齐(方案 B) ✅ 已修复
P1 v3-P1-1 robot.py numpy lazy import ✅ 已修复(附子进程回归测试)
P1 v3-P1-2 ONNX predict_delta + 元数据 ✅ 已修复(全链路 + 7 用例)
P2 v3-P2-1 验收脚本 fixed_range 适配 ✅ 已修复
P2 v3-P2-2 导出 diff 阈值断言 ✅ 已修复(P2-f 一并闭环)
P2 v3-P2-3 overrun 告警节流 + 10% 阈值 ✅ 已修复
P2 P2-a1/P2-c 残余/P2-d/P2-e/R2-4 ✅ 全部闭环(见 §六)
P3 v3-P3-1 dfc_compile --output 后缀校验 / v3-P3-2 conftest 内置 fcntl mock 未修复(边缘/环境便利)

八、本轮复核确认无问题的关键路径

  • 训练链:weighted MSE 量级归一、scheduled sampling detach 截断、空验证集兜底、stats 训练集-only 计算(含 history∪target 并集防零方差爆炸)、文件级划分防泄漏——均正确。
  • 推理链三后端:normalize/denormalize 对称、predict_delta 加回在归一化空间、imu_dim=None 鸭子类型兼容旧 checkpoint、NaN/Inf 输出兜底——均正确。
  • 部署链:HAR 输入连通性双阶段检查、pred_token 抖动校准、按 input_layerN 排序绑定、量化网格 dequant(0) 判定帧归一化、token 量级导出前拦截——均正确。
  • pybot 闭环:守护线程队列帧源、冷启动零历史、finally 落盘 recorder、执行前 isfinite 守卫、Speaker.delay 剔除防阻塞——均正确。

本报告为 v2 修复批次后的回归+新发现审计。建议优先闭环 P0-2(文档一行)与两个新 P1。