mcpField
S
sparse-autoencoder-training

sparse-autoencoder-training

github.com/orchestra-researchデータ・データベース14.1k958 回インストール19 週間前に更新
リポジトリ

sparse-autoencoder-training について

sparse-autoencoder-trainingは、メカニスティック解釈可能性の研究者向けのSAELensスキルです。スパースオートエンコーダーを学習・分析し、モデルの活性化から解釈可能な特徴を分解します。特徴の帰属分析や特徴ベースのステアリングにも対応します。

主な機能

  1. 01事前学習済みSAEの読み込み
  2. 02カスタムSAEの学習
  3. 03スパース特徴と活性化の分析
  4. 04再構成とスパース性の評価
  5. 05特徴帰属とステアリング
  6. 06Standard、Gated、TopKアーキテクチャ

活用シーン

  1. 01モデル活性化から解釈可能な特徴を発見
  2. 02モデルが学習した概念を研究
  3. 03安全性に関わる特徴を分析
  4. 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.md
README.md
tutorials.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-jbGPT-2 Small複数の残差ストリーム
gemma-2b-resGemma 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_saed_model の 4〜16 倍特徴数が増え、表現能力が高まる
l1_coefficient5e-5 〜 1e-4大きいほどスパースになるが、精度は下がる
lr1e-4 〜 1e-3標準的なオプティマイザーの学習率
l1_warm_up_steps500〜2000初期段階での特徴の消失を防ぐ
評価指標
指標目標意味
L050〜200トークンごとの平均アクティブ特徴数
CE Loss Score80〜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

主要クラスリファレンス

ClassPurpose
SAEスパースオートエンコーダーモデル
LanguageModelSAERunnerConfig学習設定
SAETrainingRunner学習ループの管理
ActivationsStoreアクティベーションの収集とバッチ処理
HookedSAETransformerTransformerLens + SAE の統合

リファレンスドキュメント

詳細な API ドキュメント、チュートリアル、高度な使い方については、references/ フォルダーを参照してください:

FileContents
references/README.md概要とクイックスタートガイド
references/api.mdSAE、TrainingSAE、設定の完全な API リファレンス
references/tutorials.md学習、分析、ステアリングのステップバイステップのチュートリアル

外部リソース

チュートリアル
論文
公式ドキュメント

SAE アーキテクチャ

ArchitectureDescriptionUse Case
StandardReLU + L1 ペナルティ汎用
Gated学習されたゲーティング機構より優れたスパース性の制御
TopK正確に K 個の特徴量が活性化一貫したスパース性
# TopK SAE (exactly 50 features active)
cfg = LanguageModelSAERunnerConfig(
    architecture="topk",
    activation_fn="topk",
    activation_fn_kwargs={"k": 50},
)

コメント