feat+exp: 轮次39——候选档位开关 --z_scale 与行程惩罚 select=ep_len/--len_w(零权重与 endpoint 逐位相同,2 条机制单测)

This commit is contained in:
cbb
2026-10-20 22:05:12 +08:00
parent cad8bb44f0
commit cd6913b136
4 changed files with 85 additions and 4 deletions
+10
View File
@@ -38,6 +38,16 @@
| 5 | 速度/余量口径(#11/#14) | `--inc_cap 1` 代价 −5.1 pp 到达、−12.5 pp 时限;`gap_margin 0.5 mm` 只付 3 题 | 已量化,投影式余量未移植 |
| 6 | 循环内共享 FK(#19)、FP16/BF16、流水线复用 | 实测分别只有 0.03 ms/次、负收益、−3.1 ms 且扰动特征 | **已判掉** |
## 轮次 39:两条没人碰过的算法杠杆——候选档位与行程惩罚(机制已单测,A/B 排队)
- **为什么是这两条**:轮次 38 的失败分类说清楚了两件事——① 到达率的缺口在"K 条候选全被拒 ⇒ 原地冻住"(63/109),② §9.2 要"关节行程 ≤ 规划器×1.10",实测行程比中位 **2.4~2.6**,而现在**没有任何机制在管行程**(选择器只看末态误差,安全层只看间隙)。另外 `--steps` 那组数顺带给了一条线索:多段推理把行程比从 2.62 拉到 1.87,说明行程主要由候选选择/动作形状决定,不是物理必然。
- **杠杆 1:候选档位与多样性(#15)**。`ml/eval/eval_cl.py` 补 `--z_scale`(rollout 早就有这个参数,只是评估没接)。四臂对照轮次 33 cap:`K=16`、`K=8 --safety_try 3`、`K=8 --safety_try 1`、`K=8 --z_scale 1.5`。要回答的是:**全拒是"真没路"还是"没备选"**——若 K=16 或 z_scale 拉大能把到达/刹车买回来,那是候选池的问题;若 `safety_try 1` 几乎不掉到达,那说明第 1 条候选就够,后面试 7 条只是在花几何查询的钱(这对 20 ms 预算直接相关)。
- **杠杆 2:行程惩罚(`select='ep_len'` + `--len_w`)**。分数从 `-末态误差` 改成 `-末态误差 − len_w·Σ_t Σ_j |Δ_j|/STEP_j`(每轴按自己的满速步长归一,所以 6 轴可比)。
- 机制单测 2 条(`tests/test_eval_cl.py::TravelPenaltySelectTest`,40 项全过):造两条**末态相同、累计位移相同**的候选,一条来回抖(归一行程 10.8)一条匀速(3.6),`goal_err` 打成常数 ⇒ 只有行程能把它们分开。实测 `len_w=0` 选到抖动那条(第 1 步 1.08°)、`len_w=1.0` 选到匀速那条(第 1 步 0.27°);另有一条**同分零权重必须与 `select='endpoint'` 逐位相同**的回归断言(rtol=atol=0),保证默认行为没被这次改动碰到。
- 待测:`len_w ∈ {0.1, 0.3, 1.0}` 三臂,看行程比能压到多少、到达与时限各付多少。这条杠杆与"到达率"是相互冲突的目标(惩罚行程=主动走慢),所以必须成对汇报,不能只报行程变好。
- 单位口径要说清:`len_w` 的量纲是"mm 误差 / 一个归一 STEP 的累计行程",16 步满速在 3 条轴上大约是 48,所以 0.1~1.0 对应的惩罚是 5~50 mm 当量——这是扫这三个值的原因,不是随手取的。
- 测试 `tests/test_eval_cl.py` 38→40 项、全套 43→45 项(`python -m unittest discover -s tests`,2.2 s 全绿)。GPU 队列顺序:backoff A/B → `--safety 0` 判别 → 候选档位 → 行程惩罚。
## 轮次 38:把 `--steps` 打通之后,闭环反而变差——瓶颈从"动作质量"移到了"安全层拒绝率"