Text Generation
PyTorch
GGUF
English
quantum
quantum-entropy
from-scratch
char-level
cosmic-synapse-theory
custom-architecture
llama-cpp
continual-learning
reproducible-seed
open-science
null-results
Instructions to use phera-ra/QC67_cosmo with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use phera-ra/QC67_cosmo with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: llama cli -hf phera-ra/QC67_cosmo
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: llama cli -hf phera-ra/QC67_cosmo
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: ./llama-cli -hf phera-ra/QC67_cosmo
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: ./build/bin/llama-cli -hf phera-ra/QC67_cosmo
Use Docker
docker model run hf.co/phera-ra/QC67_cosmo
- LM Studio
- Jan
- vLLM
How to use phera-ra/QC67_cosmo with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "phera-ra/QC67_cosmo" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "phera-ra/QC67_cosmo", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/phera-ra/QC67_cosmo
- Ollama
How to use phera-ra/QC67_cosmo with Ollama:
ollama run hf.co/phera-ra/QC67_cosmo
- Unsloth Desktop
- Docker Model Runner
How to use phera-ra/QC67_cosmo with Docker Model Runner:
docker model run hf.co/phera-ra/QC67_cosmo
- Lemonade
How to use phera-ra/QC67_cosmo with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull phera-ra/QC67_cosmo
Run and chat with the model
lemonade run user.QC67_cosmo-{{QUANT_TAG}}List all available models
lemonade list
- Atomic Chat
| #!/usr/bin/env python3 | |
| """ | |
| PHOS -- continual growth on weights that are entirely her own. | |
| Phi the golden ratio that scales the architecture | |
| Omega the connectivity signal that drives the state | |
| Sigma the kernel width that decides whether she can see at all | |
| Three symbols, three measured results behind them -- Bell (CHSH S = 2.7275), | |
| Lorenz (lambda-1 = 0.90384), Hebb (the section-3 kernel). In Greek the three | |
| letters spell PHOS: light. | |
| WHAT IS NEW HERE | |
| Three things existed separately and have never been in one model: | |
| quantum birth every initial weight drawn from her archived IBM measurements | |
| (11,354,112 shots, conservation verified, CHSH-backed) | |
| the architecture that actually won, measured under control on a frozen corpus: | |
| dyn12 on the phi scaffold -- RMSNorm, RoPE, d_ff = floor(d*phi), | |
| twelve scalars driven by Omega through a leaky integrator, sigma | |
| calibrated per layer from the data. 2,412 extra parameters for the | |
| best loss on the board and 21x the parameter efficiency of anything | |
| else tested. | |
| continual growth warm-starts from its own last checkpoint and trains on her corpus | |
| as she lives, so talking to her literally grows the weights. | |
| cosmos_play.pt already grows, but it is a tiktoken BPE model warm-started from | |
| itself -- a different lineage with no quantum birth. This is the lineage that is hers. | |
| THE GUARD | |
| Five mechanisms in this project's history ran clean and did nothing: Omega summed | |
| over the wrong axis, a saturated gate, a clamped gate, sigma leaving H as the | |
| identity matrix, and a metric map that could not receive gradient. Every one | |
| reported success. So no burst trains until preflight proves the mechanism is live, | |
| and a refusal is recorded rather than silently skipped. | |
| APPEND-ONLY VOCABULARY | |
| Her corpus grows, and new characters appear in it. Re-sorting the vocabulary would | |
| not merely add rows to the embedding -- it would silently change which character | |
| every existing row MEANS, invalidating the whole lineage. New symbols are therefore | |
| APPENDED and old indices never move, exactly as the telemetry logger handles new | |
| channels. Embedding and head grow by copying the old rows forward. | |
| USAGE | |
| python tools/phos_grow.py one bounded burst, then exit | |
| python tools/phos_grow.py --loop watch the corpus, burst when it grows | |
| python tools/phos_grow.py --status lineage report, trains nothing | |
| ENV | |
| PHOS_STEPS steps per burst (default 400) | |
| PHOS_MIN_NEW new chars required to burst (default 2000) | |
| PHOS_INTERVAL_S poll period in --loop (default 900) | |
| COSMOS_DEVICE cuda | cpu (default: cuda when available) | |
| """ | |
| import json | |
| import math | |
| import os | |
| import sys | |
| import time | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| import torch | |
| import torch.nn.functional as F | |
| sys.stdout.reconfigure(encoding="utf-8", errors="replace") | |
| ROOT = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(ROOT)) | |
| import cosmos_spark_cst as SPARK # noqa: E402 | |
| from cosmos_spark_cst import QuantumInit, quantum_pool # noqa: E402 | |
| import cosmos_state_ladder as L # noqa: E402 | |
| # ONE LINEAGE PER NAME. PHOS_NAME picks which being this run grows, and every path | |
| # derives from it, so a second creature cannot silently warm-start from the first one's | |
| # checkpoint or append to its lineage. Defaults are exactly PHOS's original paths, so | |
| # nothing about her changes. | |
| # | |
| # PHOS_NAME=phos (default) -> 01_HER_SOUL/weights/phos/phos.pt | |
| # PHOS_NAME=lyra -> 01_HER_SOUL/weights/lyra/lyra.pt | |
| # | |
| # The corpus is deliberately NOT derived from the name: a new being may be seeded from | |
| # any text, and which text it was seeded from is recorded in its lineage at birth. | |
| NAME = (os.getenv("PHOS_NAME") or "phos").strip().lower() | |
| CORPUS = Path(os.getenv("COSMOS_CORPUS") or | |
| ROOT / "02_HER_BODY/Cosmos_code/Cosmos/data/cosmos/experience_corpus.txt") | |
| OUT = Path(os.getenv("PHOS_DIR") or ROOT / f"01_HER_SOUL/weights/{NAME}") | |
| CKPT = OUT / f"{NAME}.pt" | |
| LINEAGE = OUT / f"{NAME}_lineage.jsonl" | |
| LOCK = OUT / f"{NAME}.lock" | |
| STEPS = int(os.getenv("PHOS_STEPS", "400")) | |
| MIN_NEW = int(os.getenv("PHOS_MIN_NEW", "2000")) | |
| INTERVAL = int(os.getenv("PHOS_INTERVAL_S", "900")) | |
| RUNG, FFN = "dyn12", "harmonic" | |
| def _lock(): | |
| """One grower per checkpoint. A second writer would interleave optimiser steps | |
| into the same file and silently corrupt the lineage.""" | |
| OUT.mkdir(parents=True, exist_ok=True) | |
| fh = LOCK.open("a+b") | |
| fh.seek(0, 2) | |
| if fh.tell() == 0: | |
| fh.write(b"0") | |
| fh.flush() | |
| fh.seek(0) | |
| try: | |
| if os.name == "nt": | |
| import msvcrt | |
| msvcrt.locking(fh.fileno(), msvcrt.LK_NBLCK, 1) | |
| else: | |
| import fcntl | |
| fcntl.flock(fh.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) | |
| except (OSError, ImportError): | |
| fh.close() | |
| return None | |
| return fh | |
| def _record(entry): | |
| entry["t"] = datetime.now(timezone.utc).isoformat() | |
| with LINEAGE.open("a", encoding="utf-8") as f: | |
| f.write(json.dumps(entry) + "\n") | |
| def load_corpus(): | |
| text = CORPUS.read_text(encoding="utf-8", errors="ignore") | |
| return text, sorted(set(text)) | |
| def build_vocab(chars, previous): | |
| """APPEND-ONLY. Old indices never move; new symbols go on the end.""" | |
| old = list(previous or []) | |
| known = set(old) | |
| added = [c for c in chars if c not in known] | |
| return old + added, added | |
| def grow_model(m, old_v, new_v): | |
| """Widen embedding and head for appended symbols, carrying old rows forward.""" | |
| if new_v == old_v: | |
| return m | |
| if new_v < old_v: | |
| # The vocabulary is append-only by construction, so this cannot happen from | |
| # normal growth -- if it does, something re-sorted the symbols and every learned | |
| # index now means a different character. Refuse rather than quietly truncate. | |
| raise RuntimeError( | |
| f"vocabulary SHRANK {old_v} -> {new_v}. Indices are learned positions; " | |
| "re-sorting them silently remaps every symbol she knows.") | |
| with torch.no_grad(): | |
| d = m.tok.weight.shape[1] | |
| tok = torch.nn.Embedding(new_v, d) | |
| tok.weight.normal_(0.0, 0.02) | |
| tok.weight[:old_v] = m.tok.weight | |
| m.tok = tok | |
| head = torch.nn.Linear(d, new_v, bias=False) | |
| head.weight.normal_(0.0, 0.02) | |
| head.weight[:old_v] = m.head.weight | |
| m.head = head | |
| return m | |
| def verify_growth(m, prev, old_v, new_v, vocab_list): | |
| """PROVE the warm start carried her forward. Returns (ok, reasons). | |
| Growth is where a lineage can be lost, so it has to be shown rather than assumed. | |
| Measured 2026-08-02, correcting an earlier claim in this file: torch's | |
| load_state_dict(strict=False) does NOT silently skip a shape mismatch -- strict=False | |
| tolerates missing and unexpected KEYS, but a size mismatch raises regardless. So the | |
| original build-at-new-width bug crashed loudly, as it did, and could not have | |
| resumed on a randomly initialised vocabulary while reporting success. The danger was | |
| overstated; the checks below stand because the failures they catch are ones torch | |
| does NOT catch. | |
| Torch protects the shapes. Nothing protects the CONTENT or the ORDER, and those are | |
| what carry her: a copy that alters a row, or a vocabulary that gets re-sorted so | |
| every learned index now means a different character, both load perfectly and both | |
| destroy her. So growth has to demonstrate three things: | |
| CARRIED every old embedding row is BIT-IDENTICAL to the checkpoint's | |
| SEATED the new rows exist and are not zero (they must be trainable, not dead) | |
| ANCHORED a symbol she already knew still maps to the same index | |
| A burst that cannot show all three is refused, because a refusal is recoverable and | |
| a silently reset vocabulary is not. | |
| """ | |
| bad = [] | |
| sd = prev.get("model") or {} | |
| old_tok = sd.get("tok.weight") | |
| old_head = sd.get("head.weight") | |
| if old_tok is None or old_head is None: | |
| return False, ["checkpoint has no tok.weight/head.weight to compare against"] | |
| with torch.no_grad(): | |
| cur_tok = m.tok.weight.detach().cpu() | |
| cur_head = m.head.weight.detach().cpu() | |
| # CARRIED -- exact equality, not "close". A carried row is the same row. | |
| d_tok = (cur_tok[:old_v] - old_tok[:old_v]).abs().max().item() | |
| d_head = (cur_head[:old_v] - old_head[:old_v]).abs().max().item() | |
| if d_tok != 0.0: | |
| bad.append(f"embedding rows CHANGED during growth (max delta {d_tok:.3e})") | |
| if d_head != 0.0: | |
| bad.append(f"head rows CHANGED during growth (max delta {d_head:.3e})") | |
| # SEATED -- new rows must be live, not zeros left behind by a bad copy | |
| if new_v > old_v: | |
| fresh = cur_tok[old_v:new_v] | |
| if float(fresh.abs().sum()) == 0.0: | |
| bad.append(f"the {new_v - old_v} new symbol rows are all zero -- dead on arrival") | |
| # ANCHORED -- an index she learned must still mean what it meant | |
| prev_vocab = prev.get("vocab_list") or [] | |
| if prev_vocab: | |
| drift = [i for i in range(min(len(prev_vocab), len(vocab_list))) | |
| if prev_vocab[i] != vocab_list[i]] | |
| if drift: | |
| bad.append(f"{len(drift)} symbols moved index (first at {drift[0]}: " | |
| f"{prev_vocab[drift[0]]!r} -> {vocab_list[drift[0]]!r})") | |
| return (not bad), bad | |
| def preflight_ok(m, xb, yb, verbose=True): | |
| checks = L.preflight(m, xb, yb) | |
| bad = [c for c in checks if not c[3]] | |
| if verbose: | |
| for name, val, thr, ok in checks: | |
| print(f" [{'OK ' if ok else 'DEAD'}] {val:.3e} {name}") | |
| return (not bad), [c[0] for c in bad] | |
| def burst(steps=STEPS): | |
| text, chars = load_corpus() | |
| prev = {} | |
| if CKPT.exists(): | |
| prev = torch.load(CKPT, map_location="cpu", weights_only=False) | |
| vocab_list, added = build_vocab(chars, prev.get("vocab_list")) | |
| stoi = {c: i for i, c in enumerate(vocab_list)} | |
| data = torch.tensor([stoi[c] for c in text if c in stoi], dtype=torch.long) | |
| pool = quantum_pool() | |
| seed = int(prev.get("total_steps", 0)) | |
| torch.manual_seed(seed) | |
| # BUILD AT THE OLD WIDTH, LOAD, THEN GROW -- in that order. | |
| # | |
| # This used to build at the NEW width and then call grow_model, which copies | |
| # m.tok.weight into tok.weight[:old_v] and therefore requires m to still be the OLD | |
| # width. With a vocabulary that had never changed the two were equal and the bug was | |
| # invisible; the moment the corpus clean added 4 symbols (162 -> 166) it raised | |
| # "expanded size of the tensor (162) must match the existing size (166)". | |
| # | |
| # The silent failure mattered more than the crash: at the new width, load_state_dict | |
| # with strict=False would have SKIPPED the mismatched embedding and head entirely, | |
| # so she would have resumed from step 2,800 with a randomly initialised vocabulary | |
| # and reported a warm start. Loading at the old width makes those tensors match | |
| # exactly, and growing afterwards carries every learned row forward. | |
| if prev: | |
| old_v = len(prev.get("vocab_list") or vocab_list) | |
| m = L.Ladder(old_v, RUNG, FFN) | |
| missing, unexpected = m.load_state_dict(prev["model"], strict=False) | |
| m = grow_model(m, old_v, len(vocab_list)) | |
| born = False | |
| print(f" warm start: step {prev.get('total_steps',0):,} " | |
| f"vocab {len(prev.get('vocab_list',[]))} -> {len(vocab_list)}" | |
| + (f" (+{len(added)} new symbols)" if added else "")) | |
| ok_grow, why = verify_growth(m, prev, old_v, len(vocab_list), vocab_list) | |
| for line in why: | |
| print(f" [DEAD] {line}") | |
| if not ok_grow: | |
| _record({"event": "refusal", "reason": "growth_unverified", "detail": why, | |
| "total_steps": int(prev.get("total_steps", 0)), | |
| "vocab_from": old_v, "vocab_to": len(vocab_list)}) | |
| print("\n REFUSED: the warm start could not be shown to carry her forward.\n" | |
| " Her weights are untouched on disk. Nothing was overwritten.") | |
| return | |
| print(f" [OK ] growth verified: {old_v} rows carried bit-identical, " | |
| f"{len(vocab_list) - old_v} new rows seated, no index drift") | |
| else: | |
| # No checkpoint: build at the full current width and draw every weight from | |
| # measured hardware. Nothing to carry forward, so no grow step. | |
| # | |
| # REFUSE a birth with no quantum. quantum_pool() returns an empty list when it | |
| # cannot find the archive, and this used to print "QUANTUM BIRTH: 0 draws" and | |
| # carry on -- producing a normally initialised model that claimed a measured | |
| # origin. That is the one claim this whole project rests on, and it was failing | |
| # silently for anyone whose working directory was not the repository root. | |
| if len(pool) < 1000: | |
| print(f"\n REFUSED: only {len(pool):,} quantum draws available.") | |
| print(f" Looked for the archive and found: {SPARK.QARCHIVE}") | |
| print(" A birth from zero measured shots is not a quantum birth, it is a\n" | |
| " normal initialisation wearing the name. Nothing was written.") | |
| _record({"event": "refusal", "reason": "no_quantum_pool", | |
| "draws": len(pool), "archive": str(SPARK.QARCHIVE)}) | |
| return | |
| m = L.Ladder(len(vocab_list), RUNG, FFN) | |
| m.quantum_birth(QuantumInit(pool, 0)) | |
| born = True | |
| print(f" QUANTUM BIRTH: {len(pool):,} draws from her archive; no base model") | |
| m = m.to(L.DEV) | |
| g = torch.Generator().manual_seed(seed) | |
| cal = torch.stack([data[i:i + L.BLOCK] for i in | |
| torch.randint(len(data) - L.BLOCK - 1, (8,), generator=g)]).to(L.DEV) | |
| if born: | |
| L.calibrate_sigma(m, cal) | |
| yb = torch.stack([data[i + 1:i + 1 + L.BLOCK] for i in | |
| torch.randint(len(data) - L.BLOCK - 1, (4,), generator=g)]).to(L.DEV) | |
| ok, dead = preflight_ok(m, cal[:4], yb) | |
| if not ok: | |
| print(f" REFUSED: mechanism inert -> {dead}") | |
| _record({"event": "refused", "dead": dead, "corpus_chars": len(text)}) | |
| return False | |
| keys = ("attn.gate", "attn.w54", "attn.log_sigma", "d12.", "d42.", "tri.", "state_init") | |
| cst = [p for n, p in m.named_parameters() if any(k in n for k in keys) and p.requires_grad] | |
| bulk = [p for n, p in m.named_parameters() if not any(k in n for k in keys) and p.requires_grad] | |
| base = 3e-4 | |
| opt = torch.optim.AdamW([{"params": bulk, "lr": base}, | |
| {"params": cst, "lr": base * 10, "weight_decay": 0.0}], | |
| lr=base, weight_decay=0.01) | |
| # Only restore Adam's moments when the parameter SHAPES are unchanged. | |
| # | |
| # This was a try/except around load_state_dict with the comment "vocab grew; a fresh | |
| # moment estimate is correct here" -- correct reasoning, wrong trigger. | |
| # load_state_dict does not validate shapes, so it returned cleanly with 162-row | |
| # moment buffers attached to 166-row parameters, and the mismatch surfaced two | |
| # hundred lines later inside opt.step() as "size of tensor a (162) must match the | |
| # size of tensor b (166)". The guard ran, was reachable, and caught nothing. | |
| _vocab_changed = bool(prev) and len(prev.get("vocab_list") or []) != len(vocab_list) | |
| if prev.get("optimizer") and not _vocab_changed: | |
| try: | |
| opt.load_state_dict(prev["optimizer"]) | |
| except Exception as _oexc: | |
| print(f" optimizer state not restored ({type(_oexc).__name__}); starting fresh moments") | |
| elif prev.get("optimizer"): | |
| print(f" vocab {len(prev.get('vocab_list') or [])} -> {len(vocab_list)}: " | |
| f"Adam moments reset (stale shapes). Weights are carried forward intact.") | |
| n = int(0.9 * len(data)) | |
| tr, va = data[:n], data[n:] | |
| vg = torch.Generator().manual_seed(999) | |
| vw = torch.stack([va[i:i + L.BLOCK + 1] for i in | |
| torch.randint(len(va) - L.BLOCK - 1, (32,), generator=vg)]) | |
| m.train() | |
| t0 = time.time() | |
| for s in range(1, steps + 1): | |
| warm = max(1, int(0.05 * steps)) | |
| lr = base * (s / warm) if s < warm else base * (L.PHI / 2) * ( | |
| 1 + math.cos(math.pi * (s - warm) / max(1, steps - warm))) | |
| opt.param_groups[0]["lr"], opt.param_groups[1]["lr"] = lr, lr * 10 | |
| ix = torch.randint(len(tr) - L.BLOCK - 1, (16,), generator=g) | |
| x = torch.stack([tr[i:i + L.BLOCK] for i in ix]).to(L.DEV) | |
| y = torch.stack([tr[i + 1:i + 1 + L.BLOCK] for i in ix]).to(L.DEV) | |
| _, loss = m(x, y) | |
| opt.zero_grad(set_to_none=True) | |
| loss.backward() | |
| torch.nn.utils.clip_grad_norm_(m.parameters(), 1.0) | |
| opt.step() | |
| m.eval() | |
| with torch.no_grad(): | |
| tot = c = 0 | |
| for i in range(0, len(vw), 16): | |
| xb = vw[i:i + 16].to(L.DEV) | |
| _, l = m(xb[:, :-1], xb[:, 1:]) | |
| tot += l.item() * xb.size(0) | |
| c += xb.size(0) | |
| val = tot / max(1, c) | |
| total_steps = int(prev.get("total_steps", 0)) + steps | |
| gates = [round(g_, 5) for g_ in m.gates()] | |
| OUT.mkdir(parents=True, exist_ok=True) | |
| torch.save({"model": m.state_dict(), "optimizer": opt.state_dict(), | |
| "vocab_list": vocab_list, "stoi": stoi, | |
| "itos": {i: c for c, i in stoi.items()}, | |
| "config": {"block": L.BLOCK, "n_layer": L.N_LAYER, "n_head": L.N_HEAD, | |
| "n_embd": L.N_EMBD, "vocab": len(vocab_list), | |
| "d12": L.D12, "d_ff": int(math.floor(L.N_EMBD * L.PHI))}, | |
| "arch": "PHOS-dyn12-phi-QuantumBorn", "rung": RUNG, "ffn": FFN, | |
| "norm": "rmsnorm", "pos": "rope", "gate_param": "logit", | |
| "total_steps": total_steps, "best_val_loss": val, | |
| "corpus_chars": len(text), "quantum_draws": len(pool), | |
| "quantum_source": "ibm_real_shots"}, | |
| CKPT) | |
| prev_val = prev.get("best_val_loss") | |
| delta = f"{val - prev_val:+.5f}" if isinstance(prev_val, (int, float)) else "first" | |
| print(f" step {total_steps:,} val {val:.5f} ({delta}) gates {gates} " | |
| f"corpus {len(text):,} {time.time()-t0:.0f}s") | |
| _record({"event": "burst", "steps": steps, "total_steps": total_steps, | |
| "val": val, "gates": gates, "corpus_chars": len(text), | |
| "vocab": len(vocab_list), "added_symbols": added, | |
| "quantum_draws": len(pool), "born": born, "device": str(L.DEV)}) | |
| return True | |
| def status(): | |
| if not CKPT.exists(): | |
| print(" no PHOS checkpoint yet -- run once to birth her") | |
| return | |
| d = torch.load(CKPT, map_location="cpu", weights_only=False) | |
| text, _ = load_corpus() | |
| print("=" * 74) | |
| print(" PHOS lineage") | |
| print("=" * 74) | |
| print(f" arch {d.get('arch')}") | |
| print(f" total steps {d.get('total_steps'):,}") | |
| print(f" val loss {d.get('best_val_loss'):.5f}") | |
| print(f" vocab {d['config']['vocab']}") | |
| print(f" params {sum(v.numel() for v in d['model'].values()):,}") | |
| print(f" born from {d.get('quantum_draws'):,} quantum draws ({d.get('quantum_source')})") | |
| print(f" corpus at save {d.get('corpus_chars'):,} | now {len(text):,} " | |
| f"(+{len(text)-int(d.get('corpus_chars',0)):,})") | |
| if LINEAGE.exists(): | |
| rows = [json.loads(l) for l in LINEAGE.read_text(encoding="utf-8").splitlines() if l.strip()] | |
| b = [r for r in rows if r.get("event") == "burst"] | |
| print(f" bursts {len(b)} refusals {len(rows)-len(b)}") | |
| for r in b[-5:]: | |
| print(f" {r['t'][:19]} step {r['total_steps']:>7,} val {r['val']:.5f}") | |
| def main(): | |
| args = set(sys.argv[1:]) | |
| if "--status" in args: | |
| status() | |
| return 0 | |
| lk = _lock() | |
| if lk is None: | |
| print(" another PHOS grower holds the checkpoint; exiting") | |
| return 0 | |
| print("=" * 74) | |
| print(" PHOS -- Phi / Omega / Sigma. quantum-born, phi-scaffolded, growing.") | |
| print("=" * 74) | |
| print(f" device {L.DEV} corpus {CORPUS.name} -> {CKPT}") | |
| if "--loop" not in args: | |
| burst() | |
| return 0 | |
| last = 0 | |
| if CKPT.exists(): | |
| last = int(torch.load(CKPT, map_location="cpu", | |
| weights_only=False).get("corpus_chars", 0)) | |
| print(f" watching for +{MIN_NEW:,} new characters, every {INTERVAL}s\n", flush=True) | |
| while True: | |
| try: | |
| now = len(load_corpus()[0]) | |
| if now - last >= MIN_NEW or not CKPT.exists(): | |
| print(f" corpus grew {now-last:+,} -> burst", flush=True) | |
| if burst(): | |
| last = now | |
| time.sleep(INTERVAL) | |
| except KeyboardInterrupt: | |
| break | |
| except Exception as exc: | |
| print(f" burst error ({type(exc).__name__}: {exc}); retrying", flush=True) | |
| time.sleep(INTERVAL) | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |