| """Dedup-by-tid aggregate. Handles both live eval*.log and finished eval*.log.gz.""" |
| import re |
| import gzip |
| import glob |
| import os |
|
|
| EVALS = "/imotion-vepfs/imotion_zxnet/workspace_wei/ry-dynamics-vln-ryworld/checkpoints/ryworld_stage1_discrete_20260510_025317_cw07_iw25/evals" |
| pat = re.compile( |
| r'"shortest_path_length":\s*([\d.]+).*?"NE":\s*([\d.]+).*?"success":\s*([\d.]+).*?' |
| r'"osr":\s*([\d.]+).*?"TL":\s*([\d.]+).*?"spl":\s*([\d.]+).*?"ndtw":\s*([\d.]+).*?' |
| r'"trajectory_id":\s*"([^"]+)"', |
| re.S, |
| ) |
|
|
| all_eps = {} |
| log_paths = glob.glob(f"{EVALS}/*full835*/eval*.log") + glob.glob(f"{EVALS}/*full835*/eval*.log.gz") |
| for p in sorted(log_paths): |
| if p.endswith(".gz"): |
| content = gzip.open(p, "rt").read() |
| else: |
| content = open(p).read() |
| for m in pat.finditer(content): |
| spg, ne, succ, osr, tl, spl, ndtw, tid = m.groups() |
| all_eps[tid] = { |
| "spg": float(spg), "NE": float(ne), |
| "success": int(float(succ) == 1.0), |
| "osr": int(float(osr) == 1.0), |
| "SPL": float(spl), "nDTW": float(ndtw), |
| } |
|
|
| n = len(all_eps) |
| if n == 0: |
| print("no eps found") |
| raise SystemExit |
| eps = list(all_eps.values()) |
| def avg(field): |
| return sum(e[field] for e in eps) / n |
|
|
| print(f"=== TOTAL {n}/835 ({100*n/835:.1f}%) ===") |
| print(f" SR={100*avg('success'):.1f}% OSR={100*avg('osr'):.1f}% NE={avg('NE'):.2f} SPL={100*avg('SPL'):.1f}% nDTW={avg('nDTW'):.3f}") |
| for lo, hi in [(0, 5), (5, 8), (8, 12), (12, 18)]: |
| bk = [e for e in eps if lo <= e["spg"] < hi] |
| if bk: |
| b_sr = sum(e["success"] for e in bk) / len(bk) |
| print(f" short [{lo:>2},{hi:>2})m: n={len(bk):>3} SR={100*b_sr:>4.1f}%") |
|
|