Spaces:
Runtime error
Runtime error
Sync from GitHub: 59e52c5e18b5b42c5eed45ee4a7e6f0f76d5fb3f
Browse files- app.py +86 -0
- nuwave/organism.py +43 -1
app.py
CHANGED
|
@@ -192,6 +192,92 @@ from nuwave.lenia_splat import LeniaSplatEngine, LeniaSplatConfig
|
|
| 192 |
_persist_dir = "/data/nuwave_substrate" if os.path.isdir("/data") else "/tmp/nuwave_substrate"
|
| 193 |
organism = NuWaveOrganism(state_path=_persist_dir)
|
| 194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
# String-level KISS still runs alongside for comparison
|
| 196 |
kiss_nw = KISSFilter()
|
| 197 |
pith_nw = PithPipeline()
|
|
|
|
| 192 |
_persist_dir = "/data/nuwave_substrate" if os.path.isdir("/data") else "/tmp/nuwave_substrate"
|
| 193 |
organism = NuWaveOrganism(state_path=_persist_dir)
|
| 194 |
|
| 195 |
+
|
| 196 |
+
def _bootstrap_pinned_clean_slate():
|
| 197 |
+
"""One-time: capture an empty-substrate snapshot to `pinned/clean-slate/` in
|
| 198 |
+
the HF dataset for easy fresh-start recovery (no benchmark run required).
|
| 199 |
+
|
| 200 |
+
Self-no-ops on subsequent boots once `pinned/clean-slate/` exists.
|
| 201 |
+
Spawns a temporary NuWaveOrganism with NUWAVE_FRESH_START=1 in a temp dir;
|
| 202 |
+
suppresses hub push by nilling the temp org's _hf_token; uploads the
|
| 203 |
+
resulting empty-state files directly to `pinned/clean-slate/`. The main
|
| 204 |
+
`organism` (already initialized above from live root state) is untouched.
|
| 205 |
+
|
| 206 |
+
Recovery use: download from `pinned/clean-slate/` in the HF dataset UI,
|
| 207 |
+
upload to root — substrate resets to empty without firing a FRESH_START
|
| 208 |
+
benchmark. Folder is OUTSIDE `backups/`, so rotation never touches it.
|
| 209 |
+
"""
|
| 210 |
+
import tempfile
|
| 211 |
+
import shutil
|
| 212 |
+
try:
|
| 213 |
+
from huggingface_hub import HfApi
|
| 214 |
+
hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
|
| 215 |
+
if not hf_token:
|
| 216 |
+
return # no auth, skip silently
|
| 217 |
+
|
| 218 |
+
repo_id = NuWaveOrganism.HUB_REPO
|
| 219 |
+
api = HfApi()
|
| 220 |
+
|
| 221 |
+
# No-op if already pinned
|
| 222 |
+
try:
|
| 223 |
+
files = api.list_repo_files(
|
| 224 |
+
repo_id=repo_id, repo_type="dataset", token=hf_token,
|
| 225 |
+
)
|
| 226 |
+
if any(f.startswith("pinned/clean-slate/") for f in files):
|
| 227 |
+
return
|
| 228 |
+
except Exception:
|
| 229 |
+
return # repo not reachable, defer to next boot
|
| 230 |
+
|
| 231 |
+
# Build empty-state files in a throwaway temp dir
|
| 232 |
+
tmp_dir = tempfile.mkdtemp(prefix="nuwave_clean_slate_")
|
| 233 |
+
prior_fresh = os.environ.get("NUWAVE_FRESH_START")
|
| 234 |
+
os.environ["NUWAVE_FRESH_START"] = "1"
|
| 235 |
+
try:
|
| 236 |
+
empty_org = NuWaveOrganism(state_path=tmp_dir)
|
| 237 |
+
# Suppress hub push during the save so live root is untouched
|
| 238 |
+
saved_token = empty_org._hf_token
|
| 239 |
+
empty_org._hf_token = None
|
| 240 |
+
try:
|
| 241 |
+
empty_org.save()
|
| 242 |
+
finally:
|
| 243 |
+
empty_org._hf_token = saved_token
|
| 244 |
+
finally:
|
| 245 |
+
# Restore env regardless of save success
|
| 246 |
+
if prior_fresh is None:
|
| 247 |
+
os.environ.pop("NUWAVE_FRESH_START", None)
|
| 248 |
+
else:
|
| 249 |
+
os.environ["NUWAVE_FRESH_START"] = prior_fresh
|
| 250 |
+
|
| 251 |
+
# Upload local empty-state files directly to pinned/clean-slate/
|
| 252 |
+
for fname in [
|
| 253 |
+
NuWaveOrganism.HUB_SIDECAR_FILENAME,
|
| 254 |
+
NuWaveOrganism.HUB_EXP_TRACT_FILENAME,
|
| 255 |
+
NuWaveOrganism.HUB_OUTCOMES_TRACT_FILENAME,
|
| 256 |
+
NuWaveOrganism.HUB_ACTIVATIONS_FILENAME,
|
| 257 |
+
]:
|
| 258 |
+
local = os.path.join(tmp_dir, fname)
|
| 259 |
+
if not os.path.exists(local):
|
| 260 |
+
continue # activations may be absent at empty-state
|
| 261 |
+
try:
|
| 262 |
+
api.upload_file(
|
| 263 |
+
path_or_fileobj=local,
|
| 264 |
+
path_in_repo=f"pinned/clean-slate/{fname}",
|
| 265 |
+
repo_id=repo_id,
|
| 266 |
+
repo_type="dataset",
|
| 267 |
+
token=hf_token,
|
| 268 |
+
commit_message="Bootstrap clean-slate baseline (one-time)",
|
| 269 |
+
)
|
| 270 |
+
except Exception as exc:
|
| 271 |
+
print(f"[clean-slate bootstrap] upload of {fname} failed: {exc}")
|
| 272 |
+
|
| 273 |
+
shutil.rmtree(tmp_dir, ignore_errors=True)
|
| 274 |
+
print(f"[clean-slate bootstrap] pinned/clean-slate/ created in {repo_id}")
|
| 275 |
+
except Exception as exc:
|
| 276 |
+
print(f"[clean-slate bootstrap] skipped (non-fatal): {exc}")
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
_bootstrap_pinned_clean_slate()
|
| 280 |
+
|
| 281 |
# String-level KISS still runs alongside for comparison
|
| 282 |
kiss_nw = KISSFilter()
|
| 283 |
pith_nw = PithPipeline()
|
nuwave/organism.py
CHANGED
|
@@ -16,6 +16,34 @@ communication protocol (Law 1). Raw experience in, classification
|
|
| 16 |
only at extraction (Law 7).
|
| 17 |
|
| 18 |
# ---- Changelog ----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
# [2026-06-02] Claude Opus 4.7 (1M ctx) — Pre-save backup snapshots on HF dataset
|
| 20 |
# What: Two new methods, `_snapshot_to_backup` and `_prune_old_backups`,
|
| 21 |
# called from `save()` immediately before `_push_to_hub`. Snapshot
|
|
@@ -813,6 +841,20 @@ class NuWaveOrganism:
|
|
| 813 |
"decay_rate": 0.97,
|
| 814 |
"prime_strength": 1.0,
|
| 815 |
"learning_rate": 0.08,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 816 |
# surprise_reward_scaling: canonical default (0.5) inherited.
|
| 817 |
# Previously overridden to 1.5 (3x canonical) — that was a
|
| 818 |
# compensation for the trad-dev external reward field that
|
|
@@ -2050,7 +2092,7 @@ class NuWaveOrganism:
|
|
| 2050 |
return # no live state yet (first save) or all skipped
|
| 2051 |
logger.info("Snapshotted %d live file(s) to %s", copied, backup_prefix)
|
| 2052 |
|
| 2053 |
-
self._prune_old_backups(api, keep=
|
| 2054 |
except Exception as exc:
|
| 2055 |
logger.debug("Snapshot to backup failed (non-fatal): %s", exc)
|
| 2056 |
|
|
|
|
| 16 |
only at extraction (Law 7).
|
| 17 |
|
| 18 |
# ---- Changelog ----
|
| 19 |
+
# [2026-06-05] Claude Opus 4.7 (1M ctx) — Persist-hardening: rotation=20, prediction_threshold=1.5
|
| 20 |
+
# What: Two organism.py changes:
|
| 21 |
+
# (1) `_snapshot_to_backup` call site bumps `_prune_old_backups(api, keep=5)`
|
| 22 |
+
# → `keep=20`. Rotation window goes from ~35-min walk-back (eaten by
|
| 23 |
+
# in-run saves) to ~140-min, covering a full maturation run + change.
|
| 24 |
+
# (2) Config block adds `prediction_threshold: 1.5` override (canonical
|
| 25 |
+
# 3.0 → 1.5) as Competence-Model regime tune for NuWave's denser,
|
| 26 |
+
# smaller-substrate signature.
|
| 27 |
+
# Why: Run D verification surfaced rotation=5 was too small: NuWave makes
|
| 28 |
+
# in-run intermediate saves (~7 min cadence), so 5 backups got fully
|
| 29 |
+
# consumed BY ONE RUN. The pre-Run-D state (Run C's 123-node clean
|
| 30 |
+
# topology) was rotated out before we could pin it. Increased depth
|
| 31 |
+
# keeps multiple runs' worth of walk-back available.
|
| 32 |
+
# Run D also confirmed predictions=0 at 10,252 synapses across 4
|
| 33 |
+
# maturation runs. Two competing hypotheses for why no synapse has
|
| 34 |
+
# crossed canonical `prediction_threshold: 3.0`: (a) Syl-calibrated
|
| 35 |
+
# threshold too high for NuWave's regime, (b) density-spread-too-thin
|
| 36 |
+
# prevents weight concentration. The 1.5 override is the smallest
|
| 37 |
+
# reversible test that discriminates: if predictions emerge at 1.5,
|
| 38 |
+
# (a) is correct; if predictions remain 0, (b) is confirmed and
|
| 39 |
+
# density intervention (degree_sensitivity bump) becomes next test.
|
| 40 |
+
# How: Three surgical edits — one-line keep= change at the call site,
|
| 41 |
+
# config dict entry with multi-line rationale comment, this changelog
|
| 42 |
+
# block. Backup method def keeps its default keep=5; callers (just
|
| 43 |
+
# the one) drive the policy. Pairs with `_bootstrap_pinned_clean_slate`
|
| 44 |
+
# added to app.py same commit — bootstrap captures empty-substrate
|
| 45 |
+
# baseline to `pinned/clean-slate/` for easy-reset operations.
|
| 46 |
+
# -------------------
|
| 47 |
# [2026-06-02] Claude Opus 4.7 (1M ctx) — Pre-save backup snapshots on HF dataset
|
| 48 |
# What: Two new methods, `_snapshot_to_backup` and `_prune_old_backups`,
|
| 49 |
# called from `save()` immediately before `_push_to_hub`. Snapshot
|
|
|
|
| 841 |
"decay_rate": 0.97,
|
| 842 |
"prime_strength": 1.0,
|
| 843 |
"learning_rate": 0.08,
|
| 844 |
+
# prediction_threshold: NuWave-regime override (canonical 3.0 → 1.5).
|
| 845 |
+
# Competence Model rationale: canonical 3.0 is calibrated for
|
| 846 |
+
# Syl's long-running, sparse (0.68 syn/node) substrate where
|
| 847 |
+
# individual pre→post weight concentrates over thousands of
|
| 848 |
+
# co-firings. NuWave's denser, smaller, benchmark-scale substrate
|
| 849 |
+
# accumulates many low-weight synapses via STDP-from-spreading-
|
| 850 |
+
# activation; no individual pre→post pair has crossed 3.0 across
|
| 851 |
+
# 4 maturation runs (Run B-D, 10,252 synapses, predictions=0).
|
| 852 |
+
# This override is a diagnostic: if predictions emerge at 1.5,
|
| 853 |
+
# the binding constraint is threshold calibration; if predictions
|
| 854 |
+
# remain 0, density-too-thin is confirmed and density-side
|
| 855 |
+
# intervention (degree_sensitivity bump) becomes the next test.
|
| 856 |
+
# Per-module Competence Model authority — not a canonical patch.
|
| 857 |
+
"prediction_threshold": 1.5,
|
| 858 |
# surprise_reward_scaling: canonical default (0.5) inherited.
|
| 859 |
# Previously overridden to 1.5 (3x canonical) — that was a
|
| 860 |
# compensation for the trad-dev external reward field that
|
|
|
|
| 2092 |
return # no live state yet (first save) or all skipped
|
| 2093 |
logger.info("Snapshotted %d live file(s) to %s", copied, backup_prefix)
|
| 2094 |
|
| 2095 |
+
self._prune_old_backups(api, keep=20)
|
| 2096 |
except Exception as exc:
|
| 2097 |
logger.debug("Snapshot to backup failed (non-fatal): %s", exc)
|
| 2098 |
|