diff --git a/docs/探索日志.md b/docs/探索日志.md index c47bd5c..8d2fae1 100644 --- a/docs/探索日志.md +++ b/docs/探索日志.md @@ -300,6 +300,18 @@ - 相对 §9.2:到达 42.2% vs ≥98%(差距大);碰撞 2.9% vs 0(接近策略单独 <3% 线);用时 ≤老师×1.3 为 29.1%;推理+认证 P99 未测(桌面均值 12.58 ms,预算 20 ms)。 - 未进入大规模训练(需用户确认 §9.2 锚点)。 +## 轮次 19:APG 闭环策略梯度试跑(exp: `exp/dagger-deploy`,管线修复但暂不采用) + +- **假设**:用闭环目标/碰撞损失直接微调策略(把"朝目标走"内化),减少对执行层反馈的依赖。 +- **判据**:纯策略闭环 success 上升、碰撞铰链下降;部署口径(+反馈/安全层)不降。 +- **配方**:`ml.apg.apg_finetune --init base_dag2_dag1/best.pt --steps 2`(先冒烟;原计划 500 步)。 +- **修复的两个既有 bug**(APG 此前从未实测): + 1. `kin_torch._cat_gaps` 的 `p['b'] += s` 是 in-place,而 `b` 被 autograd 索引反向图引用 → backward 报 version 错;改为 `p['b'] = p['b'] + s`。 + 2. APG 段边界 `queue.detach()` 让下一段执行的动作无梯度;改为只 detach 状态并重置队列(下一 plan 走 r=0 重新提交)。 +- **指标(2 步冒烟)**:EVAL0(纯策略)success 0 / 碰撞 31.8%;第 0 步 col(碰撞铰链均值)**409508**、gnorm 473119(被裁剪)、tgt 206.6、smooth 645;EVAL@2 success 0 / 碰撞 26.0%。 +- **结论**:管线已能跑,但**损失尺度失控**(碰撞铰链均值 40 万,远大于 margin 3mm 的合理量级);且 APG 展开是纯策略口径(无反馈/安全层/每步规划),与当前部署形态不一致。**暂不采用**,转「反馈蒸馏」。 +- **下一步**:反馈蒸馏——用最终部署配置收集 (特征, 复合动作=模型输出+目标反馈) 样本,微调模型把反馈内化。 + ## 分支清理(2026-10-20) - `feat/fb-mix`(8e5431c):反馈混合方案的中间分支,**已验证是 `exp/dagger-deploy` 的祖先**(所有提交都在后者历史里),本地/远端分支删除,内容保留在 exp/dagger-deploy。 diff --git a/ml/apg/apg_finetune.py b/ml/apg/apg_finetune.py index fcacee7..5af5560 100644 --- a/ml/apg/apg_finetune.py +++ b/ml/apg/apg_finetune.py @@ -139,7 +139,10 @@ def main(): stats['tgt'] += lt.mean().item() (seg_loss / nseg).backward() seg_loss = torch.zeros((), device=dev) - q, qp, queue, prev_d = q.detach(), qp.detach(), queue.detach(), prev_d.detach() + # 只 detach 状态并重置队列:段边界下一 plan 走 r=0 重新提交(新图有梯度); + # 沿用旧 queue 会跨过已 backward 的图(二次 backward 报错),也避免整段无梯度 + q, qp, prev_d = q.detach(), qp.detach(), prev_d.detach() + queue = torch.zeros(B, 0, 6, device=dev) # BC 锚定 X, Y, V, SG = data.batch(C['batch'] * 4) with torch.autocast('cuda', dtype=torch.bfloat16, enabled=amp): diff --git a/ml/common/kin_torch.py b/ml/common/kin_torch.py index 9096a06..ce911a7 100644 --- a/ml/common/kin_torch.py +++ b/ml/common/kin_torch.py @@ -131,7 +131,8 @@ class Kin: def _cat_gaps(parts, starts): out = {'gm': torch.cat([p.pop('gm') for p in parts], 0)} if 'b' in parts[0]: - for p, s in zip(parts, starts): p['b'] += s + # 非 in-place:b 会被 autograd 的索引反向图引用(APG 的碰撞铰链梯度路径),+= 会让 backward 报 version 错 + for p, s in zip(parts, starts): p['b'] = p['b'] + s for k in ('b', 'i', 'j', 'gap'): out[k] = torch.cat([p.pop(k) for p in parts]) # 逐键拼、拼完即释放 return out