146.9M trainable-param bowtie trunk · ~980M frozen cortex experts · exploring integrated information (Φ).
BRIAN is a research prototype that bets on topology, Φ-coupled plasticity, and closed-loop embodiment instead of raw parameter count. The core question: does a strategically-wired 146.9M-param trunk outgeneralize a flat 100M transformer on OOD tasks?
Current verdict: 🟡 inconclusive — best variant B4 achieves 2.87 gap_ratio (53% better than flat-transformer baseline at 6.12), but matched-compute comparison is still pending. The apparatus to run it landed as H59: architectures/control-100m (a param-matched vanilla control arm trained by the same pipeline, data, and recipe) plus eval protocol v2 — trunk-only evaluation on every surface, a held-out train-distribution gap denominator (gap_v2), a PG-19 second OOD axis, and per-sequence NLLs gated by brian ood compare's Welch's-t test.
BRIAN combines five mechanisms into a single differentiable training loop:
| Pillar | What it is | Verified |
|---|---|---|
| 11-stage bowtie + re-entry loops | Two re-entry paths enforce non-zero integrated information Φ | ✅ H1 |
| Differentiable Φ objective | Gaussian-MI MIP pushes gradients toward integrated states | ✅ H2–H3 |
| Sheaf H¹ contradiction detection | Narrative memory detects and resolves conflicting beliefs | ✅ H4–H5 |
| Embodied survival loop | GridWorld 10×10 with homeostatic drive shapes qualia and policy | ✅ H6.5 |
| Multi-cortex fusion | 3 frozen LM experts distil into the bowtie trunk via KL + NT-gated α | ✅ H16–H21 |
Full architecture spec and tensor shapes: docs/architecture.md.
BRIAN currently composes 18 named mechanisms drawn from neuroscience, dynamical systems, and information geometry. Every entry below is:
- a first-class DSL primitive — wires into any
.neuroarch through a single block (nfo: { … },grid_positions: { … }, …); - ReZero-disciplined — a zero-init read-out /
alpha_init=0makes the first forward bit-identical to a vanilla transformer, so additions never regress the baseline at step 0; - hypothesis-backed — every mechanism cites an entry in
hypothesis/with a formal claim, code refs, test refs, and (where available) a Lean theorem.
A Kuramoto graph (binding-by-synchrony) coupled to a Swift–Hohenberg cubic-quintic amplitude flow with Lyapunov neuroslm/modules/neural_field_oscillator.py · lib/blocks/neural_field_oscillator.neuro · docs/NEURAL_FIELD_OSCILLATOR.md
Query/key vectors are mapped into the Poincaré ball neuroslm/modules/hyperbolic_attention.py · docs/features/hyperbolic_attention.md
d_model via a zero-init head, so the first forward is bit-identical to RoPE-only baseline; the dormant code path activates as the projection lifts off zero. Provable length-OOD extrapolation.
Source: neuroslm/modules/grid_positions.py · DSL: grid_positions: { n_scales, scale_ratio, base_period }
Period-$P$ rotational embedding over the music-theoretic Tonnetz lattice — gives a closed cyclic prior under tonnetz_period chord-progression structure. Stacked with standard RoPE.
Source: neuroslm/modules/positional.py · DSL: rope_base, tonnetz_period
A 4096-slot key/value store written either uniformly or surprise-gated (top-quantile of $\mathrm{nll}{\mathrm{local}} - \mathrm{nll}{\mathrm{global}}$). Read at every layer via kNN; neuroslm/modules/episodic_memory.py · DSL: episodic_memory: { slots, k, alpha_init, write_gate }
Applies an MDRV–VBB free-energy at every adjacent layer pair; the deepest (bowtie waist) pair dominates via geometric weight decay neuroslm/modules/predictive_coding_residual.py · docs/features/predictive_coding_residual.md · DSL: mspcc: { base_weight, layer_weight_decay }
A second tied LM head over a neuroslm/modules/surprise_head.py · DSL: surprise_head: { dim, local_window }
Each layer predicts the next layer's activations from its own; only the prediction error propagates as a residual. Implements Rao–Ballard hierarchical predictive coding.
Source: neuroslm/modules/predictive_coding_residual.py · docs/features/predictive_coding_residual.md
A LayerNorm before the tied LM head suppresses GPT-2's rogue dimension (std neuroslm/cortex/multi_cortex_lm_head.py
Unmapped vocab slots get an abstain logit instead of a flat neuroslm/cortex/cortex_lm_head.py
An EMA-smoothed neurotransmitter signal collapses neuroslm/cortex/nt_alpha_gate.py
Gap-ramped: neuroslm/cortex/distillation.py
The VBB neuroslm/gif/adaptive_ramp.py · DSL: vbb_kl_floor_gamma, loss_var_window
Label smoothing magnitude is itself gap-driven — increases as OOD/train diverges, shrinks as they re-align.
Source: neuroslm/gif/label_smoothing.py · DSL: label_smoothing
Penalises pairwise alignment of attention probabilities neuroslm/gif/head_diversity.py
Cosine similarity (with learnable temperature neuroslm/modules/cosine_head.py · DSL: cosine_head: true
Divisive normalisation of layer-wise gradients by the rolling batch-loss variance — keeps SNR constant across the trunk and prevents bowtie-waist collapse.
Source: neuroslm/gif/gradient_equilibrium.py · DSL: divisive_grad_c, loss_var_min_mult
Wraps the VBB posterior on the Poincaré ball of curvature neuroslm/gif/hyperbolic_bowtie.py · DSL: vbb_curvature
Every architecture mutation and DNA patch is gated by a two-sided Welch's neuroslm/verification/improvement_gate.py · tests/verification/test_improvement_gate.py
Differentiable lower bound on integrated information via the Gaussian-MI estimator over the minimum information partition; the bounded neuroslm/iit/phi_mip.py
Narrative memory is encoded as a cellular sheaf SUPERSEDES edge. Belief revision = killing neuroslm/sheaf/contradiction.py · tests/test_narrative_memory.py
A frozen embedding learned during embodied training that survives weight reload — verified across checkpoints (H6). Used as a stable identity vector for self-reference rate and cognitive-closure metrics.
Source: collectors/personality.py
The NFG is generated from arch.neuro → Hypergraph IR → PyTorch. Re-render with:
brian compile nfg --current # → .neuro/nfg.png
brian compile nfg --current --heat heatmap.json # → .neuro/nfg.heat.pngArchitecture is specified declaratively in .neuro files — math-first ODEs and modulation rules that compile to byte-equivalent PyTorch:
export population amygdala {
count: 32,
ode: "dV/dt = (-V + x) / tau",
timescale: 0.005
}
modulation dopamine -> pfc {
effect: "multiplicative", gain: 0.6,
equation: "y = output * (c * gain)"
}
The compiler (neuroslm/compiler/module_bundler.py, ribosome.py) produces modules with source maps and byte-identity round-trip verification. 1305 tests in tests/dsl/ guard codegen correctness.
Full reference: docs/dsl.md.
The .neuro DSLs describe architectures — what tensors flow where. They
deliberately have no persistent state or control flow, so they cannot describe an
ML algorithm: an optimizer update rule, a learning rule, a gradient/flow
modulation. NGL (neuroslm/genetic/) fills that gap. It is a typed
register machine — a scalar bank and a tensor bank, plus instructions drawn
from a registry of total-semantics ops — in which an ML algorithm is a short,
evolvable program. Because state registers persist across steps and the op set
includes a conditional, NGL is Turing-complete in the linear-register-machine
sense: the substrate AutoML-Zero and the Lion optimizer discovery searched.
SGD, Momentum, RMSProp, Adam and Lion are each written as an NGL program and reproduce their PyTorch reference bit-for-bit — proof the language spans the update-rule grammar. On top of that sits a CPU discovery harness that searches the program space with a Pareto GA (mutation + crossover + novelty in the program's semantic-embedding space), scoring each candidate by training a tiny model on a synthetic task:
brian discover optimizer --task parity --generations 20 --out run.json
brian discover flow --generations 12 --out flow.json # + effective-information objectiveThe optimizer search rediscovers-and-tunes scaled gradient descent from a cold start, and — given the adaptive family in reach — selects per-coordinate gradient normalization on a task where plain SGD provably plateaus. This is the machinery behind the neuroscience-inspired-SLM goal: search for the topology and modulation that beat scaling, cheaply on CPU, before spending a GPU.
NGL also compiles an architecture into itself — every mechanic, including
attention. An nn_lang forward graph lowers to an NGL program (composite ops like
linear/rmsnorm/swiglu delegate to nn_ops; scalar-config ops like
attention carry their n_heads/… as instruction config), byte-equivalent to the
compiled module — so a whole TransformerBlock is discovery-, simplification- and
evolution-ready:
brian discover simplify --layer-file block.layer # arch → NGL → shorter equivalent
brian discover trunk --generations 12 --save my_gain # evolve + persist a modulation
brian discover optimizer --novelty 0.3 # hunt NOVEL update rules
brian modulation list # manage modulations/*.neuro
brian modulation merge my_gain other --name combo # compose gains g2(g1(h))The simplifier builds an expression DAG and applies value-preserving algebraic
rewrites to a fixpoint (dead-code elimination, (a+b)−b → a, constant folding,
like-term combination), every rewrite globally probe-verified against
shape-correct random params. The trunk auto-evolve searches an NGL
neuromodulation on the residual stream, scoring candidates by validation
perplexity jointly with a neuroanatomic-realism prior (divisive normalization,
multiplicative gain, homeostatic saturation) — improving language modelling while
staying biologically plausible. Discovered modulations persist as
modulations/*.neuro and can be listed, merged, or thrown away from brian.
The competitor is a GPU outcome. The CPU engine discovers candidate
mechanics, update rules and modulations and proves them on tiny models — but a
param-matched GPT-2 competitor comes only from GPU exploration and extensive GPU
training (brian deploy). --save carries a discovered gain law from the CPU
search to the trunk.
Design: docs/dsl_subsystem_roadmap.md §NGL.
Results: docs/findings.md H31, H32, H33.
Three frozen causal-LM experts sit above the bowtie trunk and fuse logits at the LM head:
| Domain | Expert | Params | Tokenizer bridge |
|---|---|---|---|
| General | smollm2_360m |
~360M | cross-vocab retokenise |
| Code | microsoft/CodeGPT-small-py |
~125M | direct (shared BPE) |
| Reasoning | Qwen/Qwen2.5-0.5B |
~500M | cross-vocab retokenise |
|--------|--------|--------|-----------------|
| General | smollm2_360m | ~360M | cross-vocab retokenise |
| Code | microsoft/CodeGPT-small-py | ~125M | direct (shared BPE) |
| Reasoning | Qwen/Qwen2.5-0.5B | ~500M | cross-vocab retokenise |
Three interlocking mechanisms govern the fusion:
-
cortex_pre_head_norm— LayerNorm before the tied head suppresses GPT-2's rogue dimension (std ≈ 24, 82× median). Without it, CE at step 0 = 21.3 nats (above the uniform-distribution ceiling of 10.82). With it: 10.6 nats. -
Per-position abstain logit (H21) — Unmapped vocab slots are filled with
max(mapped_logits) − ln(V_trunk)instead of a flat−1e4. This single fix dropped standalone-cortex CE from 17.37 → 4.03 nats and unlocked the entire multi-cortex pathway:Metric broken (vast 40923107) fixed (vast 40925851) Δ train PPL @ 2,000 steps 1444 102.9 -93% OOD PPL (WikiText-103-v1) 4655 295.9 -94% α_eff0.000 (collapsed) 0.500 (stable) fusion alive cortex_loss_ema~0.001 ~0.5 fusion alive -
NT-mediated α gating — Once the trunk surpasses the cortex, an EMA inhibitory signal drives
α_eff → 0so cortex experts retire automatically. The reverse also holds: cortex contribution resumes if the trunk regresses.
KL distillation runs in parallel: L_KL = T² · KL(cortex.detach()/T ‖ trunk/T) with a gap-ramped λ that saturates at 1.0 when the trunk lags and shuts off when it leads.
4955 unit tests across tests/ confirm every mechanism computes as specified:
| Hypothesis | Result |
|---|---|
| H1 — Φ > 0 for coupled outputs | ✅ Gaussian-MI MIP verified |
| H2 — Φ gradient is real | ✅ ‖∂L/∂θ‖ increases measurably |
| H3 — BDNF grows high-Φ paths preferentially | ✅ kernel rank expands on hot paths |
| H4 — Sheaf H¹ detects contradictions | ✅ "likes coffee" vs "hates coffee" → SUPERSEDES edge |
| H5 — Causal generalization from narratives | ✅ P(Joy|Gift) > 0.8 from 10 examples |
| H6 — Personality survives weight reload | ✅ identity vector stable across checkpoints |
H16 — cortex_pre_head_norm kills init loss |
✅ CE: 21.3 → 10.6 nats |
H19 — ImprovementGate (Welch's t) |
✅ p-values within 1e-6 of scipy; mutation blocked without significance |
| H21 — Per-position abstain unblocks fusion | ✅ -93% train-PPL / -94% OOD-PPL vs broken precursor |
Run all: py -3 -m pytest tests/ -v (~~10 mins on CPU).
Evaluated on WikiText-103-v1 held-out set. gap_ratio = OOD_ppl / train_ppl (lower is better):
Protocol note (H59, eval v2): rows below predate protocol v2. New runs additionally report gap_v2 = wikitext_ppl / traindist_ppl — both sides produced by the same trunk-only eval code on a held-out slice of the training distribution, so training-side regularisation (flooding, label smoothing) can no longer distort the denominator — plus a PG-19 second OOD axis, and per-sequence NLLs so arm-vs-arm comparisons run through
brian ood compare(Welch's t) instead of eyeballed ppl deltas.
| Variant | Params | Steps | train_ppl | OOD_ppl | gap_ratio | Log |
|---|---|---|---|---|---|---|
| Flat Transformer (Baseline) | 106.9M | 80,000 | 66.0 | 404.0 | 6.12 | - |
| BRIAN B1 (trunk + recursive) | 108.2M | 5,000 | 216.5 | 1372.8 | 6.34 | - |
| BRIAN B2 (trunk + ReZero) | 107.8M | 7,000 | 258.8 | 1351.5 | 5.22 | - |
| BRIAN B3 (PCT trunk) | 69.2M | 4,000 | 400.9 | 1806.6 | 4.51 | - |
| BRIAN (abstain-fix + multi-cortex, B4) | 889.6M | 2,000 | 102.9 | 295.9 | 2.87 | (log not available) |
B4 is the first variant under 3.0 gap_ratio — a 53% improvement over the flat baseline — achieved at 40x fewer steps. Absolute OOD PPL (295.9) still trails the baseline (404.0), but the baseline ran 80,000 steps. Matched-compute comparison is the immediate next experiment.
⚠️ gap_ratio drifts upward within B4 (2.05 → 2.87 from step 500 → 2,000). The 10k follow-up run will distinguish plateau from accelerating overfit. Seedocs/findings.md#H21.
Best Run Overall (OOD / Combined Score):
[`logs/20260616/gpt2/140627_500_10000.log`](logs/20260616/gpt2/140627_500_10000.log)
[mid-ood] step 9500: wikitext ppl=87.0 gap_ratio=4.37 (train_ppl=19.9) (50 seq, 6430 tok)
Most Recent Run (Last Checkpoint):
[`logs/discover/20260709T132733Z_experts.log`](logs/discover/20260709T132733Z_experts.log)
[expert-discovery] round 1/30 Qwen/Qwen2.5-0.5B: best_ce=3.3029 Δ=0.0012 evaluated=1009 (saved expert_qwen2_5_0_5b_step1) [expert:smollm2_360m] round 2: baseline_ce=2.6459 (final: sens=0.04544 improve=-0.002228 (scale_up) tight) [expert-discovery] round 2/30 HuggingFaceTB/SmolLM2-360M: best_ce=2.6455 Δ=0.0004 evaluated=380 (saved expert_smollm2_360m_step2)
python -m venv .venv
# Windows:
.\.venv\Scripts\Activate.ps1
# Linux/Mac:
source .venv/bin/activate
pip install -r requirements.txt
# Install torch separately to match your accelerator:
pip install torch --index-url https://download.pytorch.org/whl/cu121
# CPU sanity run (~~27M params)
brian train --preset=tiny --steps=2000
# A100 full run (~~240M params, bf16)
brian train --preset=xl --steps=100000 --device=cuda
# Resume latest checkpoint
python -m neuroslm.train --resume latest
# Flat transformer ablation at matched params
python -m neuroslm.train --preset xl --baseline
# Interactive generation
python -m neuroslm.generate --prompt "Once upon a time"Full Colab workflow (clone → ablation → training → benchmarks): colab_run.ipynb.
| Preset | Params | Accelerator | VRAM | Notes |
|---|---|---|---|---|
tiny |
~~27M | CPU | — | sanity / CI |
small |
~~93M | CPU | — | local dev |
medium |
~~389M | T4 | 16 GB | |
large |
~~100M | T4 | 15 GB | |
xl |
~~240M | A100 | 40 GB | standard research run |
xxl |
~~10B | 4×A100 | 320 GB |
Add --baseline for a parameter-matched flat transformer ablation.
Single source of truth for the active architecture:
[current]
arch = "architectures/rcc_bowtie" # active architecture
dna = "" # .dna path for evolutionary training
[nfg]
output = ".neuro/nfg.png"
format = "png" # png | svg | pdf | dot
engine = "dot"Override per-run with env vars: BRIAN_ARCH, BRIAN_DNA, BRIAN_NFG_OUTPUT. Contract locked by 27 tests in tests/test_project_config.py.
BRIAN can mutate its own architecture during training. Mutations are gated by ImprovementGate (Welch's t-test) — no structural change lands without statistically significant fitness gain:
from neuroslm.utils import EvolutionaryTrainingContext
with EvolutionaryTrainingContext("dna/base.dna", "checkpoints/") as ctx:
harness = BRIANHarness(ctx.arch_path, resume_from=ctx.resume_step)
for step in range(ctx.resume_step, 10000):
loss = harness.train_step(batch)
if step % 1000 == 0:
harness.checkpoint_mutations() # emits step_XXXXX.patch.dna- RAID-5 protected DNA (triple redundancy)
- Incremental patches only — not full model state
- Hot paths (ρ > 0.7) grow via BDNF; cold paths (ρ < 0.1) prune
- Fault-tolerant: patch stack replayed from any checkpoint
| Term | Source | Weight |
|---|---|---|
lm_loss |
mesolimbic-gain-modulated cross-entropy | 1.0 |
phi_loss |
−tanh(Φ/3)·3 from MIP estimator |
0.02 × maturation |
world_loss |
predicted vs target world embedding (MSE) | 0.3 × maturation |
pred_coding_loss |
per-layer next-layer prediction | 0.1 × maturation |
cortex_kl_loss |
T²·KL(cortex.detach()/T ‖ trunk/T) |
λ_t (gap-ramped, max 1.0) |
| motor, CPC, RSSM, novel aux | embodied + optional modules | 0.05–0.1 × maturation |
topo_loss (H24) |
α·(Q_h − Q*)² + γ·ε_ortho from topo_charge diagnostic |
α, γ (default 0 = diagnostic-only) |
noether_loss (H25) |
λ·(H_final − H_initial)² leapfrog Noether residual |
λ (default 0 = diagnostic-only) |
josephson_loss (H26) |
−(1/L)Σ K̄_h·R_ℓ inter-layer Josephson phase coupling |
λ_J (default 0 = diagnostic-only) |
The maturation gate _aux_w_scale ∈ [0.001, 1.0] suppresses all aux losses until step 5000 (or lm_loss < 7.5), so the LM gradient dominates during early training.
The topo_loss row (Phase 1 of the 3-mechanism THSD program) is enabled in arch.neuro by default as diagnostic-only (α = γ = 0): per-head Berg-Lüscher discrete windings Q_h and inter-layer orientation decorrelation ε_ortho are logged every step but zero is added to the loss. See docs/findings.md H24 + neuroslm/mechanisms/topo_charge.py. Activating the soft penalty (α > 0 or γ > 0) is a follow-up experiment.
The noether_loss row (Phase 2 of the THSD program) is enabled in arch.neuro by default as diagnostic-only (λ = 0): noether_H_diff = |H_final − H_initial| is logged every step but zero is added to the loss. The Liouville symplectic residual block runs one leapfrog step on the final hidden state; det(J) = 1 is guaranteed by the triangular-shear structure of the Stoermer-Verlet integrator. See docs/findings.md H25 + neuroslm/mechanisms/liouville_symplectic.py.
The josephson_loss row (Phase 3 of the THSD program) is enabled in arch.neuro by default as diagnostic-only (λ_J = 0): the Josephson order parameter R_ℓ is logged every step but zero is added to the loss. Each attention head carries a per-(head, layer, token) phase φ with intra-layer Kuramoto sync (η) and inter-layer Josephson coupling (K_h). At zero init all scalars are zero, so step-0 loss is bit-identical to vanilla (torch.equal). See docs/findings.md H26 + neuroslm/mechanisms/kjpla.py.
model.intelligence_metrics.snapshot() # Φ, identity drift, causal density, self-reference rate
model.consciousness_metrics.per_tick() # γ (binding), θ (memory), α (idling), coherence, ignition
model.narrative_stack.query_rules() # discovered causal patterns with support counts
model.personality_vector # tensor(5) — stable across checkpointspy -3 -m pytest tests/ # full suite (4955 tests, ~~10 mins)
py -3 -m pytest tests/test_phi.py -v # H1–H3: integrated information
py -3 -m pytest tests/test_narrative_memory.py -v # H4–H5: memory & causation
py -3 -m pytest tests/test_cognitive_closure.py -v # H6–H6.5: identity & embodiment
py -3 -m pytest tests/training/test_cortex_pre_head_norm.py -v # H16: catastrophic-loss fix
py -3 -m pytest tests/training/test_cortex_distillation_and_gating.py -v # H17–H18: KL + NT gating
py -3 -m pytest tests/verification/test_improvement_gate.py -v # H19: Welch's t admission gate
py -3 -m pytest tests/dsl/ -v # 1305 DSL codegen + byte-equivalencePushed to moritzroessler/BRIAN on HuggingFace Hub every 2000 steps. Configure in architectures/*/config.neuro:
checkpoint {
push_backend: "hf"
hf_repo_id: "moritzroessler/BRIAN"
hf_token_env: "HF_TOKEN"
save_every: 2000
push_every: 2000
push_optimizer: false # strips Adam state, ~2/3 size saving
}
Skip LFS on laptops (recommended):
git lfs install --local --skip-smudge # fetch stubs only
git lfs pull --include="lfs_checkpoints/neuroslm_xl_adamw_mix_800.pt" # pull one when needed| Document | Contents |
|---|---|
docs/findings.md |
Hypothesis ledger H1–H18: test files, result JSONs, raw logs. Source of truth for what's proven vs open. |
docs/architecture.md |
Full spec: 11-stage forward pass, tensor shapes, equations, IIT 4.0 theory. |
docs/formal_framework.md |
Normative math contract: sheaf ontology, H¹ guard, Φ guard, RAID-5 DNA, ImprovementGate spec, Lean roadmap. |
docs/dsl.md |
.neuro syntax, macro system, compile pipeline, module bundling, source maps. |
docs/technical_report.md |
Executive summary: proven claims, open questions, all 7 pillars. |
Open research. Issues, stars, and PRs welcome.