Files
Robot_Arm/docs/ML运行手册审查.md
T
cbb f9fa3e67b6 ml: 显存预算按 19–20 GB 落地(APG batch 128→48 + 每进程硬帽 + vram 上日志/网页);自检四处判据与环境坑修好,整轮 7/8 通过 3.5 分钟
- ml/configs/apg.json:batch 128→48。本机实测(d=192 同结构、每进程 19.2 GB 硬帽、1 步即到位)batch=128 无论 plans 取 60 还是 150 都 OOM(崩前已分配 17.85 GiB;d=32 小模型也 17.54 GiB,说明是展开图吃显存而非模型大小);48/plans=150 为 13.08、48/60 为 7.67。展开长度 plans 没动,降 plans 会把长任务绕出段截掉。
- ml/common/vram.py(新):limit() 设每进程帽 VRAM_FRAC 默认 0.78≈18.7 GiB 并打印上限;peak_gib() 供日志。train.py 与 apg_finetune.py 调用,每条记录新增 vram 字段(实测 train batch=1024 → 2.71,APG 自检档 → 0.33)。没帽时 APG 会把整卡顶到 23.6 GB、连桌面一起挤掉。
- ml/monitor.py / monitor.html:状态带 vram_budget_gb(默认 20,VRAM_BUDGET_GB 可改),GPU 显存条按预算算并超线变色,指标卡加「显存峰值」(>14 黄 >17 红)。headless 加载渲染 DOM 复核过。
- ml/configs/smoke.json 补 apg 段(batch=8)+ selftest.sh 的 APG 两项带 --config:原先不带 → 自检第 6 项按正式 batch=128 跑,本机必 OOM。
- ml/selftest.sh:gen_resume 判据由 cmp -s 改为剔除 plan_ms/cert.ms 两个墙钟字段后逐条比(旧判据恒 false);rec() 值非合法 JSON 时记 false 不再静默丢项。
- ml/selftest_proc.py:alive() 读 tasklist 改 text=True+errors='replace' 并防 None(中文 Windows 表头 GBK 会让读线程抛 UnicodeDecodeError→stdout=None→TypeError);wait_pids 带上最后一次异常。
- ml/monitor.py find_bash():便携版 git 的 mingw64 布局要再上一层找 bash,并兜 which('bash')(排除 System32 的 WSL)。本机原先返回 None → 网页「开始训练」起不动、自检进程两项没跑。
- 整轮自检重跑:gen_resume/prep_rerun/train_stop/train_stopfile/apg_resume/tree_killed/survive_parent_exit 全 true,仅 train_term false(timeout 的 TERM 送不到原生 python,rc=124 硬杀);用时 3.5 分钟。
- 文档:新增第七节(显存实测表、自检 8 项结果、四条判据/环境坑、本机改动清单);A-3 改为「实现方已改、待复跑验证」,C-5/C-6 标为已实测,D 组复核后关闭。
2026-10-18 05:34:07 +08:00

26 KiB
Raw Blame History

ML 运行手册审查(ml/README.md)· 精简版

六轮历史(0218d7f → a5e779c):第一轮 13 条、第二轮可行性、第三~五轮处置、第六轮本机实跑。已解决的条目按用户要求删去,完整原文在 git 历史里。本文件只剩三部分:仍有效的实测数字 / 仍未解决的问题 / 已复核正常的项,供实现方下一轮处置。

环境:本机 CBB-003(RTX 3090、28 核、Python 3.12 + torch 2.10 + onnxruntime 1.22、Edge + onnxruntime-web 1.20.1)。 当前结论:第 1–6 步已实测可跑;第 7–13 步零证据;R4 部署口径(纯推理)已判通过,bash ml/pipeline.sh r4 端到端 rc=0(2026-10-18 本机修复后复跑)。A 组原三处中两处已修,A-3 由实现方第七轮改掉、待本机复跑验证。第七轮本机复核与显存预算(19–20 GB)见第七节。


一、仍有效的实测数字(后续对照用)

项 数字 口径
对拍 300 条 PASS(fk 3.4e-13 mm、特征 6e-8、间隙梯度 1.4e-6),7.6 s 第 2 步
生成 1.56 s/条(80 条 122 s) 第 4 步
统计 keepRate 0.977、samplesPerTask 36.5、projected 178.4 万、exec_s p50 2.3 / p90 3.0 / max 3.7 s、cert.minGap p50 4.4 / p90 5.9 mm 88 条,未加 3 mm 过滤
预训练 4.92 M 参数、6208 样本/s(batch=1024)→ 60k 步 ≈ 2.8 h 250 步冒烟

R4(随机初始化模型;延迟只取决于结构,与是否训练无关):

接口 线程 proxy P50 P95 P99
enc_once(部署口径) 16 开 7.36 9.48 11.07
enc_once 4 开 10.22 11.69 12.92
enc_once 16 关 7.43 9.21 10.79
旧接口(对照) 16 开 9.53 11.29 16.47
旧接口 4 开 13.88 16.35 17.19

tickGapMax 全部 ≈21.5 ms(20 ms 节拍没被卡住)。背景:第五轮前默认(4 线程、无 proxy、旧接口、真查看器)P99 37.0;线程扫描 8 线程 24.9 / 16 线程 19.5 / 24 线程 25.8 → 16 最优,超线程反而挤。部署口径纯推理 P99 11.07 < 15,R4 判通过;enc_once 相对旧接口省约 30–33%。

修复后由 pipeline.sh r4 自身复跑(两次):部署口径 P99 10.22 / 11.25(P50 7.34 / 7.10),4 线程 13.58 / 13.64,无 proxy 9.28 / 10.92;webgpu 仍报 [webgpu] backend not found。

真查看器同一会话(随机权重、?policy=1&probe=1):inferMs P50/P99/max = 30.36 / 61.64 / 68,safetyMs = 63.52 / 248.76 / 320.6;622 次 plan、brakes 4、locks 48、projected 283、lookahead 219。单变量对照:__POLICY.stop() 后纯 infer 7.5 / 9.7 ms → 差额是主线程排队,不是模型慢。


二、仍未解决的问题

A. 会直接中断本机一键流程(原三处,两处已在本机修复)

已修复(本机 2026-10-18,bash ml/pipeline.sh r4 连跑两次均 rc=0、pass=true)

  • 探针页复用 detached tensor:feat 的分配移进 run()(webapp/r4_probe.html)→ proxy=1 的两种配置均正常出数。
  • pipeline.sh 7 处 json.load(open(...)) 全部补 encoding='utf-8'(:90 :110 :118 :127 :136 :138 :144)。
  • 附带发现并修掉:r4 分支末行 [ "$r" = null ] && echo 在 r=pass 时整体返回 1,set -e + EXIT trap 把通过的 r4 记成 rc=1(all 会因此停)。已改为 if ... then ... fi。

A-3 离线 ort 加载:实现方第七轮已改(绝对 URL + vendor_ort.sh),本机待复跑验证。 ik-policy-glue.js 把 ort.env.wasm.wasmPaths 设为相对前缀 vendor/ort/,ORT 对 .mjs 走 import() 需要绝对说明符 → no available backend found. ERR: [wasm] TypeError: Failed to resolve module specifier 'vendor/ort/ort-wasm-simd-threaded.mjs'。README 明确支持的离线部署路径在默认配置下不可用。(ortLocal=1 + proxy=0 未测;wasmPaths 与 proxy 无关,大概率同样失败。)复跑判据:断网/CDN 不可达时 bash ml/pipeline.sh r4 仍能出数(探针默认走本地 webapp/vendor/ort/),且 &ortLocal=1 的查看器徽标显示「策略模式就绪」。

B. 待实现方判断(数据已摆在上面;分歧按第五轮第〇节规则,以实现方为准)

B-1 R4 判据用哪个口径。 纯推理 P99 11.07 判通过;但同一台机、同一会话,整周期 plan = infer 61.6 + safety 248.8(P99),随机权重下 1/3 的规划 >100 ms。如果 R4 的意义是"浏览器能不能按 60 ms 周期推一次",纯推理口径会放过实际丢步的配置。供下一轮的建议(不要求现在改):r4.json 记两个数 infer_p99 与 plan_p99 = infer + safety,后者另设一条线(如 <45 ms,给 60 ms 周期留余量)。

B-2 safetyMs 两把尺。 bench 在 Node 里跑同一份 ik-policy.js(CPU EP),浏览器里同一段代码 p99 249 ms——互不可替代,与"仿真安全层 ≠ 部署运行时"是同一类问题换了个位置。判据:同一批贴柱题两边各测一次,差 >3× 就要解释。建议核对 certBudget=40 在贴柱位形下的实际查询次数与 makeCert 的 memo 命中率——249 ms 的量级不是"随机策略质量"能解释的;真模型是否不同未知。R9 至今无有效数据(探针只测纯推理;闭环丢步率因探针一运行 CDP 就拿不到执行槽而没采到——这本身是主线程拥挤的证据)。

B-3 WebGPU 是判定顺序里的备用通过路径,但至今零数据。 第五轮判定顺序写了"wasm 不过而 WebGPU 过,也判通过",本机 headless 报 [webgpu] backend not found,且 CDN 间歇不可达(jsdelivr 多次 000、unpkg 200)→ 需要一条真能测到 WebGPU 的路(非 headless,或 A-3 修好后本地放 ort)。

C. 尚未实测(跑之前必须知道这些是空的)

  1. 第 6–13 步全部没跑过:train 只有 250 步吞吐冒烟;m5 / apg / mine / export / bench / accept 零实测;all 端到端从未完整跑通。一次完整流程机时下界约 15–28 h,其中 apg 2–4 h/轮、mine 6 轮都是估的。
  2. 3 mm 间隙过滤的真实剔除比例(gapDrop)没测过:只测过沙箱 30 条(剔 9/29,不具代表性);上表 p50 4.4 mm 是未过滤口径。生成后看 stats.json 的 gapDrop。
  3. R2 新判据(label_std_norm)的池无关性:需在 1.7 M 样本上 --pool 50000 与 --pool 200000 两跑、差 <0.02 才成立;没做。默认 R2_STRICT=0 只警告,开着就是一道未校准的闸。
  4. R8 出题耗时:沙箱 2 题 9 分钟没出完;本机未测(policy_bench.json 会记 requested / genS,不足额时看警告)。
  5. Windows 侧生命周期未实测 → 已实测(见 7.2):整树杀净 ✅、关黑窗口训练继续 ✅、timeout 的 TERM 送不到 python ❌(超时只能硬杀,靠 STOP 文件与定时存档)。
  6. 断点续跑未在本机复核 → 已实测(见 7.2):gen 按条续写逐条一致、train STOP 2 s 存档续训、apg --resume、prep 二次运行「待打包 0 个」全部通过。
  7. APG 的机时仍然零实测(显存已量:batch=48/plans=150 → 13.08 GiB)。batch 从 128 降到 48 后每步代价与收敛都要重算一遍才知道。

D. 小遗留

webapp/models/README.md 过时 → 实现方第七轮已改,本机复核过:现在写的是 bash ml/pipeline.sh export(默认 fp32)、第 10 步、新输入签名 feat[1 或 K,83] 与 feat_dyn,并说明离线要先跑 ml/prep/vendor_ort.sh。


三、第六轮已复核正常(不在问题清单里)

  • bash ml/pipeline.sh r4 端到端:修完 A 组两处后连跑两次 rc=0、pass=true。
  • 锁:r4 阶段拿到 ml/runs/pipeline.lock,结束已删。
  • N-5 三处防护在位:查看器拒绝 random_init(提示 &probe=1)、policy_bench.cjs 拒绝、acceptance 有"部署模型是训练产物"项。
  • enc_once 运行时对接一致:只送 1 行特征(ik-policy-glue.js:52 / ik-policy.js:344),旧模型回退 [B,F]。
  • r4 导出:19.76 MB、enc_once=true、与 torch 对拍 2.2e-7。

四、建议顺序

  1. A 组修复并重跑 r4:已完成(本机 2026-10-18,rc=0、P99 11.25)。
  2. 接着 FROM=gen TO=prep 跑一次(数小时),拿 gapDrop 与 R2 两个口径的数——C-2 / C-3 随之消掉,B-2 的 Node 侧安全层数字可顺手从 m5 前的 bench 拿。
  3. B 组等上面的数字齐了再定;C-1/C-7 随第一次真跑逐项核对;A-3 由实现方已改,本机复跑 r4 时顺带验(会弹有界面窗口)。

五、实现方处置(第六轮,2026-10-18)

逐条对应第二部分。分歧按第五轮第〇节规则以实现方为准,下一轮用实测数据定。

A-3 离线 ort 加载:已修。ik-policy-glue.js 与 r4_probe.html 的本地前缀改为绝对 URL(new URL('vendor/ort/', location.href)),ORT 的 import() 不再把它当裸模块名。新增 ml/prep/vendor_ort.sh(setup 与 r4 自动调用)用 npm pack onnxruntime-web@1.20.1 把 ort.min.js、ort.webgpu.min.js 与两套 wasm/mjs 放进 webapp/vendor/ort/(33 MB,.gitignore);探针检测到本地副本就默认用它,不再依赖间歇不可达的 jsdelivr(ORT_LOCAL=0 强制 CDN)。

GBK 兜底:除了本机已补的 7 处,pipeline.sh、console.bat、console.sh、监控起的子进程统一 PYTHONUTF8=1,所有 Python 读写默认 UTF-8,不再逐处补 encoding。

B-1 R4 口径:R4 保持纯推理判据(随机权重只代表推理开销,这点不变)。整周期另立 R9,用训练好的模型在真查看器里测:python -m ml.eval.r4_probe --viewer(bench 阶段自动跑,写 ml/runs/r9_browser.json),查看器 &autotest=30 跑与 Node bench 同种子同题的 30 道贴柱题,判据 整次规划 planP99 < 45 ms 且饥饿节拍 < 1%(饥饿 = 执行时钟到点时队列为空 = 实际丢步)。r4.json 另带 viewer_ref(随机模型的同一测试),只作参考不判定——随机策略几乎每次都要认证多条候选,安全层路径不代表真模型。验收汇总加 R9 一项。方案 R9 行同步改写(原"安全层 P99 < 5 ms"不可测也不对口径)。

B-2 安全层两把尺:找到了原因,而且 Node 侧也一样慢,不是浏览器独有。沙箱 Node 单次调用:gapMatrix cap20 3.6 ms / cap40 5.5 ms、collideFree 1.5 ms、criticalPairs 3.1 ms,而推理只有 1.5 ms——耗时在几何查询,不在模型。具体三处:

  1. 截止只在候选之间检查,单条候选内部最多 40 次查询(≈150 ms)不受限 → 墙钟截止下沉到认证递归内部:第 1 条候选截止 45 ms,其余共享到 30 ms,到点判不过(certFailWhy.time),沿已认证刹停段停,安全性不变。
  2. safetyMs 从推理结束开始计,把前瞻(第二次推理 + 8 份特征 = 8 次 gapMatrix cap40)算进去了 → 拆成 lookaheadMs / safetyMs / planMs 三项分别记。
  3. 前瞻在"卡死"时也触发,随机或差的策略几乎一直卡死 → 改为只在冷启动(新目标 / 目标跳变)前瞻,与仿真 closed_loop.py(只在首块前瞻)对齐;卡死由换向锁处理。 沙箱 Node、同 2 道贴柱题、小模型实测(同一机器前后对比):安全层 P99 200.9 → 51.9 ms,前瞻 P99 126 → 83 ms(只剩冷启动那几次),整次规划 P99 236.7 → 63.3 ms(P50 57.5)。代价是沙箱上 time 截止判不过占多数、刹停多(2 vCPU 上每次 gapMatrix 约 4 ms,45 ms 只够约 10 次查询;未训练小模型本身也差)——你机器单核快 2× 左右,真模型候选第 1 条通过率高,R9 以本机实测为准;若本机 R9 仍不过,下一轮把几何查询(特征、投影、认证)整体搬进 Worker,主线程只执行。 另外 bench 与查看器都记 certQueriesP99、certMemoHitRate(沙箱 0.69–0.72)、certFailWhy;验收加"同题安全层 浏览器 / Node ≤ 3×"一项。

顺带发现并修掉一个真 bug:第五轮 enc_once 后,前瞻的 8 行特征各不相同,但 ortInfer 只送了第 1 行 → 8 个候选的前瞻价值全是同一个观测算的,冷启动时的候选排序等于随机。现在 ONNX 的 feat 轴改为动态(1 行 = 主推理编码一次;K 行 = 前瞻逐行编码,meta.feat_dyn=true),导出时对拍 8 行不同特征与 sample() 一致(2e-7 量级);第五轮导出的旧模型运行时自动退化为逐行推(正确但慢)。你本机的 r4 模型需重新导出(bash ml/pipeline.sh r4 会重导)。

B-3 WebGPU:backend not found 的直接原因是 ort.min.js 里没有 WebGPU 后端(只在 ort.webgpu.min.js)。查看器与探针在 ep=webgpu 时改载 ort.webgpu.min.js;探针先记 navigator.gpu 与适配器信息(区分"没有 GPU"与"包不对");WebGPU 配置改用有界面窗口打开(无头模式拿不到真适配器),跑完自动关。

D:webapp/models/README.md 已改为 fp32、第 10 步、新输入签名。

C 组:第七轮已处置,下一步见第六节。

六、实现方处置与待本机验证(第七轮,2026-10-18)

本节是遗留问题的唯一清单:不需要计算的已在代码里修完(「本轮已修完」);需要计算的只有一条技术验证命令(「本机技术验证」),由你的 PC 跑,沙箱不跑;做法已全部定下(「已定的做法」);需要你确认的写在「还需要你确认的」。


6.1 本轮已修完(不需要计算)

遗留 处置 位置
A-3 离线 ort 加载失败 本地前缀改绝对 URL;ml/prep/vendor_ort.sh 放好 ort 本地副本,探针默认用本地、不依赖 CDN ik-policy-glue.js、r4_probe.html、vendor_ort.sh
GBK 读中文 json 全流程 PYTHONUTF8=1(pipeline / console.bat / console.sh / 监控子进程) pipeline.sh 等
B-1 R4 口径 R4 仍判纯推理;整周期另立 R9(真查看器、训练好的模型、与 bench 同题:planP99 < 45 ms、饥饿 < 1%),验收加 R9 r4_probe.py --viewer、acceptance.py
B-2 安全层两把尺 原因定位:几何查询慢(gapMatrix 3.6–5.5 ms/次),不是模型。截止下沉到认证内部;耗时拆 4 项记录;前瞻只在冷启动;验收加"同题浏览器 / Node ≤ 3×" ik-policy.js、policy_bench.cjs
前瞻 bug(新发现) enc_once 后前瞻只送 1 行特征 → feat 轴改动态(meta.feat_dyn),导出对拍 K 行 policy.py、export_onnx.py
B-3 WebGPU 零数据 根因:ort.min.js 不含 WebGPU → 改载 ort.webgpu.min.js;有界面窗口测;记录适配器信息 同上
C-3 R2 池无关性 每次 R2 自动以 4 倍池再测一次,记 pool_check.independent(差 < 0.02) check_r2.py
C-4 R8 出题耗时 出过的题按碰撞指纹缓存,policy_bench.json 记 genS、casesCached policy_bench.cjs
C-5 / C-6 本机生命周期与续跑 新增一条命令自检(见「本机技术验证」 V1) ml/selftest.sh、ml/selftest_proc.py
C-1 第 7–13 步零实测 靠断点续跑兜底(V1 验证),正式训练分三段跑、出错从该阶段续;另备 ml/smoke.sh 全流程冒烟,不必跑 ml/smoke.sh、configs/smoke.json
续跑后数值不一致 last.pt 存 torch / CUDA / random 随机数状态,续跑 batch 顺序与一口气跑完一致 ml/common/ckpt.py
D 模型目录说明过时 已改(fp32、第 10 步、新签名) webapp/models/README.md

沙箱只做了语法检查与几秒级的对拍,以上全部以你本机结果为准。


6.2 本机技术验证(只验可行性与意外,不做正式训练)

一条命令,5–10 分钟,在仓库旁的副本目录里跑,不碰本仓库的数据与产物,跑完副本可删。

# 命令(Git Bash,仓库根目录) 耗时 回传 验证什么
V1 bash ml/pipeline.sh selftest 5–10 分钟 ml/runs/selftest.json 意外中断能否恢复:gen 截断续写、prep 二次运行、训练 STOP / 续训、APG 续跑;Windows 进程:控制台停止能否杀净整棵树、关掉黑窗口后流程是否继续、TERM 能否送到 python

判读:all_pass = true。没过就把文件发我,不用排查。

不单独跑全流程冒烟:V1 通过即证明断点续跑可靠,正式训练中途某一步出错时,已完成的阶段与训练进度都保留,我修完后从出错那一步接着跑(FROM=<阶段>),损失只是出错到发现之间的空闲时间。为缩短这段时间,正式训练按"数据 → 训练 → 后训练与评测"三段跑,每段结束看一眼(见「正式训练」)。ml/smoke.sh 保留在仓库里,不作为必跑项。


6.3 已定的做法

事项 定为
R9 通过线 整次规划 P99 < 45 ms、饥饿节拍 < 1%(60 ms 周期留 15 ms 给渲染)
浏览器测试 有界面窗口(无头拿不到真 GPU)
R9 本机不过 几何查询(特征、投影、认证)整体搬进 Worker,主线程只执行
训练余量 3 mm、R2_STRICT、共识过滤 按正式数据段的 stats.json / r2.json 定:间隙 p10 ≥ 3 mm 保持 3 mm,否则降到 p10;R2 pool_check.independent = true 且截距 < 0.10 时打开 R2_STRICT;门 1 < 0.90 自动开共识

6.4 还需要你确认的

无。V1 结果回来后,我只按结果改代码;若结果暴露出需要你决定的事,再写进本节。


6.5 正式训练(以后再跑,不在本轮)

V1 通过后再跑,分三段,每段跑完把回传文件发我:

段 命令 耗时 回传
数据 FROM=kin TO=prep bash ml/pipeline.sh all 数小时 ml/data/stats.json、ml/data/r2.json、ml/runs/r4.json
训练 FROM=train TO=m5 bash ml/pipeline.sh all 约 3–6 小时 ml/runs/m5_gate_*.json
后训练与评测 FROM=apg TO=accept bash ml/pipeline.sh all 约 10–20 小时 ml/runs/acceptance.json、policy_bench.json、r9_browser.json

任何一段中途出错:把出错信息发我,我修完后用 FROM=<出错阶段> 接着跑,前面的不重做。


七、本机复核第六/七轮处置(2026-10-18,含显存预算)

先说约束(用户定的,之前所有估算都按整卡 24 GB 写了):本机 Windows + 4K 桌面空闲就占 4.4 GB(nvidia-smi 空载 23604→4394 MiB 实测),所以 ML 只能用 19–20 GB。

7.1 APG 会直接把第 8 步打崩(实测,非推算)

用 d=192(与正式训练同结构)、--steps 1(峰值在第一次反向就到位)、每进程硬帽 19.2 GB,逐档实测 max_memory_allocated(GiB):

batch plans=60 90 120 150
32 6.14 9.53
48(已定为新值) 7.67 13.08
56 13.61
64 10.81 15.41 17.66
128(原值) OOM OOM(崩前已分配 17.85 GiB)
  • 原 batch=128 无论 plans 取 60 还是 150 都 OOM(d=32 的小模型也一样,崩前 17.54 GiB)→ 显存是被展开图吃掉的,与模型大小、数据量无关。
  • 已把 apg.json 的 batch 定为 48,plans 60→150 不动:最坏 13.08 GiB,加桌面 4.4 GB ≈ 17.5 GB,在 19–20 GB 预算内。没选"降 plans"是因为降展开长度会把长任务的绕出段截掉(就是口径-3 那个问题)。batch=64 + plans=150 要 17.66 GiB,加桌面就到 22 GB 了,不取。
  • 加了每进程显存硬帽:ml/common/vram.py,VRAM_FRAC 默认 0.78 ≈ 18.7 GiB,训练与 APG 启动时打印上限。没帽时它会把整卡顶到 23.6 GB、连桌面一起挤掉(就是这次报显存的原因)。
  • 显存用量现在看得见:train.py / apg_finetune.py 每条日志带 vram(峰值 GiB);监控页指标卡加「显存峰值」(>14 黄、>17 红),GPU 卡的显存条改成按 20 GB 预算算而不是整卡 24。实测:预训练 batch=1024 记到 vram: 2.71,APG 自检档 vram: 0.33。
  • 对照:预训练 batch=1024 峰值 2.76 GiB(够);check_r2 每样本常驻 776 B → 1.7 M 样本 1.32 GB + 分块 0.05(4× 池自检 0.2)≈ 1.6 GB,脚本里"GPU 峰值 <0.5 GB"错了约 3 倍,但不会崩。
  • 顺带:N-6 的"按空闲显存 1/4 自动定块"、出题分块等估算都要按 19 GB 重算。
  • ml/configs/smoke.json 原来没有 apg 段,而 selftest.sh 调 APG 时不带 --config → 自检第 6 项实际按正式 batch=128 跑,在本机必然 OOM、自检永远跑不完。已补 apg 段(batch=8、实测 vram 0.33 GiB)并让自检带 --config。

7.2 生命周期与断点续跑:本机整轮自检 7/8 通过,用时 3.5 分钟

项 结果
gen_resume ✅ true(判据修正后)——「续写:已有 2/6 条,从第 3 条继续」,与一口气生成逐条一致
prep_rerun ✅ true——二次运行「待打包 0 个」
train_stop ✅ true——--stop-at 20 → rc 143、last.pt 第 20 步、续训到 40 步 rc 0
train_stopfile ✅ true——写 ml/runs/STOP 后 2 s 退出并存档(第 351 步)。控制台「停止」走的就是这条路
train_term ❌ false(Windows 的真实限制)——timeout 的 TERM 送不到原生 python,rc=124 是硬杀。结论:阶段超时不能指望体面存档,靠 STOP 文件 + 每 10 分钟定时存档
apg_resume ✅ true(自检档 batch=8,vram 0.33 GiB)
tree_killed ✅ true(实测)——taskkill /T /F 把 bash→python+node 整树杀净,没留孤儿
survive_parent_exit ✅ true(实测)——启动器退出后子树仍活着 = 关掉控制台黑窗口不影响训练

用时 3.5 分钟(APG 用自检档;上一轮 APG 走正式 batch=128 时是 13.2 分钟,而且 OOM)。 之前测不到的原因:① monitor.find_bash() 在本机返回 None(Qoder 自带 git 在 mingw64\bin\git.exe,"上上级 + bin/bash.exe"推出一个不存在的路径);② selftest_proc.alive() 用 text=True 读 tasklist,中文 Windows 的表头是 GBK → 读线程 UnicodeDecodeError、stdout 变 None → TypeError,异常又被 wait_pids 的 except Exception 吞掉。

7.3 两条判据自身的问题(会让"通过/失败"失真)

  1. selftest.sh:27 用 cmp -s 逐字节比生成结果,但记录里含 plan_ms 与 cert.ms 两个墙钟耗时字段 → 两次运行不可能相同,这项永远是 false。我在副本里重跑基线、只把这两个字段剔掉后逐行比:6 条完全一致 → 续写逻辑正确,是判据错。
  2. rec() 用 json.loads 解析传入值,而 str(None).lower()=none 不是合法 JSON → 抛异常、整项静默不进结果文件,all_pass 照样算出来。所以"第七轮说自检已修完"的两项进程测试,实际上是没跑过。
  3. 自检副本只复制 git ls-files 里的文件(selftest.sh:16)→ 任何未跟踪的新文件在副本里不存在,调用它的项会以 ModuleNotFoundError 变成 rc=1,看起来像功能坏了。本轮新加 ml/common/vram.py 就踩了:train_stop/train_stopfile/apg_resume 三项同时 rc=1,git add 之后才恢复。判据建议:自检开头先 git ls-files --others --exclude-standard 非空就报出来(或改用 git ls-files -o --exclude-standard -t 一起复制)。

7.4 本机已改的(都按实测落地,不改判据含义)

位置 改动 验证
ml/monitor.py find_bash() 便携版 git 的 mingw64 布局要再上一层;再兜 which('bash')(排除 System32 的 WSL bash) 返回 ...\.qoder\bin\git\bin\bash.exe(bash 5.2.37);网页「开始训练」在本机的拦路石解除
ml/selftest_proc.py alive() / wait_pids() tasklist 用 text=True, errors='replace' 并防 None;起不来时把最后一次异常带进结果 tree_killed、survive_parent_exit 两项实测 true
ml/selftest.sh rec 解析失败记 false 不再丢项;gen_resume 判据剔除 plan_ms/cert.ms;APG 两项带 --config 重跑第 1 项已变 true(「续写:已有 2/6 条 → 逐条一致」)
ml/configs/apg.json batch 128 → 48,加 _vram 记录实测表 最坏 13.08 GiB(实测),在 19–20 GB 预算内
ml/configs/smoke.json 补 apg 段(batch=8) 自检 APG 档 vram: 0.33
ml/common/vram.py(新)+ train.py + apg/apg_finetune.py 每进程硬帽 VRAM_FRAC=0.78(启动打印上限);日志每条记录加 vram 峰值 显存上限:本进程 18.7 GiB(整卡 24.0 × 0.78);train vram: 2.71
ml/monitor.py + ml/monitor.html 状态带 vram_budget_gb(默认 20,VRAM_BUDGET_GB 可改);GPU 显存条按预算算并超线变色;指标卡加「显存峰值」 headless 加载渲染出的 DOM 里有「显存峰值 / 预算 19–20 GB(整卡 24,桌面占 4–5)」

7.5 仍需实现方处理的(我没动)

  • APG 的 steps 与机时:batch 从 128 降到 48,每步看到的任务少 2.7 倍。steps=3000 要不要加、加多少是收敛判断,我只有显存实测、没有这个依据。R2/R4/N-6 各处按整卡写的显存估算文案也要按 19–20 GB 重写。
  • R4 复跑:feat_dyn 要重导模型,探针现在会弹有界面窗口跑 viewer_ref(30 题×≤10 s)与 WebGPU——本机跑之前请知悉会有窗口,别动它。
  • B-2 的几何查询搬 Worker(若本机 R9 仍不过);R9 用真模型才有意义。