ml: 按运行手册审查修订——头分目录不互相覆盖(ml/runs/<CFG>、selected_ckpt/CKPT);统一 $PYTHON(Windows Git Bash 可跑);gen 按实测样本/任务自动补量;R10 改终态判据(≥5k 样本/s≈60k 步≤3.5h);m5 纯策略/仿真安全层双口径;无老师题定长 6 s 口径;APG 展开随批时长、端点+中点铰链、余量 3 mm(投影同步);挖错池只用本轮;门禁加 R7;bench 加 R8 对抗集与刹停率、--nc-n/--route-n/--r8-n;新增 check_r2 与 acceptance;export 默认 fp32;出题分块防 OOM;val 为空保护
This commit is contained in:
+15
-8
@@ -2,7 +2,10 @@
|
||||
python -m ml.apg.apg_finetune --init ml/runs/base/best.pt --samples ml/data/samples --out ml/runs/apg [--pool ml/runs/mine/pool.jsonl]
|
||||
每条展开固定一个噪声 z(确定性可微映射);每次推理提交 3 步(已提交前缀 3 步,与部署一致);
|
||||
截断反传:每 seg_plans 次推理(=3·seg_plans 步)反传一次并截断状态梯度。
|
||||
损失:段末到达项 + Σ碰撞铰链 ReLU(margin_train − 间隙)(逐胶囊对)+ 平滑(速度²+加速度²)+ 行程 + BC 锚定(MeanFlow 损失)。"""
|
||||
损失:段末到达项 + Σ碰撞铰链 ReLU(margin_train − 间隙)(逐胶囊对,端点+中点)+ 平滑(速度²+加速度²)+ 行程 + BC 锚定(MeanFlow 损失)。
|
||||
2026-10-18:展开长度不再定长 60 次推理(3.6 s,会截掉老师时长 > 3.6 s 的绕远题),改为覆盖本批 exec_s p90×1.2,上限 plans_max;
|
||||
"到达"仍是每 seg_plans 段末的距离项(无到达即停),属有意设计:段末项给出持续的接近梯度。
|
||||
margin_train 5 → 3 mm:老师轨迹自身最小间隙 p50 4.4 / p90 5.9 mm,5 mm 会让约一半 BC 标签与碰撞项对抗;3 mm ≈ 老师 p10。"""
|
||||
import argparse, json, math, os, random, time
|
||||
import torch
|
||||
|
||||
@@ -45,7 +48,7 @@ def main():
|
||||
opt = torch.optim.AdamW(model.parameters(), lr=C['lr'], betas=(0.9, 0.95), weight_decay=0.0)
|
||||
amp = dev.startswith('cuda') and C.get('amp') == 'bf16'
|
||||
step = torch.tensor(STEP, device=dev)
|
||||
log = open(os.path.join(a.out, 'log.jsonl'), 'a')
|
||||
log = open(os.path.join(a.out, 'log.jsonl'), 'w')
|
||||
base, _ = evaluate(model.eval(), kin, val_tasks, dev)
|
||||
print('EVAL0', json.dumps(base), flush=True); log.write(json.dumps({'eval': base, 'step': 0}) + '\n')
|
||||
best = base['success']
|
||||
@@ -62,9 +65,12 @@ def main():
|
||||
subs = torch.zeros(B, 2, 6, device=dev); nsub = torch.zeros(B, dtype=torch.long, device=dev); sub_t = torch.zeros(B, device=dev)
|
||||
opt.zero_grad(set_to_none=True)
|
||||
stats = {'col': 0.0, 'tgt': 0.0, 'smooth': 0.0}
|
||||
nseg = math.ceil(C['plans'] / C['seg_plans'])
|
||||
# 展开长度随本批任务时长:覆盖本批 exec_s 的 p90 × 1.2(无老师参考题按 6 s),夹在 [plans, plans_max]
|
||||
exb = torch.nan_to_num(ex, nan=6.0)
|
||||
n_plans = int(min(C['plans_max'], max(C['plans'], math.ceil(1.2 * torch.quantile(exb, 0.9).item() / (3 * 0.02)))))
|
||||
nseg = math.ceil(n_plans / C['seg_plans'])
|
||||
seg_loss = torch.zeros((), device=dev); prev_d = torch.zeros(B, 6, device=dev)
|
||||
for p in range(C['plans']):
|
||||
for p in range(n_plans):
|
||||
tnow = p * 3 * 0.02
|
||||
r = queue.shape[1]
|
||||
pre = torch.zeros(B, 3, 6, device=dev); pre[:, :r] = queue[:, :r]
|
||||
@@ -92,15 +98,16 @@ def main():
|
||||
for k in range(3):
|
||||
d = queue[:, k]
|
||||
qp = q; q = kin.clamp_box(q + d)
|
||||
G = kin.gaps(q, M)
|
||||
# 碰撞铰链:端点 + 中点(与仿真/运行时的离散检查一致)
|
||||
G = kin.gaps(torch.cat([q, 0.5 * (q + qp)], 0), M)
|
||||
hinge = torch.relu(M - G['gap'])
|
||||
col = torch.zeros(B, device=dev).index_add(0, G['b'], hinge)
|
||||
col = torch.zeros(2 * B, device=dev).index_add(0, G['b'], hinge).view(2, B).sum(0)
|
||||
sm = ((d / step) ** 2).sum(-1) + (((d - prev_d) / step) ** 2).sum(-1)
|
||||
prev_d = d
|
||||
seg_loss = seg_loss + C['w_col'] * col.mean() + C['w_smooth'] * sm.mean() + C['w_len'] * d.abs().sum(-1).mean()
|
||||
stats['col'] += col.mean().item(); stats['smooth'] += sm.mean().item()
|
||||
queue = commit
|
||||
if (p + 1) % C['seg_plans'] == 0 or p == C['plans'] - 1:
|
||||
if (p + 1) % C['seg_plans'] == 0 or p == n_plans - 1:
|
||||
xf = kin.cum_xf(q)
|
||||
pe = kin.fk(q, xf); Rq = kin.orient(q, xf).reshape(B, 9)
|
||||
pose = (R.abs().sum(-1) > 0).float()
|
||||
@@ -122,7 +129,7 @@ def main():
|
||||
opt.step()
|
||||
with torch.no_grad():
|
||||
e, oe = goal_err(kin, q, T, R)
|
||||
rec = {'it': it, 'err_mm_mean': e.mean().item(), 'reach_frac': ((e < 1) & (oe < 0.5)).float().mean().item(), 'bc': l_bc.item(),
|
||||
rec = {'it': it, 'plans': n_plans, 'err_mm_mean': e.mean().item(), 'reach_frac': ((e < 1) & (oe < 0.5)).float().mean().item(), 'bc': l_bc.item(),
|
||||
'gnorm': gn.item(), **stats, 'min': (time.time() - t0) / 60}
|
||||
if it % 10 == 0: print(json.dumps(rec), flush=True)
|
||||
log.write(json.dumps(rec) + '\n'); log.flush()
|
||||
|
||||
Reference in New Issue
Block a user