Skip to the content.

Cross-model findings — what the catalog has (and hasn’t) shown

A curated, descriptive reading of the catalog’s cross-model results — natural history across six transformer models (GPT-2 small/medium/large, Gemma-2-2B, Llama-3.2-1B, Qwen2.5-1.5B), a non-attention control (Mamba), and a controlled scale ladder (the GPT-NeoX Pythia family, 14m–1.4b — one architecture, same data, six sizes — used for the scaling laws). Amateur, provisional, single-corpus where noted; every claim links to the page with the data. The headline is not “here is the mechanism” but “here is what is invariant, what scales, where the outliers are, and what we learned not to trust.”

What looks invariant

What scales — within a family, not just across architectures

The sharpest lesson of the cross-model pass: several things people attribute to architecture (absolute-position vs RoPE) actually track scale.

The flagship — composition doesn’t factor through SAE features (the forge tax, from the decompilation side)

The program’s throughline: a language model is legible in the right basis even where it is not legible as single SAE features — and the unifying claim that the decompilation ceiling is the forge tax (composition doesn’t factor through the features for the same reason cov95 collapses under forging). We test it directly on real LMs (sae_forge_tax.py, on the ResidualVM + loaded SAEs): force the residual through the SAE feature basis (decode∘encode = the forge bottleneck) at a layer, and compare the damage to the composition (induction-NLL — the in-context copy that needs prev-token → induction composition) against the readout (generic next-token NLL — what the SAE features are trained to carry), each relative to its own clean baseline.

What IS the entangled core — a compact grammar head on a content bulk

Having localized the core as a shared moderate-rank subspace (DECOMPILATION.md, core_rank.py), we decompiled its structure (core_basis_decompile.py + core_grammar.py, GPT-2 s/m/l):

Knowledge — where facts live, and moving them

The catalog is about mechanisms; the knowledge axis is the decompiler goal (“the model IS the database”).

The outliers — where the next questions are

Is the computation an isolable circuit? (mostly no — it’s distributed)

The catalog names which heads are necessary. Executable decompilation tests sufficiency — keep only a circuit’s heads, ablate the rest, see how much behaviour survives.

The through-line: the named circuits are causally necessary and the dominant drivers, but the behaviour is carried by the near-whole network — a clean decompilation into a tiny sufficient subgraph does not exist here. (The reconstruction-coverage numbers are seed-stable, ±0–1% over three probe-resample seeds, so the scaling/distributedness trend is not a single-seed artifact.)

When a circuit “distributes,” what is it becoming — a weighted ensemble, or heterogeneous circuits woven in?

The cross-model dossier shows the induction circuit’s necessity and sufficiency decay with GPT-2 scale. “Distributed” could mean three different things, so we measured the full induction-head population (not just the top heads) on two axes (circuit_ensemble.py, on the ResidualVM): a functional axis (do the heads help the same token-predictions?) and a structural axis that is free of the ablation-gentleness confound — the pairwise cosine of the heads’ OV operation-matrices (do they do the same thing, weight-wise?) and the population’s spread across depth.

Verdict. Of the user’s two framings — “weighted ensemble?” vs “heterogeneous circuits with overlapping function woven in?” — the data favors the second and rejects the first: as a circuit distributes it recruits structurally different heads spread across depth, not duplicates of itself.

Separable parallel circuits or one decomposition? — it splits by architecture family

“Structurally different heads woven in” is consistent with either several complete parallel circuits (each fed by its own upstream predecessor-writer) or one circuit decomposed behind a shared front-end. The discriminator is each induction reader’s upstream writer-dependency: we ran the faithful key-only patch (circuit_writer_cluster.py, on the circuit_content_patch machinery; every zero-patch sanity = 0.0) over the whole induction population, then clustered the readers by which upstream head, removed from their key, collapses their induction attention. Shared writers → one decomposition; distinct writers → separable circuits.

Net. As an induction circuit “distributes,” it is not becoming a weighted ensemble of duplicates (OV-operation cosine ≈0). In the absolute-position family it weaves in genuinely separable sub-circuits (distinct upstream writers, fragmenting with scale); in the RoPE family it decomposes one circuit behind a shared early-writer front-end. The “more distributed with scale” headline is two different mechanisms underneath, split by the same absolute-vs-RoPE line that separates the positional register everywhere else in the catalog.

Does the population scale with INPUT size? — yes, a separate axis from model size (“same function, more inputs”)

A distinct hypothesis for why induction distributes: not (only) more parameters, but the same function applied over a larger input domain — more distinct token-types to induct over → more heads recruited, each covering a slice. We test it by holding the model fixed and scaling the input (circuit_input_scaling.py, confound-free — one forward pass, induction attention mass per head, no ablation):

But the recruited heads do not cleanly tile the input by an interpretable property (a null result). The natural follow-up — if more inputs recruit more heads, does each head own a slice of the input? — we tested directly (circuit_domain_tiling.py): for every induction position take the head that dominates its induction attention, then ask whether the dominant head is predicted by the matched token’s frequency (η² vs a label-permutation null) or whether heads own disjoint token sets (Jaccard). At a 256-type vocabulary, frequency-specialization is not significant in any of 5 models (η² ≈ its permutation null, z ≈ 0–1 — the weak gpt2 signal at a smaller vocabulary did not replicate). The low token-set Jaccard (0.04–0.06) looks like a partition but lacks a null and is confounded by the very distributedness above: with the top head holding only 1–8% of the induction attention, “which head owns this position” is a noisy label, so no clean specialist→input-slice map exists to find. So “same function over more inputs” recruits heads but they are a redundant distributed population, not crisp domain specialists carving the input along token frequency — consistent with the low functional-overlap / no-duplicates picture above. (runs/disassembly/circuits/domain_tiling_summary.json.)

Synthesis across the four tests. A distributing induction circuit is (1) not a weighted ensemble of duplicates (OV-cosine ≈0), (2) made of structurally heterogeneous heads — separable parallel sub-circuits in the absolute-position family, one shared-front-end decomposition in the RoPE family — (3) its head-count is driven by input-domain breadth as a first-class axis alongside model size, but (4) the recruited heads do not crisply specialize by an interpretable input property (token frequency): the recruitment grows a redundant distributed population, not a clean input→head tiling. Gemma is the exception to (2)’s and (3)’s regularities, as it is to most.

Does RoPE’s shared early-writer front-end make induction fragile to post-training?

If RoPE hangs most of its induction population off one shared early predecessor-writer (Llama L0 head 0.2 feeds 88% of readers), is that a single point of failure post-training could break — or is the early node protected because fine-tuning adjusts late layers more? We measured both on three base→instruct pairs of the same model (posttrain_drift.py): per-layer weight drift vs depth (lazy safetensors reads) + induction survival (induction-NLL and the prev-token writer head, base vs instruct).

Verdict. RoPE’s shared early-writer front-end is exposed (not depth-protected) but robust — under realistic post-training the predecessor-writer head persists (or, in Gemma, reorganizes to an even-earlier one while induction improves), the direct GPT-2 comparison shows no extra fragility from the concentration (GPT-2’s distributed induction degrades at least as much under a heavier fine-tune, writer head surviving in both), and the writer-dependency structure is consolidated, not broken, by post-training. The single-point-of-failure worry isn’t borne out; the failure mode that appears is graded performance degradation proportional to fine-tuning intensity, not structural breakage of the shared early node.

Methodological cautions — banked from the digs

The positional register is absolute-position-family-specific

Three independent signatures separate the GPT-2 (learned absolute position) family from the RoPE family: the attention-sink, the positional-broadcast circuit (early write-hubs → prev-token key, circuit catalog), and the larger decompilable fraction. RoPE reads relative position from the rotation, so it has no positional-broadcast plumbing to remove.

Beyond attention — Mamba (SSM) across the themes

Mamba has no attention heads and no per-layer MLP — just a residual stream of SSM mixer blocks — so the attention-based catalog (heads, K/Q/V composition, name-movers) has no analog. But the arch-generic themes run on it via a Mamba-specific harness (mamba_themes.py, the Mamba ladder 130m/370m/790m), and the result splits cleanly into what is attention-specific and what is architecture-invariant:

The through-line. What is attention-specific is the mechanism’s localization — head-circuits, the positional register, name-movers — none of which survive into the SSM (induction goes layer-distributed). What is architecture-invariant is the knowledge-storage character — a complete, queryable table whose read-out site shrinks with scale, stored as an editable but entity-leaky residual. “The model IS the database” is a property of the residual-stream LM, not of attention; the circuits that fill the database are what the mixer choice decides.

SAE recoverability — detection is cheap, allocation is a competition (not variance-greedy)

A cross-substrate test (econ-sae macro-regime, bio-sae ESM-2, and here on GPT-2) of when an unsupervised SAE recovers a known feature. For every exact-lexical ground-truth feature on GPT-2 layer-8 residuals we measure two cheap SAE-free predictors and two expensive measurements: Fisher SNR Δμᵀ(Σ_w+λI)⁻¹Δμ (detection theory) and variance-share p(1−p)‖Δμ‖²/trΣ (rate–distortion) against a linear-probe AUC (presence) and the SAELens 24 576-feature dictionary’s best-latent recovery AUC (allocation). Reproduce: scripts/recoverability_theory.py (summary in runs/substrate/recoverability_theory_summary.json); synthesis in the workspace SUPERVISION_DEPENDENCE.md.

The through-line. Rate-distortion governs reconstruction (variance captured); SAE interpretability needs monosemantic allocation (one latent per feature). They diverge for rare meaning (no co-firing mass for a latent) and diffuse meaning (split across latents) — exactly the dropped set. The robust law is two-axis: detection is cheap and near-universal; unsupervised recovery is a competition for latents won by distinctiveness and statistical mass, not by variance-share. “Compression is variance-greedy” holds only where Fisher is held roughly constant.


This page is a hand-curated narrative; the numbers live in the generated operator / circuit / MLP catalogs, the extended-embedding test, and the outlier digs, each regenerable from committed JSON. See DISASSEMBLY.md for the original GPT-2 method deep-dive.