Commit Graph
6 Commits
Author SHA1 Message Date
Omar SobhandClaude Fable 5.1 0f578087ce feat(rtx-interpret): drift-gated decoder renormalisation (SAEConfig::normalize_gate)
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
`normalize_gate: Option<(lo, hi)>` — when set, a decoder column is
rescaled to unit norm only if its norm has left the band; columns
inside are left exactly as the gradient step made them (divisor 1.0).
`None` keeps per-step renormalisation, bit for bit.

Why (omni-cortex D629/D630): per-step rescaling was measured doing
two opposite things on the same 32-unit SAE. With it off, two runs
descended cleanly to floors 3-7x LOWER than with it on — it was
fighting descent. Two other runs (lr 0.01, seeds 7 and 99) diverged
outright without it — it was also the clamp holding an unstable rate
finite, turning a blow-up into a slow oscillation that looked like a
healthy dictionary drifting. The band keeps the second role and drops
the first; D630 measures whether it does both.

The cold-start exemption is applied after the gate, unchanged. Test
pins: in-band columns bit-identical before/after, out-of-band pulled
to unit, gate None == per-step. Fixture norms sit strictly off the
band edge — a hand-scaled 2.0 came out 2.0000002 in f32 and was,
correctly, treated as outside.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-02 20:30:25 -07:00
Omar SobhandClaude Fable 5 328f65233e rtx-interpret: decoder cold-start window for reinitialized SAE units
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
reinitialize_encoder_neuron_cold / SAETrainer::reinitialize_neuron_cold
exempt a freshly reset unit's decoder column from per-step
normalize_decoder for cold_steps training steps, so its small random
init is not blown up to unit norm before it has learned anything —
the mechanism omni-cortex's D605 refutation left as the prime
suspect, now testable (D620 downstream). Runtime-only state, not
carried through checkpoints (documented); cold_steps 0 is exactly
the plain reinit, and existing entry points delegate with 0.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01B1feFAQxjbCRHePUdxuNra
2026-08-30 08:31:08 -05:00
Omar SobhandClaude Fable 5 366a46b471 rtx-interpret: seeded SAE init + coupled per-unit optimizer reset
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
SparseAutoencoder::new_seeded draws encoder/decoder weights via
randn_seeded with per-tensor SplitMix64-derived seeds (same
derivation as MambaBlock::new_seeded), so identical (config, seed)
gives bit-exact SAEs — without it, cross-instance loss comparisons
are noise (measured downstream: 0.09 vs 0.65 starts on identical
data).

SAETrainer::reinitialize_neuron couples the encoder-unit weight
reinit with zeroing that unit's optimizer moment rows (encoder row,
bias slot, decoder column), so external generate-and-test callers
can't reset weights while leaving optimizer state stale — previously
only the trainer's internal dead-neuron resampling did both. Note
train_step's update rule is plain SGD today, so the moment reset is
inert until the Adam path is switched on; the coupling is the
contract either way, and a doctored-checkpoint test pins the
row/column semantics.

Also drops a vacuous assert!(true) smoke test that failed clippy's
assertions_on_constants.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01B1feFAQxjbCRHePUdxuNra
2026-08-28 20:49:11 -05:00
osobhandClaude Opus 4.7 15b62a8f6e rtx-interpret: fix decoder transpose in SAE compute_and_apply_gradients
The encoder-gradient path through the decoder was transposing the decoder
before the matmul, producing `[batch, d_model] × [d_sae, d_model]` — a
shape mismatch for every batch > 1. The decoder is stored as
`[d_model, d_sae]`, so `recon_grad @ decoder` is already the right shape
(and matches the comment at the call site, which reads
"recon_grad @ decoder @ d_relu").

All 9 existing `sae::tests` still pass. Omni-Cortex's `LatentDictionary`
now trains correctly on batches larger than 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-24 13:58:44 -07:00
osobhandClaude Opus 4.6 02d382d5f6 style: apply rustfmt across all crates and demos
Consistent formatting pass: line wrapping, import sorting, trailing
whitespace removal, let-chain indentation, merged derive attributes,
and unsafe block reformatting.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
2026-04-12 07:01:58 -07:00
redclawsystems 4d88dc0584 Initial commit 2026-03-04 00:08:42 +00:00