Download tests/analyze_efficiency.py from logos42/headless: direct link, hf CLI and curl.
- Browser
- Download file 6.17 kB
-
https://huggingface.co/logos42/headless/resolve/main/tests/analyze_efficiency.py
- Command line
-
hf download hf://logos42/headless/tests/analyze_efficiency.py
-
curl -L -o analyze_efficiency.py https://huggingface.co/logos42/headless/resolve/main/tests/analyze_efficiency.py
6.17 kB
| #!/usr/bin/env python3 | |
| """ๅญฆไน ๆ็้ฆๆฌกๆต้็ๅๆ โโ ๅคๆฎๅจ `docs/learning_efficiency_spec.md` ยง4ใ | |
| ๆ ธๅฟๅฏน็ ง: **ๅไธไธช run ๅ ้จๅๆถ่ฎญ็ป `naive` ไธ `replay`** โ ๅคฉ็ถ้ ๅฏน | |
| (ๅ seedใๅๅใๅๆฐๆฎ้กบๅบใๅๆจกๅๅๅงๅ), ๅฏไธ็ๅทฎๅซๆฏ"่ฆไธ่ฆๅคไน ๆงๅ"ใ | |
| ไธปๅคๆฎ = `retention_gain[d] = mean(start_level[kโฅ2]) โ start_level[1]` | |
| โ "้้ๅฐ่ฟไธชๅๆถ, ไฝ ไธไธๆฅๅฐฑไผๅคๅฐ" ็ธๅฏน็ฌฌไธๆฌก็ๆนๅใ | |
| ๅคๆฎ(ไบๅ): | |
| โ ๅกซๅ ้ธ้จ: `_n_visits` ๅ จ้จ โฅ1 ไธ `steps_to_abs` ้ๅ จ็ฉบ, ๅฆๅๅค"ๆๆ ๆช้้ๆๅ" | |
| โก ่ฆ็็: ๆฅ `_already_ratio` / `_none_ratio` | |
| โข ไฟ็: `mean(replay โ naive) > 0` ไธ่ชๅฉๆณๅบ้ดไธ็ > 0 โ ๆไฟ็; ๅฆๅ็ งๅฎๅ"ๆ ไฟ็" | |
| """ | |
| from __future__ import annotations | |
| import glob | |
| import json | |
| import random | |
| import statistics as st | |
| import sys | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| B = 20000 | |
| def load(pat="results/lmeff_s*"): | |
| runs = {} | |
| for d in sorted(glob.glob(str(ROOT / pat))): | |
| f = Path(d) / "lm4_wave_results.json" | |
| if not f.exists(): | |
| continue | |
| j = json.load(open(f)) | |
| seed = int(Path(d).name.rsplit("_s", 1)[1]) | |
| runs[seed] = j | |
| return runs | |
| def rg_of(j, arm): | |
| e = (j.get(arm) or {}).get("efficiency") or {} | |
| return e | |
| def boot_ci(x, n=B, seed=0): | |
| if not x: | |
| return float("nan"), float("nan") | |
| rng = random.Random(seed) | |
| m = [] | |
| for _ in range(n): | |
| m.append(st.mean([x[rng.randrange(len(x))] for _ in range(len(x))])) | |
| m.sort() | |
| return m[int(.025 * len(m))], m[int(.975 * len(m))] | |
| runs = load() | |
| print("=" * 92) | |
| print(f"ๅญฆไน ๆ็้ฆๆฌกๆต้ โโ {len(runs)} ไธช run: {sorted(runs)}") | |
| print("=" * 92) | |
| if not runs: | |
| sys.exit("โ ๆฒกๆ็ปๆ็ฎๅฝ") | |
| # โโ โ ๅกซๅ ้ธ้จ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| print("\nโ ๅกซๅ ้ธ้จ") | |
| gate_ok = True | |
| for seed, j in sorted(runs.items()): | |
| for arm in ("naive", "replay"): | |
| e = rg_of(j, arm) | |
| nv = e.get("_n_visits") or {} | |
| if not nv: | |
| print(f" โ seed={seed} {arm}: _n_visits ็ฉบ โ ๆๆ ๆช้้") | |
| gate_ok = False | |
| continue | |
| print(f" seed={seed} {arm:6s} n_visits={nv} already={e.get('_already_ratio'):.3f}" | |
| f" none={e.get('_none_ratio'):.3f} reachable_max={e.get('reachable_max')}") | |
| print(f" โ ๅกซๅ ้ธ้จ: {'PASS' if gate_ok else '**FAIL(ๆๆ ๆช้้ๆๅ)'}") | |
| # โโ โก ไฟ็ๅข็: ้ๅๅฏน็ ง โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| print("\n" + "=" * 92) | |
| print("โก โ ไฟ็ๅข็ retention_gain โโ naive vs replay(ๅ seed ๅๅ, ๅคฉ็ถ้ ๅฏน)") | |
| print("=" * 92) | |
| pairs = [] # (seed, dom, naive, replay) | |
| doms = set() | |
| for seed, j in sorted(runs.items()): | |
| en, er = rg_of(j, "naive"), rg_of(j, "replay") | |
| rn, rr = en.get("retention_gain") or {}, er.get("retention_gain") or {} | |
| for d in sorted(set(rn) | set(rr), key=lambda x: int(x[1:])): | |
| a, b = rn.get(d), rr.get(d) | |
| if a is None or b is None: | |
| continue | |
| doms.add(d) | |
| pairs.append((seed, d, float(a), float(b))) | |
| print(f"{'ๅ':<8}{'n seed':>7}{'naive ๅๅผ':>12}{'replay ๅๅผ':>13}{'ฮ(replayโnaive)':>18}") | |
| per_dom = {} | |
| for d in sorted(doms, key=lambda x: int(x[1:])): | |
| ps = [(a, b) for _, dd, a, b in pairs if dd == d] | |
| if not ps: | |
| continue | |
| na = st.mean([a for a, _ in ps]); rp = st.mean([b for _, b in ps]) | |
| per_dom[d] = (na, rp, len(ps)) | |
| print(f"{d:<8}{len(ps):>7}{na:>12.4f}{rp:>13.4f}{rp - na:>+18.4f}") | |
| if pairs: | |
| dn = [a for _, _, a, _ in pairs] | |
| dr = [b for _, _, _, b in pairs] | |
| dif = [b - a for _, _, a, b in pairs] | |
| print(f"\n ๅ จๅๆฑๆป(n={len(pairs)} ๅฏน):") | |
| print(f" naive ๅๅผ {st.mean(dn):+.4f} (std {st.pstdev(dn):.4f})") | |
| print(f" replay ๅๅผ {st.mean(dr):+.4f} (std {st.pstdev(dr):.4f})") | |
| lo, hi = boot_ci(dif) | |
| n_pos = sum(1 for x in dif if x > 0) | |
| n_neg = sum(1 for x in dif if x < 0) | |
| print(f" ฮ(replayโnaive) = {st.mean(dif):+.4f} ่ชๅฉๆณ 95% CI [{lo:+.4f}, {hi:+.4f}]") | |
| print(f" replay ๆดๅฅฝ็ๅ: {n_pos}/{len(dif)} naive ๆดๅฅฝ: {n_neg} ๅนณ: {len(dif)-n_pos-n_neg}") | |
| print(f" โ โข ๅคๆฎ: mean>0 ไธ CI ไธ็>0 ? " | |
| f"{'**ๆไฟ็**' if (st.mean(dif) > 0 and lo > 0) else '**ๆช่พพๅฐ(็ งๅฎๅ)'}") | |
| # โโ โข ่ตท็นๆฐดๅนณๆฌ่บซ(ไธไพ่ต้ๅผ, ๆด่ดด่ฟ"่ฎฐไฝไบๅคๅฐ") โโโโโโโโโโโโโโโโโ | |
| print("\n" + "=" * 92) | |
| print("โข ่ตท็นๆฐดๅนณ start_level(k=1 vs ไปฅๅ) โโ ็ปๅฏนๅฃๅพ") | |
| print("=" * 92) | |
| print(f"{'ๅ':<8}{'arm':<8}{'k=1 ่ตท็น':>10}{'kโฅ2 ๅๅผ':>11}{'่ตท็นๆๅทฎ':>10}") | |
| for seed, j in sorted(runs.items()): | |
| for arm in ("naive", "replay"): | |
| sl = (rg_of(j, arm).get("start_level") or {}) | |
| for d in sorted(sl, key=lambda x: int(x[1:])): | |
| v = sl[d] | |
| ks = sorted(v, key=lambda x: int(x)) | |
| first, later = v[ks[0]], [v[k] for k in ks[1:]] | |
| if later: | |
| print(f"{d:<8}{arm:<8}{first:>10.3f}{st.mean(later):>11.3f}" | |
| f"{max(later)-min(later):>10.3f} seed={seed}") | |
| # โโ โฃ ๅ ถๅฎๅฃๅพ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| print("\n" + "=" * 92) | |
| print("โฃ ๅ ถๅฎๅฃๅพ(ๆดๆฐๆ็ / ่ฎฟ้ฎๅ ๅข็)") | |
| print("=" * 92) | |
| for arm in ("naive", "replay"): | |
| wg, sp = [], [] | |
| for seed, j in sorted(runs.items()): | |
| e = rg_of(j, arm) | |
| for d, v in (e.get("within_gain") or {}).items(): | |
| wg += list(v.values()) | |
| for d, v in (e.get("slope_early") or {}).items(): | |
| sp += list(v.values()) | |
| print(f" {arm:6s} within_gain ๅๅผ {st.mean(wg):+.5f} (n={len(wg)})" | |
| f" | slope_early ๅๅผ {st.mean(sp):+.6f} (n={len(sp)})") | |