Какой кодер, такой и result, друзья.

При проектировании эксперимента мы тестируем разные архитектуры. В прикладном применении нам важен выход и побочные характеристики (скорость, поддержка фреймворками, современность), а вот в теоретическом — мы пробуем найти интересный результат.

Как не найти результат там, где его нет, сравнивая модели разных архитектур? Что существует в архитектуре по её определению? Этим чудесным вопросам и посвящена статья.

Привет читателям!

Меня зовут Сабрина, и это очередной туториал из серии про то, как заглядывать моделям внутрь. Я пишу эту статью в месте, где многие хайкают. И как у хорошего хайка — у этой статьи будет несколько view points!: )

Что будет:

  1. Теория трёх масок — одна формула внимания, три способа её замаскировать.

  2. Информативность токенов и нюансы оценки.

  3. Геометрия (основная часть) — метрики анизотропия, спектр, participation ratio, CKA и что они покажут из‑за архитектуры.

  4. Вывод  — а зачем это на практике.

Рассмотрим четыре модели, малюсенькие, всё посчитается на CPU за несколько минут и, как всегда, лежит в ноутбуке на github. Берите воду, кофе, снеки и вперед!

Рассматриваемые архитектуры

Классические архитектуры языковых моделей обычно делят на три семейства: encoder‑only, decoder‑only и encoder‑decoder. На схемах (и мемах) они выглядят по‑разному и решают разные задачи, но внутри они, вообще говоря, устроены очень похоже.

Общее: Attention

Для каждого семейства основной вычислительный механизм — это attention с фиксированной и знакомой формулой, вида:

\text{Attn}(Q, K, V) = \operatorname{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}} + M\right) V

Здесь Q = XW_Q, K = XW_K, V = XW_V — линейные проекции входа, а M — аддитивная маска: матрица из нулей и -\infty. Ноль означает «смотреть можно», -\infty после softmax превращается в нулевой вес и означает «смотреть нельзя».

Если формула вам не знакома или забылась

Рассмотрим классический пример, когда на вход пришло предложение «the cat sat», и каждый токен уже превратился в вектор x_1, x_2, x_3. Слой внимания делает из каждого вектора три векторочка:

  • q_i = x_i W_Qзапрос: «что я ищу в контексте»;

  • k_i = x_i W_Kключ: «по какому признаку меня можно найти»;

  • v_i = x_i W_Vзначение: «что я отдам тому, кто меня нашёл».

Шаг 1. Совместимость. Скалярное произведение каждого запроса с каждым ключом: s_{ij} = \langle q_i, k_j \rangle. Получается матрица n \times n — «насколько токен i заинтересован в токене j».

Шаг 2. Масштаб. Делим на \sqrt{d_k}. Без этого при больших d_k скалярные произведения растут по величине, softmax уходит в насыщение (один вес ≈ 1, остальные ≈ 0), а градиенты умирают.

Шаг 3. Маска. Прибавляем M. Ноль ничего не меняет; -\infty гарантирует нулевой вес после экспоненты, потому что e^{-\infty} = 0.

Шаг 4. Softmax по строке. Каждая строка превращается в распределение: веса неотрицательны и суммируются в единицу. Ключевое слово — по строке: токен i распределяет свою единицу внимания между всеми доступными ему j.

Шаг 5. Взвешенная сумма. h_i = \sum_j a_{ij} v_j — новое представление токена есть смесь значений всех, на кого он посмотрел, с весами из шага 4.

Дальше это делается параллельно H раз (многоголовость), результаты склеиваются и проходят ещё одну линейную проекцию, а вокруг всего — residual‑связь, нормализация и MLP. Эффекты, которые мы будем эксплуатировать в туториале расположены в шагах 3–5.

Заметим, что:

  • Строка softmax обязана просуммироваться в единицу. Голова не умеет «не смотреть никуда»: если ей на этом шаге ничего не нужно, массу внимания всё равно придётся куда‑то положить.

  • Маска стоит внутри softmax, а не после него. Запрет «смотреть вперёд» — это перераспределение: оставшиеся веса нормируются заново.

Обобщая, можно сказать, что в основном в семействах меняется то каким токенам разрешено видеть какие другие токены и откуда берётся контекст для внимания. Иными словами, изначально геометрически мы сводим (грубо, но право имеем) архитектурные различия к двум вещам:

  • маске внимания

  • источнику (Q, K, V)

Архитектура

M_{ij}

Источник Q

Источник K, V

encoder‑only (BERT)

0 везде

сам слой

сам слой

decoder‑only (GPT-2)

0 при j \le i; -\infty при j > i

сам слой

сам слой

enc‑dec: encoder (T5, BART)

0 везде

encoder

encoder

enc‑dec: self‑attn декодера

треугольная

decoder

decoder

enc‑dec: cross‑attention

0 везде

decoder

encoder

Спасибо LLM за таблицы, которые учишься делать, чтобы представлять информацию компактно и сжато.

Из этой таблицы мы можем достать три важных для нас сейчас факта:

Следствие 1. Кто что видел. В каузальной модели (decoder) представление токена на позиции i — функция только префикса x_{\le i}. Формально:

h_i^{\text{causal}} = f(x_1, \dots, x_i), \qquad h_i^{\text{bidir}} = f(x_1, \dots, x_n)

Тогда по построению видим: токены внутри одной последовательности несут разный объём контекста: первый видел одно слово, последний — всё предложение.

Следствие 2. Где «смысл целого». У encoder‑only он размазан по всем позициям (плюс [CLS], который обучен агрегировать — но обучен под задачу Next Sentence Prediction). У decoder‑only — строго в последнем токене, единственном, кто видел всё. У encoder‑decoder — в выходе энкодера; а вот состояние декодера — это уже не «смысл входа», а «состояние генерации».

Следствие 3. Сколько пространств. Одно, одно и два. У encoder‑decoder пространство энкодера и пространство декодера обучались под разные роли: у них разные нормы, разные базисы и разный смысл координат.

Каждое следствие порождает геометрические нюансы и беды. На них мы и будем смотреть.

Различие: Objective

Окей, маской мы завладели, но это только половина необходимого. Справедливо заметить, что модели по постановке учатся разным задачам:

  • MLM (BERT, encoder): маскируем случайные токены и восстанавливаем их из двустороннего контекста. Каждая позиция обязана быть самодостаточной — из неё должны восстановить конкретное слово. Это давление «размазывает» информацию по всем позициям и по многим направлениям.

  • CLM (GPT-2, decoder): предсказываем следующий токен. Оптимизируется, по сути, одна функция — распределение над словарём на выходе. Пространство схлопывается вдоль направлений, полезных для next‑token‑предсказания; всё, что для этого не нужно, сжимается. Как мы увидим, схлопывание получается буквальным.

  • Span corruption (T5, encoder‑decoder) и denoising / text infilling (BART, encoder‑decoder): портим текст — выкидываем куски — и восстанавливаем его целиком. Энкодер работает двунаправленно, но его выход должен быть удобен для потребления декодером через cross‑attention. Это отдельное, третье давление на геометрию, и у T5 с BART оно реализовано по‑разному.

Напоминание постановок задач
  • MLM (BERT) — случайные 15% токенов по двустороннему контексту (из них 80% заменяются на [MASK], 10% на случайный токен, 10% остаются как есть).

    Пример: The doctor told the [MASK] that the surgery was successful. — patient.

  • NSP (BERT) — задача идут ли два куска текста подряд

    Пример: [CLS] The doctor told the patient … [SEP] The surgery took three hours. [SEP] — IsNext

  • CLM (GPT-2) — прогнозирование следующего токена по левому контексту.

    Пример: The doctor told thepatient.

  • Span corruption (T5) — обучение через выкинутые спаны, каждый под своим sentinel‑токеном.

    Пример: вход The doctor told the <X> that the surgery <Y> successful. — таргет <X> patient <Y> was <Z>

  • Denoising / text infilling (BART) — задача восстановить текст целиком после произвольной порчи: спаны схлопываются в один <mask>, предложения переставляются, токены удаляются.

    Пример: The doctor <mask> the surgery was successful. — полный оригинал

Потом это, конечно, видоизменилось (ELECTRA, DeBERTa, ALBERT — уже имеют поправки разной силы в постановке). Но основа до сих пор такая.

Запомним, что MLM требует, чтобы каждая позиция была самодостаточной — из неё восстанавливают конкретное слово. CLM оптимизирует одну позицию под одно распределение над словарём. Span corruption и denoising делают выход энкодера удобным не для классификатора, а для чтения декодером через cross‑attention. Это, вообще говоря, три разных давления на геометрию.

Отдельно нам также важен будет [CLS]: он единственная позиция BERT, которую явно учили агрегировать, — но учили под NSP, то есть под «идут ли эти два куска подряд», а это в основном решается совпадением темы.

К практике готовы

Итак, из абзацев выше мы увидели, что маска определяет, какой токен куда смотрит, а objective давит на форму, которое может принять облако из токенов. Три факта из определения маски, три задачи под семейства, а мы всё ещё ничего не проверили. Чешем руки в предвкушении и смотрим эксперимент.

Setup

Ноутбук писался на маке (MPS), тестировался на CPU. Все модели маленькие, полный прогон занимает мало минут.

Данные:

  • English Web Treebank — английские тексты из веба (блоги, отзывы, письма, форумы) с синтаксической разметкой, сделанной людьми. Из него мы возьмём и предложения для экспериментов.

Зависимости: torch: 2.8.0 | transformers: 5.10.2

Предложений в корпусе: 12544

Пример:
  'You wonder if he was manipulating the market with his bombing targets.'

Модели

Семейство

Модель

Слои

D

Внимание

Objective

encoder‑only

bert-base-uncased

12

768

двунаправленное

MLM + NSP

decoder‑only

gpt2

12

768

каузальное

CLM

encoder‑decoder

facebook/bart-base

6 + 6

768

enc: двунапр. / dec: кауз. + cross

denoising (text infilling)

encoder‑decoder

t5-small

6 + 6

512

enc: двунапр. / dec: кауз. + cross

span corruption

Список моделей, которые будут нашими объектами анализа выше. Он собран так, чтобы:

  • покрыть все три семейства в сопоставимых размерностях и при сопоставимом числе голов (первые три);

  • обеспечить контроль над другими свободными параметрами внутри encoder‑decoder (у T5: RMSNorm без сдвига, relative position bias, span corruption, у BART обычный LayerNorm, выученные абсолютные позиции, denoising‑objective)

Резонный вопрос: контроль внутри encoder‑decoder есть (две модели), а где контроль для encoder‑only и для decoder‑only? Мы схитрим, и достанем их отсюда же:

  • Контроль для encoder‑only — это энкодеры T5 и BART. Двунаправленных моделей у нас три: BERT, энкодер T5, энкодер BART.

  • Контроль для decoder‑only — это декодеры T5 и BART. Каузальных моделей у нас тоже три: GPT-2, декодер T5, декодер BART.

Они различаются размерностью, глубиной, objective, токенизатором и корпусом претрейна — то есть дают в целом достаточную вариативность.

Примечание техническое. В transformers 5.x по умолчанию используется SDPA‑реализация внимания, и при ней output_attentions=True возвращает пустой список (бага). Для любого анализа внимания нужен attn_implementation="eager".

              Тип             Модель  Слоёв   D  Голов Параметров  Словарь Что на позиции 0
   BERT (enc-only)  bert-base-uncased     12 768     12      109M    30522            [CLS]
  GPT-2 (dec-only)               gpt2     12 768     12      124M    50257              You
  T5-enc (enc-dec)           t5-small      6 512      8       35M    32100             ▁You
BART-enc (enc-dec) facebook/bart-base      6 768     12       82M    50265              <s>
  T5-dec (enc-dec)           t5-small      6 512      8       42M    32100            <pad>
BART-dec (enc-dec) facebook/bart-base      6 768     12       96M    50265             </s>

Примечание: колонка «Параметров» считает только ту часть, которую мы в моменте анализируем: для T5 и BART это энкодер, а не вся seq2seq‑модель. Поэтому числа меньше тех, что указаны на карточках моделей.

Соблазн потрогать декодеры мы, конечно, не сдерживаем — но декодер не запускается так же просто, как энкодер. Энкодеру хватает одного входа: подали текст, забрали состояния. Декодеру нужны два сразу — что прочитал энкодер (это придёт через cross‑attention) и decoder_input_ids, то есть «что уже сгенерировано». Без второго forward просто не посчитается.

Интуиция «энкодер сжал текст в один вектор, декодер его принял» — из seq2seq на RNN тут не применима. В трансформере никакого одного вектора нет: декодер вычитывает все выходные векторы энкодера через cross‑attention, заново на каждом своём слое и на каждом шаге генерации, и параллельно смотрит на то, что сам уже написал.

Состояния «для текста X» у декодера не существует — есть состояние «для пары (вход X, история Y)». Мы будем смотреть на teacher forcing: тот же текст, сдвинутый на одну позицию вправо.

Чтоб удобно было

Технически в коде мы заворачиваем декодер в обёртку с тем же интерфейсом, что у обычной модели: вызвали — получили last_hidden_state, hidden_states, attentions. После этого весь остальной код ноутбука работает с декодерными частями просто удобнее.

class DecoderStack:
    """A decoder stack with the interface of an ordinary encoder model.

    Calling it runs the FULL seq2seq model — the decoder does not exist
    without the encoder — and returns the DECODER side of the output.
    Everything downstream (influence matrices, saturation, clouds, CKA)
    therefore works with a decoder without a single change.
    """

    def __init__(self, model):
        self.model = model
        self.config = model.config

    def parameters(self):
        return self.model.get_decoder().parameters()

    def __call__(self, input_ids=None, attention_mask=None,
                 output_hidden_states=False, output_attentions=False, **_ignored):
        with torch.no_grad():
            out = self.model(
                input_ids=input_ids, attention_mask=attention_mask,
                decoder_input_ids=shift_right(input_ids, self.model),
                output_hidden_states=output_hidden_states,
                output_attentions=output_attentions,
            )
        return SimpleNamespace(
            last_hidden_state=out.last_hidden_state,          # decoder side
            hidden_states=out.decoder_hidden_states,
            attentions=out.decoder_attentions,                # decoder self-attention
            cross_attentions=out.cross_attentions,
            encoder_last_hidden_state=out.encoder_last_hidden_state,
            encoder_attentions=out.encoder_attentions,
        )

Часть 1. Проверим маску

Раз мы сказали, что attention общий, но разный, покажем это — проверим Attention интервенцией (проще говоря — вмешательством).

Как: Берём предложение. Портим токен на позиции j (заменяем на [UNK]). Смотрим, насколько изменилось скрытое состояние на каждой позиции i:

\text{Influence}[i, j] = \bigl\| h_i(x) - h_i(x_{j \to \text{UNK}}) \bigr\|_2

Это матрица n \times n. Что мы ожидаем

  • когда модель двунаправленная, порча любого токена меняет всё

  • когда модель каузальная, порча токена j физически не может повлиять на позиции i < j (j зависит от прошлых, а прошлые не менялись), отсюда верхний треугольник обязан быть нулевым.

Что мы видим

  • BERT — залитый квадрат. Влияние идёт в обе стороны, причём «из будущего» даже чуть сильнее, чем «из прошлого» (5.73 против 4.37).

  • GPT-2 — идеальный нижний треугольник. Влияние будущего — 0. Треугольная маска в чистом виде.

  • Энкодеры T5 и BART — снова квадраты, как и положено двунаправленным энкодерам: у обоих влияние будущего и прошлого одного порядка.

Ненормальные нормы

Внимательный читатель заметит, что у GPT-2 абсолютная величина влияния прошлого — десятки, у BERT, BART, T5 — единицы. Соблазнительно прочитать это эффектом, но так нельзя. Почему — увидим.

Что у декодера в encoder‑decoder (нюансы)

Со стандартными энкодерами и декодерами всё понятно — мы сейчас меняли только вход. Сделать так в декодере мы не можем: у него две маски сразу. Своя история закрыта треугольником (self‑attention) и вход энкодера (cross‑attention). Проверим, для полноты тем же самым методом.

Матриц теперь две на модель:

  • порча входа энкодера — меняем токен j в тексте, который читает энкодер, декодерную историю не трогаем. Смотрим \|\Delta h_i^{\text{dec}}\|;

  • порча истории декодера — текст на входе энкодера тот же, портим токен j в том, что декодер «уже написал».

Ожидание: первая матрица — залитый квадрат (cross‑attention без маски), вторая — нижний треугольник (self‑attention каузален).

Что мы видим

Self‑attention декодера действительно каузален — масса внимания на будущем ровно 0.0 у обеих моделей. То есть внутри себя декодер ведёт себя как GPT-2.

А вот доступ ко входу у него не каузальный. Форма cross‑attention — [batch, heads, позиции декодера, позиции энкодера], и маски там нет: каждое состояние декодера видит весь вход целиком, с самого первого шага генерации. То есть фраза «декодер каузален» верно только про его собственную историю Y, но не про вход.

На правой колонке heatmap видно, как это работает: строки — позиции декодера, столбцы — позиции энкодера, и каждая строка распределяет внимание по всему входу.

К сноске заходите, когда будете трогать код. Из неё важен факт:

В encoder‑decoder “эмбеддинг текста” — это выход энкодера. Состояние декодера — не смысл входа, а указатель в пространство энкодера плюс состояние генерации. Анализ decoder_hidden_states как анализ эмбеддингов предложения в чистом виде уже не совсем корректен. Это анализ decoder_hidden_states с учетом того, что было в энкодере (истинных эмбеддингов предложения в этом смысле).

Часть 2. Измерим маску

Следствие 1: информативность — кто сколько видел и кто сколько весит

Маску мы проверили. Теперь рассмотрим Следствие 1 из теории.

2.1 Насыщение контекстом

Обозначим за h_i(x_{1, \dots, k}) — состояние токена i в момете, где модель видела все токены до k‑го. Тогда представление токена i, когда модель впервые его увидела есть h_i(x_{1..i}) и h_i(x_{1..n}), когда модель увидела все токены.

Пример на трёх токенах

Пусть текст — «she saw ducks», и нас интересует средний токен, saw.

  • Каузальная модель. На входе she saw она считает h_2(x_{1..2}). Даём ей всё предложение целиком, she saw ducks — на позиции 2 она посчитает ровно то же самое: токен ducks стоит справа, а справа она не смотрит. Два вектора совпадают, угол между ними нулевой, \cos = 1.

  • Двунаправленная модель. На входе she saw она строит h_2 из двух слов, на входе she saw ducks — из трёх. И ducks меняет прочтение saw: это глагол «увидела», а не существительное «пила». Вектор поворачивается, \cos < 1.

Если нарисовать эти два вектора из начала координат, у каузальной модели они лягут друг на друга, а у двунаправленной между ними будет видимый угол.

Состояние токена в каждый момент времени — это вектор. У вектора есть норма и направление — эксплуатируем их для анализа. Во‑первых, чтобы сравнить два вектора (состояние токена i при полном тексте и при обрезанном ровно на нём) рассмотрим:

\text{sat}(i) = \cos\bigl(h_i(x_{1..n}),\; h_i(x_{1..i})\bigr)

Как читать:

  • \text{sat}(i) = 1— косинус нуля. То есть вектора схлопнулись. Правый контекст ничего не поменял с точки зрения направления.

  • \text{sat}(i) \ll 1— представление токена переписывается тем, что идёт после него (движется по направлению).

Для каузальной модели ответ известен заранее аналитически — там h_i вообще не зависит от x_{>i}, значит должно быть ровно 1.

fig_05.png
Сатурация токенов
тип                    последний слой   min по позициям   мин. по слоям
BERT (enc-only)                 0.4320            0.1755          0.4320
GPT-2 (dec-only)                1.0000            1.0000          1.0000
T5-enc (enc-dec)                0.4892            0.0534          0.4892
BART-enc (enc-dec)              0.5771           -0.0428          0.5771
T5-dec (enc-dec)                0.9426            0.8381          0.7607
BART-dec (enc-dec)              0.8061            0.5368          0.8061

Что мы видим

  • GPT-2 даёт 1 на всех позициях. Это и есть смысл фразы «в каузальной модели ранние токены недоконтекстуализированы». Каждый токен получает своё направление и никак не меняет его при дальнейшем добавлении контекста.

  • Все три двунаправленные модели дают заметно меньше единицы: 0.432 у BERT, 0.489 у энкодера T5, 0.577 у энкодера BART, а на отдельных позициях значения проваливаются к нулю и даже уходят в минус. То есть правый контекст переписывает представление токена почти полностью.

  • А декодеры T5 и BART дают меньше единицы — и это не противоречие. Обрезая текст, мы обрезаем вход энкодера, а его декодер читает через cross‑attention без всякой маски. Каузальна у него только собственная история (мы это проверили в части 1), поэтому в этом тесте он ведёт себя как двунаправленная модель. Ровно то же самое произойдёт с любым RAG‑подобным пайплайном: «декодерная модель» и «модель, у которой представление не зависит от правого контекста» — не синонимы.

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

Практическое следствие:

Среднее.mean(dim=1) по токенам декодер модели (у нас — GPT-2), усредняет векторы, часть которых физически не содержит информации о тексте. Первый токен видел одно слово. Второй — два. Это усреднение систематически смещено в сторону начала текста.

Для encoder моделей BERT та же операция осмысленна: там все позиции видели всё.

2.2 Attention sink: первый токен как сливной клапан

Второй фактор информативности — не «что токен видел», а «сколько внимания он получил.»

При анализе attention существует эффект: первая позиция собирает непропорционально большую долю внимания (Xiao et al., 2023, StreamingLLM). Такой эффект называется Attention sink. Он возникает потому что softmax по строке обязан просуммироваться в единицу — голова не может «не смотреть никуда». Когда голове на данном шаге нечего искать, ей нужно куда‑то слить массу внимания, и самая удобная свалка — позиция, которая видна отовсюду и не несёт содержания. Отсюда название — attention sink.

Формально оно определяется так. Пусть a^{(\ell,h)}_{ij} — вес внимания головы h слоя \ell из позиции‑запроса i в позицию‑ключ j. Мерой стока назовём

\text{sink}(\ell) = \operatorname*{median}_{h,\, i}\ a^{(\ell,h)}_{i0}

— медиану доли внимания, уходящей в позицию 0, по всем головам и всем запросам слоя. Медиана, а не среднее, и это важно: доли по головам распределены крайне несимметрично, одна голова‑сливщик с долей 0.95 утаскивает среднее вверх, и получается впечатление, будто течёт весь слой. Медиана отвечает на честный вопрос — «как ведёт себя типичная голова».

Toy‑пример

Строка softmax нормирована при любых логитах: \sum_j a_{ij} = 1. Пусть у запроса q_i нет ни одного содержательного совпадения — все \langle q_i, k_j \rangle \approx 0, — но у позиции 0 логит равен s_0 (ключ там всегда один и тот же, модели ничего не стоит его выучить). Тогда

При n = 15 достаточно s_0 \approx 4, чтобы в позицию 0 ушло больше 80% внимания. Никакой семантики: голове просто некуда деть массу, а нулевая позиция — единственный всегда доступный адрес. Эту кривую мы нарисуем рядом с реальными долями.

Обычно этот эффект описывают как свойство декодерных моделей. Проверим, так ли это и как в энкодерах — посчитаем долю массы внимания, уходящую на позицию 0, усреднив по головам и запросам, по слоям.

fig_06.png

Что мы видим

Медианно для GPT-2: к глубоким слоям до 93% всего внимания уходит в первый токен. Модель почти перестаёт «смотреть на текст» и сливает внимание в сток.

Энкодер BART — модель двунаправленная — показывает сток почти такой же силы: 0.61–0.75 начиная со второго слоя. Отсюда мы видим, что следствие слития зависит не только от архитектуры, а зависит ещё и от наличия служебного токена. А именно, для наших моделей справедливо следующее:

Тип

маска

первый токен

сток (медиана по головам и запросам)

GPT-2

каузальная

BOS (мы добавили)

до 0.93

энкодер BART

двунаправленная

<s>, всегда

до 0.75

BERT

двунаправленная

[CLS], всегда

0.36 в начале, затем 0.01–0.03

энкодер T5

двунаправленная

отсутствует

0.00–0.01, стока нет

декодер T5

каузальная

<pad> как decoder_start

до 0.93

декодер BART

каузальная

</s> как decoder_start

до 0.97

  • У GPT-2 и BART он есть и работает свалкой на всей глубине. У BERT [CLS] есть, но сток держится только в первых слоях. У T5 начального служебного токена нет — и стока нет.

  • Энкодер T5 и декодер T5 — это одна модель: один претрейн, один токенизатор, одна схема нормализации, одинаковое число слоёв и голов. Разница между ними — маска и наличие стартового токена. У энкодера начального служебного токена нет, и стока нет: 0.00–0.01 на всех шести слоях. Декодер той же самой T5 начинает последовательность с <pad> — и сток доходит до 0.93. Эффект снова включается там, где появляется постоянная пустая позиция.

  • Cross‑attention не маскирован ни у T5, ни у BART — маска здесь не участвует. И тем не менее: у BART в нулевую позицию энкодера утекает до 0.51, а у T5 — 0.00–0.01. Разница между ними ровно та же, что между их энкодерами, и объясняется тем же: у BART на позиции 0 стоит <s>, у T5 — обычное слово.

Отсюда: механизм такой: голове нужно место, куда слить лишнюю массу внимания, и лучший кандидат — позиция, которая всегда присутствует, видна отовсюду и не несёт содержания. А значит, наш служебный первый токен — часть механизма внимания, а не носитель смысла. Включать его в mean‑pooling не очень корректно — там мы подмешиванием в «эмбеддинг текста» вектор со служебной ролью и, как мы ниже увидим, аномальной величиной. Касается это и GPT-2, и BART, и BERT, и обоих декодеров — то есть всех, у кого такой токен есть.

2.3 Нормы: два порядка разницы

Attention sink имеет геометрического близнеца — аномально большие нормы на служебных позициях (их называют massive activations, Sun et al., 2024).

Посмотрим на эффект в действии.

fig_07.png

Что мы видим

У T5 нормы внутри огромные — эмбеддинги 378, к предпоследнему слою до 2 тысяч у энкодера и до 7 тысяч у декодера, — а на выходе обрушиваются до 3.3 и 14.9. Это финальный RMSNorm. То есть «у T5 самые маленькие нормы» — свойство последнего слоя, а не модели: внутри у него как раз самые большие числа из всех шести.

У GPT-2 рост монотонный: 5.2 → 262.9, в 51 раз, без единого перелома. Вот это и правда «модель копит массу в residual stream».

У BERT и энкодера BART профиль плоский — 14 и 5 от входа до выхода.

У декодера BART всё интересное на последнем слое: 10.8 держится всю глубину и скачком уходит в 50.7.

Причина в схеме нормализации: BERT использует post‑LayerNorm, GPT-2 — pre‑LayerNorm с финальным ln_f, T5 — RMSNorm без обучаемого сдвига, BART — обычный LayerNorm. Это архитектурная деталь, которая должна, в идеале, учитываться при анализе везде, где вы применяете нормы (а ещё важно смотреть на изменение по слоям).

Мне на практике помогает правило: любая метрика, чувствительная к масштабу, между архитектурами требует нормировки. И кроме того, любая метрика требует baseline.

Помимо статистик с частных примеров, мы можем анализировать и более общие вещи. Давайте посмотрим на структуры/облака точек, которые может триггерить архитектура.

Часть 3. Геометрия

Облака точек можно характеризовать разными способами. Я субъективно выбрала три красивые. Три — чтобы туториал не был очень широким, а то мы итак расползлись.

Я допускаю, что математика вам не знакома или знакома не вся. Поэтому сейчас зафиксируем интуицию и потом — формальные определения. Итак, рассмотрим:

  • Анизотропию в общем смысле — это зависимость математических свойств объекта, функции, пространства или модели от направления. Мы будем оценивать изотропность пространства — то есть наоборот — одинаковость всех направлений в модели. Сложного слова не пугайтесь — с нами тут просто будет попарный косинус.

  • Спектр и Participation ratio — характеристики матрицы, которые скажут, сколько в ней наиболее эффективных направлений.

  • CKA — метрика, позволяющая проанилизровать похожесть моделей между собой (в смысле организации пространств).

Если стало сложно, то сейчас по секциям всё уложим. Наши подопытные:

BERT (enc-only)    облако:  11924 токенов x 768 измерений
GPT-2 (dec-only)   облако:  11676 токенов x 768 измерений
T5-enc (enc-dec)   облако:  13113 токенов x 512 измерений
BART-enc (enc-dec) облако:  12220 токенов x 768 измерений
T5-dec (enc-dec)   облако:  13113 токенов x 512 измерений
BART-dec (enc-dec) облако:  12220 токенов x 768 измерений

Разное количество токенов — следствие словаря модели. Слово коровник, например, может кодироваться в модели номер 1 — одним токеном, а в модели номер два — двумя.

3.1 Анизотропия

Теория. Пространство называется изотропным, если случайно взятые из него векторы почти ортогональны. Для гауссова облака в \mathbb{R}^D это так: при большом D косинус двух случайных векторов концентрируется около нуля.

Мера отклонения от изотропии — средний попарный косинус (Ethayarajh, 2019):

A = \mathbb{E}_{i \ne j,\ s(i) \ne s(j)} \bigl[\cos(h_i, h_j)\bigr]

Здесь мы берём токены из разных предложений. Внутри одного предложения токены могут быть похожи естественным образом.

Как читать:

  • A \approx 0— изотропно, косинус информативен: если два вектора похожи, это что‑то значит;

  • A \to 1— все векторы смотрят примерно в одну сторону; косинус любой пары ≈ 1, и он не несёт информации.

Нашим контролем будет baseline — та же самая оценка для гауссова облака той же размерности. Без него мы не сможем сказать, много/мало, случайно или не случайно. А ещё это поможет нам корректнее оценить D=768 с D=512.

тип                    анизотропия   baseline
BERT (enc-only)               0.227     -0.000
GPT-2 (dec-only)              0.945     -0.000
T5-enc (enc-dec)              0.098     -0.000
BART-enc (enc-dec)            0.184     -0.000
T5-dec (enc-dec)              0.868     -0.000
BART-dec (enc-dec)            0.096     -0.000
fig_08.png

Что мы видим

Смотрите как это красиво! У GPT-2 лучи собраны в узкий пучок — любая пара векторов почти сонаправлена, — а у BERT и энкодера T5 они расходятся по всей окружности. Справа то же самое в виде распределения: у GPT-2 гистограмма косинусов прижата к единице, у остальных сидит около нуля с длинными хвостами.

  • GPT-2: 0.945. Следствие — вектора чаще сонаправлены. Отсюда косинусная близость на выходе GPT-2 почти не несёт информации.

  • BERT: 0.227. Следствие — вектора сонаправлены реже.

  • Энкодер T5: 0.098 и энкодер BART: 0.184 — самые «круглые» облака.

  • Гауссов baseline: ~0.00 для обеих размерностей. Именно он говорит нам, что 0.227 у BERT — это много, а не «почти ноль».

  • А декодеры разъехались: 0.868 у декодера T5 — почти как GPT-2, и 0.096 у декодера BART — как самые «круглые» энкодеры. Маска у них одна и та же, каузальная, а анизотропия различается в девять раз.

Уже здесь виден отпечаток типа модели: единственный decoder‑only схлопывает пространство сильнее всех, а три двунаправленных энкодера держатся в диапазоне 0.10–0.23 — при том, что objective у них три разных.

Декодеры enc‑dec ставят объяснению границу: они оба каузальные, а лежат по разные стороны диапазона. Значит, «каузальность» сама по себе анизотропию не объясняет.

Что можно сделать с высокой анизотропией

У высокой анизотропии есть две принципиально разные возможные причины.

Гипотеза А: облако правда сплющено. Векторы лежат в узком конусе, направления внутри него скоррелированы, геометрия действительно вырождена.

Гипотеза Б: облако нормальное, но сдвинуто. Представьте шар единичного радиуса с центром в точке \mu, где \|\mu\| = 10. Все точки такого шара имеют почти одинаковое направление — просто потому, что шар далеко от начала координат. Косинус между ними будет ≈ 1, хотя внутренняя структура облака совершенно нормальная.

Разница между А и Б:

  • если А — с пространством действительно беда, и информации в нём мало;

  • если Б — вся «беда» лечится одним вычитанием среднего, и информация никуда не девалась.

Различить их можно, сделав простой хинт — посчитать анизотропию после центрирования \tilde h = h - \bar h. На наших данных, мы получим следующее.

            модель  сырая  после центрирования
   BERT (enc-only)  0.227               -0.000
  GPT-2 (dec-only)  0.945                0.007
  T5-enc (enc-dec)  0.098                0.000
BART-enc (enc-dec)  0.184               -0.000
  T5-dec (enc-dec)  0.868                0.007
BART-dec (enc-dec)  0.096               -0.000

Что мы видим

Анизотропия схлопывается до нуля от одного вычитания среднего — у всех шести стеков. У GPT-2: 0.945 → 0.007. У BERT: 0.227 → −0.000. У энкодера BART: 0.184 → −0.000. И у самого «конусного» из декодеров, T5: 0.868 → 0.007.

Отсюда у нас верна гипотеза Б. Пресловутый «конус представлений» — это не вырожденная геометрия, а смещение облака от начала координат. Информация внутри облака была на месте всё это время; просто косинус, который меряет углы из начала координат, смотрел не туда.

К сноске вновь возвращайтесь, когда сядете за код. Компактное наше следствие из неё для работы:

Центрируем перед косинусом. Всегда. Причём среднее надо считать по тому же распределению текстов, на котором работаем. Без этого измеряется не похожесть текстов, а положение общего центра масс — одинаковое для всех пар.

И тут также видно почему, например, [CLS]‑эмбеддинги «без нормализации плохо работают», а после центрирования считаются нормально.

3.2 Спектр: сколько измерений модель использует

Теперь зайдём с другой стороны. У облака есть ковариационная матрица, у неё — собственные значения \lambda_1 \ge \lambda_2 \ge \dots \ge \lambda_D. Их профиль говорит, по скольким направлениям размазана дисперсия.

По ним мы можем посчитать две (вообще говоря, не две, но две « наиболее популярные) статистики. Обе устроены так, чтобы не зависеть от общего масштаба:

Participation ratio — “эффективное число активных направлений”:

\text{PR} = \frac{\left(\sum_d \lambda_d\right)^2}{\sum_d \lambda_d^2}

Если вся дисперсия в одном направлении, \text{PR} = 1. Если она поровну размазана по k направлениям, \text{PR} = k.

Effective rank — то же самое по смыслу, но через энтропию спектра (Roy & Vetterli, 2007):

\text{erank} = \exp\left(-\sum_d p_d \log p_d\right), \qquad p_d = \frac{\lambda_d}{\sum_k \lambda_k}

Обе метрики зависят от D, поэтому снова считаем гауссов baseline: для изотропного облака в \mathbb{R}^D обе величины должны быть порядка D.

            модель   D      PR   erank  var@PC1  var@10PC  PR/D
   BERT (enc-only) 768  86.295 276.577    0.068     0.247 0.112
  GPT-2 (dec-only) 768   1.856   3.640    0.723     0.961 0.002
  T5-enc (enc-dec) 512 174.653 289.630    0.027     0.160 0.341
BART-enc (enc-dec) 768 112.859 307.103    0.051     0.226 0.147
  T5-dec (enc-dec) 512   3.377   9.482    0.515     0.874 0.007
BART-dec (enc-dec) 768  67.769 197.841    0.079     0.276 0.088
       гаусс D=512 512 453.917 480.284    0.004     0.035 0.887
       гаусс D=768 768 644.736 697.919    0.003     0.026 0.839

Что мы видим

  • GPT-2: PR ≈ 1.9 при D = 768. Первая главная компонента объясняет 72% дисперсии, первые десять — 96%. Облако тысяч токенных состояний, живущее формально в 768-мерном пространстве, по дисперсии вообще‑то упаковало всё примерно в два направления.

  • BERT: PR ≈ 86, effective rank ≈ 277, и энкодер BART: PR ≈ 113 при той же D = 768. Моделька на два порядка «объёмнее» GPT-2 при той же самой размерности.

  • Энкодер T5: PR ≈ 175 при D = 512 — относительно своей размерности самый распределённый.

  • Гауссов baseline: PR ≈ 645 при D = 768 и ≈ 454 при D = 512.

  • Декодеры снова разъехались: PR ≈ 3.4 у декодера T5 (PR/D = 0.007, то есть почти GPT-2) и PR ≈ 68 у декодера BART (PR/D = 0.088, то есть почти его собственный энкодер).

Колонка PR/D делает сравнение чуть более корректным между разными D: 0.002 у GPT-2 против 0.112 у BERT, 0.147 у энкодера BART и 0.341 у энкодера T5.

Разница объясняется маской внимания и objective.

  • Objective решает, во что упирается выход. У CLM последний слой читается ровно одним линейным отображением — lm_head, то есть W_E^\top h с завязанными весами эмбеддингов. Всё, что не помогает разложить h по строкам W_E, дисперсии не получает: направление, полезное для предсказания следующего токена, усиливается, остальные ужимаются. Плюс к этому pre‑LN архитектура GPT-2 накапливает в residual stream несколько координат‑гигантов (те самые massive activations из раздела 2.3), и они забирают почти весь след ковариации. Отсюда \text{PR} \approx 2: это «вся дисперсия сложена в пару служебных направлений».

    У MLM давление обратное: из каждой позиции нужно восстановить её собственный токен, то есть каждая позиция обязана нести и идентичность слова, и контекст. Одно направление такое не вместит — дисперсия расползается по десяткам.

    У span corruption и denoising выход энкодера не читается линейным классификатором: его читает декодер через cross‑attention, на всех позициях и на всех слоях сразу. Такое представление выгоднее держать «широким» — отсюда самые большие PR/D у энкодеров T5 и BART.

  • Маска определяет, сколько независимых ролей у позиций. В двунаправленном типе все позиции равноправны и каждая видит весь текст, поэтому облако токенов — это облако разных контекстуализированных смыслов. В каузальном типе позиция i видит только префикс, и соседние позиции отличаются ровно на один токен: состояния идут почти вложенной цепочкой, сильно скоррелированной вдоль текста.

Отсюда полное следствие: форму облака задаёт не маска, а то, что читает выход, плюс схема нормализации. Маска сюда входит только косвенно — через то, что каузальный выход обычно читается одной линейной головой.

Что тогда вообще определяется маской? Не форма, а структура сходств — «какие тексты эта модель считает похожими». Поехали к финалу.

3.3 Сравнивать два пространства между собой

Мы описали каждое облако по отдельности. Перейдем к финальной части — оценим насколько похожи пространства двух разных моделей?

Наивный ответ — «посчитаем косинус между эмбеддингами BERT и GPT-2» — не просто плох, он не определён. Координаты h^{\text{BERT}}_5 и h^{\text{GPT-2}}_5 — это разные числа про разные вещи; между базисами двух независимо обученных моделей нет никакого соответствия. А для T5 ещё и размерности не совпадают.

Самый классический вариант корректно померить два пространства Linear CKA (Centered Kernel Alignment, Kornblith et al., 2019):

\text{CKA}(X, Y) = \frac{\|Y^\top X\|_F^2}{\|X^\top X\|_F \cdot \|Y^\top Y\|_F}, \qquad X, Y \text{ центрированы}

CKA сравнивает не координаты, а матрицы попарных сходств объектов: «одинаково ли эти два пространства считают, какие тексты похожи друг на друга». Отсюда инвариантность к ортогональным поворотам и к изотропному масштабированию и работоспособность при разных D.

Linear CKA, n=2000 текстов, mean pooling:

                  BERT (enc-only)  GPT-2 (dec-only)  T5-enc (enc-dec)  BART-enc (enc-dec)  T5-dec (enc-dec)  BART-dec (enc-dec)
BERT (enc-only)              1.000             0.125             0.653               0.721             0.146               0.673
GPT-2 (dec-only)             0.125             1.000             0.206               0.228             0.235               0.278
T5-enc (enc-dec)             0.653             0.206             1.000               0.779             0.307               0.711
BART-enc (enc-dec)           0.721             0.228             0.779               1.000             0.270               0.823
T5-dec (enc-dec)             0.146             0.235             0.307               0.270             1.000               0.378
BART-dec (enc-dec)           0.673             0.278             0.711               0.823             0.378               1.000

Шумовая нижняя граница — CKA той же модели против гауссова облака:

  BERT (enc-only)    vs шум: 0.087
  GPT-2 (dec-only)   vs шум: 0.019
  T5-enc (enc-dec)   vs шум: 0.082
  BART-enc (enc-dec) vs шум: 0.086
  T5-dec (enc-dec)   vs шум: 0.022
  BART-dec (enc-dec) vs шум: 0.085

Зависимость шума от размера выборки (шум против шума, D=768):
  n=  300: 0.717
  n=  600: 0.563
  n= 2000: 0.278

Что мы видим

По baseline:

  • У CKA есть сильное конечно‑выборочное смещение. Два полностью случайных облака при n = 300 дают CKA около 0.72, при n = 600 — около 0.56, и даже при n = 2000 — всё ещё около 0.28. Причина в том, что при n, сравнимом с D, у двух случайных облаков неизбежно находится много совпадающих направлений просто по определению.

Это ловушка: нельзя посчитать CKA на паре сотен примеров, получить 0.6 и написать «пространства похожи». Поэтому мы взяли для этого раздела 2000 текстов и посчитали шумовую нижнюю границу для каждой модели отдельно — CKA той же модели против гауссова облака той же формы.

По результатам моделей:

пара

CKA

что общего

энкодер T5 ↔ энкодер BART

0.779

двунаправленность

BERT ↔ энкодер BART

0.721

двунаправленность

BERT ↔ энкодер T5

0.653

двунаправленность

GPT-2 ↔ энкодер BART

0.228

GPT-2 ↔ энкодер T5

0.206

GPT-2 ↔ BERT

0.125

одинаковые D, глубина, число голов

декодер BART ↔ энкодер BART

0.823

самая похожая пара во всей матрице

декодер BART ↔ энкодер T5

0.711

каузальный тип внутри «двунаправленного» кластера

декодер BART ↔ BERT

0.673

и с BERT тоже

декодер T5 ↔ энкодер T5

0.307

тут собственный энкодер далеко

декодер T5 ↔ GPT-2

0.235

«сосед по маске» тоже далеко

декодер T5 ↔ BERT

0.146

при шумовой границе 0.022

  • Три двунаправленных энкодера — плотный кластер 0.65–0.78. У них разные D, глубина, objective, токенизатор и корпус претрейна. Общее ровно одно — двунаправленная маска.

  • GPT-2 стоит в стороне от каждого из них (0.13–0.23) при шуме 0.02–0.09. Причём самая низкая похожесть во всей матрице — 0.125 у пары BERT/GPT-2, то есть у пары, которая совпадает по D, по глубине и по числу голов. Различаются они только маской.

  • А декодеры enc‑dec вносят вопросы. BART‑dec попал внутрь кластера двунаправленных (0.823 со своим энкодером, 0.673 с BERT), а T5-dec лежит сам по себе (0.15–0.38). Маска у них при этом одна и та же, каузальная.

    Понять результат

    Причин у этого расхождения может быть две:

    1. Протокол. Мы сами подали декодеру тот же текст teacher forcing‑ом, так что он прочитал его дважды: через cross‑attention и как собственную историю. Соблазнительно объявить, что вся похожесть отсюда, — но не совсем. Проверка в ноутбкуке: те же CKA, но декодеру подаётся либо фиксированный нейтральный префикс, либо вообще один стартовый токен. В обоих случаях единственный канал к тексту — cross‑attention.

    2. Вырожденность пространства. Шум метрики у декодера T5 — 0.022, как у GPT-2 (0.019), а у декодера BART — 0.085, как у энкодеров. Это схлопнутые пространства из 3.1–3.2: у декодера T5 анизотропия 0.868 и PR 3.4, совпадать ему просто нечем. Низкий CKA у вырожденного стека читается как «мало измеримых направлений», а не как «другая структура».

    Проверка в ноутбуке дала следующее: Teacher forcing завысил, но эффект не создал. Когда декодер текста не видел вовсе, BART‑dec держит 0.664 со своим энкодером и 0.655 с BERT — то есть остаётся внутри двунаправленного кластера (0.65–0.78). Значит, дело не в протоколе, а в cross‑attention: декодер читает выход энкодера без маски и наследует его структуру сходств. Версия «виновата подача данных» не подтвердилась.

    А вот вторая причина, геометрическая, работает. Шумная граница по baseline у декодера T5 — 0.022, как у GPT-2 (0.019), а у декодера BART — 0.085, как у энкодеров. Это те же самые схлопнутые пространства из 3.1–3.2: у декодера T5 анизотропия 0.868 и PR 3.4, совпадать ему просто нечем. Низкий CKA у вырожденного стека читается как «мало измеримых направлений», а не как «другая структура».

    Отсюда версия тезиса:

    > Среди типов, чья геометрия не вырождена, тип внимания — самый сильный группирующий фактор: три двунаправленных энкодера дают 0.65–0.78, а GPT-2 отстоит от каждого из них на 0.13–0.23 при шумовом пороге 0.02–0.09. Но маска не единственный фактор: вырожденность пространства обрубает измеримую похожесть (декодер T5), а cross‑attention возвращает декодеру структуру входа (декодер BART).

    Я не выношу однозначного вывода из сноски, ибо мы работаем с маленькими моделями. Для обобщения всего здесь должны быть масштабы (и данных, и моделей). Цель моих туториалов — показать эффекты и анализ.

Вывод

Мы посмотрели много картинок и почитали много чисел. Возникает вопрос: зачем это нужно? Ответ: чтобы понимать, откуда брать вектор и как агрегировать токены.

Вообще, общие правила такие:

  • центрируем и стандартизируем перед любой метрикой над эмбеддингами — раздел 3.1 показал, что иначе меряется положение общего центра масс, а не похожесть текстов;

  • служебный первый токен в пулинг не кладём — по разделам 2.2 и 2.3 это элемент механизма внимания с аномальной нормой, а не смысл;

  • у каузального типа не берём first, у encoder‑decoder берём выход энкодера, а если декодера — то с оговорками, о которых ниже;

  • а дальше выбираем пулинг sweep‑ом на своей задаче.

Почему не всегда последний токен для декодерных моделей?

Расхожий совет «у каузальной модели берите last» держится на наблюдении: последний токен — единственный, кто видел весь текст. Но оптимизирован он под предсказание следующего токена, а не под описание прочитанного: его состояние отвечает на вопрос «что я скажу дальше». Усреднение же собирает сигнал со всех позиций, и обычно этого хватает с запасом — даже с поправкой на разную экспозицию контекста из части 2. Плюс техническая ловушка (я так первую статью чуть не проср...чуть не потеряла!): H[:, -1, :] при right padding возьмёт padding, а не последний токен.

Но: если модель дообучали под эмбеддинги с пулингом по последнему токену, брать надо именно его — там objective выровнен под вашу задачу специально.

Почему не всегда первый для энкодерных моделей?

Потому что «первый токен» — это три разные вещи в трёх моделях, и это видно прямо в таблице типов: у BERT на позиции 0 стоит [CLS], у BART — <s>, а у энкодера T5 никакого начального служебного токена нет вовсе, там обычное слово. [CLS] действительно обучен агрегировать, но под NSP — под «идут ли эти два куска текста подряд», а не под «о чём этот текст».

И первая позиция может дать attention sink с аномальной нормой (до 0.75 медианной массы внимания у энкодера BART), то есть служебный элемент механизма, а не носитель смысла.

Но: если модель дообучали агрегации в служебном токене — забываем это и берем его. 

Почему нужно быть осторожным с токенами декодера в encoder‑decoder моделях?

Потому что состояние декодера — это не представление входа, а смесь «что я прочитал через cross‑attention» и «что я уже написал». Две причины держаться от него подальше:

  • Другой масштаб. Медианные нормы могут быть больше энкодерных. Складывать и считать косинус состояния без нормализации нельзя.

  • Похожесть на энкодер частично создаётся подачей. Мы подаём декодеру тот же текст teacher forcing‑ом, и контроль из 3.3 показал, во что это обходится: без подачи текста CKA декодера BART со своим энкодером падает с 0.823 до 0.664. Эффект не исчезает — структуру входа декодер наследует через cross‑attention, — но часть числа всё‑таки про наш способ подачи, а не про модель.

    Итого: если нужен вектор текста из encoder‑decoder — это выход энкодера. Состояния декодера имеют смысл, когда вас интересует именно генерация, а не текст.

Уносим самое-самое главное

Архитектура говорит, какие позиции могли что‑то узнать. Природа свойства говорит, где оно живёт. Токенизатор говорит, что вообще лежит на позиции 0. Для выбора пулинга нужны все три — и дешёвый sweep на своих данных честнее любого общего совета.

И шпору ниже тоже уносим. Первое сентября на носу — куда без шпор.

encoder‑only

decoder‑only

encoder‑decoder

Маска

полная

треугольная

enc: полная / dec: треуг. + cross без маски

Кто видел весь текст

все позиции

только последняя

все позиции энкодера

Откуда брать эмбеддинг текста

mean без спец‑токенов

mean (не last и точно не first)

mean по выходу энкодера

Чего избегать

[CLS] без файнтюна

first, сырой косинус, H[:,-1,:]

состояния декодера как «смысл входа»

Обязательная обработка

центрирование

центрирование

центрирование, раздельно для enc и dec

Какой слой

проверить sweep‑ом

проверить sweep‑ом

проверить sweep‑ом

Сравнение с другой моделью

CKA с шумовым анализом

CKA с шумовым анализом

CKA, раздельно enc/dec

Чего не делать

  1. Косинус без центрирования.

  2. first у каузального типа и служебный первый токен в пулинге, если этого не требует задача.

  3. [CLS] как готовый эмбеддинг предложения , если этого не допускает задача.

  4. H[:, -1, :] при right padding. Возьмёте padding вместо последнего токена — молча, без ошибки. Только attention_mask.sum(1) - 1.

  5. Нормы, анизотропия и PR между моделями разной D без baseline. Без гауссова контроля числа несопоставимы.

  6. Косинус между эмбеддингами разных моделей. Общего базиса у независимо обученных моделей не существует — нужен CKA.

  7. CKA на маленькой выборке. При n \approx D два случайных облака дают 0.5–0.7. Берите n \gg D и считайте шумовую нижнюю границу для каждой модели отдельно.

  8. Смешивание энкодера и декодера — и состояние декодера как «эмбеддинг входа».

Спасибо, что дочитали!

Потыкать дальше предлагаю:

  • Повторить на roberta-base, pythia-410m, mt5-small — и проверить, держится ли кластеризация по типу маски на других семействах и языках.

  • Посмотреть, как метрики ведут себя с ростом масштаба: massive activations и attention sink на моделях от 1B выражены резче (Sun et al., 2024).

И как всегда зову к себе за новыми материалами и страданиями

Присоединяйтесь к Just Data Blog, ставьте лайки и я буду лайкать на выходных, чтобы писать дальше!: )

До встречи!