ml: 显存预算按 19–20 GB 落地(APG batch 128→48 + 每进程硬帽 + vram 上日志/网页);自检四处判据与环境坑修好,整轮 7/8 通过 3.5 分钟
- ml/configs/apg.json:batch 128→48。本机实测(d=192 同结构、每进程 19.2 GB 硬帽、1 步即到位)batch=128 无论 plans 取 60 还是 150 都 OOM(崩前已分配 17.85 GiB;d=32 小模型也 17.54 GiB,说明是展开图吃显存而非模型大小);48/plans=150 为 13.08、48/60 为 7.67。展开长度 plans 没动,降 plans 会把长任务绕出段截掉。
- ml/common/vram.py(新):limit() 设每进程帽 VRAM_FRAC 默认 0.78≈18.7 GiB 并打印上限;peak_gib() 供日志。train.py 与 apg_finetune.py 调用,每条记录新增 vram 字段(实测 train batch=1024 → 2.71,APG 自检档 → 0.33)。没帽时 APG 会把整卡顶到 23.6 GB、连桌面一起挤掉。
- ml/monitor.py / monitor.html:状态带 vram_budget_gb(默认 20,VRAM_BUDGET_GB 可改),GPU 显存条按预算算并超线变色,指标卡加「显存峰值」(>14 黄 >17 红)。headless 加载渲染 DOM 复核过。
- ml/configs/smoke.json 补 apg 段(batch=8)+ selftest.sh 的 APG 两项带 --config:原先不带 → 自检第 6 项按正式 batch=128 跑,本机必 OOM。
- ml/selftest.sh:gen_resume 判据由 cmp -s 改为剔除 plan_ms/cert.ms 两个墙钟字段后逐条比(旧判据恒 false);rec() 值非合法 JSON 时记 false 不再静默丢项。
- ml/selftest_proc.py:alive() 读 tasklist 改 text=True+errors='replace' 并防 None(中文 Windows 表头 GBK 会让读线程抛 UnicodeDecodeError→stdout=None→TypeError);wait_pids 带上最后一次异常。
- ml/monitor.py find_bash():便携版 git 的 mingw64 布局要再上一层找 bash,并兜 which('bash')(排除 System32 的 WSL)。本机原先返回 None → 网页「开始训练」起不动、自检进程两项没跑。
- 整轮自检重跑:gen_resume/prep_rerun/train_stop/train_stopfile/apg_resume/tree_killed/survive_parent_exit 全 true,仅 train_term false(timeout 的 TERM 送不到原生 python,rc=124 硬杀);用时 3.5 分钟。
- 文档:新增第七节(显存实测表、自检 8 项结果、四条判据/环境坑、本机改动清单);A-3 改为「实现方已改、待复跑验证」,C-5/C-6 标为已实测,D 组复核后关闭。
This commit is contained in:
+6
-3
@@ -436,6 +436,7 @@ function renderKpis() {
|
||||
tile('展开内到达比例', pct(r.reach_frac), '误差 < 1 mm 且姿态 < 0.5°', '', last('reach_frac'), COLORS[2]);
|
||||
tile('闭环到达率', pct(e.success) + dlt('success'), `最好 ${pct(best)}`, '', evs('success'), COLORS[2]);
|
||||
tile('碰撞率', pct(e.collision_rate, 2) + dlt('collision_rate', -1), '关安全层', e.collision_rate > 0.03 ? 'warn' : '', evs('collision_rate'), COLORS[3]);
|
||||
tile('显存峰值', isNum(r.vram) ? `${r.vram.toFixed(2)}<small>GiB</small>` : '—', '预算 19–20 GB(整卡 24,桌面占 4–5)', r.vram > 17 ? 'bad' : r.vram > 14 ? 'warn' : '', last('vram'), COLORS[1]);
|
||||
} else {
|
||||
const sps = r.samples_per_s;
|
||||
tile('总损失', fmt(r.loss, 4), `MF ${fmt(r.mf)} · FK ${fmt(r.fk_cm)} cm`, '', ema(last('loss'), 0.9), COLORS[0]);
|
||||
@@ -443,6 +444,7 @@ function renderKpis() {
|
||||
tile('闭环到达率', pct(e.success) + dlt('success'), evals.length ? `最好 ${pct(best)} · @${e.x.toLocaleString()} 步` : '尚未评估', '', evs('success'), COLORS[2]);
|
||||
tile('碰撞率', pct(e.collision_rate, 2) + dlt('collision_rate', -1), '关安全层,部署另有护栏', e.collision_rate > 0.03 ? 'warn' : '', evs('collision_rate'), COLORS[3]);
|
||||
tile('梯度范数', fmt(r.gnorm), '裁剪阈值 1.0', r.gnorm > 5 ? 'warn' : '', ema(last('gnorm'), 0.9), COLORS[4]);
|
||||
tile('显存峰值', isNum(r.vram) ? `${r.vram.toFixed(2)}<small>GiB</small>` : '—', '预算 19–20 GB(整卡 24,桌面占 4–5)', r.vram > 17 ? 'bad' : r.vram > 14 ? 'warn' : '', last('vram'), COLORS[1]);
|
||||
}
|
||||
$('kpis').innerHTML = tiles.map(t => t.html).join('');
|
||||
[...$('kpis').querySelectorAll('canvas')].forEach((cv, i) => spark(cv, tiles[i].sp, tiles[i].color));
|
||||
@@ -477,7 +479,7 @@ async function poll() {
|
||||
render();
|
||||
}
|
||||
const P = lastStatus.pipeline, busy = (job && job.running) || (P && P.current);
|
||||
if (DEMO) { setPill('demo', '示例数据'); if (!$('demobar')) $('pipe').insertAdjacentHTML('beforebegin', `<div class="demobar" id="demobar">这是示例数据,不是你的训练。${location.protocol === 'file:' ? '直接双击 monitor.html 只能看示例;' : ''}看真实训练请双击 ml/console.bat(或 python -m ml.monitor --open)。</div>`); }
|
||||
if (DEMO) { setPill('demo', '示例数据'); if (!$('demobar')) $('pipe').closest('.hero').insertAdjacentHTML('beforebegin', `<div class="demobar" id="demobar">这是示例数据,不是你的训练。${location.protocol === 'file:' ? '直接双击 monitor.html 只能看示例;' : ''}看真实训练请双击 ml/console.bat(或 python -m ml.monitor --open)。</div>`); }
|
||||
else if (busy) setPill('live', `运行中 · ${P && P.current ? SM[P.current]?.n || P.current : '启动中'}`);
|
||||
else if (cur && Date.now() / 1000 - lastMtime < 120) setPill('live', `运行中 · ${ago(lastMtime)}更新`);
|
||||
else setPill('', '空闲');
|
||||
@@ -531,15 +533,16 @@ function renderStatus(s) {
|
||||
|
||||
// GPU
|
||||
const G = s.gpu || [];
|
||||
const BUD = (s.vram_budget_gb || 24) * 1024; // 显存预算(MB):桌面常驻占 4–5 GB,不能按整卡 24 GB 看
|
||||
$('gputime').textContent = G.length ? '实时' : '';
|
||||
$('gpu').innerHTML = G.length ? G.map(g => {
|
||||
const u = g.util ?? 0, C = 2 * Math.PI * 50, col = u > 85 ? css('--ok') : u > 50 ? css('--accent') : css('--warn');
|
||||
const memP = 100 * g.mem_used / g.mem_total, tc = g.temp > 83 ? css('--bad') : g.temp > 75 ? css('--warn') : css('--c6');
|
||||
const memP = 100 * g.mem_used / BUD, tc = g.temp > 83 ? css('--bad') : g.temp > 75 ? css('--warn') : css('--c6');
|
||||
const row = (k, v, p, c) => `<div class="gr"><div class="l"><span>${k}</span><b>${v}</b></div><div class="mini"><div style="width:${Math.min(100, p)}%;background:${c}"></div></div></div>`;
|
||||
return `<div class="gpuwrap"><div class="ring"><svg width="116" height="116"><circle cx="58" cy="58" r="50" stroke="#1b2433" stroke-width="10" fill="none"/>
|
||||
<circle cx="58" cy="58" r="50" stroke="${col}" stroke-width="10" fill="none" stroke-linecap="round" stroke-dasharray="${C}" stroke-dashoffset="${C * (1 - u / 100)}" style="transition:stroke-dashoffset .6s"/></svg>
|
||||
<div class="c"><div><b>${u}%</b><span>利用率</span></div></div></div>
|
||||
<div class="gpurows">${row('显存', `${(g.mem_used / 1024).toFixed(1)} / ${(g.mem_total / 1024).toFixed(0)} GB`, memP, css('--accent2'))}
|
||||
<div class="gpurows">${row('显存', `${(g.mem_used / 1024).toFixed(1)} / ${(BUD / 1024).toFixed(0)} GB 预算(整卡 ${(g.mem_total / 1024).toFixed(0)})`, memP, memP > 100 ? css('--bad') : memP > 85 ? css('--warn') : css('--accent2'))}
|
||||
${row('温度', `${g.temp} °C`, g.temp, tc)}${row('功耗', g.power != null ? `${Math.round(g.power)} W` : '—', g.power ? g.power / 3.5 : 0, css('--c7'))}</div></div>
|
||||
<div class="gname">${g.name}</div>`;
|
||||
}).join('<hr style="border:none;border-top:1px solid var(--line);margin:14px 0">') : empty('未检测到 nvidia-smi');
|
||||
|
||||
Reference in New Issue
Block a user