kefirski.me
EMNLPPaper 0620269 min read

Kronecker Factorization Improves Efficiency and Interpretability of Sparse Autoencoders

Factorizing the sparse autoencoder encoder into Kronecker-structured heads with a differentiable AND gate cuts its cost and produces features that compose, with visibly less absorption.

The encoder is the part nobody optimized

A sparse autoencoder rewrites a transformer activation xRd\mathbf{x}\in\mathbb{R}^{d} as a handful of active directions from a large learned dictionary: f=TopK(Wencx+b)\mathbf{f}=\operatorname{TopK}(W_{\mathrm{enc}}\mathbf{x}+\mathbf{b}), then reconstructs x^=Wdecf+bdec\hat{\mathbf{x}}=W_{\mathrm{dec}}\mathbf{f}+\mathbf{b}_{\mathrm{dec}}. Those directions are the currency of mechanistic interpretability: they are what we inspect, name, and steer.

Scaling this recipe is where the trouble starts. With dictionary size FF far above dd, the decoder can exploit sparsity, and fused sparse-dense kernels already make it cheap. The encoder cannot: it multiplies every token by a dense F×dF\times d matrix before TopK has anything to select from, an O(Fd)\mathcal{O}(Fd) cost that dominates training. Gated and Switch variants reroute the computation, but each expert still carries a dense projection inside.

Classical SAEs also give the dictionary no internal structure: feature 4,913 has no designed relationship to feature 4,914, even though real features are heavily correlated. We built KronSAE to attack both problems with one mechanism.

Compose features instead of enumerating them

We split the latent space into hh independent heads. Head kk owns two thin projections: a composition base PkRm×dP^{k}\in\mathbb{R}^{m\times d} and a composition extension QkRn×dQ^{k}\in\mathbb{R}^{n\times d}, with mndm\le n\ll d. Their rectified outputs p=ReLU(Pkx)\mathbf{p}=\operatorname{ReLU}(P^{k}\mathbf{x}) and q=ReLU(Qkx)\mathbf{q}=\operatorname{ReLU}(Q^{k}\mathbf{x}) are pre-latents: raw ingredients rather than finished features.

Every pair of ingredients is then multiplied into a feature, giving an m×nm\times n grid per head, which is exactly an element-wise square root of the Kronecker product pq\sqrt{\mathbf{p}\otimes\mathbf{q}}. The full dictionary has F=hmnF=h\,m\,n entries, but each token only ever touches h(m+n)h(m+n) projection rows, so the encoder cost falls from O(Fd)\mathcal{O}(Fd) to O(h(m+n)d)\mathcal{O}(h(m+n)d). TopK then runs over the concatenated grids as usual, and any sparse decoder kernel plugs in unchanged.

A dictionary as a multiplication table

Encoder mechanism
The dense encoder computes every dictionary entry directly. A KronSAE head computes m + n pre-latents and gets m·n features from their pairwise compositions; here m = 2 and n = 4 turn six rows into eight features.

Encoder cost relative to a dense TopK encoder

% of dense encoder FLOPs
Encoder cost relative to a dense TopK encoder Encoder FLOPs and parameters as a share of the dense baseline at equal dictionary size, computed from our cost formula: the ratio is (m+n)/(m·n). Larger per-head grids buy more savings but couple more features. m=2, n=4: KronSAE 75% m=4, n=4: KronSAE 50% m=4, n=8: KronSAE 37.5% m=8, n=8: KronSAE 25% 0255075100 75%KronSAE: m=2, n=4, 75%m=2, n=450%KronSAE: m=4, n=4, 50%m=4, n=437.5%KronSAE: m=4, n=8, 37.5%m=4, n=825%KronSAE: m=8, n=8, 25%m=8, n=8 % of dense encoder FLOPs
Encoder FLOPs and parameters as a share of the dense baseline at equal dictionary size, computed from our cost formula: the ratio is (m+n)/(m·n). Larger per-head grids buy more savings but couple more features.

A differentiable AND

How the pair (ui,vj)(u_i, v_j) is multiplied matters. We combine pre-latents with an operator we call mAND, a smooth stand-in for a Boolean AND gate:

mAND(ui,vj)={uivj,ui>0 and vj>0,0,otherwise.\operatorname{mAND}(u_i,v_j)=\begin{cases}\sqrt{u_i\,v_j}, & u_i>0 \text{ and } v_j>0,\\[2pt] 0, & \text{otherwise.}\end{cases}

A post-latent can fire only when both of its parents fire, so the set of inputs activating feature zijz_{ij} is exactly the intersection PQ\mathcal{P}\cap\mathcal{Q} of its parents' activation sets. The square root keeps magnitudes tame when both parents are large. In our ablation the gate earns its keep: at a 125M-token budget, mAND beats both the plain product uvu\cdot v and the rectified product on every configuration we tested.

Composition activations at a 125M-token budget

ConfigurationmANDReLU(u)·ReLU(v)u·v
F = 32768, m=2, n=40.83360.82670.8237
F = 32768, m=4, n=80.82200.81910.8143
F = 65536, m=2, n=40.84450.83280.8297
F = 65536, m=4, n=80.83500.82970.8251
Explained variance on Qwen-2.5-1.5B activations. The AND-like gate with the magnitude-preserving square root wins in every configuration; smaller per-head grids with more heads reconstruct best.

Reconstruction holds, absorption drops

We train against TopK, Matryoshka, and Switch baselines on Qwen-2.5-1.5B, Gemma-2-2B, and Pythia-1.4B activations under an iso-FLOPs budget: every KronSAE gets exactly the compute its dense counterpart would burn. Across dictionary sizes, sparsity levels 0{16,,128}\ell_0\in\{16,\dots,128\}, and layers, the factorized encoder matches the baselines' explained variance despite training far fewer parameters, and the gap narrows as dictionaries grow.

Best explained variance by dictionary size, Pythia-1.4B

explained variance
KronSAETopK SAE
Best explained variance by dictionary size, Pythia-1.4B At a fixed 125M-token budget the factorized encoder ties the dense one at 32k features and pulls ahead as the dictionary grows, 0.810 against 0.801 at 131k. The y-axis is zoomed to the competitive range. KronSAE: 32k, 0.793; 65k, 0.805; 131k, 0.810 TopK SAE: 32k, 0.793; 65k, 0.802; 131k, 0.801 0.780.790.80.810.82 32k65k131k KronSAE: 32k, 0.793KronSAE: 65k, 0.805KronSAE: 131k, 0.810TopK SAE: 32k, 0.793TopK SAE: 65k, 0.802TopK SAE: 131k, 0.801 dictionary size explained variance
At a fixed 125M-token budget the factorized encoder ties the dense one at 32k features and pulls ahead as the dictionary grows, 0.810 against 0.801 at 131k. The y-axis is zoomed to the competitive range.

The interpretability side is where the structure pays off most. Feature absorption, where a specific feature like "Lion" swallows a general one like "starts with L", is a known failure mode of flat dictionaries. Because our post-latents fire only when their broader parents fire, a specific feature cannot silently subsume a general one; the hierarchy is architectural, not incidental.

Mean absorption score by sparsity, Pythia-1.4B

mean absorption score
KronSAETopK SAE
Mean absorption score by sparsity, Pythia-1.4B In the sparse regimes where absorption actually bites, the AND hierarchy roughly halves it: 0.244 against 0.445 at 16 active latents. By 128 active latents both architectures are clean. KronSAE: 16, 0.244; 32, 0.129; 64, 0.033; 128, 0.007; 256, 0.003 TopK SAE: 16, 0.445; 32, 0.233; 64, 0.058; 128, 0.006; 256, 0.004 00.130.250.380.5 163264128256 KronSAE: 16, 0.244KronSAE: 32, 0.129KronSAE: 64, 0.033KronSAE: 128, 0.007KronSAE: 256, 0.003TopK SAE: 16, 0.445TopK SAE: 32, 0.233TopK SAE: 64, 0.058TopK SAE: 128, 0.006TopK SAE: 256, 0.004 active latents per token mean absorption score
In the sparse regimes where absorption actually bites, the AND hierarchy roughly halves it: 0.244 against 0.445 at 16 active latents. By 128 active latents both architectures are clean.

The choice of selector matters too: swapping TopK for JumpReLU inside KronSAE degrades explained variance at every sparsity we tried, while KronSAE with TopK edges out the plain TopK SAE, 0.814 against 0.809 at 0=32\ell_0=32. The factorization and the hard selector appear to work as a team.

Inside the heads: AND gates we can read

Because every feature has exactly two parents, we can read the composition mechanism directly. Pre-latents turn out deliberately polysemantic: one base in head 23 mixes "-like" comparatives, spiritual vocabulary, and geographic direction words. Each extension in the head then selects one meaning, and the intersections come out cleaner than either parent, scoring up to 0.93 in our automated interpretability pipeline.

One base, three meanings, three features

Measured example
A real head from Qwen-2.5-1.5B with our pipeline's interpretations and scores. The polysemantic base (score 0.84) resolves into three distinct features once each extension picks out one of its meanings.

The same structure shows up statistically: features inside a head correlate far more with each other than with the rest of the dictionary, and on synthetic data with a planted block covariance, KronSAE recovers the block structure where a TopK SAE mostly loses it, with an RV similarity of 0.30 against 0.12 in the best configuration. Not every interaction is a textbook intersection, though; some compositions produce genuinely new semantics, like an instrument base and a possession extension yielding a therapy feature.

The trade-offs we accept

The design has a dial. Pushing mm down to 1 and the head count up maximizes explained variance but makes pre-latents so overloaded that interpretability slips; our practical recommendation is to start at m=2m=2 and spend the savings on more heads. And because KronSAE simply has fewer trainable parameters, a dense TopK encoder will eventually win once training budgets grow very large; our results target the 125M-to-2B-token regime where most interpretability work actually happens.

What we take away is bigger than the FLOPs ledger. Dictionary entries do not have to be enumerated; they can be composed from reusable parts, with the composition rule chosen so we can read it. Transcoders, crosscoders, and richer gates than AND are the obvious next places to apply the same idea.

An SAE feature does not have to be enumerated; it can be composed, and composition turns out to be cheaper and cleaner at the same time.