Views
No views yet

| Property | Value |
|---|---|
| Base model | Qwen3-30B-A3B-Base |
SAE width (d_sae) | 131072 |
Hidden size (d_model) | 2048 |
| Expansion factor | 64× |
| Top-K | 100 |
| Hook point | Residual stream |
| Layers covered | 0 – 47 (48 layers total) |
| File format | PyTorch .pt dict |
layer{n}.sae.pt is a Python dict with four tensors:| Key | Shape | Description |
|---|---|---|
W_enc | (131072, 2048) | Encoder weight matrix |
W_dec | (2048, 131072) | Decoder weight matrix |
b_enc | (131072,) | Encoder bias |
b_dec | (2048,) | Decoder bias |
layer0.sae.pt
layer1.sae.pt
...
layer47.sae.pt1import torch
2from transformers import AutoTokenizer, AutoModelForCausalLM
3
4# ── 1. Load base model ────────────────────────────────────────────────────────
5model_name = "Qwen/Qwen3-30B-A3B-Base"
6tokenizer = AutoTokenizer.from_pretrained(model_name)
7model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float32)
8model.eval()
9
10# ── 2. Load SAE for a target layer ───────────────────────────────────────────
11LAYER = 0 # choose any layer in 0–47
12sae = torch.load(f"layer{LAYER}.sae.pt", map_location="cpu")
13W_enc = sae["W_enc"] # (131072, 2048)
14b_enc = sae["b_enc"] # (131072,)
15
16def get_feature_acts(residual: torch.Tensor) -> torch.Tensor:
17 """residual: (..., 2048) → sparse feature activations (..., 131072)"""
18 pre_acts = residual @ W_enc.T + b_enc
19 topk_vals, topk_idx = pre_acts.topk(100, dim=-1)
20 acts = torch.zeros_like(pre_acts)
21 acts.scatter_(-1, topk_idx, topk_vals)
22 return acts
23
24# ── 3. Hook residual stream after the target transformer layer ────────────────
25captured = {}
26
27def _hook(module, input, output):
28 hidden = output[0] if isinstance(output, tuple) else output
29 captured["residual"] = hidden.detach().cpu()
30
31hook = model.model.layers[LAYER].register_forward_hook(_hook)
32
33# ── 4. Forward pass ───────────────────────────────────────────────────────────
34text = "The capital of France is"
35inputs = tokenizer(text, return_tensors="pt")
36with torch.no_grad():
37 model(**inputs)
38hook.remove()
39
40# ── 5. Extract feature activations ───────────────────────────────────────────
41residual = captured["residual"] # (1, seq_len, 2048)
42feature_acts = get_feature_acts(residual) # (1, seq_len, 131072)
43
44# Inspect active features for the last token
45last_token_acts = feature_acts[0, -1] # (131072,)
46active_idx = last_token_acts.nonzero(as_tuple=True)[0]
47print(f"Active features : {active_idx.tolist()}")
48print(f"Feature values : {last_token_acts[active_idx].tolist()}")app.py. You can run it locally:python app.py \
--model Qwen/Qwen3-30B-A3B-Base \
--model-name-sae-trained-from qwen3-30b-a3b-base \
--model-name-analyzing-now qwen3-30b-a3b \
--sae-path Qwen/SAE-Res-Qwen3-30B-A3B-Base-W128K-L0_100 \
--top-k 100 \
--num-layers 48 \
--sae-width 131072 \
--d-model 2048 \
--server-port 78601@misc{qwen_scope,
2 title={{Qwen-Scope}: Turning Sparse Features into Development Tools for Large Language Models},
3 author={Boyi Deng and Xu Wang and Yaoning Wang and Yu Wan and Yubo Ma and Baosong Yang and Haoran Wei and Jialong Tang and Huan Lin and Ruize Gao and Tianhao Li and Qian Cao and Xuancheng Ren and Xiaodong Deng and An Yang and Fei Huang and Dayiheng Liu and Jingren Zhou},
4 year={2026},
5 eprint={2605.11887},
6 archivePrefix={arXiv},
7 primaryClass={cs.CL},
8 url={https://arxiv.org/abs/2605.11887},
9}