SPIRA / python /README.md
thefinalboss's picture
SPIRA v3: cortex representation repair β€” direct input pathway, multi-timescale trace banks, structured trigram inputs; controlled A/B (SNN alone 0.40% -> 2.07% in-vocab held-out vs bigram 4.94% at matched vocab 4096); paper, README and docs updated to third iteration
6923c51 verified
|
Raw History Blame Contribute Delete
11.6 kB

SPIRA β€” Spiking Plastic Recurrent Architecture

A CPU-only sequence-learning system outside the transformer/BPE/backpropagation paradigm, built from three components:

Component What it replaces
EPT β€” Entropy-Patch Tokenization BPE / WordPiece / SentencePiece
Hierarchical spiking cortex β€” LIF reservoir + slow area, reward-modulated plasticity Transformer + backprop
Hippocampus β€” one-shot associative memory + replay consolidation Fine-tuning / gradient learning

This is v2 of the prototype: a 16,384-column readout (chosen from a measured coverage curve), a two-timescale hierarchical cortex (fast 512-neuron reservoir + slow 256-neuron area reading the pooled spike volley every 8 tokens), and hippocampal replay that consolidates one-shot memories into cortical weights.

Headline results (2 vCPU, 4 GB RAM, 13.2 MB mixed text+code corpus)

Proof Result
One-shot learning 99.3% exact recall after a single 0.4 s pass over an unseen book
Systems consolidation (v2) cortex-only recall of that book 0.3% β†’ 46.9% (64.2% in-vocab, 138Γ—) after replaying 100k hippocampal tokens β€” the AM itself stays at 99.3%
Pattern completion 99.0% recall with 1 of 4 context patches corrupted (sparse AM); 52.3% in the deployed full AM (46% load)
Replay interference none β€” held-out test accuracy improves slightly after replay (0.34% β†’ 0.75% cortex-only)
Zero-shot coverage 6.3% patch novelty on held-out text+code; the 16k readout covers 64% of held-out targets (v1: 38% at 4k)
Efficiency β‰ˆ9.2 M synaptic MACs/token β€” β‰ˆ81Γ— fewer ops/token than GPT-2-small training (v1 at 4k vocab: 2.4 M, 314Γ—)
Generation β‰ˆ2,000 chars/s closed-loop on 2 vCPU, in-browser at ~450-700 chars/s
One-shot write rate 1,199,996 associations in 18 s, with an exact checkpoint round-trip

Honest negative results (reported in the paper): the cortex does not amortize generalization to unseen documents (test in-vocab 0.49% vs a bigram's 7.7%), and the slow area's token-level fusion self-discounts to Ξ²β‰ˆ0.06 at this scale β€” its value is as a second consolidation substrate during replay. See ../paper/spira_paper.pdf, Sections 7–8.

What's new in v3 (cortex representation repair)

Diagnosis probes on the shipped v2 checkpoint showed the held-out weakness was representational: the readout state carried β‰ˆ1 token of memory (current patch decodable at 99.94%, previous patch at 39.7% vs 33.0% majority chance), and an offline ridge readout on the same states scored 0.36% β€” worse than the online delta readout (0.51%). v3 changes the readout's input, not its learning rule:

  • Direct input pathway (direct_input=True, direct_tau=0.5): a decaying trace of the exact input-neuron pattern is concatenated to the readout state, so the delta rule sees the recent input identities directly.
  • Multi-timescale trace banks (trace_taus=(0.4, 0.8, 0.95)): the reservoir keeps one spike-trace bank per Ο„; slow banks are normalized by (1 βˆ’ Ο„) so the Ο„=0.95 bank does not swamp the fast one. With the direct pathway, the readout state is n_state = 512 Γ— 3 + 1024 = 2560 (v2: 512), and W_out is (2560, V+1).
  • Structured inputs (structured_inputs=True, k_tri=6): each patch activates 6 full-hash input neurons plus 6 byte-trigram hash neurons, so patches sharing byte trigrams share input neurons.
  • Compatibility mode: direct_input=False, trace_taus=(0.4,), structured_inputs=False reproduces the v2 architecture exactly (n_state = 512); v3 checkpoints record the new fields and restore them on SPIRA.load().
  • Bug fix: v2's model.train() referenced an undefined ok_mask (NameError) β€” training only ever ran through scripts/train_chunk.py. Fixed in v3; SPIRA.train() now runs standalone.

Controlled A/B (same protocol both arms β€” rebuilt corpus, vocab 4096, 200k tokens Γ— 2 epochs, AM 50k contexts, held-out test 20k positions, coverage 45.24%): SNN alone, in-vocab β€” 0.40% (v2) β†’ 2.07% (v3), patch bigram @4096 on the same positions 4.94%. The beat-the-bigram criterion is not met (gap Γ—12.4 β†’ Γ—2.4); trained region 3.76% β†’ 13.29%. Training costs 189 t/s vs ~530 t/s and the checkpoint grows 14.6 MB β†’ 45.9 MB. See ../V3_REPORT.md and artifacts/metrics_v3_ab.json.

Repository layout

spira/                  Python package (NumPy only, CPU-only)
  hashing.py            FNV-1a-64, splitmix64, mulberry32 β€” bit-compatible with the TS port
  ept.py                entropy-patch tokenizer (order-1 Markov surprisal, content addressing)
  spiking.py            LIF reservoir + Dale's law + homeostatic thresholds,
                        Rescorla-Wagner readout gated by dopaminergic RPE,
                        reward-modulated recurrent STDP, and the hierarchical
                        slow area G (windowed spike volleys, top-down prior,
                        counterfactual trust gain beta); v3: multi-timescale
                        trace banks + direct input pathway to the readout
  hippocampus.py        one-shot memory: primary full-key hash (pattern separation)
                        + leave-one-out lanes (CA3 pattern completion), exact
                        derivable-slot checkpoint round-trip
  model.py              SPIRA wrapper: build / train / generate / teach / replay /
                        calibrate_fusion / eval / save-load; v3 config:
                        direct_input, trace_taus, direct_tau, structured_inputs,
                        k_tri (defaults reproduce v3; flags off = v2 architecture)
  baselines.py          gzip, byte-level BPE (HuggingFace tokenizers), sparse
                        n-gram predictors
  train.py              training CLI
  evaluate.py           full evaluation harness (coverage curve, compression,
                        prediction + hierarchy ablation, one-shot, REPLAY
                        consolidation experiment, correction, generation) β€”
                        resumable by section
  export_deploy.py      JSON artifact export for the browser demo (format v2)
artifacts/              trained checkpoint, metrics.json, deploy artifact,
                        figures, browser-demo screenshots
paper/                  LaTeX source + compiled research paper (spira_paper.pdf)

Quick start

# build the corpus (Gutenberg books + Python stdlib code)
python3 scripts/build_corpus.py

# chunked training (background processes are killed between calls in sandboxes;
# each chunk fits a single tool/shell call). v2 defaults: vocab 16384, hierarchy on.
python3 scripts/train_chunk.py --start 0      --count 150000            # chunk 1 (fresh build)
python3 scripts/train_chunk.py --start 150000 --count 150000            # ... continue to 600k
python3 scripts/train_chunk.py --start 0      --count 150000            # epoch 2
python3 scripts/train_chunk.py --start 450000 --count 150000 --raster   # epoch 2 end + raster
python3 scripts/train_chunk.py --am-only                               # hippocampal write pass (1.2M)
python3 scripts/train_chunk.py --start 450000 --warmup 150000           # re-adapt operating point

# full evaluation (resumable: completed sections are skipped on re-run)
python3 -m spira.evaluate --model artifacts/spira_model.npz \
    --train data/train.bin --test data/test.bin \
    --oneshot data/oneshot.bin --out artifacts/metrics.json

# hippocampal replay -> cortical consolidation (in a few lines)
python3 - << 'EOF'
import sys; sys.path.insert(0, ".")
from spira import SPIRA
m = SPIRA.load("artifacts/spira_model.npz")
print(m.teach_bytes(open("data/oneshot.bin", "rb").read()[:60000]))
print("before replay:", m.eval_stream(open("data/oneshot.bin","rb").read()[:60000], use_am=False, max_positions=4000)["hier_acc"])
print(m.replay(100000))   # the "sleep" pass
print("after replay:", m.eval_stream(open("data/oneshot.bin","rb").read()[:60000], use_am=False, max_positions=4000)["hier_acc"])
EOF

# export the browser-demo artifact (format v2, includes the slow area)
python3 -m spira.export_deploy --model artifacts/spira_model.npz \
    --out artifacts/spira_deploy.json --am-cap 100000 --am-min-count 1

Design notes (the interesting parts)

  • Constant-information tokens. Each EPT patch carries β‰ˆ15.9 bits of accumulated surprisal; low-entropy text yields long patches, high-entropy text short ones. Patch identity is the FNV-1a-64 hash of the bytes β€” the same substring is always the same token, anywhere, with zero vocabulary learning.
  • The readout rule is local. Readout units apply a Widrow–Hoff / Rescorla–Wagner delta rule on their own activity, gated by dopamine d = r βˆ’ baseline(r). No gradients, no chain rule, no autodiff.
  • Mean-centering the spike trace matters. The raw trace carries a dense shared background that otherwise makes every column's score correlate with frequency; subtracting a slow EMA of the trace (homeostatic scaling) is what makes per-context learning converge.
  • Learned state includes the operating point. Homeostatic thresholds, the trace mean, the slow area's homeostatic scalars, the top-down gain Ξ², and STDP-shaped recurrent weights must be checkpointed together β€” omitting any of them (or resetting Ξ² to its init) silently destroys the readout's regime.
  • The hierarchy must be variance-matched and counterfactually credited. The slow readout's raw scores live at ~20Γ— the fast one's scale; fusing raw scores lets a tiny gain swamp the fast argmax, so the prior is rescaled by Οƒ_fast/Οƒ_slow (measured once, like the EPT budget). And a gain rule that rewards the slow area for ranking frequent truths high degenerates into a frequency prior β€” only saved-vs-corrupted counterfactual attribution calibrates Ξ² honestly (it self-discounts to β‰ˆ0.06 at this scale).
  • Hippocampal replay closes the complementary-systems loop. Teaching retains the episodic token trace; replay re-runs random 512-token slices through the cortex in full training mode, so one-shot material becomes slow cortical weight while the hippocampus stays intact (0.3% β†’ 46.9% cortex-only recall, zero interference β€” held-out accuracy actually improves slightly).
  • Associative-memory checkpoints are easy to get subtly wrong. Entries must be packed and restored at their derivable slots (primary + leave-one-out hashes); an early format that rebuilt entries at lane-value addresses made the reloaded corpus memory invisible to queries β€” and inflated v1's corruption-robustness number, which had been measured against an accidentally-empty hippocampus.
  • Hybrid hippocampal addressing. A primary full-key hash gives every distinct context its own slot (capacity); leave-one-out key hashes let a query with one corrupted lane still reach the entry (completion). Completion strength trades against table load (99% at 0.8% load vs 52% at 46% load); two corrupted lanes is an explicit architectural cliff.
  • The TS port is compatible. web/src/lib/spira/ regenerates the reservoir from the same seeded PRNG (mulberry32), shares the exact hashing spec, ports the slow area (stepG + variance-matched fusion), and loads the same deploy artifact, so browser inference matches the Python prototype. (Replay is Python-only.)

Citation

See ../paper/spira_paper.pdf β€” SPIRA: Sequence Learning Without Backpropagation or GPU Clusters, preprint, October 2026 (third iteration).