Денойзер активаций для стиринга GPT-2
Веса поправки к скрытым состояниям для уменьшения потери связности текста при
активационном стиринге \(h + \alpha v\). Вмешательство и починка применяются к
выходу блока 6
GPT-2 small,
направления взяты из
SAE OpenAI
resid_post_mlp_v5_32k, слой 6. Код, протокол и отчет:
github.com/NikitaLosev/steering-denoiser,
файл
report/REPORT.md.
Это не модель для AutoModel.from_pretrained. Файлы подключаются руками через
хук к потоку скрытых состояний (residual stream), пример ниже.
Лицензия MIT относится к весам денойзера и коду загрузчика из этого
репозитория. Веса GPT-2, SAE и Qwen принадлежат их авторам; проверочные
направления являются колонками декодера SAE OpenAI.
Файлы
| файл | что это |
|---|
denoiser_rank1_sae.pt | веса денойзера, 11.7 млн параметров, вход (batch, 768) |
denoiser.py | загрузка весов, из зависимостей только torch |
wiener_layer6.pt | среднее и спектр ковариации активаций слоя 6; из них собирается оператор Винера |
val_directions.pt | 46 исторически отобранных направлений с метаданными, из них 44 проверочных |
Как загрузить
Пример скачивает снимок репозитория и загружает денойзер; кроме torch нужен
пакет huggingface_hub.
1import sys
2import torch
3from huggingface_hub import snapshot_download
4
5local_dir = snapshot_download('NikitaLosev/steering-denoiser-gpt2')
6sys.path.insert(0, local_dir)
7from denoiser import load_denoiser
8
9model = load_denoiser(f'{local_dir}/denoiser_rank1_sae.pt')
10h_steered = torch.randn(4, 768) * 30
11r = torch.full((4,), 1.5)
12fixed = model(h_steered, r)
13print(fixed.shape)
Вывод: torch.Size([4, 768]). Аргумент r - сила искажения по позициям,
равная \(\alpha / \lVert h \rVert\). Загрузка идет через weights_only=True.
Оператор Винера из статистики, без обучения; оператор и вход должны быть на
одном устройстве и в одном типе данных:
1blob = torch.load(f'{local_dir}/wiener_layer6.pt', weights_only=True)
2mu, lam, evecs = blob['mean'], blob['eigenvalues'], blob['eigenvectors']
3w = torch.diag(lam / (lam + blob['default_sigma2']))
4operator = (evecs @ w @ evecs.T).to(h_steered.device, h_steered.dtype)
5mu = mu.to(h_steered.device, h_steered.dtype)
6
7def repair(x):
8 return mu + (x - mu) @ operator.T
Поправка применяется ко всем позициям, кроме нулевой: в собранном дампе ее
норма примерно в 35 раз выше медианной 87.75, поэтому нулевая позиция
исключена из проверенного протокола. Проверенный диапазон силы: от 40 до 250.
Обучение денойзера
6000 шагов на миллионе активаций openwebtext. Искажение - сдвиг \(h + \alpha u\)
вдоль случайных колонок декодера SAE из обучающего пула латентов; точные
индексы 44 главных проверочных направлений в обучение не входили,
геометрически близкие обучающие колонки отдельно не исключались. Сила \(\alpha / \lVert h \rVert\)
равномерна от 0 до 3, десятая часть примеров чистая, сила подается в сеть
через синус-косинусное кодирование. Сквозная абляция в отчете: интерполяционная
схема зашумления из постановки проигрывает этому чекпойнту 0.76, сдвиги
вдоль случайной сферы 0.28, вариант без условия по силе 0.17.
Результаты
Прирост выраженности признака при равном dist_1, то есть при равной доле
различных токенов, относительно сырого стиринга. 44 направления, строго
лежащие в проверочном пуле (два из 46
отобранных оказались из обучающего пула и исключены), у всех методов одна
область качества по dist_1 и общая точка без стиринга, продолжения
обрезаются перед первым токеном конца текста, значимость - двусторонняя
случайная смена знаков парных разностей. Главные агрегаты пересчитываются
тестами репозитория кода.
| метод | прирост | стандартная ошибка | лучше сырого |
|---|
| обученный денойзер | +1.153 | 0.165 | 40 из 44 |
| оператор Винера | +0.705 | 0.102 | 40 из 44 |
Парная разница в пользу денойзера \(+0.448 \pm 0.110\), p = 0.00025.
Знак сохраняется после нормировки на масштаб латента, по трем дополнительным
парам метрик и на 20 строго отложенных направлениях, добавленных позже.
Происхождение
| артефакт | версия |
|---|
| GPT-2 | ревизия 607a30d783dfa663caf39e06633721c8d4cfcd7e |
| Qwen2.5-0.5B, оценка кросс-энтропии | ревизия 060db6499f32faf8b98477b0a26969ef7d8b9987 |
| корпус Skylion007/openwebtext | ревизия 79d93d786212f7344586290adb811d4ae6a1762c |
| веса SAE | sha256 f259cf911cddc72d059c50706c81348668f1099bb284de285f877bd49ab31580 |
Хеши файлов этого репозитория:
| файл | sha256 |
|---|
denoiser_rank1_sae.pt | 54d2d542b82aa6bc4f707956d5549a6603ff2ee7f3f40e630037e71105f8423a |
wiener_layer6.pt | 435ff153cbe48dd019eaf70e3813f44ab0a7bebdf96760bdfff5d978909c5641 |
val_directions.pt | fa71d85b748c0f84174f27c63826a93591e3701630f46be5794259980ef3dde3 |
Ограничения
- Одна модель, один слой вмешательства, одно начальное значение генератора.
- Направления взяты из одного словаря SAE и могут быть зависимы между собой.
- Основная метрика выраженности замкнута на тот же SAE; проверка по доле
токенов не использует активации SAE, но связана с процедурой отбора.
- Человеческой оценки смысла сгенерированного текста не было.