File size: 6,962 Bytes
65e4c84 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | """read_codebook.py — projective reading of cultivated aleph codebooks.
Antipodal-collapse extraction on trained codebooks + projective statistics on
RP^(D-1) — applied to the exp012 AR-bed specimens.
Recipe per the Polygonal Omega article (geometric-tri-band-ft2): collapse = (row_i - row_j)/2 normalized for each MUTUAL-STRONGEST
pair with cos < -0.9 — "a deterministic tensor operation," not clustering.
Projective metric ALWAYS arccos|<a,b>| (metric-alignment rule, reading-voids-ft1).
D=4 scope is the validated regime (D=5 walked back; axis count grows with D).
Readouts per specimen:
pairs / n_axes / unpaired — antipodal structure
proj_angle mean vs uniform baseline, deviation — near-uniform RP^(D-1)?
drift from home + binding fraction @0.29154 — cultivation record
erank of the axis set — spectral occupancy
verdict: PROJECTIVE-CLEAN (|dev|<0.05, util>0.95, secondary pairs<=3) /
-MOSTLY / STRUCTURED / DEGENERATE (per Polygonal Omega thresholds)
Usage (terminal): python read_codebook.py <ckpt_or_dir> [more paths...]
Colab: paste geolip_vitals.py cell first (optional), then this file, then
read_all(r"/content/data/ar_ckpts").
"""
from __future__ import annotations
import math
import sys
import torch
import torch.nn.functional as F
BINDING = 0.29154
@torch.no_grad()
def antipodal_collapse(codebook: torch.Tensor, thresh: float = -0.9) -> dict:
"""Mutual-strongest antipodal pairing + collapse to axes on RP^(D-1)."""
A = F.normalize(codebook.float(), dim=-1)
K = A.shape[0]
cos = A @ A.T
cos.fill_diagonal_(2.0) # exclude self from minima
nearest_neg = cos.argmin(dim=-1) # most-antipodal partner
pairs = []
used = set()
for i in range(K):
j = int(nearest_neg[i])
if i < j and int(nearest_neg[j]) == i and cos[i, j] < thresh:
pairs.append((i, j))
used.update((i, j))
axes = [F.normalize((A[i] - A[j]) / 2.0, dim=-1) for i, j in pairs]
axes += [A[i] for i in range(K) if i not in used] # unpaired rows as axes
axes = torch.stack(axes) if axes else A[:0]
# sign-canon onto RP: first nonzero coordinate positive
for r in range(axes.shape[0]):
nz = torch.nonzero(axes[r].abs() > 1e-8)
if nz.numel() and axes[r, nz[0, 0]] < 0:
axes[r] = -axes[r]
return {"pairs": len(pairs), "n_axes": axes.shape[0],
"unpaired": K - 2 * len(pairs), "axes": axes}
@torch.no_grad()
def projective_stats(axes: torch.Tensor, n_baseline: int = 20000,
seed: int = 0) -> dict:
"""Mean projective angle arccos|<a,b>| vs a uniform-RP baseline at same (n, D)."""
n, D = axes.shape
if n < 2:
return {"proj_angle_mean": None, "uniform_baseline": None,
"deviation": None, "erank": None}
def mean_angle(rows):
c = (rows @ rows.T).abs().clamp(max=1.0)
iu = torch.triu_indices(rows.shape[0], rows.shape[0], offset=1)
return torch.arccos(c[iu[0], iu[1]]).mean().item()
obs = mean_angle(axes)
g = torch.Generator().manual_seed(seed)
base_angles = []
m = max(2, n)
for _ in range(max(1, n_baseline // max(1, m * (m - 1) // 2))):
r = F.normalize(torch.randn(m, D, generator=g), dim=-1)
base_angles.append(mean_angle(r))
base = sum(base_angles) / len(base_angles)
s = torch.linalg.svdvals(axes)
p = (s / s.sum().clamp_min(1e-12))
erank = float(torch.exp(-(p.clamp_min(1e-12) * p.clamp_min(1e-12).log()).sum()))
return {"proj_angle_mean": round(obs, 4), "uniform_baseline": round(base, 4),
"deviation": round(obs - base, 4), "erank": round(erank, 3)}
@torch.no_grad()
def read_specimen(path: str) -> dict:
ck = torch.load(path, map_location="cpu", weights_only=True)
out = {"file": path.split("\\")[-1].split("/")[-1],
"arm": ck.get("arm"), "seed": ck.get("seed"),
"steps": ck.get("steps"), "val_bpb": round(ck.get("val_bpb", -1), 4)}
if "state_dict" in ck: # full specimen checkpoint
sd = ck["state_dict"]
books = {k[:-len(".codebook")]: sd[k] for k in sd
if k.endswith("addr.codebook") or k.endswith("head_addr.codebook")}
homes = {k[:-len(".home")]: sd[k] for k in sd if k.endswith(".home")}
else: # bare genome dict (exp014+ champion files):
# books under flat/root/branch* keys; *_proj entries are projections
books = {k: v for k, v in ck.items()
if torch.is_tensor(v) and v.ndim == 2
and (k in ("flat", "root") or k.startswith("branch"))}
homes = {}
reads = {}
for name, cb in books.items():
col = antipodal_collapse(cb)
stats = projective_stats(col["axes"])
home = homes.get(name)
drift = None
binding = None
if home is not None and home.shape == cb.shape:
a = F.normalize(cb.float(), dim=-1)
b = F.normalize(home.float(), dim=-1)
dr = torch.arccos((a * b).sum(-1).clamp(-1, 1))
drift = round(dr.mean().item(), 4)
binding = round(((dr - BINDING).abs() <= 0.05).float().mean().item(), 4)
util = col["n_axes"] / cb.shape[0]
dev = stats["deviation"]
if dev is not None and abs(dev) < 0.05 and util > 0.95 and col["pairs"] <= 3:
verdict = "PROJECTIVE-CLEAN"
elif dev is not None and abs(dev) < 0.05:
verdict = "PROJECTIVE-MOSTLY"
elif dev is not None and dev > 0.05:
verdict = "STRUCTURED(repulsive)"
else:
verdict = "DEGENERATE/CLUMPED" if dev is not None else "TOO-FEW-AXES"
reads[name] = {
"pairs": col["pairs"], "n_axes": col["n_axes"], **stats,
"drift": drift, "binding_frac": binding, "verdict": verdict}
out["codebooks"] = reads
return out
def read_all(root: str) -> list:
import glob, os
results = []
for p in sorted(glob.glob(os.path.join(root, "*.pt"))):
r = read_specimen(p)
print(r, flush=True)
results.append(r)
return results
def _in_notebook() -> bool:
try:
get_ipython() # type: ignore[name-defined] # noqa: F821
return True
except NameError:
return False
if __name__ == "__main__":
if _in_notebook():
print("Notebook mode: call read_all(r'<data_root>/ar_ckpts') in the next cell.")
else:
args = [a for a in sys.argv[1:] if not a.startswith("-")]
if not args:
print("usage: python read_codebook.py <ckpt_or_dir> [...]")
for a in args:
import os
read_all(a) if os.path.isdir(a) else print(read_specimen(a))
|