From 1f2f2a2bb11669cfbc78b08dc2c37c58fe0ec009 Mon Sep 17 00:00:00 2001 From: cbb <2625274797@qq.com> Date: Mon, 19 Oct 2026 02:33:46 +0800 Subject: [PATCH] =?UTF-8?q?monitor:=20=E5=BC=80=E7=8E=AF=E6=8C=87=E6=A0=87?= =?UTF-8?q?=E4=B8=A4=E5=BC=A0=E5=9B=BE=EF=BC=9Bpstate:=20train=20=E5=BD=92?= =?UTF-8?q?=E6=A1=A3=E5=8A=A0=20review=5F*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ml/monitor.html | 12 +++++++++++- ml/pstate.py | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ml/monitor.html b/ml/monitor.html index 3d7153a..fb51c7e 100644 --- a/ml/monitor.html +++ b/ml/monitor.html @@ -450,6 +450,10 @@ function buildCharts(kind) { b: new Chart(c, '损失分量', { logy: () => logyOn, xmax: total, xmin0: true, hidden: ['smooth'] }), e: new Chart(c, '闭环评估(val,部署节奏,关安全层)', { percent: true, range: [0, 1], xmax: total, xmin0: true, note: kind === 'bench' ? '测速运行不评估' : '每 2000 步', emptyText: kind === 'bench' ? '测速运行不做闭环评估' : '第一次评估在第 2000 步' }), + o: new Chart(c, '开环误差(mm)', { xmax: total, xmin0: true, note: kind === 'bench' ? '测速运行不评估' : 'val 样本、老师状态 · 16 步末端误差 · 越低越好', + emptyText: kind === 'bench' ? '测速运行不做闭环评估' : '第一次评估在第 2000 步' }), + d: new Chart(c, '候选多样性', { xmax: total, xmin0: true, note: kind === 'bench' ? '测速运行不评估' : '候选间标准差 / 动作幅度 · 塌成单峰时接近 0', + emptyText: kind === 'bench' ? '测速运行不做闭环评估' : '第一次评估在第 2000 步' }), t: new Chart(c, '吞吐(样本/s)', { xmax: total, xmin0: true, zero: true, refs: [{ y: 5000, label: 'R10 通过线 5000', color: css('--bad') }] }), }; } @@ -471,6 +475,11 @@ function render() { } const E = (k, label, best) => { const pts = evals.filter(e => isNum(e[k])).map(e => [e.x, e[k]]); let b = null; if (best && pts.length) b = pts.reduce((m, p) => p[1] > m[1] ? p : m); return { name: k, label, dots: true, pts, best: b }; }; charts.e.set([E('success', '到达率', true), E('collision_rate', '碰撞率'), E('time_ok_1p3', '≤ 老师时长×1.3'), E('start_fail', '起步失败')]); + if (charts.o) { // 开环指标只随 train.py 的评估写进日志;APG 分支没建这两张图 + const Emin = (k, label) => { const pts = evals.filter(e => isNum(e[k])).map(e => [e.x, e[k]]); let b = null; if (pts.length) b = pts.reduce((m, p) => p[1] < m[1] ? p : m); return { name: k, label, dots: true, pts, best: b }; }; + charts.o.set([Emin('ol_fk_mm', '候选 0'), { name: 'ol_best_mm', label: '8 候选最好', dots: true, pts: evals.filter(e => isNum(e.ol_best_mm)).map(e => [e.x, e.ol_best_mm]) }]); + charts.d.set([{ name: 'ol_div', label: '多样性', dots: true, pts: evals.filter(e => isNum(e.ol_div)).map(e => [e.x, e.ol_div]) }]); + } renderProgress(); renderKpis(); } @@ -847,7 +856,8 @@ function demoApi() { function trainEval(x, t0, sps) { const q = 1 - Math.exp(-x / 14000); return { eval: { step: x, t: t0 + x * 1024 / sps, n: 512, n_ref: 512, success: Math.min(0.975, 0.08 + 0.87 * q + 0.012 * gauss()), collision_rate: Math.max(0.004, 0.31 * (1 - q) + 0.012 + 0.005 * gauss()), - time_ok_1p3: Math.min(0.95, 0.05 + 0.8 * q + 0.012 * gauss()), start_fail: Math.max(0, 0.05 * (1 - q) + 0.003 * gauss()) } }; + time_ok_1p3: Math.min(0.95, 0.05 + 0.8 * q + 0.012 * gauss()), start_fail: Math.max(0, 0.05 * (1 - q) + 0.003 * gauss()), + ol_fk_mm: 5.5 * Math.exp(-x / 12000) + 2.0 + 0.25 * gauss(), ol_best_mm: 3.8 * Math.exp(-x / 12000) + 1.7 + 0.16 * gauss(), ol_div: Math.min(0.9, 0.16 + 0.45 * (1 - Math.exp(-x / 9000)) + 0.02 * gauss()) } }; } function trainLog(total, from, to, sps, t0, evalEvery = 2000, wta = false) { const L = []; diff --git a/ml/pstate.py b/ml/pstate.py index 7b1eb3a..173c0dc 100644 --- a/ml/pstate.py +++ b/ml/pstate.py @@ -47,7 +47,8 @@ PARAM_KEYS = list(AFFECTS) PRODUCTS = { 'r4': ['ml/runs/r4', 'ml/runs/r4.json'], 'gate1': ['ml/data/consistency.json'], 'gen': ['ml/data/shard_*', 'ml/data/log_*', 'ml/data/stats.json'], 'prep': ['ml/data/samples', 'ml/data/r2.json'], - 'train': ['ml/runs/base', 'ml/runs/wta', 'ml/runs/small', 'ml/runs/bench_*', 'ml/runs/replay_teacher.json'], + 'train': ['ml/runs/base', 'ml/runs/wta', 'ml/runs/small', 'ml/runs/bench_*', 'ml/runs/replay_teacher.json', + 'ml/runs/review_*'], # 评审快照包(_review_pack.py 从 base 打的,内含 log.jsonl 会被监控页当成一条"预训练"运行);重做 train 时一并归档 'dagger': ['ml/runs/*_dag[0-9]*', 'ml/runs/*_dagger.ckpt', 'ml/data/dag_*', 'ml/data/samples_dag_*'], 'm5': ['ml/runs/m5_*', 'ml/runs/selected_ckpt'], 'apg': ['ml/runs/apg', 'ml/runs/current.pt'], 'mine': ['ml/runs/mine', 'ml/runs/apg_r*', 'ml/data/e2', 'ml/data/samples_e2'],