Qwen3-30B-A3B MoE-Output Sparse Autoencoders

TopK sparse autoencoders (k = 100, 2^20 latents) trained on the MoE block output of Qwen3-30B-A3B at layers 4, 30 and 46, released with the paper Sparse AutoEncoders Reveal That MoE Experts Exhibit Human-Interpretable Fine-Grained Specialization (project page, code, paper).

Files

layer_4/sae.safetensors     layer_4/config.json
layer_30/sae.safetensors    layer_30/config.json
layer_46/sae.safetensors    layer_46/config.json

Each SAE reads the output of model.model.layers[L].mlp (the Qwen3MoeSparseMoeBlock, before the residual addition, layers 0-indexed) as is, without any normalization. sae.safetensors (about 17.2 GB) holds four float32 tensors:

Tensor Shape
W_enc [2048, 1048576]
b_enc [1048576]
W_dec [1048576, 2048], rows have unit norm
b_dec [2048]
f     = TopK_100(ReLU(y @ W_enc + b_enc))
y_hat = f @ W_dec + b_dec

Latent i is column i of W_enc and row i of W_dec; the paper writes it as L-F<i>, e.g. 30-F97783. config.json lists the same settings.

Usage

import torch
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from transformers import AutoModelForCausalLM, AutoTokenizer

LAYER, K = 30, 100
DEVICE = "cuda"  # the SAE takes about 17 GB on top of the model

sae = load_file(
    hf_hub_download("ByteDance-Seed/Qwen3-30B-A3B-MoE-SAE", f"layer_{LAYER}/sae.safetensors"),
    device = DEVICE,
)

def encode(y):
    """y: [..., 2048] raw MoE output. Returns the activations and ids of the top-K latents, [..., K]."""
    pre_acts = y.float() @ sae["W_enc"] + sae["b_enc"]
    return torch.topk(torch.relu(pre_acts), K, dim = -1)

def decode(acts, ids):
    return torch.einsum("...k,...kd->...d", acts, sae["W_dec"][ids]) + sae["b_dec"]

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-30B-A3B", torch_dtype = torch.bfloat16, device_map = "auto")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-30B-A3B")

captured = {}
def hook(module, inputs, output):
    # Qwen3MoeSparseMoeBlock returns (hidden_states, router_logits) in transformers 4.x
    captured["y"] = output[0] if isinstance(output, tuple) else output

handle = model.model.layers[LAYER].mlp.register_forward_hook(hook)
inputs = tokenizer("def binary_search(arr, x):", return_tensors = "pt").to(model.device)
with torch.no_grad():
    model(**inputs)
handle.remove()

y = captured["y"][0].to(DEVICE)   # [seq_len, 2048]
acts, ids = encode(y)             # [seq_len, 100] each
y_hat = decode(acts, ids)         # [seq_len, 2048]

The dense pre-activation takes 4 MiB per token, so encode long inputs in chunks.

Training

Each SAE was trained independently on MoE block outputs collected from the Olmo 3 training corpus: 5/8 Dolma 3 pretraining data, 1/4 Dolci-Think-SFT (reasoning chains of thought) and 1/8 Dolci-Instruct-SFT (instruction following). Training used a TopK activation with k decaying from 1000 to 100 over the first 10,000 steps, an auxiliary loss, AdamW and about 3.2B tokens per SAE; the full recipe is given in the appendix "SAE training details" of the paper.

Evaluation

Fraction of variance unexplained (FVU) of the reconstruction, as reported in the paper:

Layer FVU
4 12.6%
30 25.1%
46 7.6%

License

Apache License 2.0. The base model Qwen3-30B-A3B is released under the Apache License 2.0. The SAEs were trained on activations computed from Dolma 3, Dolci-Think-SFT and Dolci-Instruct-SFT, which Ai2 makes available under the ODC-BY v1.0 license.

Citation

@misc{zhuo2026saeinterpretsmoesparse,
  title         = {SAE Interprets MoE: Sparse AutoEncoders Reveal That MoE Experts Exhibit Human-Interpretable Fine-Grained Specialization},
  author        = {Anyuan Zhuo and Shaohua Zhang and Yuan Lin and Pinyan Lu},
  year          = {2026},
  eprint        = {2611.08089},
  archivePrefix = {arXiv},
  primaryClass  = {cs.LG},
  url           = {https://arxiv.org/abs/2611.08089}
}
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for ByteDance-Seed/Qwen3-30B-A3B-MoE-SAE

Finetuned
(91)
this model

Paper for ByteDance-Seed/Qwen3-30B-A3B-MoE-SAE