exp(dagger-deploy): 部分安全前缀(执行到首个不安全步)——刹停 27.4→8.6、到达 38.3%、碰撞 1.6%;新增 commit_n 参数(每步规划实验);更正 replan=empty 实为 r=0 规划非每步
This commit is contained in:
+47
-10
@@ -128,11 +128,12 @@
|
||||
| dag1 best(轮次 6) | 1.2 | **23.4%** | 1.6% | **0.454** | 31.4 | 953 ms |
|
||||
|
||||
- **结论**:部署分布 DAgger 把刹停降 18–40%、时延降 ~31 ms,但到达率未突破 23% 平台(-0.7 pp),属边际权衡改善;历史最佳到达仍是 dag1+gain1.2(23.4%)。
|
||||
- **下一步**:试每步重规划(replan='empty',让反馈逐步生效)与安全层候选 K=16(减少全拒刹停)。
|
||||
- **下一步**:试 replan=empty(r=0 规划,让反馈逐步生效)与安全层候选 K=16(减少全拒刹停)。
|
||||
|
||||
## 轮次 9:每步重规划 / K=16 安全候选(exp: `exp/dagger-deploy`,新历史最佳)
|
||||
## 轮次 9:replan=empty(队列空时规划、r=0)/ K=16 安全候选(exp: `exp/dagger-deploy`,新历史最佳)
|
||||
|
||||
- **假设**:反馈混合是逐步修正的,每 3 步重规划会滞后;每步重规划(replan='empty')让反馈逐步生效。K=16 给安全层更多候选、减少全拒。
|
||||
- **假设**:replan='empty'(每次队列空时规划、无前缀 r=0)比默认 r=3 更适合反馈混合。K=16 给安全层更多候选、减少全拒。
|
||||
(更正:replan='empty' 仍是每 3 步规划一次——队列空才规划,commit 3 步;收益来自 r=0 无前缀,不是规划频率。)
|
||||
- **判据**:部署口径 reach > 23.4% 且碰撞 ≤1.6%、刹停/时延不恶化。
|
||||
- **配方**:dag2 best;`replan='empty'`(每次 r=0 规划);`K=16`。n=128,safety=True。
|
||||
- **对照**:轮次 8(dag2+gain1.2:22.7% / 1.6% / 0.491 / 25.9 / 922 ms)。
|
||||
@@ -144,12 +145,12 @@
|
||||
| gain1.2 + K=16 | 21.1% | 1.6% | 0.451 | 19.4 | 1629 ms |
|
||||
| gain1.0 + K=16 | 21.9% | 4.7% | 0.506 | 14.6 | 1588 ms |
|
||||
|
||||
- **结论**:**每步重规划全面改善**(到达 +3.9 pp、碰撞 1.6→0.8%、刹停 25.9→20.6、时延 922→845 ms),成为**新历史最佳**。K=16 无收益且时延翻倍(1629 ms),淘汰。
|
||||
- **下一步**:每步重规划下重扫增益(0.8/1.0/1.5/2.0),找新最优。
|
||||
- **结论**:**replan=empty(r=0)全面改善**(到达 +3.9 pp、碰撞 1.6→0.8%、刹停 25.9→20.6、时延 922→845 ms),成为**新历史最佳**。K=16 无收益且时延翻倍(1629 ms),淘汰。
|
||||
- **下一步**:replan=empty 下重扫增益(0.8/1.0/1.5/2.0),找新最优。
|
||||
|
||||
## 轮次 10:每步重规划下的增益重扫(exp: `exp/dagger-deploy`,新历史最佳)
|
||||
## 轮次 10:replan=empty(r=0)下的增益重扫(exp: `exp/dagger-deploy`,新历史最佳)
|
||||
|
||||
- **假设**:反馈每步生效后,最优增益会上移。
|
||||
- **假设**:r=0 规划下,最优增益会上移。
|
||||
- **判据**:reach > 26.6%(轮次 9)且碰撞 ≤1.6%;同时比较刹停/时延。
|
||||
- **配方**:dag2 best,`replan='empty'`,gain ∈ {0.8, 1.0, 1.2, 1.5, 2.0},safety=True,n=128。
|
||||
- **对照**:轮次 9(gain 1.2:26.6% / 0.8% / 0.453 / 20.6 / 845 ms)。
|
||||
@@ -163,7 +164,7 @@
|
||||
| **1.5** | **28.9%** | 0.8% | **0.411** | 28.5 | 844 ms |
|
||||
| 2.0 | 28.9% | 0.8% | 0.414 | 44.9 | 914 ms |
|
||||
|
||||
- **结论**:到达在 gain 1.5 封顶(28.9%),2.0 无收益且刹停翻倍(44.9)。**按到达优先/碰撞 ≤3%:历史最佳 = gain 1.5 + 每步重规划(28.9% / 0.8% / 0.411 / 28.5 / 844 ms)**;按碰撞优先:gain 1.0(22.7% / 0.0% / 0.489 / 15.2 / 810 ms)。n=128 的差异约 3–4 题,需 n=256 复核。
|
||||
- **结论**:到达在 gain 1.5 封顶(28.9%),2.0 无收益且刹停翻倍(44.9)。**按到达优先/碰撞 ≤3%:历史最佳 = gain 1.5 + replan=empty(28.9% / 0.8% / 0.411 / 28.5 / 844 ms)**;按碰撞优先:gain 1.0(22.7% / 0.0% / 0.489 / 15.2 / 810 ms)。n=128 的差异约 3–4 题,需 n=256 复核。
|
||||
- **下一步**:n=256 复核 gain 1.0 / 1.2 / 1.5;若平台稳定,再决定是否 DAgger 第 3 轮(采集用新部署配置)。
|
||||
|
||||
## 轮次 11:n=256 复核(发现前 128 题偏难)
|
||||
@@ -180,7 +181,7 @@
|
||||
| 1.2 | 26.6% | **34.8%** | 1.2% | 0.392 | 18.6 | 752 ms |
|
||||
| 1.5 | 28.9% | **36.7%** | 1.6% | 0.323 | 27.4 | 760 ms |
|
||||
|
||||
- **结论**:前 128 题显著偏难;n=256 上 **gain 1.5 + 每步重规划 = 到达 36.7% / 碰撞 1.6% / ratio2s 0.323 / 刹停 27.4 / 760 ms**(新历史最佳)。gain 1.0 更保守(31.6% / 碰撞 0.8% / 刹停 15.0)。排名与 n=128 一致(1.5 > 1.2 > 1.0)。
|
||||
- **结论**:前 128 题显著偏难;n=256 上 **gain 1.5 + replan=empty = 到达 36.7% / 碰撞 1.6% / ratio2s 0.323 / 刹停 27.4 / 760 ms**(新历史最佳)。gain 1.0 更保守(31.6% / 碰撞 0.8% / 刹停 15.0)。排名与 n=128 一致(1.5 > 1.2 > 1.0)。
|
||||
- **下一步**:n=512 复核 gain 1.2/1.5;随后评估 DAgger 第 3 轮(部署分布采集)与监控页回写。
|
||||
|
||||
## 轮次 12:n=512 复核(稳定结论)
|
||||
@@ -196,10 +197,46 @@
|
||||
| 1.2 | 34.8% | **32.6%** | 1.0% | 0.435 | 18.6 | 722 ms |
|
||||
| 1.5 | 36.7% | **33.4%** | 1.0% | 0.399 | 28.1 | 738 ms |
|
||||
|
||||
- **结论**:n=512 稳定在 **33% 左右**(n=256 略乐观);**历史最佳(n=512,部署口径)= gain 1.5 + 每步重规划:到达 33.4% / 碰撞 1.0% / ratio2s 0.399 / 刹停 28.1 / 738 ms**。保守版 gain 1.2:32.6% / 1.0% / 0.435 / 18.6 / 722 ms(刹停少 1/3)。
|
||||
- **结论**:n=512 稳定在 **33% 左右**(n=256 略乐观);**历史最佳(n=512,部署口径)= gain 1.5 + replan=empty:到达 33.4% / 碰撞 1.0% / ratio2s 0.399 / 刹停 28.1 / 738 ms**。保守版 gain 1.2:32.6% / 1.0% / 0.435 / 18.6 / 722 ms(刹停少 1/3)。
|
||||
- **监控页回写**:`ml/monitor.py` 新增 `/api/explore`(读 docs/探索日志.md),`ml/monitor.html` 新增「闭环探索日志」卡片;Edge headless 截图确认渲染正常(http://127.0.0.1:8100)。
|
||||
- **下一步**:候选选择器(consist/value/first)与 K=4 在反馈+每步重规划下是否影响到达/刹停。
|
||||
|
||||
## 轮次 13:选择器 / K / 失败模式(exp: `exp/dagger-deploy`)
|
||||
|
||||
- **假设**:反馈混合下,候选选择器与候选数 K 会影响到达/时延;失败模式可指导下一步。
|
||||
- **判据**:reach > 36.7% 或时延显著下降;同时报告 time_ok_1p3。
|
||||
- **配方**:dag2 best,replan='empty',gain 1.5,safety=True,n=256。
|
||||
- **对照**:轮次 11/12(consist K=8:36.7%)。
|
||||
- **指标**:
|
||||
|
||||
| 配置 | 到达 | 碰撞 | ratio2s | 刹停/题 | 墙钟/题 |
|
||||
|---|---|---|---|---|---|
|
||||
| consist K=8 | 36.7% | 1.6% | 0.323 | 27.4 | 764 ms |
|
||||
| value K=8 | 35.9% | 1.6% | 0.334 | 29.4 | 1063 ms |
|
||||
| first K=8 | 36.3% | 1.2% | 0.338 | 28.1 | 780 ms |
|
||||
| K=6 | 35.9% | 1.6% | 0.353 | 28.6 | 627 ms |
|
||||
| K=4 | 31.6% | 1.2% | 0.396 | 32.6 | 482 ms |
|
||||
|
||||
- **失败模式(n=256,consist K=8)**:失败 149 题中 **碰撞仅 3 题(1.2%)、超时无碰撞 146 题(57.0%)**;失败题终点误差 p50 140 mm;`time_ok_1p3` 仅 **13.3%**;成功题 t_done p50 2.74 s(时限 p50 3.4 s);刹停 27.4 次/题。
|
||||
- **结论**:选择器无差别(consist 略优);K=8 到达最佳,K=6 省 18% 时延(到达 -0.8 pp)。**当前真正的瓶颈是时间效率(频繁刹停→超时),不是碰撞**。§9.2 的「用时 ≤ 老师×1.3」当前只有 13.3%。
|
||||
- **下一步**:每步重规划下,安全层只需认证第 1 步(现在验 3 步,过度保守→全拒→刹停);改 `safety_steps=1` 验证能否在保持低碰撞的同时大幅减少刹停。
|
||||
|
||||
## 轮次 14:部分安全前缀(exp: `exp/dagger-deploy`,刹停大降)
|
||||
|
||||
- **假设**:安全层现在要求 3 步全安全才执行,候选只要第 2–3 步有碰撞就全拒刹停;改为「执行到第一个不安全步为止」可减少刹停。
|
||||
- **判据**:刹停显著下降、到达不降、碰撞 ≤3%。
|
||||
- **配方**:dag2 best,replan='empty',gain 1.5,safety=True,`safety_partial=1`;n=256。
|
||||
- **对照**:全窗口(轮次 11/13:36.7% / 1.6% / 0.323 / 27.4 / 775 ms)。
|
||||
- **指标**:
|
||||
|
||||
| 安全层 | 到达 | time_ok_1p3 | 碰撞 | ratio2s | 刹停/题 | 墙钟/题 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 3 步全安全 | 36.7% | 13.3% | 1.6% | 0.323 | 27.4 | 775 ms |
|
||||
| **部分安全前缀** | **38.3%** | 13.7% | 1.6% | **0.308** | **8.6** | 770 ms |
|
||||
|
||||
- **结论**:刹停 **27.4→8.6(-69%)**、到达 +1.6 pp、碰撞不变——**部分安全前缀有效**(新最佳:38.3% / 1.6% / 0.308 / 8.6 / 770 ms)。但 `time_ok_1p3` 仍 13.7%:说明超时主因不是刹停,而是**执行粒度**——部分前缀的填充零步仍在消耗时间。
|
||||
- **下一步**:commit_n=1(每次只提交 1 步、每步规划,无填充步),验证时间效率。
|
||||
|
||||
## 轮次统计
|
||||
|
||||
- 连续无实质进展轮数:0(轮次 5 出现实质进展:reach 0→20.3%)。
|
||||
|
||||
+28
-10
@@ -142,7 +142,7 @@ class TeacherOracle:
|
||||
@torch.no_grad()
|
||||
def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None, return_traj=False, use_sub=True, sub_override=None,
|
||||
qp0=None, steps=1, z_scale=1.0, select='consist', oracle=None, replan='r3', sub_rule='cross',
|
||||
fb_gain=0.0, fb_scale=0.0, fb_near=0.2, fb_fallback=0.0):
|
||||
fb_gain=0.0, fb_scale=0.0, fb_near=0.2, fb_fallback=0.0, safety_partial=0, commit_n=3):
|
||||
"""use_sub=False:不用子目标(sf=0);sub_override=(subs [B,M,6] 绝对关节角, n [B] 个数 或 need [B] bool):冷启动时用给定途经点代替子目标头;
|
||||
qp0 [B,6]:起点的上一帧(默认 = q0,即静止起步)。steps:MeanFlow 采样段数;z_scale:噪声缩放;
|
||||
select:consist(部署口径:冷启动价值前瞻、之后与上一条已提交计划的一致性)/ value(每次都价值前瞻)/ first(不选,取第 0 条)。
|
||||
@@ -227,34 +227,52 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None,
|
||||
# 新候选 fut[0] 是 qe_new 再走 1 步 = 对应 last[4]。JS 部署(ik-policy.js)同一处同样修正。
|
||||
n = min(fut.shape[2], last.shape[1] - 4)
|
||||
w = 0.85 ** torch.arange(n, device=device, dtype=torch.float32)
|
||||
d2 = (((fut[:, :, :n] - last[:, None, 4:4 + n]) / step) ** 2).sum(-1)
|
||||
d2 = (((fut[:, :, :n] - last[:, None, commit_n + 1:commit_n + 1 + n]) / step) ** 2).sum(-1)
|
||||
# 2026-10-19(审查 review_closedloop F5):上一次是刹停或 DLS 接管的行没有「已提交计划」,
|
||||
# 与 JS(lastPlan = null → 一致性项缺席、各候选同分 → 取第 0 条)一致:同分,稳定排序取第 0 条
|
||||
score = torch.where(last_ok[:, None], -(d2 * w).sum(-1), torch.zeros_like(d2[..., 0]))
|
||||
order = torch.sort(score, dim=-1, descending=True, stable=True).indices
|
||||
pick = order[:, 0]
|
||||
commit = inc[ar, pick, r:r + 3]
|
||||
commit = inc[ar, pick, r:r + commit_n]
|
||||
committed = torch.ones(B, dtype=torch.bool, device=device)
|
||||
if safety:
|
||||
ok_any = torch.zeros(B, dtype=torch.bool, device=device)
|
||||
chosen = torch.zeros(B, 3, 6, device=device); chosen_k = pick.clone()
|
||||
if safety and safety_partial: # 2026-10-20:允许「部分安全前缀」——执行到第一个不安全步为止,而不是全拒刹停
|
||||
maxlen = torch.zeros(B, dtype=torch.long, device=device)
|
||||
chosen = torch.zeros(B, commit_n, 6, device=device); chosen_k = pick.clone()
|
||||
for kk in range(K):
|
||||
ck = inc[ar, order[:, kk], r:r + 3]
|
||||
ck = inc[ar, order[:, kk], r:r + commit_n]
|
||||
pts = qe[:, None] + torch.cumsum(ck, 1)
|
||||
mids = torch.cat([qe[:, None], pts[:, :-1]], 1) + 0.5 * ck
|
||||
allq = torch.cat([pts, mids], 1).reshape(-1, 6)
|
||||
okk = (kin.gaps(allq, 0.5)['gm'].min(-1).values > 0).view(B, 6).all(-1)
|
||||
ok6 = (kin.gaps(allq, 0.5)['gm'].min(-1).values > 0).view(B, 6)
|
||||
okstep = ok6[:, :commit_n] & ok6[:, commit_n:] # 每步:步点与其中点都安全
|
||||
plen = torch.cumprod(okstep.long(), 1).sum(1) # 安全前缀长度 0..3
|
||||
take = plen > maxlen
|
||||
chosen = torch.where(take[:, None, None], ck, chosen); chosen_k = torch.where(take, order[:, kk], chosen_k)
|
||||
maxlen = torch.maximum(maxlen, plen)
|
||||
msk = (torch.arange(commit_n, device=device)[None] < maxlen[:, None])
|
||||
commit = torch.where(msk[..., None], chosen, torch.zeros_like(chosen))
|
||||
brakes += (maxlen == 0).float()
|
||||
pick = chosen_k; committed = maxlen > 0
|
||||
elif safety:
|
||||
ok_any = torch.zeros(B, dtype=torch.bool, device=device)
|
||||
chosen = torch.zeros(B, commit_n, 6, device=device); chosen_k = pick.clone()
|
||||
for kk in range(K):
|
||||
ck = inc[ar, order[:, kk], r:r + commit_n]
|
||||
pts = qe[:, None] + torch.cumsum(ck, 1)
|
||||
mids = torch.cat([qe[:, None], pts[:, :-1]], 1) + 0.5 * ck
|
||||
allq = torch.cat([pts, mids], 1).reshape(-1, 6)
|
||||
okk = (kin.gaps(allq, 0.5)['gm'].min(-1).values > 0).view(B, 2 * commit_n).all(-1)
|
||||
take = okk & ~ok_any
|
||||
chosen = torch.where(take[:, None, None], ck, chosen); chosen_k = torch.where(take, order[:, kk], chosen_k); ok_any |= okk
|
||||
commit = torch.where(ok_any[:, None, None], chosen, torch.zeros_like(chosen))
|
||||
if fb_gain > 0 and fb_fallback > 0: # 全拒时的兜底:半速朝目标走一步(须通过安全认证),避免原地停滞
|
||||
fb1 = dls_steps(kin, qe, T, R, n=1) * fb_fallback
|
||||
ok1 = kin.gaps(qe + fb1[:, 0], 0.5)['gm'].min(-1).values > 0
|
||||
commit = torch.where((~ok_any & ok1)[:, None, None], fb1.expand(-1, 3, -1), commit)
|
||||
commit = torch.where((~ok_any & ok1)[:, None, None], fb1.expand(-1, commit_n, -1), commit)
|
||||
brakes += (~ok_any).float()
|
||||
pick = chosen_k; committed = ok_any
|
||||
if near.any():
|
||||
ref = dls_steps(kin, qe, T, R)
|
||||
ref = dls_steps(kin, qe, T, R, n=commit_n)
|
||||
commit = torch.where(near[:, None, None], ref, commit)
|
||||
dls_it = torch.where(near & (dls_it < 0), torch.full_like(dls_it, it), dls_it)
|
||||
committed = committed & ~near
|
||||
|
||||
Reference in New Issue
Block a user