exp: 轮次45——tie(等长安全前缀按沿路最小间隙定夺)判掉

两臂 n=256 同 seed 背靠背(配方=轮次42 K8+cert_batch=1+inc_cap=1):到达 0.5234→0.5039
(-1.95pp,逐题配对丢6赢1净-5,McNemar 精确 p=0.125 与零不可分),时限内 +1.17pp、
刹停 -9%、行程比 -0.076、执行碰撞仍为 0(判据未放松)。丢的 6 题 5 题在 A 类(开阔区)
=买余量卖进度的签名。

仪表与离线数交叉验证:改选率 5.58% 对上轮次44 独立测得的"执行点间隙落在 0.2–0.5mm 占
5.6%",并列率 79.0% 对上"满前缀 79.4%" ⇒ 分辨率上界被宽相位截顶 gcap=max(0.5,margin+0.5)
锁死,5.6% 是这个家族在 cap=0.5 下的天花板,不是实现没调好。

结构性发现:#24 作用在错的人群——tie 只在 maxlen>0 触发,而失败主人群是全拒(maxlen=0,
未到达题 22% 的规划);全拒那条已由 backoff(轮次43)判掉。前置条件记为 #28(gcap 与
gap_margin 解耦)。

实现账:新增 tie 与触发计数器(生产端 per 数组+dump 键、消费端汇总 tie_* 同批改完,
tie=0 时 22/22 老键逐位复现);修掉 tie 分支局部名 nmax 顶掉主循环总步数的遮蔽 bug,
守卫单测做过变异检查;计数器正对照可手算(tie_opp=tie_changed=n_plans)。47 项测试绿。
This commit is contained in:
cbb
2026-10-21 00:33:44 +08:00
parent 350f386c02
commit 72c8835229
8 changed files with 564 additions and 5 deletions
+107
View File
@@ -0,0 +1,107 @@
{
"config": {
"ckpt": "ml/runs/base_dag2_dag1/best.pt",
"samples": "ml/data/samples",
"tasks": null,
"split": "val",
"n": 256,
"K": 8,
"commit": 2,
"fb": 2.2,
"ki": 0.0,
"fb_scale": 0.0,
"fb_near": 0.2,
"fb_fallback": 0.0,
"kdecay": 0.9,
"kimax": 0.5,
"fb_every": 1,
"safety_try": 0,
"sel_w": 0.1,
"dls_safety": 1,
"fb_clear": 0.0,
"fb_cmin": 0.3,
"sub_refresh": 0,
"fb_block_gain": 0.5,
"dump": "ml/runs/round42_K8cb1_rows.json",
"out": "docs/experiment_round42_K8cb1_dump.json",
"trace": null,
"select": "endpoint",
"replan": "empty",
"safety": 1,
"partial": 1,
"inc_cap": 1,
"gap_margin": 0.0,
"cert_batch": 1,
"steps": 1,
"z_scale": 1.0,
"len_w": 0.0,
"backoff": 0,
"max_sec": null,
"seed": 0,
"dls": "analytic",
"device": "cuda"
},
"batch_size": 256,
"batch_seed_rule": "same seed per batch",
"checkpoint_sha256": "f7f686fd8ee92fb6948fbcc4ee954636065ad87bb54f661c4f8f575bc16c2ce1",
"tasks_sha256": "249bd93457825cda98c59e64d9a096d3473c69aeb3553de1dea6d9e56be71772",
"kin_fp": "2ebcbf17",
"act_scale": 1.0,
"metrics": {
"n": 256,
"n_ref": 256,
"success": 0.5234375,
"collision_free_success": 0.5234375,
"time_ok_1p3": 0.265625,
"collision_rate": 0.0,
"collision_steps_mean": 0.0,
"travel_ratio_median": 2.615795850753784,
"time_mean_s": 2.486567258834839,
"brakes_mean": 19.5546875,
"start_fail": 0.0,
"goal_ratio_2s": 0.27920001745224,
"err_fail_med": 204.71360778808594,
"err_success_med": 0.21751396358013153,
"dls_share": 0.61328125,
"time_budget": "teacher×2(≥3 s)",
"speed_ratio_p50": 1.0000016689300537,
"speed_ratio_p95": 1.0000101327896118,
"speed_ratio_max": 1.0000101327896118,
"over_vmax_rate": 0.0,
"accel_ratio_p95": 1.0000016689300537,
"accel_ratio_max": 1.0000101327896118,
"reverse_p50": 0.24741201102733612,
"reverse_mean": 0.25991496443748474,
"reverse_moving_p50": 0.32581019401550293,
"moving_share_p50": 0.9587156176567078,
"brake_rate_mean": 0.10028044879436493,
"brake_rate_p50": 0.0051282052882015705,
"brake_rate_p90": 0.3153846263885498,
"stuck_share": 0.234375,
"n_plans_mean": 195.0,
"success_reachable": 0.5514403581619263,
"by_cat": {
"A": [
128,
96
],
"B": [
74,
20
],
"C": [
32,
11
],
"D": [
13,
0
],
"Dr": [
9,
7
]
}
},
"simulation_wall_s": 397.44336470001144
}
+111
View File
@@ -0,0 +1,111 @@
{
"config": {
"ckpt": "ml/runs/base_dag2_dag1/best.pt",
"samples": "ml/data/samples",
"tasks": null,
"split": "val",
"n": 64,
"K": 8,
"commit": 2,
"fb": 2.2,
"ki": 0.0,
"fb_scale": 0.0,
"fb_near": 0.2,
"fb_fallback": 0.0,
"kdecay": 0.9,
"kimax": 0.5,
"fb_every": 1,
"safety_try": 0,
"sel_w": 0.1,
"dls_safety": 1,
"fb_clear": 0.0,
"fb_cmin": 0.3,
"sub_refresh": 0,
"fb_block_gain": 0.5,
"dump": "ml/runs/round44_tieprobe64_rows.json",
"out": "docs/experiment_round44_tieprobe64.json",
"trace": null,
"select": "endpoint",
"replan": "empty",
"safety": 1,
"partial": 1,
"inc_cap": 1,
"gap_margin": 0.0,
"cert_batch": 1,
"steps": 1,
"z_scale": 1.0,
"len_w": 0.0,
"tie": 1,
"backoff": 0,
"max_sec": null,
"seed": 0,
"dls": "analytic",
"device": "cuda"
},
"batch_size": 256,
"batch_seed_rule": "same seed per batch",
"checkpoint_sha256": "f7f686fd8ee92fb6948fbcc4ee954636065ad87bb54f661c4f8f575bc16c2ce1",
"tasks_sha256": "6185a312dbae3bf5b361c4b9ff3aa11b7329d9723cff2be9b9157563d6b6ec1c",
"kin_fp": "2ebcbf17",
"act_scale": 1.0,
"metrics": {
"n": 64,
"n_ref": 64,
"success": 0.40625,
"collision_free_success": 0.40625,
"time_ok_1p3": 0.234375,
"collision_rate": 0.0,
"collision_steps_mean": 0.0,
"travel_ratio_median": 2.358931303024292,
"time_mean_s": 2.3323075771331787,
"brakes_mean": 18.71875,
"start_fail": 0.0,
"goal_ratio_2s": 0.33309799432754517,
"err_fail_med": 229.02410888671875,
"err_success_med": 0.22094391286373138,
"dls_share": 0.515625,
"time_budget": "teacher×2(≥3 s)",
"speed_ratio_p50": 1.0000016689300537,
"speed_ratio_p95": 1.0000091791152954,
"speed_ratio_max": 1.0000101327896118,
"over_vmax_rate": 0.0,
"accel_ratio_p95": 1.0000016689300537,
"accel_ratio_max": 1.0000101327896118,
"reverse_p50": 0.25150150060653687,
"reverse_mean": 0.25861242413520813,
"reverse_moving_p50": 0.318452388048172,
"moving_share_p50": 0.9090909361839294,
"brake_rate_mean": 0.10696429014205933,
"brake_rate_p50": 0.017142856493592262,
"brake_rate_p90": 0.33142855763435364,
"stuck_share": 0.21875,
"n_plans_mean": 175.0,
"success_reachable": 0.4262295067310333,
"by_cat": {
"A": [
28,
14
],
"B": [
21,
6
],
"C": [
9,
4
],
"D": [
3,
0
],
"Dr": [
3,
2
]
},
"tie_opp_rate_mean": 0.7484821081161499,
"tie_changed_rate_mean": 0.07437500357627869,
"tie_opp_task_share": 1.0
},
"simulation_wall_s": 78.19308080000337
}
+108
View File
@@ -0,0 +1,108 @@
{
"config": {
"ckpt": "ml/runs/base_dag2_dag1/best.pt",
"samples": "ml/data/samples",
"tasks": null,
"split": "val",
"n": 256,
"K": 8,
"commit": 2,
"fb": 2.2,
"ki": 0.0,
"fb_scale": 0.0,
"fb_near": 0.2,
"fb_fallback": 0.0,
"kdecay": 0.9,
"kimax": 0.5,
"fb_every": 1,
"safety_try": 0,
"sel_w": 0.1,
"dls_safety": 1,
"fb_clear": 0.0,
"fb_cmin": 0.3,
"sub_refresh": 0,
"fb_block_gain": 0.5,
"dump": "ml/runs/round45_tie0_rows.json",
"out": "docs/experiment_round45_tie0.json",
"trace": null,
"select": "endpoint",
"replan": "empty",
"safety": 1,
"partial": 1,
"inc_cap": 1,
"gap_margin": 0.0,
"cert_batch": 1,
"steps": 1,
"z_scale": 1.0,
"len_w": 0.0,
"tie": 0,
"backoff": 0,
"max_sec": null,
"seed": 0,
"dls": "analytic",
"device": "cuda"
},
"batch_size": 256,
"batch_seed_rule": "same seed per batch",
"checkpoint_sha256": "f7f686fd8ee92fb6948fbcc4ee954636065ad87bb54f661c4f8f575bc16c2ce1",
"tasks_sha256": "249bd93457825cda98c59e64d9a096d3473c69aeb3553de1dea6d9e56be71772",
"kin_fp": "2ebcbf17",
"act_scale": 1.0,
"metrics": {
"n": 256,
"n_ref": 256,
"success": 0.5234375,
"collision_free_success": 0.5234375,
"time_ok_1p3": 0.265625,
"collision_rate": 0.0,
"collision_steps_mean": 0.0,
"travel_ratio_median": 2.615795850753784,
"time_mean_s": 2.486567258834839,
"brakes_mean": 19.5546875,
"start_fail": 0.0,
"goal_ratio_2s": 0.27920001745224,
"err_fail_med": 204.71360778808594,
"err_success_med": 0.21751396358013153,
"dls_share": 0.61328125,
"time_budget": "teacher×2(≥3 s)",
"speed_ratio_p50": 1.0000016689300537,
"speed_ratio_p95": 1.0000101327896118,
"speed_ratio_max": 1.0000101327896118,
"over_vmax_rate": 0.0,
"accel_ratio_p95": 1.0000016689300537,
"accel_ratio_max": 1.0000101327896118,
"reverse_p50": 0.24741201102733612,
"reverse_mean": 0.25991496443748474,
"reverse_moving_p50": 0.32581019401550293,
"moving_share_p50": 0.9587156176567078,
"brake_rate_mean": 0.10028044879436493,
"brake_rate_p50": 0.0051282052882015705,
"brake_rate_p90": 0.3153846263885498,
"stuck_share": 0.234375,
"n_plans_mean": 195.0,
"success_reachable": 0.5514403581619263,
"by_cat": {
"A": [
128,
96
],
"B": [
74,
20
],
"C": [
32,
11
],
"D": [
13,
0
],
"Dr": [
9,
7
]
}
},
"simulation_wall_s": 317.56223549999413
}
+111
View File
@@ -0,0 +1,111 @@
{
"config": {
"ckpt": "ml/runs/base_dag2_dag1/best.pt",
"samples": "ml/data/samples",
"tasks": null,
"split": "val",
"n": 256,
"K": 8,
"commit": 2,
"fb": 2.2,
"ki": 0.0,
"fb_scale": 0.0,
"fb_near": 0.2,
"fb_fallback": 0.0,
"kdecay": 0.9,
"kimax": 0.5,
"fb_every": 1,
"safety_try": 0,
"sel_w": 0.1,
"dls_safety": 1,
"fb_clear": 0.0,
"fb_cmin": 0.3,
"sub_refresh": 0,
"fb_block_gain": 0.5,
"dump": "ml/runs/round45_tie1_rows.json",
"out": "docs/experiment_round45_tie1.json",
"trace": null,
"select": "endpoint",
"replan": "empty",
"safety": 1,
"partial": 1,
"inc_cap": 1,
"gap_margin": 0.0,
"cert_batch": 1,
"steps": 1,
"z_scale": 1.0,
"len_w": 0.0,
"tie": 1,
"backoff": 0,
"max_sec": null,
"seed": 0,
"dls": "analytic",
"device": "cuda"
},
"batch_size": 256,
"batch_seed_rule": "same seed per batch",
"checkpoint_sha256": "f7f686fd8ee92fb6948fbcc4ee954636065ad87bb54f661c4f8f575bc16c2ce1",
"tasks_sha256": "249bd93457825cda98c59e64d9a096d3473c69aeb3553de1dea6d9e56be71772",
"kin_fp": "2ebcbf17",
"act_scale": 1.0,
"metrics": {
"n": 256,
"n_ref": 256,
"success": 0.50390625,
"collision_free_success": 0.50390625,
"time_ok_1p3": 0.27734375,
"collision_rate": 0.0,
"collision_steps_mean": 0.0,
"travel_ratio_median": 2.53989315032959,
"time_mean_s": 2.3586044311523438,
"brakes_mean": 17.7890625,
"start_fail": 0.0,
"goal_ratio_2s": 0.27920001745224,
"err_fail_med": 213.06358337402344,
"err_success_med": 0.22968679666519165,
"dls_share": 0.62109375,
"time_budget": "teacher×2(≥3 s)",
"speed_ratio_p50": 1.0000016689300537,
"speed_ratio_p95": 1.0000101327896118,
"speed_ratio_max": 1.0000101327896118,
"over_vmax_rate": 0.0,
"accel_ratio_p95": 1.0000016689300537,
"accel_ratio_max": 1.0000101327896118,
"reverse_p50": 0.25315314531326294,
"reverse_mean": 0.26444095373153687,
"reverse_moving_p50": 0.3198198080062866,
"moving_share_p50": 0.9772727489471436,
"brake_rate_mean": 0.09122596681118011,
"brake_rate_p50": 0.0,
"brake_rate_p90": 0.3282051384449005,
"stuck_share": 0.203125,
"n_plans_mean": 195.0,
"success_reachable": 0.5308641791343689,
"by_cat": {
"A": [
128,
91
],
"B": [
74,
19
],
"C": [
32,
12
],
"D": [
13,
0
],
"Dr": [
9,
7
]
},
"tie_opp_rate_mean": 0.7898838520050049,
"tie_changed_rate_mean": 0.055829327553510666,
"tie_opp_task_share": 1.0
},
"simulation_wall_s": 283.46215640001174
}
+25 -1
View File
@@ -31,7 +31,8 @@
| 序 | 候选 | 支撑证据 | 状态 |
|---|---|---|---|
| 0 | **把"沿路最小间隙"接进候选打分**(#24) | 安全层的拒绝是真实几何(端点/中点穿模),而 `cert_batch=1` 已经在同一次 gaps 调用里算了 K 条候选各 `2·commit_n` 个点的间隙——**这些信息目前只用来判通过/拒绝,没进打分**。做法:`score = −e_end − w·relu(gap_ref − min_gap_path)`,让"会穿模"的候选在排序阶段就出局,而不是等安全层全拒。代价为零(同一批数),判据完全不放松 | 待实现(链跑完后动库) |
| 0 | ~~把"沿路最小间隙"接进候选打分~~(极端版 = `--tie 1`:只在"前缀最长"的并列集合内按余量定夺,零额外几何) | 轮次 45 两臂:到达 −1.95 pp(净 −5 题,McNemar p=0.125 与零不可分)、时限 +1.17 pp、刹停 −9%、行程 −0.076、**碰撞仍 0**;且分辨率被 `gcap=0.5 mm` 截顶锁死(并列 79% 但只有 5.6% 可分辨,与轮次 44 离线 5.6% 对上) | **判掉**:买余量卖进度,且作用在 `maxlen>0` 的人群——失败主人群是全拒(`maxlen=0`)。前置条件见 #28 |
| 0b | **#28 抬宽相位截顶 `gcap` 并与 `gap_margin` 解耦** | 现在 `--gap_margin 1.5` 会同时抬截顶值和验收门限,动一个必动另一个;`_coarse` 保留 `d ≤ cp_lim + cap` 的胶囊对 ⇒ 成本随壳层体积涨,而 GPU 周期 P50 已 33.5 ms | 未实现(要新增只改数值精度的参数,不许碰判据) |
| 1 | **候选数翻倍 K=8→16** | 轮次 39 实测:到达 **+3.9 pp**、时限内 **+3.1 pp**、**刹车 −30%**(19.55→13.77)、碰撞仍 0、行程比不变 ⇒ 很多"全拒"是**没备选**而不是真没路 | **正向**;认证/打分成本要用独占微基准量完才能谈部署 |
| 2 | **全拒时缩步顶上**(`--backoff`:首选候选按 1/2、1/4、1/8 并进同一次认证,只在原候选连第 1 步都不安全时启用) | 失败分类 63/109 是"被冻住"、未到组 37% 步为零运动;但 4 题 CPU 冒烟提示转化率只 ~13% | 代码与单测已落,256 题四臂待补跑(判读规则已预注册) |
| 3 | **白费比例惩罚**(`select=ep_waste --len_w`,罚 `1−同轴净/总` × 当前误差) | 换向是**全局**现象(~1/4 的(步,轴)对在反向,到达/未到达两组差不多);净位移只占总行程 0.445 | 已实现+正对照单测(可手算 2/18);三臂排队 |
@@ -108,6 +109,29 @@
- **对 `backoff` 的预期与判据**:全拒意味着"连第 1 步的端点或中点已经穿进障碍",缩步能不能救取决于**穿得有多深**(穿 0.1 mm 救得回,穿 3 mm 救不回)。这个数转储里没记(只记被选中那条),所以直接由 `backoff_mean`/`reject_all_mean` 来量:
`reject_all_mean ≈ 原全拒次数`(=backoff_mean+brakes_mean,与轮次 33 cap 的 19.55 可比),`backoff_mean/(backoff_mean+brakes_mean)` 就是"缩步能救回的比例"。这是补跑(#22)要读的第一个数。
## 轮次 45:`tie`(等长安全前缀按沿路最小间隙定夺)判掉——它买的是余量,卖的是进度,而且作用在错的人群上
- **做法**:`cert_batch=1` 已经在同一次几何调用里算了 K 条候选各 `2·commit_n` 个点的间隙,但这些信息只用来判通过/拒绝。`--tie 1` 让"前缀最长"的并列集合改由**沿路最小间隙**定夺;零额外几何调用,判据一个字没动(仍是 `gap > gap_margin`)。
- **先测触发率再花钱**(阈值预注册:<1% 直接判掉,≥5% 才跑两臂)。n=64 探针:并列率 `tie_opp_rate=74.8%`、真的改选率 `tie_changed_rate=7.4%` ⇒ 过线,才投 256 题两臂。
- **两臂 A/B(n=256、同 seed、同窗口背靠背,配方=轮次 42 的 `K8 + cert_batch=1 + inc_cap=1`)**:
| 读数 | A `tie=0` | B `tie=1` | 差 |
|---|---|---|---|
| 到达 / 无碰撞到达 | 0.5234 | 0.5039 | **−1.95 pp** |
| 时限内(≤1.3×老师) | 0.2656 | 0.2773 | +1.17 pp |
| 执行碰撞率 | 0.0 | **0.0** | 判据未放松(硬门槛通过) |
| 刹停/题 | 19.55 | 17.79 | −9.0% |
| 卡住题占比(刹停>20%) | 23.4% | 20.3% | −3.1 pp |
| 行程比中位 | 2.6158 | 2.5399 | −0.076 |
| 到达均值用时 | 2.487 s | 2.359 s | −0.128 s |
- **统计诚实**:逐题配对**丢 6 题、赢 1 题,净 −5**;McNemar 精确双侧 **p = 0.125** ⇒ 到达差异在这个分母上与零不可分。所以结论不是"它显著变差",而是**没有任何正向证据,且方向为负**;而刹停/行程/用时全部朝"更保守"的方向动,与到达同向恶化是一个自洽的签名,不是噪声。丢的 6 题里 **5 题在 A 类(开阔均匀区)**,唯一赢的那题在 C 类(贴立柱)。
- **仪表与独立离线数对上了(这条比 A/B 本身更有说服力)**:本轮 256 题的改选率 **5.58%**,与轮次 44 纯离线量到的"执行点间隙落在 0.2–0.5 mm 的占比 **5.6%**"逐位同量级;并列率 79.0% 对上"满前缀 79.4%"。⇒ **余量能分辨的上界就是"有多少执行点真的贴进 0.5 mm 以内"**,被宽相位截顶 `gcap = max(0.5, gap_margin+0.5)` 锁死(凡沿途间隙都 >0.5 mm 的候选,`min_gap` 恒等于 0.5,排序上完全并列)。所以 5.6% 是这个家族在 cap=0.5 下的**天花板**,不是实现没调好。
- **机理判读**:并列集合里"余量最大"的那条通常也是"位移最小"的那条。默认口径由选择器分数(终点误差)定夺 = 用进度换余量的风险由策略承担;`tie=1` 把判据整个换成余量 ⇒ 在根本没有障碍的 A 类纯亏进度。正确形态若要保留这条线,只能是"进度 + 余量"的加权,而加权又要一个新的自由系数——在当前 −5 的背景下不值得一轮。
- **结构性发现(否掉的是实现,更是提问方式)**:#24 从提出起就**作用在错的人群**。失败主人群是"全拒(`maxlen=0`)"——未到达题 22.0% 的规划连第 1 步都不安全;而 `tie` 只在 `maxlen>0` 时触发。全拒人群的杠杆是 `backoff`(轮次 43 已判掉:能救回停步、救不回通路)。⇒ "选哪条活路"这件事,对已经走通的路影响很小,对走不通的路毫无影响。
- **本轮踩到并修掉的实现洞**:tie 分支里我用了局部名 `nmax`,把主循环的"总步数"顶掉 ⇒ 进度回调 `%d` 收到张量直接炸(第一次 n=64 探针就是这么失败的)。修法是改名 `ntile`,并补一条守卫单测(tie=1 必须带 `progress` 跑通且 `total` 保持标量);**守卫做过变异检查**——把 `ntile` 换回 `nmax`,守卫立刻变红。计数器的正对照也可手算:夹具里两条候选永远全安全 ⇒ `tie_opp = tie_changed = n_plans`、两个比率恒 1。47 项测试全绿。
- **不采纳**。前置条件记为 #28:先把"数值截顶 `gcap`"与"验收门限 `gap_margin`"解耦(现在 `--gap_margin 1.5` 会同时抬截顶值和门限,动一个必动另一个),再量 cap=0.5/2/5 mm 下的分辨率与几何耗时(`_coarse` 保留 `d ≤ cp_lim + cap` 的胶囊对,成本随壳层体积涨)。**但即使分辨率上来,人群错配也不会被修好**,所以这条只作为"贴边题(C 类)里选哪条活路"的低优先候选保留。
## #27:K=16 的增益**不集中在 B/C**——B 类缺口是策略能力,不是候选容量(轮次 44,逐题 dump)
- K=8 与 K=16(都 `--cert_batch 1 --inc_cap 1`,同 256 题同 seed)逐题对齐后按类别: