From 7a8e5aab639b6093b328b054cb152011ab83b300 Mon Sep 17 00:00:00 2001 From: cbb <2625274797@qq.com> Date: Tue, 20 Oct 2026 09:41:44 +0800 Subject: [PATCH] =?UTF-8?q?exp(dagger-deploy):=20=E8=BD=AE=E6=AC=A121?= =?UTF-8?q?=E2=80=94=E2=80=94DAgger-3=EF=BC=88=E9=83=A8=E7=BD=B2=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=87=87=E9=9B=86500=E9=A2=98+15000=E6=AD=A5=E5=BE=AE?= =?UTF-8?q?=E8=B0=83=EF=BC=89=E8=B4=9F=E7=BB=93=E8=AE=BA=EF=BC=9A=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E5=8F=A3=E5=BE=84=2039.5%=20vs=20dag2=2043.8%?= =?UTF-8?q?=EF=BC=8C=E5=BC=80=E7=8E=AF=E9=80=80=E5=8C=96=E5=88=B019.5mm?= =?UTF-8?q?=EF=BC=9B=E4=B8=8B=E4=B8=80=E6=AD=A5=E8=AF=95=E5=86=BB=E7=BB=93?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E5=99=A8=E5=8F=AA=E8=B0=83=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/探索日志.md | 17 +++++++++++++++++ ml/configs/base_dag3.json | 11 +++++++++++ ml/dagger/collect.py | 5 ++++- ml/dagger/run.sh | 2 +- 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 ml/configs/base_dag3.json diff --git a/docs/探索日志.md b/docs/探索日志.md index b81e9ac..6a61028 100644 --- a/docs/探索日志.md +++ b/docs/探索日志.md @@ -330,6 +330,23 @@ - **结论**:**反馈未内化**——`gain=0` 时到达仅 0.8%(与基线纯策略一样);`gain=1.8` 时与基线持平(43.4 vs 43.8,差约 1 题),碰撞/刹停略差。蒸馏样本占比仅 8.5%、标签仍以主数据增量为主,模型没有学会"看目标修正"。此配方不成立。 - **下一步**:与最终部署配置一致的 DAgger 第 3 轮(采集时已用 safety+fb 1.2,但仍是 3 步提交/全窗口;现在部署是每步规划+部分前缀)。 +## 轮次 21:DAgger-3(最终部署配置采集)(exp: `exp/dagger-deploy`,负结论) + +- **假设**:用最终部署配置(每步规划 + 部分安全前缀 + 反馈 gain1.8 + 安全层)采集,训练分布与部署完全一致,可继续提升。 +- **判据**:部署口径 success > 43.8%(dag2 基线,n=256)。 +- **配方**:`collect --fb_gain 1.8 --safety 1 --replan empty --commit_n 1 --safety_partial 1`(500 题、73 起点)→ 老师重规划 → 打包 → 从 dag2 best 微调 15000 步(lr 3e-4,配置 base_dag3)。 +- **对照**:dag2 + gain1.8(n=256:43.8% / 28.9% / 1.6% / 0.216 / 40.0 / 956 ms)。 +- **指标(n=256,部署口径)**: + +| 模型 | gain | 到达 | time_ok_1p3 | 碰撞 | ratio2s | 刹停/题 | 墙钟/题 | +|---|---|---|---|---|---|---|---| +| dag3 | 1.5 | 39.8% | 16.0% | 1.2% | 0.360 | 14.7 | 912 ms | +| dag3 | 1.8 | 39.5% | 21.1% | 1.2% | 0.320 | 24.5 | 935 ms | +| dag2(基线) | 1.8 | **43.8%** | **28.9%** | 1.6% | **0.216** | 40.0 | 956 ms | + +- **结论**:DAgger-3 到达 **-4.3 pp**(39.5 vs 43.8),time_ok -7.8 pp;碰撞/刹停略好但主指标下降。开环进一步退化(ol_fk 19.5 mm vs dag2 15.7)。**负结论**:继续微调(15000 步 lr 3e-4)会退化主分布,训练侧收益递减。 +- **下一步**:冻结编码器、只微调解码器(假设:微调退化来自表征漂移),用同一份数据与预算验证。 + ## 分支清理(2026-10-20) - `feat/fb-mix`(8e5431c):反馈混合方案的中间分支,**已验证是 `exp/dagger-deploy` 的祖先**(所有提交都在后者历史里),本地/远端分支删除,内容保留在 exp/dagger-deploy。 diff --git a/ml/configs/base_dag3.json b/ml/configs/base_dag3.json new file mode 100644 index 0000000..3d48d3b --- /dev/null +++ b/ml/configs/base_dag3.json @@ -0,0 +1,11 @@ +{ + "model": {"d": 192, "heads": 8, "ff": 768, "enc": 4, "dec": 4}, + "train": { + "batch": 1024, "lr": 1e-3, "warmup": 1000, "steps": 24000, "wd": 0.01, "betas": [0.9, 0.95], + "amp": "bf16", "grad_clip": 1.0, + "w_mf": 1.0, "w_fk": 0.5, "w_smooth": 0.05, "w_value": 0.1, "w_sub": 0.1, + "p_neq": 0.5, "p_edge": 0.1, "p_neq_warm": 5000, "fk_tmax": 0.3, "fk_caps": 96, + "ema": 0.999, "aug_pre_drop": 0.15, "aug_pre_sigma": 0.1, "aug_dq_sigma": 0.3, + "ckpt_min": 10, "eval_every": 2000, "eval_tasks": 512, "log_every": 50, "patience_evals": 5 + } +} diff --git a/ml/dagger/collect.py b/ml/dagger/collect.py index a083a08..f5ed802 100644 --- a/ml/dagger/collect.py +++ b/ml/dagger/collect.py @@ -30,6 +30,8 @@ def main(): ap.add_argument('--device', default='cuda' if torch.cuda.is_available() else 'cpu') ap.add_argument('--fb_gain', type=float, default=0.0, help='部署分布采集:目标反馈增益(与 rollout 一致)') ap.add_argument('--safety', type=int, default=0, help='部署分布采集:是否开安全层') + ap.add_argument('--replan', default='r3'); ap.add_argument('--commit_n', type=int, default=3) + ap.add_argument('--safety_partial', type=int, default=0) a = ap.parse_args() gap_min = float(os.environ.get('MIN_GAP_MM') or 3) os.makedirs(a.out, exist_ok=True) @@ -43,7 +45,8 @@ def main(): for i in range(0, len(tasks), a.bs): tb = tasks[i:i + a.bs] with torch.no_grad(): - _, per = rollout(model, kin, tb, a.device, K=8, safety=bool(a.safety), seed=a.seed * 100003 + i, return_traj=True, fb_gain=a.fb_gain) + _, per = rollout(model, kin, tb, a.device, K=8, safety=bool(a.safety), seed=a.seed * 100003 + i, return_traj=True, + fb_gain=a.fb_gain, replan=a.replan, commit_n=a.commit_n, safety_partial=a.safety_partial) tr = per['traj'].to(a.device) # [B,T,6] B, Tn, _ = tr.shape _, T, R, _, _ = tasks_to_tensors(tb, a.device) diff --git a/ml/dagger/run.sh b/ml/dagger/run.sh index ed038d7..250e848 100644 --- a/ml/dagger/run.sh +++ b/ml/dagger/run.sh @@ -24,7 +24,7 @@ for ((r=1; r<=R; r++)); do SAMPLES="$SAMPLES $SD" if [ -f $OUT/done ]; then echo "[dagger] 第 $r 轮已完成,跳过"; CK=$($PY -m ml.common.ckpt pick $OUT); continue; fi if [ -f $D/collect.json ]; then echo "[dagger] 第 $r 轮起点已采集,跳过" - else echo "[dagger] 第 $r 轮:用 $CK 闭环采起点($N 题)"; $PY -m ml.dagger.collect --ckpt $CK --samples ml/data/samples --n $N --seed $r --parts $P --out $D --fb_gain ${FB_GAIN:-0} --safety ${DAG_SAFETY:-0}; fi + else echo "[dagger] 第 $r 轮:用 $CK 闭环采起点($N 题)"; $PY -m ml.dagger.collect --ckpt $CK --samples ml/data/samples --n $N --seed $r --parts $P --out $D --fb_gain ${FB_GAIN:-0} --safety ${DAG_SAFETY:-0} --replan ${DAG_REPLAN:-r3} --commit_n ${DAG_COMMIT_N:-3} --safety_partial ${DAG_PARTIAL:-0}; fi cat $D/collect.json pids=() for f in $D/tasks_*.jsonl; do