Downloads · 30 days
0
siddharthmb/2026.TA.gemma2_2b_gemmascope_transcoders_instruct_ft_L0-24-25
2026.TA.gemma2_2b_gemmascope_transcoders_instruct_ft_L0-24-25 is a machine learning model from siddharthmb. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
The setup. GemmaScope transcoders are sparse, interpretable modules that approximate each MLP layer of google/gemma-2-2b: for a layer, transcoder(x) ≈ MLPbase(x) where x is the post-ln2 hidden state, and only a small…
Downloads · 30 days
0
Access
Public
Updated Oct 11, 2026
Repo size
907 MB
Likes
0
Public
Click a slice to open those files.
.safetensors906 MB · 100%
From the Hugging Face model README
The setup. GemmaScope transcoders are sparse, interpretable modules that approximate each MLP layer of google/gemma-2-2b: for a layer, transcoder(x) ≈ MLP_base(x) where x is the post-ln2 hidden state, and only a small number of features fire (low L0 = active features/token). They are the building block circuit-tracer uses to turn a forward pass into an interpretable feature graph. Crucially, they were trained to imitate the base MLP on the base model's hidden states.
The problem this fixes. When you circuit-trace the base↔instruct gap, you feed these transcoders the instruction-tuned model's (google/gemma-2-2b-it) hidden states instead — a distribution shift. We measured that this degrades reconstruction: on instruct hidden states the FVU (fraction of variance unexplained; 0 = perfect, lower is better) is higher than on base hidden states at every layer, worst at the endpoints — layer 0 +33%, layer 24 +32%, layer 25 +104%. In a circuit graph that lost fidelity shows up as larger "error nodes" (computation the graph cannot attribute to interpretable features).
What this artifact is. The three worst-hit transcoders — layers 0, 24, 25 (width_16k, from the average_l0_76-nearest per-layer selection) — re-fine-tuned to keep imitating the base MLP but accurately on the instruct input distribution. Each file is the full transcoder state (W_enc, W_dec, b_enc, b_dec; the JumpReLU threshold is frozen and unchanged), a drop-in replacement for the corresponding pretrained GemmaScope layer.
finetuned_layer_0.safetensors, finetuned_layer_24.safetensors, finetuned_layer_25.safetensorsHow it was trained. Supervised, per layer, starting from the pretrained GemmaScope weights, minimizing MSE(transcoder(x), MLP_base(x)) with x = the instruct model's blocks.L.ln2.hook_normalized, over ~2M instruct-distribution tokens (~14 min, lr 1e-4, JumpReLU threshold frozen). A per-layer decoder-norm-weighted L1 sparsity penalty (l1_coeff = [0, 1e-3, 1e-3] for layers [0, 24, 25]) holds L0 at the base operating point — layer 0 was already at base L0 so it gets no penalty; layers 24/25 overshoot without one.
The result — feature detectors are unchanged; reconstruction and sparsity recover. The fine-tune moved the decoder/biases, not what each feature detects: per-feature cos(W_enc_orig, W_enc_ft) = 0.9997, with zero features below 0.99 — so the feature identities (and their Neuronpedia/collected activation examples) are intact. On 200k held-out instruct tokens, reconstruction improves and sparsity lands on the base target:
| layer | FVU before → after | base-input FVU (target) | L0 before → after (no-penalty → +L1) | base L0 |
|---|---|---|---|---|
| 0 | 0.108 → 0.075 (−31%) | 0.082 | 81 → 81 | 80 |
| 24 | 0.281 → 0.228 (−19%) | 0.21 | 67 → 56.6 | 56 |
| 25 | 0.317 → 0.221 (−30%) | 0.15 | 81 → 68.2 | 65 |
The reconstruction gap the shift opened is mostly closed, and the sparsity overshoot (L24 67, L25 81) is removed — L0 sits on the base operating point at a ~3% FVU cost. In circuit-tracer attribution graphs, this lowers the error-node fraction ~5% on every tested prompt (0.258→0.239, 0.275→0.265, 0.273→0.260) — more of the graph carried by interpretable features.
One-sentence version. Three GemmaScope transcoders re-tuned to still reconstruct the base gemma-2-2b MLP sparsely, but on instruction-tuned hidden states — closing most of the reconstruction gap the distribution shift opened while leaving the features (and their sparsity) intact.
Base-vs-instruct shift (motivation), 26-layer profile:

Reconstruction (FVU) and sparsity (L0) before/after the fine-tune, and the sparsity-penalty comparison (reconstruction-only vs +L1):

These patch onto the pretrained GemmaScope set at load time (layers 0/24/25 replaced). With the transcoder-adapters repo, pass the flag to any GemmaScope-loading tool — it accepts this HF repo id directly:
# Circuit-tracer visualizer (production base attribution / combined overlay + serve):
uv run --extra viz python -m analysis.attribution.graphs.build_graphs --graph_kind overlay \
--base_model google/gemma-2-2b --gemmascope_width width_16k --gemmascope_l0 average_l0_76 \
--finetuned_transcoder_dir siddharthmb/2026.TA.gemma2_2b_gemmascope_transcoders_instruct_ft_L0-24-25 \
--finetuned_layers 0 24 25 ... --serve
# FVU/L0 evaluation:
uv run --extra viz python -m experiments.transcoder_input_shift.scripts.transcoder_input_shift \
--gemmascope_width width_16k --gemmascope_l0 average_l0_76 --sources base instruct --layers 0 24 25 \
--finetuned_transcoder_dir siddharthmb/2026.TA.gemma2_2b_gemmascope_transcoders_instruct_ft_L0-24-25 --finetuned_layers 0 24 25
Or apply directly: load the GemmaScope TranscoderSet, then for each layer copy finetuned_layer_{L}.safetensors's W_enc/W_dec/b_enc/b_dec in place.
# 1) The fine-tune that produced these weights (job 16123724):
uv run --extra viz python -m experiments.transcoder_input_shift.scripts.finetune_transcoder_shift \
--gemmascope_width width_16k --gemmascope_l0 average_l0_76 \
--layers 0 24 25 --l1_coeff 0 1e-3 1e-3 \
--train_tokens 2000000 --eval_tokens 200000 --lr 1e-4 --wandb
# 2) The base-vs-instruct shift measurement (Experiment 1, job 16113808):
uv run --extra viz python -m experiments.transcoder_input_shift.scripts.transcoder_input_shift \
--gemmascope_width width_16k --gemmascope_l0 average_l0_76 --sources base instruct --layers all --max_tokens 500000 --wandb
google/gemma-scope-2b-pt-transcoders (width_16k, per-layer average_l0_76-nearest selection); base model google/gemma-2-2b; instruct-input source google/gemma-2-2b-it.siddharthmb/2026.transcoder-adapters.lmsys-chat-1m-splits (rendered with the -it chat template); the shift was also verified on web = science-of-finetuning/fineweb-1m-sample.siddharth-stanford/transcoder-feature-collection.$LARGE_ARTIFACTS_DIR=/nlp/scr/siddharth):
finetune_report.json: .../transcoder-adapters/transcoder_input_shift_finetune/ft_gemmascope_width_16k_average_l0_76_L0-24-25_20260710_025814_16123724/encoder_drift.json (in that dir, also included here).../transcoder-adapters/transcoder_input_shift/... (jobs 16113538 chat, 16113604 web, 16113808 all-layers).../transcoder-adapters/transcoder_finetune_graphs/L0-24-25_20260710_171004_16129263/logs/finetune_transcoder_shift/*16123724*, logs/transcoder_input_shift/, logs/compare_finetuned_graphs/*16129263*experiments/transcoder_input_shift/writeup.md in the repo.finetune_report.json (before/after eval), encoder_drift.json, summary.md, gemmascope_config.json (the exact per-layer L0 selection).Note on L0 selection. These use the average_l0_76-nearest per-layer selection (this project's convention), which differs from the canonical mntss/gemma-scope-transcoders selection at 18/26 layers — so Neuronpedia feature descriptions keyed to mntss align only where the L0 coincides; the collected activation examples (same selection) align everywhere.