Обучение разреженных автоэнкодеров
Предоставляет руководство по обучению и анализу разреженных автоэнкодеров (SAE) с использованием SAELens для декомпозиции активаций нейронных сетей на интерпретируемые признаки. Используйте для обнаружения интерпретируемых признаков, анализа суперпозиции или изучения моносемических представлений в языковых моделях.
Метаданные навыка
| Источник | Опционально — установка через vibeos skills install official/mlops/saelens |
| Путь | optional-skills/mlops/saelens |
| Версия | 1.0.0 |
| Автор | Orchestra Research |
| Лицензия | MIT |
| Зависимости | sae-lens>=6.0.0, transformer-lens>=2.0.0, torch>=2.0.0 |
| Платформы | linux, macos, windows |
| Теги | Разреженные автоэнкодеры, SAE, Механистическая интерпретируемость, Обнаружение признаков, Суперпозиция |
Справочная информация: полный SKILL.md
Ниже приведено полное определение навыка, которое VibeOS загружает при активации этого навыка. Агент видит эти инструкции, когда навык активен.
SAELens: Разреженные автоэнкодеры для механистической интерпретируемости
SAELens — основная библиотека для обучения и анализа разреженных автоэнкодеров (SAE) — техники декомпозиции полисемантических активаций нейронных сетей в разреженные, интерпретируемые признаки. Основана на новаторских исследованиях Anthropic по моносемичности.
GitHub: jbloomAus/SAELens (более 1100 звёзд)
Проблема: полисемантичность и суперпозиция
Отдельные нейроны в нейронных сетях являются полисемантичными — они активируются в семантически различных контекстах. Это происходит потому, что модели используют суперпозицию для представления большего количества признаков, чем у них есть нейронов, что затрудняет интерпретируемость.
SAE решают эту проблему путём декомпозиции плотных активаций в разреженные, моносемические признаки — обычно для любого входного сигнала активируется лишь небольшое количество признаков, и каждый признак соответствует интерпретируемому концепту.
Когда использовать SAELens
Используйте SAELens, когда нужно:
- Обнаружить интерпретируемые признаки в активациях модели
- Понять, какие концепты изучила модель
- Изучить суперпозицию и геометрию признаков
- Выполнять управление или абляцию на основе признаков
- Анализировать признаки, связанные с безопасностью (обман, предвзятость, вредоносный контент)
Рассмотрите альтернативы, когда:
- Нужен базовый анализ активаций → Используйте TransformerLens напрямую
- Нужны эксперименты по каузальному вмешательству → Используйте pyvene или TransformerLens
- Нужно управление в продакшене → Рассмотрите прямую инженерию активаций
Установка
pip install sae-lens
Требования: Python 3.10+, transformer-lens>=2.0.0
Основные концепции
Что изучают SAE
SAE обучаются восстанавливать активации модели через разреженное узкое место:
Входная активация → Кодировщик → Разреженные признаки → Декодировщик → Восстановленная активация
(d_model) ↓ (d_sae >> d_model) ↓ (d_model)
штраф за штраф за
разреженность восстановление
Функция потерь: MSE(оригинал, восстановленное) + L1_коэффициент × L1(признаки)
Ключевое подтверждение (исследование Anthropic)
В работе «Towards Monosemanticity» оценщики-люди обнаружили, что 70% признаков SAE действительно интерпретируемы. Обнаруженные признаки включают:
- Последовательности ДНК, юридический язык, HTTP-запросы
- Текст на иврите, утверждения о питании, синтаксис кода
- Тональность, именованные сущности, грамматические структуры
Рабочий процесс 1: Загрузка и анализ предобученных SAE
Пошаговое руководство
from transformer_lens import HookedTransformer
from sae_lens import SAE
# 1. Загрузка модели и предобученного 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. Получение активаций модели
tokens = model.to_tokens("Столица Франции — Париж")
_, cache = model.run_with_cache(tokens)
activations = cache["resid_pre", 8] # [batch, pos, d_model]
# 3. Кодирование в признаки SAE
sae_features = sae.encode(activations) # [batch, pos, d_sae]
print(f"Активных признаков: {(sae_features > 0).sum()}")
# 4. Поиск топ-признаков для каждой позиции
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}': признаки {top_features.indices.tolist()}")
# 5. Восстановление активаций
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. Настройка обучения
cfg = LanguageModelSAERunnerConfig(
# Модель
model_name="gpt2-small",
hook_name="blocks.8.hook_resid_pre",
hook_layer=8,
d_in=768, # Размерность модели
# Архитектура SAE
architecture="standard", # или "gated", "topk"
d_sae=768 * 8, # Коэффициент расширения 8
activation_fn="relu",
# Обучение
lr=4e-4,
l1_coefficient=8e-5, # Штраф за разреженность
l1_warm_up_steps=1000,
train_batch_size_tokens=4096,
training_tokens=100_000_000,
# Данные
dataset_path="monology/pile-uncopyrighted",
context_size=128,
# Логирование
log_to_wandb=True,
wandb_project="sae-training",
# Сохранение контрольных точек
checkpoint_path="checkpoints",
n_checkpoints=5,
)
# 2. Обучение
trainer = SAETrainingRunner(cfg)
sae = trainer.run()
# 3. Оценка
print(f"L0 (среднее активных признаков): {trainer.metrics['l0']}")
print(f"Восстановление CE Loss: {trainer.metrics['ce_loss_score']}")
Ключевые гиперпараметры
| Параметр | Типичное значение | Эффект |
|---|---|---|
d_sae | 4–16× d_model | Больше признаков, выше ёмкость |
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% | Восстановленная кросс-энтропия относительно оригинала |
| Мёртвые признаки | <5% | Признаки, которые никогда не активируются |
| Объяснённая дисперсия | >90% | Качество восстановления |
Контрольный список
- Выбрать целевой слой и точку перехвата
- Установить коэффициент расширения (d_sae = 4–16× d_model)
- Настроить L1-коэффициент для желаемой разреженности
- Включить разогрев L1 для предотвращения гибели признаков
- Отслеживать метрики во время обучения (W&B)
- Проверить L0 и восстановление CE Loss
- Проверить долю мёртвых признаков
Рабочий процесс 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"
)
# Поиск того, что активирует конкретный признак
feature_idx = 1234
test_texts = [
"Учёный провёл эксперимент",
"Я люблю шоколадный торт",
"Код компилируется успешно",
"Париж прекрасен весной",
]
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):
"""Добавляет направление признака SAE в остаточный поток."""
tokens = model.to_tokens(prompt)
# Получение направления признака из декодировщика
feature_direction = sae.W_dec[feature_idx] # [d_model]
def steering_hook(activation, hook):
# Добавление масштабированного направления признака на всех позициях
activation += strength * feature_direction
return activation
# Генерация с управлением
output = model.generate(
tokens,
max_new_tokens=50,
fwd_hooks=[("blocks.8.hook_resid_pre", steering_hook)]
)
return model.to_string(output[0])
Атрибуция признаков
# Какие признаки больше всего влияют на конкретный вывод?
tokens = model.to_tokens("Столица Франции —")
_, cache = model.run_with_cache(tokens)
# Получение признаков на последней позиции
features = sae.encode(cache["resid_pre", 8])[0, -1] # [d_sae]
# Получение атрибуции логитов для каждого признака
# Вклад признака = активация_признака × вес_декодировщика × развоплощение
W_dec = sae.W_dec # [d_sae, d_model]
W_U = model.W_U # [d_model, vocab]
# Вклад в логит "Париж"
paris_token = model.to_single_token(" Париж")
feature_contributions = features * (W_dec @ W_U[:, paris_token])
top_features = feature_contributions.topk(10)
print("Топ-признаки для предсказания 'Париж':")
for idx, val in zip(top_features.indices, top_features.values):
print(f" Признак {idx.item()}: {val.item():.3f}")
Частые проблемы и решения
Проблема: Высокая доля мёртвых признаков
# НЕПРАВИЛЬНО: Без разогрева признаки умирают рано
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=1e-4,
l1_warm_up_steps=0, # Плохо!
)
# ПРАВИЛЬНО: Разогрев L1-штрафа
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=8e-5,
l1_warm_up_steps=1000, # Постепенное увеличение
use_ghost_grads=True, # Оживление мёртвых признаков
)
Проблема: Плохое восстановление (низкое восстановление CE)
# Уменьшение штрафа за разреженность
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=5e-5, # Ниже = лучше восстановление
d_sae=768 * 16, # Больше ёмкости
)
Проблема: Признаки не интерпретируемы
# Увеличение разреженности (выше L1)
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=1e-4, # Выше = разреженнее, более интерпретируемо
)
# Или использование архитектуры TopK
cfg = LanguageModelSAERunnerConfig(
architecture="topk",
activation_fn_kwargs={"k": 50}, # Ровно 50 активных признаков
)
Проблема: Ошибки памяти во время обучения
cfg = LanguageModelSAERunnerConfig(
train_batch_size_tokens=2048, # Уменьшение размера батча
store_batch_size_prompts=4, # Меньше промптов в буфере
n_batches_in_buffer=8, # Меньший буфер активаций
)
Интеграция с Neuronpedia
Просматривайте признаки предобученных SAE на neuronpedia.org:
# Признаки индексируются по ID SAE
# Пример: gpt2-small слой 8 признак 1234
# → neuronpedia.org/gpt2-small/8-res-jb/1234
Справочник по ключевым классам
| Класс | Назначение |
|---|---|
SAE | Модель разреженного автоэнкодера |
LanguageModelSAERunnerConfig | Конфигурация обучения |
SAETrainingRunner | Менеджер цикла обучения |
ActivationsStore | Сбор и пакетирование активаций |
HookedSAETransformer | Интеграция TransformerLens + SAE |
Справочная документация
Подробную документацию по API, учебные пособия и расширенное использование см. в папке references/:
| Файл | Содержание |
|---|---|
references/README.md | Обзор и краткое руководство |
references/api.md | Полная справка по API для SAE, TrainingSAE, конфигураций |
references/tutorials.md | Пошаговые руководства по обучению, анализу, управлению |
Внешние ресурсы
Учебные пособия
Статьи
- Towards Monosemanticity — Anthropic (2023)
- Scaling Monosemanticity — Anthropic (2024)
- Sparse Autoencoders Find Highly Interpretable Features — Cunningham и др. (ICLR 2024)
Официальная документация
- Документация SAELens
- Neuronpedia — Браузер признаков
Архитектуры SAE
| Архитектура | Описание | Сценарий использования |
|---|---|---|
| Standard | ReLU + L1-штраф | Общего назначения |
| Gated | Изученный механизм стробирования | Лучший контроль разреженности |
| TopK | Ровно K активных признаков | Постоянная разреженность |
# TopK SAE (ровно 50 активных признаков)
cfg = LanguageModelSAERunnerConfig(
architecture="topk",
activation_fn="topk",
activation_fn_kwargs={"k": 50},
)