AbstractPhil commited on
Commit
5c049df
·
verified ·
1 Parent(s): 1e6fa24

exp000 baseline wall + substrate (runner-2 line opened)

Browse files
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ exp000_baselines/base_lune_cond_0.png filter=lfs diff=lfs merge=lfs -text
37
+ exp000_baselines/json_ckpt2500_cond_0.png filter=lfs diff=lfs merge=lfs -text
38
+ exp000_baselines/json_ckpt2500_shuffled_0.png filter=lfs diff=lfs merge=lfs -text
39
+ exp000_baselines/json_vit_cond_0.png filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - diffusion
5
+ - adapters
6
+ - aleph
7
+ - geolip
8
+ ---
9
+
10
+ # geolip-aleph-diffusion
11
+
12
+ Testable **aleph adapters** for the geolip diffusion variants — the certified
13
+ components of the geolip-aleph-qwen text line (frozen-trunk relay adapters with
14
+ closed-form aleph addressing, zero-init out weight+bias, near-zero gates,
15
+ bit-exact toggle contract) ported to diffusion trunks. Runner-2 line of the
16
+ geolip program.
17
+
18
+ ## Substrates
19
+
20
+ | variant | trunk | trainer path |
21
+ |---|---|---|
22
+ | SD15-Lune rectified flow | `AbstractPhil/sd15-flow-lune-json-prompt` ckpt-2500 (+ base lune, json-vit) | custom beds (this repo, `substrate/`) |
23
+ | Anima / Cosmos-Predict2 2B DiT | `circlestone-labs/Anima` (NC weights — all derived checkpoints NC) | `AbstractEyes/diffusion-pipe` branch `feat/aleph-adapter` |
24
+ | SDXL | `AbstractPhil/geolip-sdxl-aleph` phase-1 ckpts | read-only capacity battery first |
25
+
26
+ Sampler of record (Lune family): rectified flow, `v = noise − x0`, Euler on the
27
+ **SHIFT=2.5-warped** sigma grid `σ = 2.5u/(1+1.5u)`, `VAE_SCALE 0.18215`. Text
28
+ conditioning is the trainer's 225-token 3-chunk CLIP encoding (`encode_clip_225`,
29
+ 227 positions) — never a bare 77-token encode.
30
+
31
+ ## Standing rules of the line
32
+
33
+ - Adapter dtype **matches the trunk dtype** (fp32 adapters on a low-precision
34
+ trunk inject fp32 noise; judged gauges still run fp32).
35
+ - Pure Adam, weight-decay 0 on adapter paths — never AdamW.
36
+ - No comparative selectors (argmax/softmax routing/VQ) anywhere near the aleph;
37
+ the addresser is the closed-form sinh/cosh read.
38
+ - All-adapters-off ≡ frozen trunk **bit-exact** (code-path-skip toggles), gated
39
+ before and after every training run.
40
+ - Every result reads against the exp000 zero-shot baseline wall below; paired
41
+ designs with derangement (no-fixed-point) controls; judges self-test on known
42
+ answers before scoring; 1-seed results ship as **candidates**.
43
+
44
+ ## Baseline wall (exp000)
45
+
46
+ CLIP-L image↔image cosine, original vs regenerated from the row's own
47
+ `json_prompt` (`vit_json_prompt` for json-vit), **conditional vs shuffled-JSON
48
+ (derangement)**, n=24 held-out rows of `synthetic-object-relations-json`,
49
+ paired seeds, 30 steps, guidance 6.0, fp32 judge features:
50
+
51
+ | model | cond | shuffled | **cond − shuffled** |
52
+ |---|---|---|---|
53
+ | json_vit (latest ckpt) | 0.8072 | 0.5568 | **+0.2504** |
54
+ | json_ckpt2500 | 0.7536 | 0.5437 | **+0.2099** |
55
+ | base_lune (18765) | 0.6347 | 0.5272 | **+0.1075** |
56
+
57
+ Reading: the json-prompt finetunes carry ~2× the base UNet's scene information
58
+ from structured-JSON conditioning. Caveats: n=24, single seed bank; CLIP-L
59
+ image-image cosine has a high floor (~0.988 for pure-noise pairs on identical
60
+ resolution) so gaps live in a narrow band — the paired design is load-bearing.
61
+
62
+ ## Experiments
63
+
64
+ | exp | question | status |
65
+ |---|---|---|
66
+ | exp000_baselines | zero-shot baseline wall (above) | **shipped** |
67
+ | exp001_sd15_relay | relay-all16 vs matched LoRA-r32 vs frozen, paired val flow-MSE + round-trip | running |
68
+ | exp002_sd15_addrcond | frozen byte-trigram aleph address into the cond stream — 4-arm causal | staged |
69
+ | exp003_sigma_registers | sign-code separations: what is a diffusion "register"? | staged |
70
+ | exp004_anima_relay | relays on the 2B DiT via diffusion-pipe (bf16-matched) | staged |
71
+ | exp005_sdxl_tree4a | the SDXL capacity battery (guidepost/scaffold/skeleton) | designed |
72
+
73
+ Code for each experiment ships in its folder with `results.json` from the run
74
+ ledger. Substrate modules in `substrate/`.
exp000_baselines/README.md ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # exp000_baselines — the SD15-Lune zero-shot baseline wall
2
+
3
+ **Question.** How much scene information do the frozen SD15-Lune variants carry
4
+ from their own structured-JSON conditioning, before any adapter exists? Every
5
+ later adapter claim in this repo reads against these rows.
6
+
7
+ **Design.** n=24 held-out tail rows of
8
+ `AbstractPhil/synthetic-object-relations-json` (the json trainer's own dataset;
9
+ columns autodetected and printed, never assumed). For each model: generate from
10
+ the row's GT prompt column, **conditional vs shuffled (derangement — no fixed
11
+ points)**, shared per-index seeds, 30 Euler steps on the SHIFT=2.5-warped sigma
12
+ grid (trainer-matched), guidance 6.0, 512px. Judge: CLIP-L (openai
13
+ clip-vit-large-patch14) image features fp32, cosine of regenerated vs original
14
+ image, after a known-answer self-test (self-cos > 0.999; noise-pair below).
15
+
16
+ **Results** (`results.json`):
17
+
18
+ | model | cond col | cond | shuffled | gap |
19
+ |---|---|---|---|---|
20
+ | json_vit (auto latest) | vit_json_prompt | 0.8072 | 0.5568 | **+0.2504** |
21
+ | json_ckpt2500 | json_prompt | 0.7536 | 0.5437 | **+0.2099** |
22
+ | base_lune 18765 | json_prompt | 0.6347 | 0.5272 | **+0.1075** |
23
+
24
+ **Reading.** Both json finetunes roughly double the base UNet's conditional
25
+ grounding; json_vit is the strongest carrier. The shuffled columns sit near
26
+ each other (0.53–0.56) — the derangement control behaves.
27
+
28
+ **Honest caveats.** Single seed bank (candidate rows); n=24; CLIP-L img-img
29
+ cosine has a high floor (noise pairs ≈0.988 at matched resolution), so only the
30
+ paired gap is meaningful, never the absolute cosine; generation ran fp16
31
+ (inference-only; judge features fp32); guidance 6.0 follows the
32
+ before/after reference bed (an earlier prototype bed used 4.0 — not
33
+ comparable). Sample images: `*_0.png` (first row per arm).
34
+
35
+ **Ops note.** The judge self-test caught a transformers-5 API change
36
+ (`get_image_features` returning an output object) before any GPU spend —
37
+ scorer known-answer self-tests are a standing gate of this line.
38
+
39
+ GPU cost: ~4 minutes total on an RTX 6000 Ada (all three models, both arms).
exp000_baselines/base_lune_cond_0.png ADDED

Git LFS Details

  • SHA256: c1e2743811db822df0c8f96925259ef81747fd73c2b990e2ef55f3e7b8571c6c
  • Pointer size: 131 Bytes
  • Size of remote file: 531 kB
exp000_baselines/d1_exp000_baselines.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """d1_exp000_baselines.py — exp000: the SD15-Lune zero-shot baseline wall.
2
+
3
+ Every later adapter claim reads against these rows (claims discipline). For
4
+ each frozen model {json-prompt ckpt-2500, base lune 18765}: generate from GT
5
+ json_prompt CONDITIONAL vs SHUFFLED-json (derangement — no fixed points), CLIP-L
6
+ image-image cosine original-vs-regen per arm. The cond-minus-shuffled gap is
7
+ the scene-information gauge (pod/v35_expP1_sd15.py judge, contract-checked).
8
+
9
+ Data: AbstractPhil/synthetic-object-relations-json (the json trainer's own
10
+ dataset), parquet-direct, held-out tail rows, columns AUTODETECTED and printed
11
+ (never assumed). Sampler: pod2/d1_lune_sampler.py (SHIFT=2.5 grid — the
12
+ trainer-matched sampler of record). All judge features fp32.
13
+
14
+ Local: python pod2/d1_exp000_baselines.py --smoke (parse only)
15
+ Pod: python pod2/d1_exp000_baselines.py --run (GPU; ledgered)
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import io
20
+ import json
21
+ import os
22
+ import sys
23
+
24
+ sys.path[:0] = ["pod2", "."]
25
+
26
+ import torch
27
+
28
+ from pod_ledger import ledger_run, note
29
+ from aleph_diffusion_core import derangement
30
+ from d1_lune_sampler import encode_clip_225, flow_sample, decode
31
+
32
+ DATASET = "AbstractPhil/synthetic-object-relations-json"
33
+ SD_BASE = "stable-diffusion-v1-5/stable-diffusion-v1-5"
34
+ MODELS = [
35
+ ("json_ckpt2500", "AbstractPhil/sd15-flow-lune-json-prompt",
36
+ "checkpoint-00002500/unet", "json_prompt"),
37
+ ("base_lune", "AbstractPhil/sd15-flow-lune-flux",
38
+ "flux_t2_6_pose_t4_6_port_t1_4/checkpoint-00018765/unet", "json_prompt"),
39
+ ("json_vit", "AbstractPhil/sd15-flow-lune-json-vit",
40
+ "auto", "vit_json_prompt"),
41
+ ]
42
+ N, STEPS, GUIDANCE, SEED = 24, 30, 6.0, 1234
43
+ OUT_DIR = ("/workspace/data/dexp000" if os.path.isdir("/workspace")
44
+ else os.path.join(os.environ.get("GEOLIP_DATA", "./data"),
45
+ "dexp000"))
46
+
47
+
48
+ def load_rows(n=N):
49
+ """Parquet-direct held-out tail; autodetect image + json columns."""
50
+ from huggingface_hub import HfApi, hf_hub_download
51
+ import pyarrow.parquet as pq
52
+ api = HfApi()
53
+ files = sorted(f for f in api.list_repo_files(DATASET, repo_type="dataset")
54
+ if f.endswith(".parquet"))
55
+ assert files, f"no parquet files in {DATASET}"
56
+ path = hf_hub_download(DATASET, files[-1], repo_type="dataset")
57
+ tbl = pq.read_table(path)
58
+ cols = tbl.column_names
59
+ print(f"[exp000] columns: {cols}", flush=True)
60
+ img_col = next((c for c in cols if c in
61
+ ("image", "img", "jpeg", "png", "image_bytes")), None)
62
+ cond_cols = sorted({m[3] for m in MODELS})
63
+ assert img_col and all(c in cols for c in cond_cols), \
64
+ f"column autodetect failed (img={img_col}, need {cond_cols}) — inspect"
65
+ rows = tbl.slice(max(0, tbl.num_rows - n), n).to_pylist()
66
+ out = []
67
+ for r in rows:
68
+ img = r[img_col]
69
+ if isinstance(img, dict):
70
+ img = img.get("bytes")
71
+ row = {"image_bytes": img}
72
+ for c in cond_cols:
73
+ v = r[c]
74
+ row[c] = v if isinstance(v, str) else json.dumps(v)
75
+ out.append(row)
76
+ print(f"[exp000] {len(out)} held-out rows (tail of {files[-1]})",
77
+ flush=True)
78
+ return out
79
+
80
+
81
+ def judge_selftest(clip_model, clip_proc, device):
82
+ """Known-answer scorer check (silent-zero law): img vs itself == 1,
83
+ img vs noise well below."""
84
+ import numpy as np
85
+ from PIL import Image
86
+ rng = np.random.default_rng(0)
87
+ a = Image.fromarray(rng.integers(0, 255, (256, 256, 3), dtype=np.uint8))
88
+ b = Image.fromarray(rng.integers(0, 255, (256, 256, 3), dtype=np.uint8))
89
+
90
+ def feat(im):
91
+ with torch.no_grad():
92
+ inp = clip_proc(images=im, return_tensors="pt").to(device)
93
+ out = clip_model.get_image_features(**inp)
94
+ if not torch.is_tensor(out): # transformers>=5 returns an
95
+ out = getattr(out, "image_embeds", None) \
96
+ if getattr(out, "image_embeds", None) is not None \
97
+ else out.pooler_output # output object, not a tensor
98
+ f = out.float()
99
+ return torch.nn.functional.normalize(f, dim=-1)
100
+
101
+ same = (feat(a) @ feat(a).T).item()
102
+ diff = (feat(a) @ feat(b).T).item()
103
+ assert same > 0.999, f"judge self-test: self-cos {same}"
104
+ assert diff < same, "judge self-test: noise pair >= self pair"
105
+ print(f"[exp000] judge self-test ok (self {same:.4f}, noise {diff:.4f})",
106
+ flush=True)
107
+ return feat
108
+
109
+
110
+ def run(device="cuda"):
111
+ os.makedirs(OUT_DIR, exist_ok=True)
112
+ import numpy as np
113
+ from PIL import Image
114
+ from diffusers import UNet2DConditionModel, AutoencoderKL
115
+ from transformers import (CLIPTextModel, CLIPTokenizer, CLIPModel,
116
+ CLIPProcessor)
117
+
118
+ rows = load_rows()
119
+ perm = derangement(len(rows), seed=SEED)
120
+
121
+ vae = AutoencoderKL.from_pretrained(
122
+ SD_BASE, subfolder="vae", torch_dtype=torch.float32).to(device).eval()
123
+ tok = CLIPTokenizer.from_pretrained(SD_BASE, subfolder="tokenizer")
124
+ te = CLIPTextModel.from_pretrained(
125
+ SD_BASE, subfolder="text_encoder",
126
+ torch_dtype=torch.float32).to(device).eval()
127
+ clip = CLIPModel.from_pretrained(
128
+ "openai/clip-vit-large-patch14",
129
+ torch_dtype=torch.float32).to(device).eval()
130
+ cproc = CLIPProcessor.from_pretrained("openai/clip-vit-large-patch14")
131
+ feat = judge_selftest(clip, cproc, device)
132
+
133
+ orig_feats = torch.cat([
134
+ feat(Image.open(io.BytesIO(r["image_bytes"])).convert("RGB"))
135
+ for r in rows])
136
+
137
+ def resolve_sub(repo, sub):
138
+ if sub != "auto":
139
+ return sub
140
+ from huggingface_hub import HfApi
141
+ cks = sorted({f.split("/")[0] for f in
142
+ HfApi().list_repo_files(repo)
143
+ if f.startswith("checkpoint-")})
144
+ assert cks, f"no checkpoints in {repo}"
145
+ return f"{cks[-1]}/unet"
146
+
147
+ results = {}
148
+ for label, repo, sub, cond_col in MODELS:
149
+ prompts = [r[cond_col] for r in rows]
150
+ shuffled = [prompts[i] for i in perm.tolist()]
151
+ with torch.no_grad():
152
+ ehs_cond = encode_clip_225(prompts, tok, te, device)
153
+ ehs_shuf = encode_clip_225(shuffled, tok, te, device)
154
+ with ledger_run(f"dexp000 baseline {label}", budget_h=1.0) as h:
155
+ unet = UNet2DConditionModel.from_pretrained(
156
+ repo, subfolder=resolve_sub(repo, sub),
157
+ torch_dtype=torch.float16).to(device)
158
+ unet.eval()
159
+ arms = {}
160
+ for arm, ehs in (("cond", ehs_cond), ("shuffled", ehs_shuf)):
161
+ imgs = []
162
+ for i in range(0, len(prompts), 6):
163
+ lat = flow_sample(unet, ehs[i:i + 6].half(),
164
+ n_steps=STEPS, guidance=GUIDANCE,
165
+ seed=SEED + i, device=device)
166
+ imgs.extend(decode(vae, lat.float()))
167
+ pil = [Image.fromarray((im * 255).astype(np.uint8))
168
+ for im in imgs]
169
+ f = torch.cat([feat(p) for p in pil])
170
+ cos = (f * orig_feats).sum(-1)
171
+ arms[arm] = {"mean_cos": round(cos.mean().item(), 4),
172
+ "per_row": [round(c, 4) for c in cos.tolist()]}
173
+ for j, p in enumerate(pil[:6]):
174
+ p.save(os.path.join(OUT_DIR, f"{label}_{arm}_{j}.png"))
175
+ gap = arms["cond"]["mean_cos"] - arms["shuffled"]["mean_cos"]
176
+ results[label] = {**arms, "cond_minus_shuffled": round(gap, 4)}
177
+ h["verdict"] = f"cond-shuf gap {gap:+.4f}"
178
+ del unet
179
+ torch.cuda.empty_cache()
180
+ note(f"exp000 {label}: {json.dumps(results[label]['cond_minus_shuffled'])}")
181
+
182
+ with open(os.path.join(OUT_DIR, "results.json"), "w") as f:
183
+ json.dump({"n": N, "steps": STEPS, "guidance": GUIDANCE, "seed": SEED,
184
+ "sampler": "shifted SHIFT=2.5 (trainer-matched)",
185
+ "models": results}, f, indent=2)
186
+ print(json.dumps(results, indent=2))
187
+ return results
188
+
189
+
190
+ def smoke():
191
+ p = derangement(N, seed=SEED)
192
+ assert not (p == torch.arange(N)).any()
193
+ assert len(MODELS) == 3 and all(len(m) == 4 for m in MODELS) and OUT_DIR
194
+ print("d1_exp000_baselines smoke PASSED (parse + derangement; GPU run is "
195
+ "pod work)")
196
+
197
+
198
+ if __name__ == "__main__":
199
+ if "--run" in sys.argv:
200
+ run()
201
+ else:
202
+ smoke()
exp000_baselines/json_ckpt2500_cond_0.png ADDED

Git LFS Details

  • SHA256: 33eac2270a12f06953b1f0c042cd125a45d8df0740fac7321f2104914310057d
  • Pointer size: 131 Bytes
  • Size of remote file: 165 kB
exp000_baselines/json_ckpt2500_shuffled_0.png ADDED

Git LFS Details

  • SHA256: a34ca3b2f88df920b6833d419a143db09804bd492a5fc4b0dee712997f882c76
  • Pointer size: 131 Bytes
  • Size of remote file: 224 kB
exp000_baselines/json_vit_cond_0.png ADDED

Git LFS Details

  • SHA256: 1f34b3d86e02e74b32753615c4295d20af4a88849423472585803858097e7d29
  • Pointer size: 131 Bytes
  • Size of remote file: 333 kB
exp000_baselines/results.json ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "n": 24,
3
+ "steps": 30,
4
+ "guidance": 6.0,
5
+ "seed": 1234,
6
+ "sampler": "shifted SHIFT=2.5 (trainer-matched)",
7
+ "models": {
8
+ "json_ckpt2500": {
9
+ "cond": {
10
+ "mean_cos": 0.7536,
11
+ "per_row": [
12
+ 0.8035,
13
+ 0.9148,
14
+ 0.7331,
15
+ 0.6688,
16
+ 0.4755,
17
+ 0.7231,
18
+ 0.7083,
19
+ 0.5943,
20
+ 0.7487,
21
+ 0.8701,
22
+ 0.7032,
23
+ 0.8887,
24
+ 0.832,
25
+ 0.9014,
26
+ 0.611,
27
+ 0.8087,
28
+ 0.6524,
29
+ 0.7803,
30
+ 0.8273,
31
+ 0.6996,
32
+ 0.7105,
33
+ 0.8917,
34
+ 0.7518,
35
+ 0.7874
36
+ ]
37
+ },
38
+ "shuffled": {
39
+ "mean_cos": 0.5437,
40
+ "per_row": [
41
+ 0.5435,
42
+ 0.6425,
43
+ 0.5901,
44
+ 0.4604,
45
+ 0.5282,
46
+ 0.4898,
47
+ 0.6984,
48
+ 0.4481,
49
+ 0.3883,
50
+ 0.5295,
51
+ 0.6005,
52
+ 0.6636,
53
+ 0.5471,
54
+ 0.7058,
55
+ 0.4693,
56
+ 0.5594,
57
+ 0.5301,
58
+ 0.4889,
59
+ 0.3852,
60
+ 0.503,
61
+ 0.4944,
62
+ 0.4945,
63
+ 0.6633,
64
+ 0.6256
65
+ ]
66
+ },
67
+ "cond_minus_shuffled": 0.2099
68
+ },
69
+ "base_lune": {
70
+ "cond": {
71
+ "mean_cos": 0.6347,
72
+ "per_row": [
73
+ 0.5411,
74
+ 0.8111,
75
+ 0.6828,
76
+ 0.6286,
77
+ 0.4581,
78
+ 0.7579,
79
+ 0.6248,
80
+ 0.4867,
81
+ 0.669,
82
+ 0.5588,
83
+ 0.794,
84
+ 0.707,
85
+ 0.6291,
86
+ 0.6393,
87
+ 0.5809,
88
+ 0.6189,
89
+ 0.6138,
90
+ 0.6916,
91
+ 0.5286,
92
+ 0.488,
93
+ 0.6567,
94
+ 0.7892,
95
+ 0.6652,
96
+ 0.6113
97
+ ]
98
+ },
99
+ "shuffled": {
100
+ "mean_cos": 0.5272,
101
+ "per_row": [
102
+ 0.4326,
103
+ 0.5854,
104
+ 0.5153,
105
+ 0.5229,
106
+ 0.4735,
107
+ 0.5902,
108
+ 0.6787,
109
+ 0.4701,
110
+ 0.4958,
111
+ 0.5693,
112
+ 0.5736,
113
+ 0.6151,
114
+ 0.5454,
115
+ 0.5444,
116
+ 0.4825,
117
+ 0.5683,
118
+ 0.4995,
119
+ 0.4937,
120
+ 0.4329,
121
+ 0.4747,
122
+ 0.4512,
123
+ 0.4787,
124
+ 0.4917,
125
+ 0.6676
126
+ ]
127
+ },
128
+ "cond_minus_shuffled": 0.1075
129
+ },
130
+ "json_vit": {
131
+ "cond": {
132
+ "mean_cos": 0.8072,
133
+ "per_row": [
134
+ 0.8537,
135
+ 0.9141,
136
+ 0.8594,
137
+ 0.7998,
138
+ 0.7337,
139
+ 0.87,
140
+ 0.8184,
141
+ 0.6666,
142
+ 0.7627,
143
+ 0.8301,
144
+ 0.8526,
145
+ 0.9045,
146
+ 0.6834,
147
+ 0.9177,
148
+ 0.8277,
149
+ 0.7235,
150
+ 0.7074,
151
+ 0.9092,
152
+ 0.8024,
153
+ 0.7627,
154
+ 0.7616,
155
+ 0.8436,
156
+ 0.8002,
157
+ 0.7667
158
+ ]
159
+ },
160
+ "shuffled": {
161
+ "mean_cos": 0.5568,
162
+ "per_row": [
163
+ 0.5882,
164
+ 0.4861,
165
+ 0.5141,
166
+ 0.5191,
167
+ 0.5185,
168
+ 0.5729,
169
+ 0.6989,
170
+ 0.4491,
171
+ 0.5066,
172
+ 0.5497,
173
+ 0.5242,
174
+ 0.5634,
175
+ 0.5902,
176
+ 0.7063,
177
+ 0.5484,
178
+ 0.5393,
179
+ 0.5639,
180
+ 0.5951,
181
+ 0.4585,
182
+ 0.5238,
183
+ 0.4823,
184
+ 0.5658,
185
+ 0.6907,
186
+ 0.6077
187
+ ]
188
+ },
189
+ "cond_minus_shuffled": 0.2504
190
+ }
191
+ }
192
+ }
substrate/aleph_diffusion_core.py ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """aleph_diffusion_core.py — runner-2 diffusion aleph-adapter core (exp001+).
2
+
3
+ The certified components ported to diffusion trunks (repos/geolip-aleph-diffusion.md):
4
+ AlephAddress — verbatim port of tools/aleph_routed_attention.py:51 (closed-form
5
+ sinh/cosh read over 2K oriented half-axes; canon/aleph_core.md).
6
+ RelayPatch2D — the RelayPatchwork port (tools/qwen_exp002_refine.py:96):
7
+ per-block residual relay on token-space hidden states [B,T,d].
8
+ Zero-init out weight AND bias (exp006 bias-leak law), gate -3.0,
9
+ enabled=False returns x via code-path skip (toggle law bit-exact).
10
+ AlephCondAdapter— conditioning-stream address injection (geolip-sdxl-aleph
11
+ addr_adapter precedent): frozen [32,128] address -> 32 cond
12
+ positions, everything zero-init => exact zeros at init.
13
+ Sign-code gauge — register-probe separation, DIAGONAL EXCLUDED (documented
14
+ discontinuity vs the qwen line; canon/register_probe_gauge.md).
15
+ Parity utils — P-TOGGLE / P-INIT / P-FIRE / P-SAVE gate helpers.
16
+
17
+ Riders: pure Adam wd=0 downstream; no comparative selectors in any gradient path
18
+ (argmax appears ONLY in read-only gauges); fp32 for paired gauges; no GAP on
19
+ feature paths (pooling appears ONLY in read-only gauges).
20
+
21
+ CPU cert: python pod2/aleph_diffusion_core.py (shapes/parity only — never
22
+ CPU-train for accuracy; house law).
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import math
27
+
28
+ import torch
29
+ import torch.nn as nn
30
+ import torch.nn.functional as F
31
+
32
+ PHI = math.sqrt(2.0)
33
+ PSI = 1.533751168755204288118041
34
+
35
+
36
+ def super_fibonacci_s3(n: int, dtype=torch.float32) -> torch.Tensor:
37
+ """Near-uniform unit quaternions (Alexa CVPR'22), constants per canon."""
38
+ i = torch.arange(n, dtype=torch.float64)
39
+ s = (i + 0.5) / n
40
+ r = torch.sqrt(s)
41
+ R = torch.sqrt(1.0 - s)
42
+ alpha = 2.0 * math.pi * i / PHI
43
+ beta = 2.0 * math.pi * i / PSI
44
+ q = torch.stack([r * torch.sin(alpha), r * torch.cos(alpha),
45
+ R * torch.sin(beta), R * torch.cos(beta)], dim=-1)
46
+ return F.normalize(q, dim=-1).to(dtype)
47
+
48
+
49
+ class AlephAddress(nn.Module):
50
+ """The aleph addresser over 2K oriented half-axes [+A; -A].
51
+ m_hat(x): closed-form soft read Sum_k sinh(u_k)A_k / Sum_k cosh(u_k), stable
52
+ via max-|u| factor-out; 2K never materialized. Codebook trains ONLY through
53
+ whatever consumes the address (no commit/EMA/VQ)."""
54
+
55
+ def __init__(self, K: int = 64, D: int = 4, tau: float = 0.1,
56
+ init: str = "random", codebook: torch.Tensor | None = None,
57
+ learnable: bool = True):
58
+ super().__init__()
59
+ self.K, self.D, self.tau = K, D, tau
60
+ if codebook is not None:
61
+ A = F.normalize(codebook.detach().clone().float(), dim=-1)
62
+ assert A.shape == (K, D), f"custom codebook must be ({K},{D})"
63
+ elif init == "fibonacci":
64
+ assert D == 4, "fibonacci init is defined on S^3 (D=4) only"
65
+ A = super_fibonacci_s3(K)
66
+ elif init == "random":
67
+ A = F.normalize(torch.randn(K, D), dim=-1)
68
+ else:
69
+ raise ValueError(f"unknown init '{init}'")
70
+ if learnable:
71
+ self.codebook = nn.Parameter(A)
72
+ else:
73
+ self.register_buffer("codebook", A)
74
+ self.register_buffer("home", A.detach().clone())
75
+
76
+ def _u(self, x: torch.Tensor) -> torch.Tensor:
77
+ A = F.normalize(self.codebook, dim=-1)
78
+ return (F.normalize(x, dim=-1) @ A.transpose(-1, -2)) / self.tau
79
+
80
+ def m_hat(self, x: torch.Tensor) -> torch.Tensor:
81
+ """Closed-form soft read (decoders read THIS, never the raw codebook)."""
82
+ u = self._u(x)
83
+ m = u.abs().amax(dim=-1, keepdim=True)
84
+ ep, en = torch.exp(u - m), torch.exp(-u - m)
85
+ num = ep - en # ∝ 2 sinh(u)
86
+ den = (ep + en).sum(dim=-1, keepdim=True) # ∝ 2 Σ cosh(u)
87
+ A = F.normalize(self.codebook, dim=-1)
88
+ return (num @ A) / den
89
+
90
+ @torch.no_grad()
91
+ def export_codebook(self) -> torch.Tensor:
92
+ return F.normalize(self.codebook.detach(), dim=-1).clone()
93
+
94
+
95
+ class SquaredReLU(nn.Module):
96
+ def forward(self, x):
97
+ return F.relu(x) ** 2
98
+
99
+
100
+ class RelayPatch2D(nn.Module):
101
+ """Per-block residual relay for diffusion token streams.
102
+ forward(x[B,T,d]) = x + sigmoid(gate) * consume(m_hat(proj(x) slots)).
103
+ Toggle law: enabled=False returns x UNTOUCHED (code-path skip, bit-exact)."""
104
+
105
+ def __init__(self, d: int, n_slots: int = 16, K: int = 64, tau: float = 0.1,
106
+ hidden: int = 178, init: str = "random"):
107
+ super().__init__()
108
+ self.d, self.n_slots, self.hidden = d, n_slots, hidden
109
+ self.proj = nn.Linear(d, n_slots * 4, bias=False)
110
+ nn.init.orthogonal_(self.proj.weight)
111
+ self.addr = AlephAddress(K, 4, tau, init)
112
+ self.consume = nn.Sequential(
113
+ nn.Linear(n_slots * 4, hidden), SquaredReLU(),
114
+ nn.LayerNorm(hidden), nn.Linear(hidden, d))
115
+ nn.init.zeros_(self.consume[-1].weight) # zero-init out: weight
116
+ nn.init.zeros_(self.consume[-1].bias) # AND bias (exp006 law)
117
+ self.gate = nn.Parameter(torch.tensor(-3.0))
118
+ self.enabled = True # plain attr, not a buffer
119
+ self.telemetry = False # read-only ratio stash switch
120
+ self.last_delta_ratio = None
121
+
122
+ def assert_zero_init(self):
123
+ w, b = self.consume[-1].weight, self.consume[-1].bias
124
+ assert w.abs().max().item() == 0.0, "out weight not zero-init"
125
+ assert b.abs().max().item() == 0.0, "out BIAS not zero-init (leak law)"
126
+
127
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
128
+ if not self.enabled:
129
+ return x
130
+ lead = x.shape[:-1]
131
+ slots = self.proj(x).view(*lead, self.n_slots, 4)
132
+ feats = self.addr.m_hat(slots).reshape(*lead, self.n_slots * 4)
133
+ delta = torch.sigmoid(self.gate) * self.consume(feats)
134
+ if self.telemetry:
135
+ with torch.no_grad():
136
+ self.last_delta_ratio = (
137
+ delta.norm() / x.norm().clamp_min(1e-12)).item()
138
+ return x + delta
139
+
140
+ @classmethod
141
+ def from_state_dict(cls, sd: dict) -> "RelayPatch2D":
142
+ """Rebuild dims FROM the state dict (runner_hook discipline: never trust
143
+ constructor defaults), then strict-load."""
144
+ d = sd["proj.weight"].shape[1]
145
+ n_slots = sd["proj.weight"].shape[0] // 4
146
+ hidden = sd["consume.0.weight"].shape[0]
147
+ K = sd["addr.codebook"].shape[0]
148
+ m = cls(d, n_slots=n_slots, K=K, hidden=hidden)
149
+ m.load_state_dict(sd, strict=True)
150
+ return m
151
+
152
+
153
+ class BlockWithRelay(nn.Module):
154
+ """Wrap pattern (pod/v35_substrate.py:182 lineage): adapter reads the
155
+ hidden-states output of the wrapped block; tuple outputs pass through."""
156
+
157
+ def __init__(self, block: nn.Module, relay: nn.Module):
158
+ super().__init__()
159
+ self.block = block
160
+ self.relay = relay
161
+
162
+ def forward(self, *args, **kwargs):
163
+ out = self.block(*args, **kwargs)
164
+ if isinstance(out, tuple):
165
+ return (self.relay(out[0]),) + out[1:]
166
+ return self.relay(out)
167
+
168
+
169
+ class AlephCondAdapter(nn.Module):
170
+ """Frozen [N_ADDR, addr_dim] address -> N_ADDR conditioning positions.
171
+ Everything zero-init => tokens are EXACT zeros at init and when disabled
172
+ (the position-presence offset is handled by the bed: SD15 masked-append,
173
+ Anima write-into-padding)."""
174
+
175
+ def __init__(self, cond_dim: int, addr_dim: int = 128, n_addr: int = 32):
176
+ super().__init__()
177
+ self.cond_dim, self.addr_dim, self.n_addr = cond_dim, addr_dim, n_addr
178
+ self.addr_proj = nn.Linear(addr_dim, cond_dim)
179
+ nn.init.zeros_(self.addr_proj.weight)
180
+ nn.init.zeros_(self.addr_proj.bias)
181
+ self.pos_table = nn.Parameter(torch.zeros(n_addr, cond_dim))
182
+ self.gate = nn.Parameter(torch.tensor(-3.0))
183
+ self.enabled = True
184
+
185
+ def assert_zero_init(self):
186
+ assert self.addr_proj.weight.abs().max().item() == 0.0
187
+ assert self.addr_proj.bias.abs().max().item() == 0.0
188
+ assert self.pos_table.abs().max().item() == 0.0
189
+
190
+ def tokens(self, addr: torch.Tensor) -> torch.Tensor:
191
+ """addr [B, n_addr, addr_dim] -> [B, n_addr, cond_dim]."""
192
+ assert addr.shape[-2:] == (self.n_addr, self.addr_dim), addr.shape
193
+ if not self.enabled:
194
+ return addr.new_zeros(*addr.shape[:-1], self.cond_dim)
195
+ return torch.sigmoid(self.gate) * (self.addr_proj(addr) + self.pos_table)
196
+
197
+ @classmethod
198
+ def from_state_dict(cls, sd: dict) -> "AlephCondAdapter":
199
+ cond_dim, addr_dim = sd["addr_proj.weight"].shape
200
+ n_addr = sd["pos_table"].shape[0]
201
+ m = cls(cond_dim, addr_dim=addr_dim, n_addr=n_addr)
202
+ m.load_state_dict(sd, strict=True)
203
+ return m
204
+
205
+
206
+ # ── parity gates ─────────────────────────────────────────────────────────────
207
+
208
+ def toggle_parity(frozen_fn, adapted_fn, probes, exact: bool = True) -> float:
209
+ """P-TOGGLE / P-INIT: max |frozen(x) - adapted(x)| over probes.
210
+ exact=True asserts BIT-EXACT (0.0)."""
211
+ worst = 0.0
212
+ with torch.no_grad():
213
+ for p in probes:
214
+ a, b = frozen_fn(p), adapted_fn(p)
215
+ d = (a - b).abs().max().item()
216
+ worst = max(worst, d)
217
+ if exact:
218
+ assert worst == 0.0, f"parity broken: max|delta| = {worst}"
219
+ return worst
220
+
221
+
222
+ class FireCounter:
223
+ """P-FIRE: forward-hook counters — every adapter fires, none silently dead."""
224
+
225
+ def __init__(self, adapters):
226
+ self.adapters = list(adapters)
227
+ self.counts = [0] * len(self.adapters)
228
+ self._handles = []
229
+
230
+ def __enter__(self):
231
+ for i, a in enumerate(self.adapters):
232
+ def mk(i):
233
+ def hook(mod, inp, out):
234
+ self.counts[i] += 1
235
+ return hook
236
+ self._handles.append(a.register_forward_hook(mk(i)))
237
+ return self
238
+
239
+ def __exit__(self, *exc):
240
+ for h in self._handles:
241
+ h.remove()
242
+
243
+ def assert_all_fired(self, at_least: int = 1):
244
+ dead = [i for i, c in enumerate(self.counts) if c < at_least]
245
+ assert not dead, f"adapters never fired at sites {dead}"
246
+
247
+
248
+ def save_relay_stack(adapters: nn.ModuleList, path: str):
249
+ torch.save({"relays": [a.state_dict() for a in adapters]}, path)
250
+
251
+
252
+ def load_relay_stack(path: str) -> nn.ModuleList:
253
+ ck = torch.load(path, map_location="cpu", weights_only=True)
254
+ return nn.ModuleList(RelayPatch2D.from_state_dict(sd) for sd in ck["relays"])
255
+
256
+
257
+ # ── read-only gauges (argmax/pooling legal ONLY here) ────────────────────────
258
+
259
+ SIGMA_BANDS = ((1.00, 0.75), (0.75, 0.50), (0.50, 0.25), (0.25, 0.00))
260
+
261
+
262
+ def sigma_band(sigma: float) -> int:
263
+ for i, (hi, lo) in enumerate(SIGMA_BANDS):
264
+ if lo < sigma <= hi or (i == len(SIGMA_BANDS) - 1 and sigma <= hi):
265
+ return i
266
+ return 0
267
+
268
+
269
+ @torch.no_grad()
270
+ def sign_codes(relay: RelayPatch2D, x: torch.Tensor) -> torch.Tensor:
271
+ """Per-position per-slot code: winner half-axis id*2 + orientation bit,
272
+ read from the addressing cosines (read-only hook; gauge, not gradient)."""
273
+ lead = x.shape[:-1]
274
+ slots = relay.proj(x).view(*lead, relay.n_slots, relay.addr.D)
275
+ A = F.normalize(relay.addr.codebook, dim=-1)
276
+ cos = F.normalize(slots, dim=-1) @ A.transpose(-1, -2)
277
+ idx = cos.abs().argmax(dim=-1)
278
+ orient = torch.gather(cos, -1, idx.unsqueeze(-1)).squeeze(-1) > 0
279
+ return idx * 2 + orient.long() # (..., n_slots)
280
+
281
+
282
+ @torch.no_grad()
283
+ def separation_no_diag(codes_by_register: dict[str, torch.Tensor]) -> float:
284
+ """Register separation = mean inter-register Hamming − mean intra-register
285
+ Hamming, intra DIAGONAL EXCLUDED (the r2 gauge restart; qwen-line numbers
286
+ are NOT comparable — canon/register_probe_gauge.md). Inter keeps same-input
287
+ (i,i) cross-register pairs: same input under two registers is a REAL pair
288
+ (pure register effect), so two near-identical registers read sep ~ -intra/n,
289
+ not 0. codes: (n_inputs, ..., n_slots) int tensors, inputs ALIGNED across
290
+ registers (assert same n)."""
291
+ regs = list(codes_by_register)
292
+ ns = {codes_by_register[r].shape[0] for r in regs}
293
+ assert len(ns) == 1, f"unaligned register inputs: {ns}"
294
+ n = ns.pop()
295
+ assert n >= max(8, n // 2), "too few aligned inputs"
296
+
297
+ def ham(a, b): # fraction of differing code entries
298
+ return (a != b).float().mean().item()
299
+
300
+ intra, inter = [], []
301
+ for r in regs:
302
+ c = codes_by_register[r]
303
+ for i in range(n):
304
+ for j in range(i + 1, n): # i<j: diagonal excluded
305
+ intra.append(ham(c[i], c[j]))
306
+ for a_i in range(len(regs)):
307
+ for b_i in range(a_i + 1, len(regs)):
308
+ ca, cb = codes_by_register[regs[a_i]], codes_by_register[regs[b_i]]
309
+ for i in range(n):
310
+ for j in range(n):
311
+ inter.append(ham(ca[i], cb[j]))
312
+ return (sum(inter) / max(len(inter), 1)) - (sum(intra) / max(len(intra), 1))
313
+
314
+
315
+ def derangement(n: int, seed: int = 0) -> torch.Tensor:
316
+ """Permutation with NO fixed points (the shuffled-control law)."""
317
+ g = torch.Generator().manual_seed(seed)
318
+ while True:
319
+ p = torch.randperm(n, generator=g)
320
+ if not (p == torch.arange(n)).any():
321
+ return p
322
+
323
+
324
+ @torch.no_grad()
325
+ def gate_stats(adapters) -> dict:
326
+ gates = [torch.sigmoid(a.gate).item() for a in adapters if hasattr(a, "gate")]
327
+ return {"gate_mean": round(sum(gates) / max(len(gates), 1), 5),
328
+ "gate_min": round(min(gates), 5) if gates else None,
329
+ "gate_max": round(max(gates), 5) if gates else None}
330
+
331
+
332
+ # ── CPU cert suite (shapes/parity ONLY — never CPU-train) ───────────────────
333
+
334
+ def _smoke():
335
+ torch.manual_seed(0)
336
+
337
+ # 1) super-fibonacci: shape + unit norm
338
+ q = super_fibonacci_s3(64)
339
+ assert q.shape == (64, 4)
340
+ assert (q.norm(dim=-1) - 1).abs().max() < 1e-6
341
+
342
+ # 2) closed-form m_hat == explicit 2K softmax read (<=1e-6 fp32)
343
+ addr = AlephAddress(K=64, D=4)
344
+ x = torch.randn(5, 7, 16, 4)
345
+ u = addr._u(x)
346
+ p = torch.softmax(torch.cat([u, -u], dim=-1), dim=-1)
347
+ A = F.normalize(addr.codebook, dim=-1)
348
+ explicit = p[..., :64] @ A - p[..., 64:] @ A
349
+ assert (addr.m_hat(x) - explicit).abs().max() < 1e-6, "closed form != 2K softmax"
350
+
351
+ # 3) RelayPatch2D: zero-init, init parity, toggle parity, shape
352
+ for d in (320, 640, 1280, 2048):
353
+ r = RelayPatch2D(d)
354
+ r.assert_zero_init()
355
+ xb = torch.randn(2, 9, d)
356
+ assert torch.equal(r(xb), xb), "P-INIT broken (zero-init must be exact)"
357
+ r.enabled = False
358
+ assert r(xb) is xb, "P-TOGGLE broken (must be code-path skip)"
359
+ r.enabled = True
360
+ nn.init.normal_(r.consume[-1].weight, std=0.02) # pretend trained
361
+ nn.init.normal_(r.consume[-1].bias, std=0.02)
362
+ assert r(xb).shape == xb.shape and not torch.equal(r(xb), xb)
363
+ n_params = sum(p.numel() for p in RelayPatch2D(1280).parameters())
364
+ print(f" relay params @d=1280: {n_params:,}")
365
+
366
+ # 4) toy-stub toggle parity through BlockWithRelay
367
+ class ToyBlock(nn.Module):
368
+ def __init__(self, d):
369
+ super().__init__()
370
+ self.lin = nn.Linear(d, d)
371
+
372
+ def forward(self, x):
373
+ return x + torch.tanh(self.lin(x))
374
+
375
+ d = 64
376
+ torch.manual_seed(1)
377
+ frozen = nn.Sequential(ToyBlock(d), ToyBlock(d))
378
+ relays = nn.ModuleList([RelayPatch2D(d) for _ in range(2)])
379
+ for rl in relays: # pretend trained
380
+ nn.init.normal_(rl.consume[-1].weight, std=0.02)
381
+ wrapped = nn.Sequential(*[BlockWithRelay(b, r)
382
+ for b, r in zip(frozen, relays)])
383
+ probes = [torch.randn(2, 5, d) for _ in range(4)]
384
+ for rl in relays:
385
+ rl.enabled = False
386
+ toggle_parity(lambda p: frozen(p), lambda p: wrapped(p), probes, exact=True)
387
+ for rl in relays:
388
+ rl.enabled = True
389
+ worst = toggle_parity(lambda p: frozen(p), lambda p: wrapped(p), probes,
390
+ exact=False)
391
+ assert worst > 0, "trained adapters produced no delta (dead sites?)"
392
+
393
+ # 5) P-FIRE
394
+ with FireCounter(relays) as fc:
395
+ wrapped(probes[0])
396
+ fc.assert_all_fired()
397
+
398
+ # 6) P-SAVE: dims-from-state-dict round trip + re-parity
399
+ import tempfile, os
400
+ path = os.path.join(tempfile.gettempdir(), "r2_relay_smoke.pt")
401
+ save_relay_stack(relays, path)
402
+ relays2 = load_relay_stack(path)
403
+ for a, b in zip(relays, relays2):
404
+ for (ka, va), (kb, vb) in zip(a.state_dict().items(),
405
+ b.state_dict().items()):
406
+ assert ka == kb and torch.equal(va, vb)
407
+
408
+ # 7) AlephCondAdapter: exact zeros at init + disabled + round trip
409
+ for cd in (768, 1024, 2048):
410
+ c = AlephCondAdapter(cd)
411
+ c.assert_zero_init()
412
+ a32 = torch.randn(3, 32, 128)
413
+ assert c.tokens(a32).abs().max().item() == 0.0, "cond tokens not exact 0"
414
+ c.enabled = False
415
+ assert c.tokens(a32).abs().max().item() == 0.0
416
+ c2 = AlephCondAdapter.from_state_dict(c.state_dict())
417
+ assert c2.cond_dim == cd
418
+
419
+ # 8) sign codes + separation gauge (intra diagonal excluded)
420
+ r = RelayPatch2D(64)
421
+ xa = torch.randn(10, 6, 64)
422
+ codes_a = sign_codes(r, xa)
423
+ assert codes_a.shape == (10, 6, 16)
424
+ assert torch.equal(codes_a, sign_codes(r, xa)), "codes not deterministic"
425
+ # mechanics on constructed codes: intra of constant register = 0 (diagonal
426
+ # exclusion working), all-differ registers => inter 1 => sep exactly 1.0
427
+ cz = torch.zeros(10, 6, 16, dtype=torch.long)
428
+ co = torch.ones(10, 6, 16, dtype=torch.long)
429
+ assert separation_no_diag({"z": cz, "o": co}) == 1.0
430
+ assert separation_no_diag({"z": cz, "z2": cz.clone()}) == 0.0
431
+ # near-identical REAL registers read ~ -intra/n (documented, not a bug)
432
+ same = separation_no_diag({"a": codes_a, "b": codes_a.clone()})
433
+ assert same <= 0.0
434
+ print(f" sep(identical real)={same:.4f} (expected ~ -intra/n)")
435
+
436
+ # 9) derangement: no fixed points
437
+ for n in (5, 12, 24):
438
+ p = derangement(n, seed=3)
439
+ assert not (p == torch.arange(n)).any()
440
+
441
+ # 10) sigma bands cover [0,1]
442
+ assert [sigma_band(s) for s in (1.0, 0.8, 0.6, 0.3, 0.0)] == [0, 0, 1, 2, 3]
443
+
444
+ print("aleph_diffusion_core smoke PASSED (closed-form parity, zero-init "
445
+ "W+b, bit-exact toggles, fire counters, save/load dims-from-sd, "
446
+ "cond-adapter exact zeros, no-diag gauge, derangement)")
447
+
448
+
449
+ if __name__ == "__main__":
450
+ _smoke()
substrate/d1_lune_sampler.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """d1_lune_sampler.py — SD15-Lune rectified-flow sampler + 225-token CLIP encoder.
2
+
3
+ PORTED VERBATIM (read-only law) from E:\\coworkers\\qwen_runner_1\\colab\\
4
+ sd15_lune_before_after.py (the sampler of record — repos/geolip-aleph-diffusion.md):
5
+ encode_clip_225 — 3 x 75-token chunked CLIP -> [B, 227, 768]. ALL judging in
6
+ this line conditions through THIS, never a bare 77-token encode.
7
+ flow_sample — Euler ODE sigma 1->0 on the SHIFT-warped grid
8
+ sigma = (shift*u)/(1+(shift-1)*u), v = noise - x0, batched CFG.
9
+ NOTE: pod/v35_expP1_sd15.py used an UNSHIFTED grid — that
10
+ discrepancy is ledgered in R0a; THIS grid matches the trainer.
11
+ Defaults from the source bed: STEPS 30, SHIFT 2.5, VAE_SCALE 0.18215, 64x64
12
+ latents (512px). Guidance differs across Phil's beds (6.0 before/after bed,
13
+ 4.0 expP1) — beds pass it explicitly and ledger it.
14
+
15
+ CPU cert: python pod2/d1_lune_sampler.py (sigma-grid math + dummy-UNet
16
+ integration shape check only; real sampling is pod work).
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import torch
21
+
22
+ VAE_SCALE = 0.18215
23
+ SHIFT = 2.5
24
+ STEPS = 30
25
+
26
+
27
+ def encode_clip_225(prompts, tokenizer, text_encoder, device):
28
+ """Encode text as 3 x 75-token chunks -> one 227-length hidden sequence."""
29
+ chunk_len = tokenizer.model_max_length # 77
30
+ body_len = chunk_len - 2 # 75
31
+ n_chunks = 3
32
+ ids = tokenizer(prompts, padding="max_length",
33
+ max_length=body_len * n_chunks + 2,
34
+ truncation=True, return_tensors="pt").input_ids # [B, 227]
35
+ bos, eos = ids[:, :1], ids[:, -1:]
36
+ chunks = []
37
+ for k in range(n_chunks):
38
+ s = 1 + k * body_len
39
+ chunks.append(torch.cat([bos, ids[:, s:s + body_len], eos], dim=1))
40
+ ids = torch.stack(chunks, dim=1).reshape(-1, chunk_len).to(device)
41
+ hs = text_encoder(ids)[0] # [B*3, 77, 768]
42
+ hs = hs.reshape(len(prompts), n_chunks * chunk_len, -1)
43
+ out = [hs[:, :1]]
44
+ for k in range(n_chunks):
45
+ s = k * chunk_len + 1
46
+ out.append(hs[:, s:s + body_len])
47
+ out.append(hs[:, -1:])
48
+ return torch.cat(out, dim=1) # [B, 227, 768]
49
+
50
+
51
+ def shifted_sigmas(n_steps: int, shift: float = SHIFT,
52
+ device="cpu") -> torch.Tensor:
53
+ u = torch.linspace(1.0, 0.0, n_steps + 1, device=device)
54
+ return (shift * u) / (1 + (shift - 1) * u)
55
+
56
+
57
+ @torch.no_grad()
58
+ def flow_sample(unet, ehs_cond, *, n_steps=STEPS, guidance=6.0, shift=SHIFT,
59
+ seed=1234, device="cuda", latent_hw=64,
60
+ encoder_attention_mask=None):
61
+ """Integrate the rectified-flow ODE sigma 1->0; unet predicts v = noise - x0.
62
+ encoder_attention_mask (optional, [2B, L]): the Tier-A masked-append toggle
63
+ path — passed through to the UNet when provided."""
64
+ B = ehs_cond.shape[0]
65
+ g = torch.Generator(device=device).manual_seed(seed)
66
+ x = torch.randn(B, 4, latent_hw, latent_hw, generator=g, device=device,
67
+ dtype=torch.float32).to(ehs_cond.dtype) # noise drawn fp32
68
+ # for seed comparability across dtypes, then cast to the UNet's dtype
69
+ ehs_in = torch.cat([ehs_cond, torch.zeros_like(ehs_cond)], dim=0)
70
+ sigmas = shifted_sigmas(n_steps, shift, device)
71
+ kw = {}
72
+ if encoder_attention_mask is not None:
73
+ kw["encoder_attention_mask"] = encoder_attention_mask
74
+ for i in range(n_steps):
75
+ s, s_next = float(sigmas[i]), float(sigmas[i + 1])
76
+ t = torch.full((2 * B,), s * 1000.0, device=device)
77
+ v = unet(torch.cat([x, x], dim=0), t, ehs_in, return_dict=False,
78
+ **kw)[0]
79
+ v_cond, v_uncond = v.chunk(2)
80
+ v = v_uncond + guidance * (v_cond - v_uncond)
81
+ x = x + (s_next - s) * v # Euler (sigma down)
82
+ return x
83
+
84
+
85
+ @torch.no_grad()
86
+ def decode(vae, latents):
87
+ img = vae.decode(latents / VAE_SCALE).sample
88
+ img = (img / 2 + 0.5).clamp(0, 1)
89
+ return img.permute(0, 2, 3, 1).float().cpu().numpy()
90
+
91
+
92
+ def _smoke():
93
+ s = shifted_sigmas(30)
94
+ assert abs(float(s[0]) - 1.0) < 1e-6 and abs(float(s[-1])) < 1e-6, \
95
+ "shifted grid must span 1 -> 0 exactly"
96
+ assert (s[:-1] > s[1:]).all(), "sigmas must be strictly decreasing"
97
+ mid_shifted = float(shifted_sigmas(2)[1]) # u=0.5 -> 2.5*.5/1.75
98
+ assert abs(mid_shifted - (1.25 / 1.75)) < 1e-6, "SHIFT=2.5 warp wrong"
99
+
100
+ class DummyUNet:
101
+ def __call__(self, x, t, ehs, return_dict=False, **kw):
102
+ return (torch.zeros_like(x),)
103
+
104
+ out = flow_sample(DummyUNet(), torch.zeros(2, 227, 768), n_steps=4,
105
+ guidance=1.0, seed=0, device="cpu")
106
+ assert out.shape == (2, 4, 64, 64)
107
+ print("d1_lune_sampler smoke PASSED (shifted grid endpoints + monotone, "
108
+ "warp value, dummy integration shape)")
109
+
110
+
111
+ if __name__ == "__main__":
112
+ _smoke()
substrate/d1_substrate.py ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """d1_substrate.py — runner-2 diffusion substrate gates (Day 0; no science on
2
+ an uncertified substrate; SUBSTRATE FROZEN AT THE GATE).
3
+
4
+ Gates (charter: history/plans/2026-07-16_runner2_diffusion_charter.md):
5
+ G1 env — torch/cuda/dtype facts; Blackwell sm_120 riders (torch>=2.7/
6
+ cu128; flash-attn must NOT be installed — SDPA is the path).
7
+ G2 memory — set_per_process_memory_fraction(R2_MEM_FRACTION) so overruns
8
+ fail LOUDLY; card + VRAM printed and ledgered.
9
+ G3 hf — HF_TOKEN env-only + whoami.
10
+ G4 sd15 — ckpt-2500 UNet loads; site enumeration ASSERTS 16
11
+ BasicTransformerBlocks; relay attach; P-INIT/P-TOGGLE bit-exact
12
+ parity; P-FIRE; peak_mem + s/step printed.
13
+ G5 mask — encoder_attention_mask bit-exact probe (Tier-A toggle path);
14
+ on failure the masked-append design falls back to length-toggle
15
+ + measured presence-offset (ledgered, never silent).
16
+ G6 adam — plain torch.optim.Adam constructs and IS Adam (never AdamW).
17
+
18
+ Local: python pod2/d1_substrate.py --smoke (parse/shape gates only)
19
+ Pod: python pod2/d1_substrate.py --gate (all gates, GPU)
20
+ """
21
+ from __future__ import annotations
22
+
23
+ import os
24
+ import sys
25
+ import time
26
+
27
+ sys.path[:0] = ["pod2", "."]
28
+
29
+ import torch
30
+
31
+ from aleph_diffusion_core import (RelayPatch2D, BlockWithRelay, FireCounter,
32
+ toggle_parity)
33
+
34
+ SD_REPO = "AbstractPhil/sd15-flow-lune-json-prompt"
35
+ SD_SUB = "checkpoint-00002500/unet"
36
+ SD_BASE = "stable-diffusion-v1-5/stable-diffusion-v1-5"
37
+ EXPECTED_SD15_SITES = 16
38
+ MEM_FRACTION = float(os.environ.get("R2_MEM_FRACTION", "0.92"))
39
+
40
+
41
+ def gate_env():
42
+ info = {"torch": torch.__version__,
43
+ "cuda_available": torch.cuda.is_available()}
44
+ if torch.cuda.is_available():
45
+ cap = torch.cuda.get_device_capability(0)
46
+ info["device"] = torch.cuda.get_device_name(0)
47
+ info["sm"] = f"sm_{cap[0]}{cap[1]}"
48
+ info["vram_gb"] = round(
49
+ torch.cuda.get_device_properties(0).total_memory / 2**30, 1)
50
+ if cap >= (12, 0):
51
+ try:
52
+ import flash_attn # noqa: F401
53
+ raise AssertionError(
54
+ "flash-attn installed on sm_120 — BROKEN there; uninstall "
55
+ "(SDPA is the sanctioned path, repos/anima-trainer.md)")
56
+ except ImportError:
57
+ pass
58
+ maj, mnr = torch.__version__.split(".")[:2]
59
+ assert (int(maj), int(mnr)) >= (2, 7), \
60
+ "Blackwell sm_120 needs torch>=2.7/cu128"
61
+ print(f"[G1 env] {info}", flush=True)
62
+ return info
63
+
64
+
65
+ def gate_memory():
66
+ assert torch.cuda.is_available(), "G2 needs the pod GPU"
67
+ torch.cuda.set_per_process_memory_fraction(MEM_FRACTION, 0)
68
+ total = torch.cuda.get_device_properties(0).total_memory / 2**30
69
+ print(f"[G2 mem] fraction {MEM_FRACTION} of {total:.1f}GB "
70
+ f"(~{MEM_FRACTION * total:.1f}GB) — overruns now fail LOUDLY",
71
+ flush=True)
72
+
73
+
74
+ def gate_hf():
75
+ assert os.environ.get("HF_TOKEN"), "HF_TOKEN missing from env (env-only law)"
76
+ from huggingface_hub import whoami
77
+ print(f"[G3 hf] identity: {whoami()['name']}", flush=True)
78
+
79
+
80
+ def enumerate_sd15_sites(unet):
81
+ """Walk named_modules; return [(qualified_name, block, width)] for every
82
+ BasicTransformerBlock. NEVER trust a hardcoded count — assert it."""
83
+ from diffusers.models.attention import BasicTransformerBlock
84
+ sites = []
85
+ for name, mod in unet.named_modules():
86
+ if isinstance(mod, BasicTransformerBlock):
87
+ sites.append((name, mod, mod.norm1.normalized_shape[0]))
88
+ return sites
89
+
90
+
91
+ def attach_relays(unet, site_filter=None):
92
+ """Wrap each BasicTransformerBlock with BlockWithRelay(RelayPatch2D(d)).
93
+ Returns nn.ModuleList of relays (fp32) in site order."""
94
+ sites = enumerate_sd15_sites(unet)
95
+ if site_filter:
96
+ sites = [s for s in sites if site_filter(s[0])]
97
+ relays = torch.nn.ModuleList()
98
+ for name, block, d in sites:
99
+ p0 = next(block.parameters())
100
+ # DTYPE LAW (Phil 2026-07-16): adapter dtype MATCHES the trunk dtype
101
+ # (fp32 adapters on a low-precision trunk spin fp32 noise into the
102
+ # environment). SD15 exp001 trunk is fp32 -> matched by construction.
103
+ relay = RelayPatch2D(d).to(device=p0.device, dtype=p0.dtype)
104
+ wrapped = BlockWithRelay(block, relay)
105
+ parent = unet
106
+ parts = name.split(".")
107
+ for p in parts[:-1]:
108
+ parent = getattr(parent, p) if not p.isdigit() else parent[int(p)]
109
+ last = parts[-1]
110
+ if last.isdigit():
111
+ parent[int(last)] = wrapped
112
+ else:
113
+ setattr(parent, last, wrapped)
114
+ relays.append(relay)
115
+ return relays, [s[0] for s in sites]
116
+
117
+
118
+ def _probe_batch(device, n=2, seed=7, cond_len=227):
119
+ g = torch.Generator(device="cpu").manual_seed(seed)
120
+ x = torch.randn(n, 4, 64, 64, generator=g).to(device)
121
+ t = torch.full((n,), 500.0, device=device)
122
+ ehs = torch.randn(n, cond_len, 768, generator=g).to(device)
123
+ return x, t, ehs
124
+
125
+
126
+ def gate_sd15(device="cuda"):
127
+ from diffusers import UNet2DConditionModel
128
+ t0 = time.time()
129
+ unet = UNet2DConditionModel.from_pretrained(
130
+ SD_REPO, subfolder=SD_SUB, torch_dtype=torch.float32).to(device)
131
+ unet.eval()
132
+ print(f"[G4 sd15] UNet loaded fp32 in {time.time() - t0:.1f}s", flush=True)
133
+
134
+ sites = enumerate_sd15_sites(unet)
135
+ widths = [w for _, _, w in sites]
136
+ assert len(sites) == EXPECTED_SD15_SITES, \
137
+ f"site map changed: {len(sites)} blocks (expected {EXPECTED_SD15_SITES})"
138
+ print(f"[G4 sd15] {len(sites)} BasicTransformerBlocks, widths {widths}",
139
+ flush=True)
140
+
141
+ probes = [_probe_batch(device, seed=s) for s in (7, 11, 13, 17)]
142
+ with torch.no_grad():
143
+ frozen_out = [unet(x, t, ehs, return_dict=False)[0]
144
+ for x, t, ehs in probes]
145
+
146
+ relays, names = attach_relays(unet)
147
+ for r in relays:
148
+ r.assert_zero_init() # P-INIT precondition
149
+
150
+ def adapted(i):
151
+ x, t, ehs = probes[i]
152
+ with torch.no_grad():
153
+ return unet(x, t, ehs, return_dict=False)[0]
154
+
155
+ # P-INIT: zero-init enabled adapters == frozen, bit-exact
156
+ worst = max((adapted(i) - frozen_out[i]).abs().max().item()
157
+ for i in range(len(probes)))
158
+ assert worst == 0.0, f"P-INIT broken: max|delta| {worst} (bias leak class?)"
159
+ # P-TOGGLE: disabled == frozen, bit-exact
160
+ for r in relays:
161
+ r.enabled = False
162
+ worst = max((adapted(i) - frozen_out[i]).abs().max().item()
163
+ for i in range(len(probes)))
164
+ assert worst == 0.0, f"P-TOGGLE broken: max|delta| {worst}"
165
+ for r in relays:
166
+ r.enabled = True
167
+ # P-FIRE
168
+ with FireCounter(relays) as fc:
169
+ adapted(0)
170
+ fc.assert_all_fired()
171
+
172
+ torch.cuda.reset_peak_memory_stats()
173
+ t0 = time.time()
174
+ adapted(0)
175
+ dt_ = time.time() - t0
176
+ peak = torch.cuda.max_memory_allocated() / 2**30
177
+ print(f"[G4 sd15] parity gates GREEN | forward {dt_:.2f}s | "
178
+ f"peak_mem {peak:.2f}GB", flush=True)
179
+ return unet, relays, names
180
+
181
+
182
+ def gate_mask(unet, device="cuda"):
183
+ """G5: masked-append vs plain must match; bit-exact preferred, else the
184
+ delta is MEASURED and the Tier-A design falls back (never silent)."""
185
+ x, t, ehs = _probe_batch(device, seed=23)
186
+ extra = torch.randn(ehs.shape[0], 32, 768, device=device)
187
+ ehs_app = torch.cat([ehs, extra], dim=1)
188
+ mask = torch.cat([torch.ones(ehs.shape[:2], device=device),
189
+ torch.zeros(ehs.shape[0], 32, device=device)],
190
+ dim=1).bool()
191
+ with torch.no_grad():
192
+ plain = unet(x, t, ehs, return_dict=False)[0]
193
+ masked = unet(x, t, ehs_app, encoder_attention_mask=mask,
194
+ return_dict=False)[0]
195
+ delta = (plain - masked).abs().max().item()
196
+ verdict = ("BIT-EXACT" if delta == 0.0 else
197
+ f"delta {delta:.3e} — masked-append NOT bit-exact; Tier-A "
198
+ f"toggle falls back to length-toggle + measured offset")
199
+ print(f"[G5 mask] {verdict}", flush=True)
200
+ return delta
201
+
202
+
203
+ def gate_adam():
204
+ opt = torch.optim.Adam([torch.nn.Parameter(torch.zeros(2))], lr=1e-3,
205
+ weight_decay=0.0)
206
+ assert type(opt) is torch.optim.Adam and not isinstance(
207
+ opt, torch.optim.AdamW), "pure-Adam law violated"
208
+ print("[G6 adam] torch.optim.Adam constructs, wd=0, not AdamW", flush=True)
209
+
210
+
211
+ def smoke():
212
+ """Local parse/shape gates (no GPU, no model downloads)."""
213
+ gate_adam()
214
+ r = RelayPatch2D(320)
215
+ r.assert_zero_init()
216
+ x = torch.randn(1, 4, 320)
217
+ assert torch.equal(r(x), x)
218
+ print("d1_substrate smoke PASSED (adam gate + relay parity, local)")
219
+
220
+
221
+ def gate():
222
+ gate_env()
223
+ gate_memory()
224
+ gate_hf()
225
+ gate_adam()
226
+ unet, relays, names = gate_sd15()
227
+ gate_mask(unet)
228
+ print("[substrate] ALL GATES GREEN — substrate FROZEN", flush=True)
229
+
230
+
231
+ if __name__ == "__main__":
232
+ if "--gate" in sys.argv:
233
+ gate()
234
+ else:
235
+ smoke()
substrate/pod_ledger.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """pod_ledger.py — RUNNER-2 campaign clock + utilization ledger
2
+ (COPY of runner 1's pod/pod_ledger.py per the charter — never import or edit
3
+ the original; its WINDOW constants are runner 1's live campaign clock.)
4
+
5
+ WINDOW: PLACEHOLDER 2026-07-16 -> 2026-07-20 UTC — Phil sets the real rental
6
+ window at kickoff; override via env R2_WINDOW_START_UTC / R2_WINDOW_END_UTC
7
+ (ISO, e.g. 2026-07-17T00:00) or edit the constants below THEN, not mid-run.
8
+
9
+ Usage (pod-side, wraps every run):
10
+ from pod_ledger import ledger_run, burn_down
11
+ with ledger_run("dexp001 sd15 relay all16", budget_h=1.5):
12
+ ... # the run; row written on exit, verdict settable
13
+ burn_down() # print remaining wall/allocated/reserve
14
+
15
+ Ledger file: JSONL at LEDGER_PATH (pod: /workspace/ledger2/pod2_ledger.jsonl;
16
+ local fallback under GEOLIP_DATA). Rows: {kind: run|note|day_report, name,
17
+ start_utc, end_utc, hours, budget_h, verdict, note}. The daily report for
18
+ Phil aggregates by day + experiment.
19
+
20
+ Colab/pod-safe: stdlib only.
21
+ """
22
+ from __future__ import annotations
23
+ import contextlib
24
+ import datetime as dt
25
+ import json
26
+ import os
27
+
28
+ # r2 window (PLACEHOLDER until kickoff; env-overridable, ISO format)
29
+ def _win(env, default):
30
+ v = os.environ.get(env)
31
+ if v:
32
+ return dt.datetime.fromisoformat(v).replace(tzinfo=dt.timezone.utc)
33
+ return default
34
+
35
+
36
+ WINDOW_START_UTC = _win("R2_WINDOW_START_UTC",
37
+ dt.datetime(2026, 7, 16, 0, 0, tzinfo=dt.timezone.utc))
38
+ WINDOW_END_UTC = _win("R2_WINDOW_END_UTC",
39
+ dt.datetime(2026, 7, 20, 0, 0, tzinfo=dt.timezone.utc))
40
+ TOTAL_H = (WINDOW_END_UTC - WINDOW_START_UTC).total_seconds() / 3600.0
41
+ RESERVE_H = 12.0
42
+
43
+ _DEFAULT_DIRS = ("/workspace/ledger2",
44
+ os.path.join(os.environ.get("GEOLIP_DATA", "./data"),
45
+ "pod_ledger"))
46
+
47
+
48
+ def _ledger_path():
49
+ for d in _DEFAULT_DIRS:
50
+ try:
51
+ os.makedirs(d, exist_ok=True)
52
+ return os.path.join(d, "pod2_ledger.jsonl")
53
+ except OSError:
54
+ continue
55
+ return "pod2_ledger.jsonl"
56
+
57
+
58
+ LEDGER_PATH = _ledger_path()
59
+
60
+
61
+ def _now():
62
+ return dt.datetime.now(dt.timezone.utc)
63
+
64
+
65
+ def _write(row: dict):
66
+ row["ts"] = _now().isoformat()
67
+ with open(LEDGER_PATH, "a", encoding="utf-8") as f:
68
+ f.write(json.dumps(row) + "\n")
69
+
70
+
71
+ def _rows():
72
+ if not os.path.exists(LEDGER_PATH):
73
+ return []
74
+ return [json.loads(l) for l in open(LEDGER_PATH, encoding="utf-8")]
75
+
76
+
77
+ def note(text: str):
78
+ _write({"kind": "note", "note": text})
79
+ print(f"[ledger] {text}", flush=True)
80
+
81
+
82
+ def spent_hours() -> float:
83
+ return sum(r.get("hours", 0.0) for r in _rows() if r.get("kind") == "run")
84
+
85
+
86
+ def wall_remaining_h() -> float:
87
+ return max(0.0, (WINDOW_END_UTC - _now()).total_seconds() / 3600.0)
88
+
89
+
90
+ def burn_down(print_it=True) -> dict:
91
+ spent = spent_hours()
92
+ wall = wall_remaining_h()
93
+ elapsed = TOTAL_H - wall
94
+ state = {
95
+ "wall_elapsed_h": round(elapsed, 2),
96
+ "wall_remaining_h": round(wall, 2),
97
+ "gpu_hours_ledgered": round(spent, 2),
98
+ "allocatable_remaining_h": round(max(0.0, wall - RESERVE_H), 2),
99
+ "reserve_h": RESERVE_H,
100
+ "utilization_pct_of_elapsed": round(100 * spent / max(elapsed, 0.01),
101
+ 1),
102
+ }
103
+ if print_it:
104
+ print(f"[burn-down] wall {state['wall_elapsed_h']:.1f}h elapsed / "
105
+ f"{state['wall_remaining_h']:.1f}h left | runs "
106
+ f"{state['gpu_hours_ledgered']:.1f}h ledgered "
107
+ f"({state['utilization_pct_of_elapsed']:.0f}% of elapsed) | "
108
+ f"allocatable {state['allocatable_remaining_h']:.1f}h "
109
+ f"(reserve {RESERVE_H:.0f}h)", flush=True)
110
+ return state
111
+
112
+
113
+ @contextlib.contextmanager
114
+ def ledger_run(name: str, budget_h: float = None):
115
+ """Time a run; write the row on exit (even on failure, with verdict)."""
116
+ start = _now()
117
+ print(f"[ledger] START {name}"
118
+ + (f" (budget {budget_h}h)" if budget_h else ""), flush=True)
119
+ holder = {"verdict": None}
120
+ try:
121
+ yield holder
122
+ verdict = holder["verdict"] or "completed"
123
+ except BaseException as e:
124
+ verdict = f"FAILED: {type(e).__name__}: {e}"
125
+ raise
126
+ finally:
127
+ end = _now()
128
+ hours = (end - start).total_seconds() / 3600.0
129
+ over = (budget_h is not None and hours > budget_h)
130
+ _write({"kind": "run", "name": name,
131
+ "start_utc": start.isoformat(), "end_utc": end.isoformat(),
132
+ "hours": round(hours, 3), "budget_h": budget_h,
133
+ "over_budget": over, "verdict": verdict})
134
+ print(f"[ledger] END {name}: {hours:.2f}h"
135
+ + (" ** OVER BUDGET **" if over else ""), flush=True)
136
+ burn_down()
137
+
138
+
139
+ def day_report() -> str:
140
+ """Aggregate for Phil's daily check-in."""
141
+ rows = [r for r in _rows() if r.get("kind") == "run"]
142
+ by_day = {}
143
+ for r in rows:
144
+ day = r["start_utc"][:10]
145
+ by_day.setdefault(day, []).append(r)
146
+ lines = ["POD UTILIZATION REPORT", "=" * 40]
147
+ for day in sorted(by_day):
148
+ runs = by_day[day]
149
+ total = sum(r["hours"] for r in runs)
150
+ lines.append(f"\n{day}: {total:.1f}h across {len(runs)} runs")
151
+ for r in runs:
152
+ flag = " **OVER**" if r.get("over_budget") else ""
153
+ lines.append(f" {r['hours']:5.2f}h {r['name']}"
154
+ f" [{str(r['verdict'])[:60]}]{flag}")
155
+ s = burn_down(print_it=False)
156
+ lines.append(f"\nWall: {s['wall_elapsed_h']:.1f}h elapsed, "
157
+ f"{s['wall_remaining_h']:.1f}h remaining "
158
+ f"({s['allocatable_remaining_h']:.1f}h allocatable + "
159
+ f"{s['reserve_h']:.0f}h reserve)")
160
+ report = "\n".join(lines)
161
+ _write({"kind": "day_report", "note": report})
162
+ return report
163
+
164
+
165
+ def smoke():
166
+ import tempfile, time
167
+ global LEDGER_PATH
168
+ old = LEDGER_PATH
169
+ LEDGER_PATH = os.path.join(tempfile.gettempdir(), "pod_ledger_smoke.jsonl")
170
+ if os.path.exists(LEDGER_PATH):
171
+ os.remove(LEDGER_PATH)
172
+ note("smoke start")
173
+ with ledger_run("smoke-run", budget_h=0.00001) as h: # 0.036s budget
174
+ time.sleep(0.05)
175
+ h["verdict"] = "smoke ok"
176
+ try:
177
+ with ledger_run("smoke-fail", budget_h=1.0):
178
+ raise ValueError("boom")
179
+ except ValueError:
180
+ pass
181
+ rows = _rows()
182
+ kinds = [r["kind"] for r in rows]
183
+ assert kinds.count("run") == 2
184
+ runs = [r for r in rows if r["kind"] == "run"]
185
+ assert runs[0]["verdict"] == "smoke ok" and runs[0]["over_budget"]
186
+ assert runs[1]["verdict"].startswith("FAILED: ValueError")
187
+ rep = day_report()
188
+ assert "smoke-run" in rep and "OVER" in rep
189
+ s = burn_down(print_it=False)
190
+ assert 0 <= s["wall_remaining_h"] <= TOTAL_H
191
+ LEDGER_PATH = old
192
+ print("pod_ledger smoke passed (run rows, failure verdicts, "
193
+ "over-budget flags, report, burn-down)")
194
+
195
+
196
+ if __name__ == "__main__":
197
+ smoke()