kefirski.me
EMNLPPaper 1220257 min read

Train One SAE Across Multiple Sparsity Budgets

One sparse autoencoder trained to reconstruct well at every sparsity budget replaces a shelf of fixed-k models, without losing interpretability or training speed.

Interpretability, priced per sparsity level

A sparse autoencoder turns an opaque residual-stream activation xx into a short list of nameable parts: an encoder scores latents, l=σ(Wencx+benc)\mathbf{l}=\sigma(W_{\mathrm{enc}}x+b_{\mathrm{enc}}), a TopK activation keeps the kk largest, and the reconstruction is a scaled sum of decoder embeddings, x^=itopkliei+bdec\hat{x}=\sum_{i\in\operatorname{top}_k} l_i\,e_i+b_{\mathrm{dec}}. Gao and colleagues made this the standard recipe, and BatchTopK from Bussmann and colleagues enforces the same budget across a batch.

The budget kk is not a knob you can turn later. Train at k=128k=128 and evaluate at 32, and reconstruction quality falls off a cliff; the dictionary was never asked to make its first 32 features stand on their own. So teams keep shelves of models: a sparse one for clean case studies, a dense one for faithful reconstruction, each trained separately.

We measure fidelity as the fraction of unexplained variance, FVU=Var(xx^)/Var(x)\operatorname{FVU}=\operatorname{Var}(x-\hat{x})/\operatorname{Var}(x), and sparsity as the number of active latents 0\ell_0, which for TopK activations equals kk exactly. The question we set out to answer: can one dictionary be honest at every 0\ell_0 at once?

Score every prefix, not just the last

TopK already sorts the surviving latents by activation value, and the standard objective wastes that ordering. We define the prefix reconstruction x^j\hat{x}_j built from only the top jj latents and penalize every prefix at once, Lhier=1JjJxx^j2\mathcal{L}_{\mathrm{hier}}=\tfrac{1}{|\mathcal{J}|}\sum_{j\in\mathcal{J}}\lVert x-\hat{x}_j\rVert^2 with J={1,,K}\mathcal{J}=\{1,\dots,K\}. Under this loss the optimal reconstruction improves monotonically as jj grows, a property the vanilla objective simply does not have.

One loss term per prefix

The objective
Vanilla TopK trains the dictionary to reconstruct only with all K active features. The hierarchical loss also scores the top-1, top-4, and every other prefix, forcing the strongest features to stand on their own.

The extra terms cost almost nothing. All prefixes fall out of one cumulative sum in a single forward pass, and J\mathcal{J} can be thinned: scoring every 8th prefix, {1,8,16,,128}\{1,8,16,\dots,128\}, is indistinguishable from the full set while cutting loss terms eightfold. Only aggressive thinning, every 64th term, starts to hurt below 0=128\ell_0=128.

One dictionary, any budget

We trained a single HierarchicalTopK autoencoder with K=128K=128 on layer-12 outputs of Gemma-2 2B, dictionary size D=65,536D=65{,}536, on a billion FineWeb tokens, against TopK and BatchTopK baselines trained separately at k{32,64,128}k\in\{32,64,128\} and a JumpReLU sweep. Across the whole 0\ell_0 range up to 128, the one model matches or beats the specialists on explained variance: the Pareto frontier belongs to a single set of weights.

A shelf of specialists versus one dial

Deployment
Fixed-k training produces one specialist per budget, each guaranteed only at its own k. One hierarchical dictionary serves the whole range, with the budget chosen after training.

Inference-time interpolation is exactly what fixed-kk training breaks, and our dense 0\ell_0 grid shows it: the baselines degrade away from their trained points while the hierarchical model glides. The one exception flatters nobody's defaults: BatchTopK, which mixes budgets across samples during training, keeps improving into 0[128,512]\ell_0\in[128,512], a range almost never used in practice.

The richer objective is free at step time

Milliseconds per training step, measured

ms per step
Milliseconds per training step, measured Batch 64, hidden size 2,304, dictionary 65,536, 128 active latents. Fusing the reconstruction error into the sparse decoder makes both of our kernels faster than the stock TopK baseline, and the full hierarchical objective adds only 0.13 ms over fused TopK at effectively unchanged peak memory, 6,371 versus 6,370 MB. stock TopK: stock TopK kernel 10.48 fused TopK: fused TopK kernel 9.92 fused Hierarchical: fused Hierarchical kernel 10.05 036912 10.48stock TopK kernel: stock TopK, 10.48stock TopKGao and colleagues9.92fused TopK kernel: fused TopK, 9.92fused TopKours10.05fused Hierarchical kernel: fused Hierarchical, 10.05fused Hierarchicalours ms per step
Batch 64, hidden size 2,304, dictionary 65,536, 128 active latents. Fusing the reconstruction error into the sparse decoder makes both of our kernels faster than the stock TopK baseline, and the full hierarchical objective adds only 0.13 ms over fused TopK at effectively unchanged peak memory, 6,371 versus 6,370 MB.

The obvious objection is speed, so we fused the loss into the sparse-decoder Triton kernel. Our fused vanilla-TopK kernel runs 5.3 percent faster than the stock implementation from Gao and colleagues, and the full hierarchical objective still comes in 4.1 percent faster, 10.05 milliseconds per step against 10.48. Training across every budget costs, in wall-clock terms, nothing.

Why fixed-k dictionaries rot when you turn the dial

The failure has a mechanism. Call a feature almost dead when it fires less than once per 10510^5 tokens. Evaluate a k=128k=128 TopK or BatchTopK model at smaller budgets and almost-dead features multiply quickly; the hierarchical model keeps far more of its dictionary alive, because its strongest features were trained to carry reconstructions alone.

The dictionary's internal ordering tells the same story. In a well-behaved reconstruction, the cosine similarity between successively added decoder embeddings should fall as rank increases; vanilla TopK shows the opposite trend, while ours decreases monotonically. Swapping the activation rule at inference barely moves us either: a plain TopK autoencoder loses explained variance from 0.8577 to 0.8511 under a JumpReLU threshold, and the hierarchical model is virtually unchanged.

Interpretability survives the dial too. On the SAE Bench detection score, our model at 0=128\ell_0=128 stays nearly as interpretable as itself at 0=32\ell_0=32, while separately trained TopK and BatchTopK models become measurably less interpretable as they get denser. Density usually taxes interpretability; the hierarchical ordering pays that tax once, at training time.

What we have not shown

Our evidence lives on one model and one corpus, Gemma-2 2B and a FineWeb subsample, and our interpretability numbers are automated proxies rather than human studies. Nested dictionaries have relatives, Matryoshka-style autoencoders among them; ours differs by scoring every prefix inside a single objective. The claim we stand behind is operational: rank the features once, score every prefix, and stop retraining a new dictionary for every sparsity budget.

Rank the latents once and score every prefix; one autoencoder then serves every sparsity budget you will actually use.