sparse-autoencoder-training について
sparse-autoencoder-trainingは、メカニスティック解釈可能性の研究者向けのSAELensスキルです。スパースオートエンコーダーを学習・分析し、モデルの活性化から解釈可能な特徴を分解します。特徴の帰属分析や特徴ベースのステアリングにも対応します。
主な機能
- 01事前学習済みSAEの読み込み
- 02カスタムSAEの学習
- 03スパース特徴と活性化の分析
- 04再構成とスパース性の評価
- 05特徴帰属とステアリング
- 06Standard、Gated、TopKアーキテクチャ
活用シーン
- 01モデル活性化から解釈可能な特徴を発見
- 02モデルが学習した概念を研究
- 03安全性に関わる特徴を分析
- 04特徴を使ってモデルをステアリング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ orchestra-research/ ai-research-skills --skill sparse-autoencoder-trainingインストール後、Claude Code で/sparse-autoencoder-trainingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api.mdREADME.mdtutorials.md詳細
SAELens: 機械的解釈可能性のためのスパースオートエンコーダー
SAELens は、スパースオートエンコーダー(SAE)の学習と分析のための主要なライブラリです。SAE は、多義的なニューラルネットワークの活性化を、スパースで解釈可能な特徴に分解する手法です。Anthropic の画期的な単義性(monosemanticity)研究に基づいています。
GitHub: jbloomAus/SAELens(1,100+ スター)
問題:多義性と重ね合わせ
ニューラルネットワークの個々のニューロンは 多義的 です。つまり、意味的に異なる複数の文脈で活性化します。これは、モデルが 重ね合わせ(superposition) を使って、ニューロン数より多くの特徴を表現しているために起こり、解釈を難しくしています。
SAE はこの問題を解決します。高密度な活性化を、スパースで単義的な特徴に分解します。通常、任意の入力に対して活性化する特徴はごく少数であり、各特徴は解釈可能な概念に対応します。
SAELens を使うべき場面
次のような場合に SAELens を使用してください:
- モデルの活性化の中から解釈可能な特徴を発見したい
- モデルが何の概念を学習したのかを理解したい
- 重ね合わせと特徴の幾何構造を研究したい
- 特徴ベースのステアリングやアブレーションを行いたい
- 安全性に関連する特徴(欺瞞、バイアス、有害なコンテンツ)を分析したい
次のような場合は代替手段を検討してください:
- 基本的な活性化分析が必要 → TransformerLens を直接使用
- 因果的な介入実験を行いたい → pyvene または TransformerLens を使用
- 本番環境でのステアリングが必要 → 直接的な活性化エンジニアリングを検討
インストール
pip install sae-lens
要件:Python 3.10+、transformer-lens>=2.0.0
中核的な概念
SAE が学習するもの
SAE は、スパースなボトルネックを通じてモデルの活性化を再構成するように学習されます:
Input Activation → Encoder → Sparse Features → Decoder → Reconstructed Activation
(d_model) ↓ (d_sae >> d_model) ↓ (d_model)
sparsity reconstruction
penalty loss
損失関数:MSE(original, reconstructed) + L1_coefficient × L1(features)
主要な検証(Anthropic の研究)
「Towards Monosemanticity」では、人間の評価者が SAE の特徴の 70% が本当に解釈可能である と判定しました。発見された特徴には次のものがあります:
- DNA 配列、法律用語、HTTP リクエスト
- ヘブライ語のテキスト、栄養表示、コードの構文
- 感情、固有表現、文法構造
ワークフロー 1:事前学習済み SAE の読み込みと分析
ステップごとの手順
from transformer_lens import HookedTransformer
from sae_lens import SAE
# 1. Load model and pre-trained SAE
model = HookedTransformer.from_pretrained("gpt2-small", device="cuda")
sae, cfg_dict, sparsity = SAE.from_pretrained(
release="gpt2-small-res-jb",
sae_id="blocks.8.hook_resid_pre",
device="cuda"
)
# 2. Get model activations
tokens = model.to_tokens("The capital of France is Paris")
_, cache = model.run_with_cache(tokens)
activations = cache["resid_pre", 8] # [batch, pos, d_model]
# 3. Encode to SAE features
sae_features = sae.encode(activations) # [batch, pos, d_sae]
print(f"Active features: {(sae_features > 0).sum()}")
# 4. Find top features for each position
for pos in range(tokens.shape[1]):
top_features = sae_features[0, pos].topk(5)
token = model.to_str_tokens(tokens[0, pos:pos+1])[0]
print(f"Token '{token}': features {top_features.indices.tolist()}")
# 5. Reconstruct activations
reconstructed = sae.decode(sae_features)
reconstruction_error = (activations - reconstructed).norm()
利用可能な事前学習済み SAE
| リリース | モデル | レイヤー |
|---|---|---|
gpt2-small-res-jb | GPT-2 Small | 複数の残差ストリーム |
gemma-2b-res | Gemma 2B | 残差ストリーム |
| HuggingFace 上の各種 | タグ saelens で検索 | 各種 |
チェックリスト
- TransformerLens でモデルを読み込む
- 対象レイヤーに対応する SAE を読み込む
- 活性化をスパースな特徴にエンコードする
- トークンごとに最も強く活性化する特徴を特定する
- 再構成の品質を検証する
ワークフロー 2:カスタム SAE の学習
ステップごとの手順
from sae_lens import SAE, LanguageModelSAERunnerConfig, SAETrainingRunner
# 1. Configure training
cfg = LanguageModelSAERunnerConfig(
# Model
model_name="gpt2-small",
hook_name="blocks.8.hook_resid_pre",
hook_layer=8,
d_in=768, # Model dimension
# SAE architecture
architecture="standard", # or "gated", "topk"
d_sae=768 * 8, # Expansion factor of 8
activation_fn="relu",
# Training
lr=4e-4,
l1_coefficient=8e-5, # Sparsity penalty
l1_warm_up_steps=1000,
train_batch_size_tokens=4096,
training_tokens=100_000_000,
# Data
dataset_path="monology/pile-uncopyrighted",
context_size=128,
# Logging
log_to_wandb=True,
wandb_project="sae-training",
# Checkpointing
checkpoint_path="checkpoints",
n_checkpoints=5,
)
# 2. Train
trainer = SAETrainingRunner(cfg)
sae = trainer.run()
# 3. Evaluate
print(f"L0 (avg active features): {trainer.metrics['l0']}")
print(f"CE Loss Recovered: {trainer.metrics['ce_loss_score']}")
主要なハイパーパラメーター
| パラメーター | 一般的な値 | 効果 |
|---|---|---|
d_sae | d_model の 4〜16 倍 | 特徴数が増え、表現能力が高まる |
l1_coefficient | 5e-5 〜 1e-4 | 大きいほどスパースになるが、精度は下がる |
lr | 1e-4 〜 1e-3 | 標準的なオプティマイザーの学習率 |
l1_warm_up_steps | 500〜2000 | 初期段階での特徴の消失を防ぐ |
評価指標
| 指標 | 目標 | 意味 |
|---|---|---|
| L0 | 50〜200 | トークンごとの平均アクティブ特徴数 |
| CE Loss Score | 80〜95% | 元のモデルと比べて回復された交差エントロピー |
| Dead Features | <5% | 一度も活性化しない特徴 |
| Explained Variance | >90% | 再構成の品質 |
チェックリスト
- 対象レイヤーとフックポイントを選ぶ
- 拡張係数を設定する(d_sae = d_model の 4〜16 倍)
- 目的のスパース性に合わせて L1 係数を調整する
- Dead Features を防ぐために L1 ウォームアップを有効にする
- 学習中の指標を監視する(W&B)
- L0 と CE 損失の回復を検証する
- Dead Feature の割合を確認する
ワークフロー 3:特徴の分析とステアリング
個々の特徴の分析
from transformer_lens import HookedTransformer
from sae_lens import SAE
import torch
model = HookedTransformer.from_pretrained("gpt2-small", device="cuda")
sae, _, _ = SAE.from_pretrained(
release="gpt2-small-res-jb",
sae_id="blocks.8.hook_resid_pre",
device="cuda"
)
# Find what activates a specific feature
feature_idx = 1234
test_texts = [
"The scientist conducted an experiment",
"I love chocolate cake",
"The code compiles successfully",
"Paris is beautiful in spring",
]
for text in test_texts:
tokens = model.to_tokens(text)
_, cache = model.run_with_cache(tokens)
features = sae.encode(cache["resid_pre", 8])
activation = features[0, :, feature_idx].max().item()
print(f"{activation:.3f}: {text}")
特徴ステアリング
def steer_with_feature(model, sae, prompt, feature_idx, strength=5.0):
"""Add SAE feature direction to residual stream."""
tokens = model.to_tokens(prompt)
# Get feature direction from decoder
feature_direction = sae.W_dec[feature_idx] # [d_model]
def steering_hook(activation, hook):
# Add scaled feature direction at all positions
activation += strength * feature_direction
return activation
# Generate with steering
output = model.generate(
tokens,
max_new_tokens=50,
fwd_hooks=[("blocks.8.hook_resid_pre", steering_hook)]
)
return model.to_string(output[0])
特徴の寄与分析(Feature Attribution)
# Which features most affect a specific output?
tokens = model.to_tokens("The capital of France is")
_, cache = model.run_with_cache(tokens)
# Get features at final position
features = sae.encode(cache["resid_pre", 8])[0, -1] # [d_sae]
# Get logit attribution per feature
# Feature contribution = feature_activation × decoder_weight × unembedding
W_dec = sae.W_dec # [d_sae, d_model]
W_U = model.W_U # [d_model, vocab]
# Contribution to "Paris" logit
paris_token = model.to_single_token(" Paris")
feature_contributions = features * (W_dec @ W_U[:, paris_token])
top_features = feature_contributions.topk(10)
print("Top features for 'Paris' prediction:")
for idx, val in zip(top_features.indices, top_features.values):
print(f" Feature {idx.item()}: {val.item():.3f}")
よくある問題と解決策
問題:Dead Feature の割合が高い
# WRONG: No warm-up, features die early
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=1e-4,
l1_warm_up_steps=0, # Bad!
)
# RIGHT: Warm-up L1 penalty
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=8e-5,
l1_warm_up_steps=1000, # Gradually increase
use_ghost_grads=True, # Revive dead features
)
Issue: Poor reconstruction (low CE recovery)
# Reduce sparsity penalty
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=5e-5, # Lower = better reconstruction
d_sae=768 * 16, # More capacity
)
Issue: Features not interpretable
# Increase sparsity (higher L1)
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=1e-4, # Higher = sparser, more interpretable
)
# Or use TopK architecture
cfg = LanguageModelSAERunnerConfig(
architecture="topk",
activation_fn_kwargs={"k": 50}, # Exactly 50 active features
)
Issue: Memory errors during training
cfg = LanguageModelSAERunnerConfig(
train_batch_size_tokens=2048, # Reduce batch size
store_batch_size_prompts=4, # Fewer prompts in buffer
n_batches_in_buffer=8, # Smaller activation buffer
)
Neuronpedia との連携
事前学習済みの SAE 特徴量は neuronpedia.org で閲覧できます:
# Features are indexed by SAE ID
# Example: gpt2-small layer 8 feature 1234
# → neuronpedia.org/gpt2-small/8-res-jb/1234
主要クラスリファレンス
| Class | Purpose |
|---|---|
SAE | スパースオートエンコーダーモデル |
LanguageModelSAERunnerConfig | 学習設定 |
SAETrainingRunner | 学習ループの管理 |
ActivationsStore | アクティベーションの収集とバッチ処理 |
HookedSAETransformer | TransformerLens + SAE の統合 |
リファレンスドキュメント
詳細な API ドキュメント、チュートリアル、高度な使い方については、references/ フォルダーを参照してください:
| File | Contents |
|---|---|
| references/README.md | 概要とクイックスタートガイド |
| references/api.md | SAE、TrainingSAE、設定の完全な API リファレンス |
| references/tutorials.md | 学習、分析、ステアリングのステップバイステップのチュートリアル |
外部リソース
チュートリアル
論文
- Towards Monosemanticity - Anthropic (2023)
- Scaling Monosemanticity - Anthropic (2024)
- Sparse Autoencoders Find Highly Interpretable Features - Cunningham et al. (ICLR 2024)
公式ドキュメント
- SAELens Docs
- Neuronpedia - 特徴量ブラウザー
SAE アーキテクチャ
| Architecture | Description | Use Case |
|---|---|---|
| Standard | ReLU + L1 ペナルティ | 汎用 |
| Gated | 学習されたゲーティング機構 | より優れたスパース性の制御 |
| TopK | 正確に K 個の特徴量が活性化 | 一貫したスパース性 |
# TopK SAE (exactly 50 features active)
cfg = LanguageModelSAERunnerConfig(
architecture="topk",
activation_fn="topk",
activation_fn_kwargs={"k": 50},
)