SAELens 6.54 folds decoder norms as the SAE loads

1 hour ago

SAELens 6.54 adds one argument to its loaders. Pass fold_W_dec_norm equals True, and the SAE comes back with every decoder row scaled to unit length. If you compare activations between features, or try to reproduce values from another tool, this is likely the setting you want.

Ask about this presentation

Chapters

  1. 0:00Fold decoder norms at load time
  2. 0:20Why decoder norms matter
  3. 0:46What folding does
  4. 1:04How to use it
  5. 1:20Every loader takes the flag
  6. 1:46Where folding is not supported
  7. 2:09Upgrading
Show transcript
  1. SAELens 6.54 adds one argument to its loaders. Pass fold_W_dec_norm equals True, and the SAE comes back with every decoder row scaled to unit length. If you compare activations between features, or try to reproduce values from another tool, this is likely the setting you want.

    Slide text
    SAEs banner from the SAELens docs

    SAELens 6.54 folds decoder norms as the SAE loads

    fold_W_dec_norm=True
  2. Most SAEs aren't trained with a unit-norm decoder. When decoder rows have different lengths, a feature's activation size and the length of its decoder direction are tangled together. So activations can't be compared between features, and analyses that assume a unit-norm decoder won't reproduce. It's also a common reason values fail to match Neuronpedia dashboards, which are computed after folding.

    Slide text
    SAE Lens v6.54.0

    Most SAEs ship with decoder rows of different lengths

    So activations can't be compared between features

    row 0
    row 1
    row 2
    row 3
    row 4

    Decoder row lengths, illustration

  3. Folding rescales every decoder row to unit length and moves that length into the encoder weights and biases. It's a reparameterization, so the reconstruction stays the same. What changes is the feature activations. They're rescaled onto a footing you can compare from one feature to the next.

    Slide text
    SAE Lens v6.54.0

    Folding moves each row's length into the encoder

    row 0
    row 1
    row 2
    row 3
    row 4
    →
    Encoder weights and biases
    take on each row's old length
    ✓Reconstruction unchanged
  4. Here's the example from the usage docs, loading a Gemma Scope SAE. The new keyword goes straight into from_pretrained. It gives the same result as loading first and then calling the fold method yourself, which you could already do before this release.

    Slide text
    SAE Lens v6.54.0

    Pass the flag to the loader you already call

    New in 6.54
    sae = SAE.from_pretrained(
        release="gemma-scope-2b-pt-res-canonical",
        sae_id="layer_12/width_16k/canonical",
        fold_W_dec_norm=True,
    )
    Same result as
    sae = SAE.from_pretrained(...)
    sae.fold_W_dec_norm()
  5. The flag works on all three loading paths: from_pretrained, the variant that also returns the config and sparsity, and load_from_disk for SAEs you saved yourself. The fold runs last, after the SAE is on your chosen device and data type. New tests check that folding on load gives the same parameters as loading and then folding, for every foldable architecture loaded from disk, and for a standard SAE through from_pretrained.

    Slide text
    SAE Lens v6.54.0

    All three loaders take the flag

    SAE.from_pretrained
    SAE.from_pretrained_with_cfg_and_sparsity
    SAE.load_from_disk
    Folds last
    after the SAE moves to your device and dtype
    Tested against folding by hand
    same parameters as folding by hand
  6. Folding isn't supported for every architecture, which is why the flag defaults to False. That includes TopK SAEs without the setting that rescales activations by decoder norm, and matching pursuit SAEs. In both, rescaling activations could change which features get selected. Ask for a fold on one of these and you get a NotImplementedError.

    Slide text
    SAE Lens v6.54.0

    Some SAEs can't be folded, so the flag defaults to False

    TopK SAEs
    without rescale_acts_by_decoder_norm
    Matching pursuit SAEs
    rescaling could change which features are selected

    Asking for a fold on these raises NotImplementedError

  7. Upgrading to SAELens 6.54 changes nothing in your existing code, because the flag defaults to False. If you compare activations between features, or check your numbers against Neuronpedia, pass the flag and your SAE loads with its decoder norms folded. Leave it off for TopK SAEs without decoder-norm rescaling, and for matching pursuit SAEs. The full write-up is in the usage docs, under Folding Decoder Norms.

    Slide text
    SAE Lens v6.54.0
    sae-lens 6.54.0

    Nothing changes until you pass the flag.

    Turn it on
    when you compare activations between features or check values against Neuronpedia
    Leave it off
    for TopK SAEs without decoder-norm rescaling, and matching pursuit SAEs

    SAELens docs: Usage › Folding Decoder Norms

What happened in AI today, in your inbox

One short email each evening. Read it and you’re caught up.

Built in New York with ❤️