Download src/graph_analysis.py from GOVINDFROM/parallel-consistent-masked-diffusion: direct link, hf CLI and curl.
- Browser
- Download file 5.53 kB
-
https://huggingface.co/GOVINDFROM/parallel-consistent-masked-diffusion/resolve/main/src/graph_analysis.py
- Command line
-
hf download hf://GOVINDFROM/parallel-consistent-masked-diffusion/src/graph_analysis.py
-
curl -L -o graph_analysis.py https://huggingface.co/GOVINDFROM/parallel-consistent-masked-diffusion/resolve/main/src/graph_analysis.py
5.53 kB
| """Statistics for the graph experiments, done properly. | |
| Two things the training script reports naively and this one fixes. | |
| 1. "% of the ceiling" invites over-reading. One-pass validity is a binomial | |
| proportion over n_gen samples, and at the ceilings involved (V* below 1% for | |
| the strongly constrained families) the sampling error is comparable to V* | |
| itself. A run scoring 0.93% against V* = 0.82% has NOT beaten an | |
| information-theoretic bound - it is one standard error away from it. What | |
| matters is whether the confidence interval CONTAINS V*, which is the | |
| statement "the model is at the limit". | |
| 2. Uniqueness as unique/valid is meaningless for small families. The perfect | |
| matchings on 6 nodes number exactly 15, so a model that recovers the whole | |
| family reports 15/4072 = 0.4% "uniqueness" and looks degenerate while being | |
| flawless. Coverage - distinct valid graphs as a fraction of |F| - is the | |
| correct metric here. | |
| Also assembles the quality-vs-compute frontier, which is the comparison the | |
| entropy-budget rule exists to win: at equal or lower NFE, does it hold more | |
| validity than fixed-K? | |
| """ | |
| import glob, json, math, os, sys | |
| from collections import defaultdict | |
| import numpy as np | |
| RUNS = os.environ.get("RUNS", "runs") | |
| def wilson(k, n, z=1.96): | |
| """Wilson score interval - correct for proportions near 0, unlike normal | |
| approximation, which is exactly the regime V* lives in.""" | |
| if n == 0: | |
| return (0.0, 0.0) | |
| p = k / n | |
| d = 1 + z * z / n | |
| c = (p + z * z / (2 * n)) / d | |
| h = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / d | |
| return (max(0.0, c - h), min(1.0, c + h)) | |
| runs = defaultdict(list) | |
| for f in sorted(glob.glob(f"{RUNS}/gr1-*/result.json")): | |
| r = json.load(open(f)) | |
| runs[(r["args"]["family"], r["args"]["mode"])].append(r) | |
| if not runs: | |
| sys.exit("no gr1 results yet") | |
| print("=" * 96) | |
| print("ONE-PASS VALIDITY AGAINST THE EXACT CEILING V*") | |
| print("=" * 96) | |
| print("V* is the best any model can do at one pass: it already assumes perfect") | |
| print("marginals. The question is whether the interval contains it.\n") | |
| print(f"{'family':<13}{'TC':>6}{'V*':>9} {'mode':<13}{'observed':>9}" | |
| f"{'95% CI':>20}{'verdict':>24}") | |
| summary = {} | |
| for (fam, mode) in sorted(runs): | |
| rs = runs[(fam, mode)] | |
| ex = rs[0]["exact"] | |
| V = ex["one_pass_ceiling"] | |
| n = sum(r["args"]["n_gen"] for r in rs) | |
| k = sum(r["decode"]["fixedK_1"]["validity"] * r["args"]["n_gen"] for r in rs) | |
| p = k / n | |
| lo, hi = wilson(k, n) | |
| if lo <= V <= hi: | |
| verdict = "at the limit" | |
| elif p > V: | |
| verdict = "ABOVE limit (check!)" | |
| else: | |
| verdict = "below limit (mode i)" | |
| summary[(fam, mode)] = dict(V=V, p=p, lo=lo, hi=hi, verdict=verdict) | |
| print(f"{fam:<13}{ex['total_correlation_bits']:>6.2f}{V*100:>8.3f}% {mode:<13}" | |
| f"{p*100:>9.3f}% [{lo*100:>5.3f},{hi*100:>5.3f}]%{verdict:>24}") | |
| print() | |
| print("=" * 96) | |
| print("COVERAGE: distinct valid graphs as a fraction of the family") | |
| print("=" * 96) | |
| print("unique/valid is misleading here - the matching family has only 15 members,") | |
| print("so recovering all of them shows up as 0.4% 'uniqueness'.\n") | |
| print(f"{'family':<13}{'|F|':>7} {'mode':<13}{'rule':<18}{'valid':>9}" | |
| f"{'distinct':>10}{'coverage':>10}") | |
| for (fam, mode) in sorted(runs): | |
| rs = runs[(fam, mode)] | |
| M = rs[0]["exact"]["size"] | |
| for rule in ("fixedK_1", "fixedK_8", "entbudget_0.25"): | |
| if rule not in rs[0]["decode"]: | |
| continue | |
| val = np.mean([r["decode"][rule]["validity"] for r in rs]) | |
| uq = np.mean([r["decode"][rule]["unique"] for r in rs]) | |
| ngen = rs[0]["args"]["n_gen"] | |
| distinct = val * ngen * uq | |
| print(f"{fam:<13}{M:>7} {mode:<13}{rule:<18}{val*100:>8.2f}%" | |
| f"{distinct:>10.0f}{min(1.0, distinct/M)*100:>9.1f}%") | |
| print() | |
| print("=" * 96) | |
| print("QUALITY vs COMPUTE: does the entropy budget dominate fixed-K?") | |
| print("=" * 96) | |
| print("The rule exists to spend passes where the dependence actually is. It wins") | |
| print("only if it holds more validity at the SAME or LOWER number of passes.\n") | |
| for (fam, mode) in sorted(runs): | |
| rs = runs[(fam, mode)] | |
| pts = defaultdict(list) | |
| for r in rs: | |
| for k_, v in r["decode"].items(): | |
| fam_kind = "entropy-budget" if k_.startswith("entbudget") else "fixed-K" | |
| pts[fam_kind].append((v["nfe"], v["validity"])) | |
| def curve(kind): | |
| # average validity across seeds at each distinct NFE, ordered by NFE | |
| out = [] | |
| for n in sorted({p[0] for p in pts[kind]}): | |
| vs = [v for m, v in pts[kind] if m == n] | |
| out.append((float(n), float(np.mean(vs)))) | |
| return out | |
| fk, eb = curve("fixed-K"), curve("entropy-budget") | |
| print(f"-- {fam} / {mode}") | |
| print(f" {'fixed-K':<16}" + " ".join(f"{n:.0f}->{v*100:.1f}%" for n, v in fk)) | |
| print(f" {'entropy-budget':<16}" + " ".join(f"{n:.0f}->{v*100:.1f}%" for n, v in eb)) | |
| # a dominating point: at most the NFE and strictly more validity | |
| wins = [(n, v) for n, v in eb | |
| if any(n <= fn and v > fv + 1e-9 for fn, fv in fk)] | |
| print(f" entropy-budget points dominating some fixed-K point: " | |
| f"{[(int(n), round(v*100,1)) for n, v in wins] or 'none'}") | |
| json.dump({f"{k[0]}/{k[1]}": v for k, v in summary.items()}, | |
| open(os.path.join(os.environ.get("OUT", "figures"), | |
| "graph_ceiling.json"), "w"), indent=2, default=float) | |
| print("\nwrote graph_ceiling.json") | |