Привет, друзья! В прошлой статье мы разобрали идею применения автоэнкодеров к трансоформерам. Там весь наш pipeline проходил на идее сжатия признакового простраПривет, друзья! В прошлой статье мы разобрали идею применения автоэнкодеров к трансоформерам. Там весь наш pipeline проходил на идее сжатия признакового простра

SAE: введение, пояснение и код

Привет, друзья! В прошлой статье мы разобрали идею применения автоэнкодеров к трансоформерам. Там весь наш pipeline проходил на идее сжатия признакового пространства так, чтобы поделить кошек и собак. Но что делать, если у нас не задача классификации, а задача next token prediction? Да и признаки не соответствуют "собакам" и "кошкам", а охватывают все богатство естественного языка...

Ответ сообщества сейчас такой — давайте использовать SAE.

SAE: Sparse Autoencoders

Разреженным автокодировщиком назовем модель SAE(x) = Dec (Enc(x)) = Dec(z), (все эти обозначения нам понадобятся), такую, что: d(Enc(x)) \gg d(x), где d(\cdot)— функция, возвращающая размерность.

Говоря словами — это автокодировщик, у которого скрытая рамерность "раздута" и сильно больше размерности эмбеддинга.

Идею SAE популяризовали Antropic, в октябре 2023 показав эффективность SAE на игрушечной модели, а потом, в мае 2024, расширив результаты для Claude 3.

Что делает AE SparseAE?

Обучение SAE происходит по стандартной минимизации функции потерь, которая делает результат выхода декодера близким к начальному x. Базовый пример такой функции — MSE. Сама по себе раздутая размерность не гарантирует эффективную разреженость, потому что задача имеет бесконечно много решений и совершенно не факт, что лучшие по MSE — разрежены. Обычно это реализуется через дополнительный член в функции потерь:

\mathcal{L} = |x - \hat{x}|^2 + \lambda \cdot |z|_1

или через аналогичную регуляризацию, поощряющую нули, почти нули или редкие всплески активаций.

Почему? (Можете пропустить этот блок)

Давайте сделаем вид, что энкодер у нас уже фиксирован и что штрафа (члена с \lambda) нет. Тогда

\hat x = Wz,\quad W\in\mathbb{R}^{d\times D}, z\in\mathbb{R}^D, x\in\mathbb{R}^d.

Оптимизируем по (z):

L(z)=|x-Wz|_2^2.

Берём производную:

\nabla_z L(z)= 2W^\top(Wz-x)

На константу нам всё равно. Она минимума не изменит. Поэтому условие оптимума (стационарная точка):

\nabla_z L(z)=0 \Longleftrightarrow W^\top W z = W^\top x.

Почему решений много (недоопределённость при (D>d))

Матрица W^\top W имеет размер D\times D, но её ранг rank(W^\top W)=rank(W)\le d < D,
а значитW^\top W вырождена (ее определитель — 0, обратной матрицы нет, всё грустно), стало быть решений либо нет, либо их бесконечно много.

И размерность множества решений может быть как минимум D-rank(W)\ge D-d, что при D=16 000 (стандартный SAE размер), а d = 2304 — размер эмбеддингов — есть 13 696. Не самое разреженное в мире.

Именно поэтому без L1/top-k и т.п. MSE не “выбирает” разреженный я: оптимум не единственный, и плотненькие решения столь же хороши по MSE. Поэтому мы штрафуем. И на практике — активны 100-200 нейронов на input +/-.

Зачем такой “толстый” скрытый слой?

Расширение пространства — это способ бороться с полисемантичностью — явлением, когда 1 нейрон кодирует много признаков. Эмпирически показано, что если латентное пространство в 10–100 раз больше embedding space, то модель может позволить себе паттерн:

  • один нейрон — один или одно осмысленное подмножество признаков (нейрон golden bridge, нейрон немецкого языка и пр). Он включается редко, но всегда по одному и тому же смыслу.

В какой точке обучают SAE?

Чтобы ответить на этот вопрос, давайте рассмотрим процесс трансформации эмбеддинга при проходе через конкретный блок трансформера.

x_pre (x_i)──► Attention (MultiHeadAttn)──► x_mid (3) ──► MLP (5) ──► x_post (6)
x_pre (x_i)──► Attention (MultiHeadAttn)──► x_mid (3) ──► MLP (5) ──► x_post (6)

​Если посмотреть на SAE, обученные на конкретных моделях, то можно встретить следующие точки:

### Скрипт загрузки таблицы со списком SAE из sae-lens ### Полный ноутбук-туториал — в конце статьи from sae_lens.loading.pretrained_saes_directory import get_pretrained_saes_directory df = pd.DataFrame.from_records( {k: v.__dict__ for k, v in get_pretrained_saes_directory().items()} ).T.reset_index(drop=True) print("SAEs in the GTP2 Small Resid Pre release") for k, v in df.loc[df.release == "gpt2-small-res-jb", "saes_map"].values[0].items(): print(f"SAE id: {k} for hook point: {v}") print("-" * 50) print("SAEs in the feature splitting release") for k, v in ( df.loc[df.release == "gpt2-small-res-jb-feature-splitting", "saes_map"] .values[0] .items() ): print(f"SAE id: {k} for hook point: {v}") print("-" * 50) print("SAEs in the Gemma base model release") for k, v in df.loc[df.release == "gemma-2b-res-jb", "saes_map"].values[0].items(): print(f"SAE id: {k} for hook point: {v}") ### OUTPUT: #.... #SAE id: blocks.11.hook_resid_pre for hook point: blocks.11.hook_resid_pre #SAE id: blocks.11.hook_resid_post for hook point: blocks.11.hook_resid_post #....

Нас интересуют hook_resid_pre и hook_resid_post. Соотнося с картинкой выше — это вход в attention блок и выход после MLP. Иногда также можно встретить SAE, обученные на hook_resid_mid — представление после attention до MLP.

Выбор зависит от цели анализа.

  • hook_resid_pre — для анализа глобальных признаков, выделенных до слоя;

  • hook_resid_mid — для выделения вклада attention;

  • hook_resid_post — для анализа эффекта блока целиком.

На сегодняшний день единого «рецепта» или стандарта, какой именно слой/точка лучший всего для обучения SAE — нет. И наиболее частое место — hook_resid_pre.

Работа с обученным SAE

После обучения SAE на конкретной модели (они не переносятся между моделями, разве что часто между базовой моделью и её чат-версией, хотя может мы просто ещё не все знаем) его можно рассматривать как словарь признаков. Только чтобы извлечь из этого словаря активизировавшийся признак — нужно прогнать данные и зафиксировать непутевые нейроны в разжатом представлении. Перелагая это на формулы, для входа xмы смотрим:

z=Enc(x)
f62ef6447e419387357754cdd7d77e0f.png

И, как я говорила выше, для любого xбудет активно небольшое подмножество латентных нейронов. К примеру, при типичном размере SAE D=16 000 ненулевыми оказываются порядка 100–200 компонент. Это и позволяет рассматривать латентное пространство не как плотную смесь признаков, а как набор активируемых направлений.

Интерпретация отдельного SAE-признака (SAE-нейрона) обычно начинается с отбора токенов, на которых он имеет наибольшую активацию. Если нейрон стабильно активируется на сходных контекстах — например, на границах кавычек, в структурах перечисления, в немецких предложениях или в индукционных паттернах — это, путём обобщения, позволяет предположить, что он кодирует.

Размечать признаки руками — долго, поэтому для себя можно и нужно работать с библиотеками. Давайте рассмотрим анализ нейронов в том же SAE Lens.

from IPython.display import IFrame # Посмотрим на признак со случайным индексом feature_idx = 3777 html_template = "https://neuronpedia.org/{}/{}/{}?embed=true&embedexplanation=true&embedplots=true&embedtest=true&height=300" def get_dashboard_html(sae_release="gpt2-small", sae_id="7-res-jb", feature_idx=0): return html_template.format(sae_release, sae_id, feature_idx) html = get_dashboard_html( sae_release="gpt2-small", sae_id="7-res-jb", feature_idx=feature_idx ) IFrame(html, width=1200, height=600)Пример изучения паттернов активации нейрона в SAE Lens.

Пример изучения паттернов активации нейрона в SAE Lens.

Компоненты полученного дашборда позволяют проанализировать:

1. Описание признака (верхний левый угол, Feature Description) — phrases related to anticipation or holding back

2. Графики логитов (левый угол, Logit Plots) — топ positive и negative лоигтов признака. По определению, чем больше значений логита, тем сильнее активация.

3. Графики плотностей активаций (правый угол, Activations Density Plot) — распределени активаций данного признака на каком-то случайно выбранном кусочке данных.

- Верхний график показывает, как часто были активации, не равные нулю. По оси x — сила активации признака, по оси y — частота.

- Нижний график — показывает плотность отрицательных и положительных логарифмов от логитов (то есть вероятностей).

4. Поле для тестирования активации признака — Test Activation. Здесь можно ввести свой текст и оценить реакцию признака на него.

5. Примеры, с наиболее сильными активациями признака —Top Activations, после текста. На них можно анализировать предложения и место, на котором загорается признак.

  • Важное тут — SAE не дают «истинного» или «единственно правильного» разложения модели. Они зависят от слоя, точки в блоке, гиперпараметров и даже конкретной инициализации. Тем не менее, SAE-шки на сегодня — один из самых популярных инструментов. С ними можно делать многое, в том числе искать circuts — цепочки преобразований внутри модели, управлять поведением — например заставлять говорить только о собаках (или умнее — заменять/удалять факты из модели) , и много другое.

Базовая теория на этом заканчивается. И чтобы было лучше — предлагаю закрепить ей на практике с этим ноутбуком.

В нём описано:

  • извлечение активаций через hook_resid_pre;

  • процесс извлечения признаков на аннотированном и нет SAE;

  • анализ разреженных латентных признаков + пара кивков для самопроверки;

Пусть он будет вам полезен!
Спасибо за чтение! Другие туториалы публикую в блоге (https://t.me/jdata_blog) и на [гитхаб](https://github.com/SadSabrina/XAI-open_materials/tree/main)!

Удачи и успешных решений,
Ваш Дата-автор!

Источник

Возможности рынка
Логотип TokenFi
TokenFi Курс (TOKEN)
$0.005211
$0.005211$0.005211
+1.14%
USD
График цены TokenFi (TOKEN) в реальном времени
Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу service@support.mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.

Вам также может быть интересно

Виталик Бутерин призывает к реформам децентрализованных стейблкоинов

Виталик Бутерин призывает к реформам децентрализованных стейблкоинов

Виталик Бутерин подчеркивает необходимость редизайна децентрализованных стейблкоинов с акцентом на независимость от доллара США, оракулы и проблемы доходности от стейкинга.Читать далее...
Поделиться
Coinstats2026/01/12 06:46
Заморозка USDT Tether: Ошеломляющая конфискация $182 миллионов с кошельков Tron

Заморозка USDT Tether: Ошеломляющая конфискация $182 миллионов с кошельков Tron

BitcoinWorld Заморозка Tether USDT: Ошеломляющая конфискация $182 миллионов из кошельков Tron В решительном шаге, подчеркивающем развивающееся пересечение криптовалюты
Поделиться
bitcoinworld2026/01/12 07:15
Спрос на стейблкоины становится массовым! Эмитенты заработали $5 млрд на блокчейне Ethereum

Спрос на стейблкоины становится массовым! Эмитенты заработали $5 млрд на блокчейне Ethereum

Статья «Спрос на стейблкоины становится массовым! Эмитенты получили $5 млрд на блокчейне Ethereum» появилась на BitcoinEthereumNews.com. На фоне всех этих постоянно растущих цифр,
Поделиться
BitcoinEthereumNews2026/01/12 07:01