Files
Robot_Arm/ml/smoke.sh
T

49 lines
3.7 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# 全流程冒烟(2026-10-18 第七轮,遗留 C-1:第 6–13 步从没跑过,第一次真跑要 15–28 h,中途才崩代价太大)。
# 在仓库旁边建一份副本(默认 ../<仓库名>_smoke,可设 SMOKE_DIR),用极小参数把 kin → accept 整条 `all` 跑一遍:
# 2000 条老师任务(够出真实的 keepRate / gapDrop / 间隙分位 / R2,作数据侧可行性依据)、极小模型、M5/APG/挖错各缩到几十题、bench 每集几题、查看器 3 题。
# 训练侧只验证"每个阶段都能跑完、产物格式对、阶段之间衔接对",模型数值没有意义(门槛按冒烟放行:M5_STRICT=0 R4_STRICT=0 R2_STRICT=0);
# 数据侧(stats / r2)数值有意义,汇总进 smoke.json。
# 不碰本仓库的 ml/data、ml/runs、webapp/models。结果:本仓库 ml/runs/smoke.json(每阶段返回码与耗时)+ 副本里的完整日志。
# 用法:bash ml/smoke.sh 预计 40–70 分钟(28 核 + 3090;生成 2000 条约 4 分钟,若门 1 触发共识约 20 分钟;其余阶段多数几分钟)
set -e -o pipefail
cd "$(dirname "$0")/.."
SRC=$(pwd); PY=${PYTHON:-python}
D=${SMOKE_DIR:-$(dirname "$SRC")/$(basename "$SRC")_smoke}
echo "[smoke] 副本目录:$D"
rm -rf "$D"; mkdir -p "$D"
# 只拷受版本管理的文件(含未提交改动)+ 运行需要的本地依赖;数据与产物不拷
git ls-files -z | tar --null -T - -cf - | (cd "$D" && tar xf -)
for x in ml/node_modules webapp/vendor/ort webapp/generated; do [ -d "$x" ] && { mkdir -p "$D/$(dirname $x)"; cp -r "$x" "$D/$x"; }; done
cd "$D"
export N_TASKS=2000 NPROC=${SMOKE_NPROC:-$(( $(nproc) > 24 ? 24 : $(nproc) ))} TARGET_SAMPLES=1 CFG=ml/configs/smoke.json BENCH_STEPS=50 \
M5_N=32 M5_STRICT=0 AUTO_WTA=0 R4_STRICT=0 R2_STRICT=0 R2_ARGS="--queries 2000 --pool 15000" \
R4_ARGS="--viewer-n 3" APG_FIRST_STEPS=20 ROUNDS=1 APG_STEPS=20 MINE_N=128 MINE_GATE_N=64 \
BENCH_ARGS="--nc-n 3 --route-n 3 --r8-n 2" VIEWER_N=3 MONITOR=0 FRESH=1 PIPE_OWNER=冒烟
t0=$(date +%s); rc=0
bash ml/pipeline.sh all 2>&1 | tee ml/runs_smoke.log || rc=$?
mkdir -p "$SRC/ml/runs"
$PY - "$D" "$rc" "$(( $(date +%s) - t0 ))" "$SRC/ml/runs/smoke.json" <<'PY'
import json, os, sys
d, rc, sec, out = sys.argv[1], int(sys.argv[2]), int(sys.argv[3]), sys.argv[4]
p = os.path.join(d, 'ml', 'runs', 'pipeline.json')
st = json.load(open(p, encoding='utf-8')) if os.path.exists(p) else {}
stages = {k: {'rc': v.get('rc'), 'min': round((v['end'] - v['start']) / 60, 1) if v.get('end') and v.get('start') else None} for k, v in (st.get('stages') or {}).items()}
acc = os.path.join(d, 'ml', 'runs', 'acceptance.json')
def rd(*p):
try: return json.load(open(os.path.join(d, *p), encoding='utf-8'))
except Exception: return None
stx = rd('ml', 'data', 'stats.json') or {}
data = {k: stx.get(k) for k in ('tasks', 'keepRate', 'gapDrop', 'vertexMinGapMm', 'planMs', 'samplesPerTask', 'consensusDrop')}
data['r2'] = rd('ml', 'data', 'r2.json'); data['gate1'] = rd('ml', 'runs', 'consistency.json')
data['r4'] = rd('ml', 'runs', 'r4.json'); data['r9'] = rd('ml', 'runs', 'r9_browser.json')
pb = rd('ml', 'runs', 'policy_bench.json') or {}
data['r8_genS'] = (pb.get('r8_adversarial') or {}).get('genS')
res = {'rc': rc, 'wall_s': sec, 'dir': d, 'stages': stages, 'acceptance_written': os.path.exists(acc),
'data': data, 'log': os.path.join(d, 'ml', 'runs_smoke.log'),
'note': '训练侧只看每阶段 rc=0 与 acceptance_written;data 段(2000 条任务的统计、R2、门 1、R4、R9 路径、R8 出题耗时)是可行性依据'}
json.dump(res, open(out, 'w', encoding='utf-8'), indent=1, ensure_ascii=False)
print('[smoke] rc=%d,%d 分钟;结果 %s' % (rc, sec // 60, out))
PY
exit $rc