• Русский
  • Блок трансформера

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

    Это происходит внутри каждого токена, в небольшой нейросети под названием MLP (многослойный перцептрон: умножение на матрицу, «изгиб», снова умножение на матрицу). Внимание плюс MLP, с небольшой «обвязкой» вокруг, образуют один блок трансформера — его также называют слоем. Модель — это такой блок, повторённый десятки раз, каждый раз со своими весами.

    Один блок, шаг за шагом

    Блок оборачивает обе части одинаково. Берётся копия вектора токена, она нормализуется (её числа приводятся к стандартному масштабу, подробнее ниже), часть блока работает с этой копией, а результат прибавляется обратно к исходному вектору. Нормализация перед каждой частью называется схемой pre-norm; её используют почти все современные модели.

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

    Рисунок 6.1 · Внутри блока трансформера
    RMSNormМногоголовое вниманиеRMSNormMLP (d → 4d → d)вход xв следующий блокостаточный поток
    остаточный поток0.71.0−0.70.6−1.41.4−0.70.5
    ветка
    1/8

    Вектор токена входит в блок. Вертикальная линия — остаточный поток: сам вектор, который переходит из блока в блок.

    Толстая вертикальная линия — остаточный поток. Каждая боковая ветка нормализует копию вектора, преобразует её и прибавляет результат обратно в точке ⊕. Полоски показывают 8 чисел игрушечного вектора по ходу пути (числа MLP считаются по-настоящему; поправка от внимания условная, ведь одному токену не на кого смотреть).

    Весь блок записывается двумя строчками:

    x←x+Attention(Norm(x))x \leftarrow x + \text{Attention}(\text{Norm}(x)) x←x+MLP(Norm(x))x \leftarrow x + \text{MLP}(\text{Norm}(x))

    Остаточный поток

    Самое важное решение в архитектуре выглядит самым скучным: это +. Блок никогда не заменяет вектор: он читает нормализованную копию и прибавляет поправку. Представьте вектор как общий блокнот, в который каждый блок может заглянуть и что-то дописать.

    Из этого следуют две важные вещи:

    • Глубокие сети обучаются. При обратном распространении (глава 8) градиент (сигнал поправки для каждого веса) идёт прямо вниз по потоку через каждый +, так что даже первый блок модели из 100 блоков получает ясный сигнал для обучения. Без остаточных связей глубокие сети почти не учатся.
    • Блоки могут специализироваться. Каждый блок добавляет лишь немного, поэтому ранние блоки могут заниматься написанием и грамматикой, а поздние — строить более абстрактные признаки, и все пишут в одно и то же пространство.

    Нормализация и активация

    Две небольшие детали держат числа в порядке. Нормализация масштабирует вектор так, чтобы его числа были в среднем порядка 1. Сам поток «плывёт», пока сотня блоков дописывает в него поправки; а раз каждая часть читает нормализованную копию, любое внимание и любой MLP получают вход привычного масштаба, что бы ни случилось выше по течению. Функции активации внутри MLP добавляют «изгиб», без которого сеть была бы одним большим умножением матриц. Самая простая, ReLU, — это просто max⁡(0,x)\max(0, x); GELU и SiLU — её гладкие версии: положительные числа пропускают, а отрицательные прижимают к 0.

    Рисунок 6.2 · Нормализация и функции активации
    вход · среднее 0.44 · rms 1.02
    выход · rms 1.00

    RMSNorm убирает только общий размер: тяните «масштаб» — выход не меняется, а вот «сдвиг» на него влияет. В настоящих слоях результат затем умножается на обучаемый коэффициент для каждого измерения.

    Нормализация: двигайте масштаб и сдвиг и сравните RMSNorm с LayerNorm. Активации: нарисованы все три кривые, выбранная выделена; двигайте x, чтобы прочитать значение.

    GPT-2 использовала LayerNorm: вычесть среднее, разделить на стандартное отклонение (типичное расстояние чисел от их среднего). Большинство современных моделей (Llama, Mistral, Qwen, Gemma) используют более простую RMSNorm, которая пропускает среднее:

    RMSNorm(x)=x1d∑ixi2+ϵ⊙g\text{RMSNorm}(x) = \frac{x}{\sqrt{\tfrac{1}{d}\sum_i x_i^2 + \epsilon}} \odot g

    где gg — обучаемый коэффициент для каждого измерения, ϵ\epsilon — крошечное число, чтобы не делить на ноль, а ⊙\odot — поэлементное умножение. Работает не хуже и дешевле.

    MLP

    MLP (его ещё называют полносвязной сетью, feed-forward) применяется к каждому токену отдельно: здесь ни один токен не смотрит на другой. Классический вариант расширяет вектор в 4 раза, применяет активацию и проецирует обратно — умножает на вторую матрицу, возвращая исходную ширину. Широкая середина даёт простор: каждое её число может откликаться на свой шаблон в векторе. А активация между матрицами необходима: два умножения на матрицу подряд без ничего между ними сводятся к одному.

    MLP(x)=W2 GELU(W1x)\text{MLP}(x) = W_2\, \text{GELU}(W_1 x)

    Современные модели используют вариант с затвором, SwiGLU, с тремя матрицами: одна ветка проходит через SiLU и работает как «затвор», поэлементно умножающий другую ветку:

    SwiGLU(x)=W2(SiLU(W1x)⊙W3x)\text{SwiGLU}(x) = W_2\big(\text{SiLU}(W_1 x) \odot W_3 x\big)

    В больших моделях примерно две трети всех параметров сидят в этих MLP.

    Блоки друг на друге

    Выход блока имеет ровно ту же форму, что и вход, поэтому блоки можно ставить стопкой. У каждого токена свой столбец векторов, который поднимается через всю модель, а на каждом блоке внимание передаёт информацию между столбцами.

    Рисунок 6.3 · Стопка блоков
    Столбцы — токены, строки — блоки. Импульсы поднимаются по остаточному потоку каждого токена; на каждом блоке связи внимания (пунктир) переносят информацию от более ранних токенов к более поздним. Информация течёт только вправо, к более поздним токенам.

    Наверху применяется финальная нормализация, а вектор каждого токена умножается на матрицу обратного эмбеддинга (unembedding, размером словарь × dmodeld_\text{model}) — получается по одному логиту (оценке) на каждый токен словаря. При генерации важна только последняя позиция: её логиты предсказывают следующий токен. При обучении каждая позиция сразу предсказывает свой следующий токен. GPT-2 использует для этого ту же таблицу эмбеддингов (связывание весов, weight tying); большинство более крупных моделей держат отдельную выходную матрицу.

    Вот и вся модель, от текста до предсказания:

    1. Разбить текст на токены (глава 2).
    2. Взять вектор каждого токена из таблицы эмбеддингов (глава 3) и прибавить вектор позиции, если модель его использует (модели с RoPE вместо этого поворачивают запросы и ключи внутри внимания, глава 4).
    3. Провести все векторы вверх через блоки. В каждом блоке внимание даёт токенам обменяться информацией (глава 5), затем MLP работает с каждым токеном отдельно; оба прибавляют свой результат к потоку.
    4. Ещё раз нормализовать и умножить на матрицу обратного эмбеддинга: по логиту на каждый токен словаря.
    5. Softmax превращает логиты последней позиции в вероятности, и выбирается один токен (глава 9). Его дописывают в текст, и всё начинается заново.

    Как рождается ответ

    Каждый блок только прибавляет к остаточному потоку, поэтому поток всё время живёт в одном и том же пространстве. Значит, можно схитрить: взять поток после блока 3 или блока 7, раньше времени применить финальную нормализацию и обратный эмбеддинг и спросить: «а что модель сказала бы сейчас?» Этот приём называется logit lens («линза логитов»).

    Рисунок 6.4 · Логит-линза
    Эйфелева·башня·находится·в·городе·Париже?
    после блока 4
    ·Москве9.0%
    ·Лондоне5.0%
    ·Риме3.0%
    ·Париже2.0%
    ·Берлине2.0%
    Вероятность «Париже» после каждого блока

    Средние блоки: модель поняла, что дальше будет название города. Города соревнуются.

    Догадка о следующем токене после каждого блока 12-блочной модели для промпта «Эйфелева башня находится в городе». Нажмите кнопку или двигайте ползунок. Ранние блоки угадывают грамматические «заполнители», средние сужают выбор до городов, верхние уверенно выбирают ответ. Числа придуманы вручную, но именно такую форму логит-линза обычно показывает на настоящих моделях.

    Картина совпадает с тем, что находят исследования интерпретируемости: нижние слои работают с локальными, поверхностными признаками (написание, грамматика, несколько предыдущих токенов), средние собирают смысл и ищут факты, а верхние превращают всё это в уверенное предсказание.

    Что хранит MLP

    Где живёт факт вроде «Эйфелева башня — в Париже»? Эксперименты, в которых редактируют или отключают отдельные слои MLP, указывают на средние MLP. Удобная картинка — память «ключ — значение»: строки W1W_1 — это ключи, которые совпадают с шаблонами в потоке («речь об Эйфелевой башне»), а соответствующие столбцы W2W_2 — значения, которые дописывают связанную информацию («Париж, Франция») обратно в поток.

    Так чисто бывает редко, потому что модели хранят гораздо больше признаков (понятий, которые они умеют распознавать), чем у них измерений. 4096-мерный поток вмещает многие тысячи почти перпендикулярных направлений, и модели этим пользуются. Это называется суперпозицией:

    Рисунок 6.5 · Признаков больше, чем измерений
    кошка0.00
    Париж0.65
    код0.00
    прошедшее время0.00
    сарказм0.00

    Чистое чтение: светятся только активные признаки.

    Ближайшая пара: 72° · ● скрытый вектор h

    Каждая стрелка — признак, записанный как направление в пространстве всего из 2 чисел. Включайте признаки и следите за чтением: при 3–5 признаках и одном активном за раз небольшой порог (ReLU со смещением) читает их чисто. Включите два несоседних признака в пятиугольнике или втисните 6 и больше — и выключенные признаки начнут светиться, а включённые могут погаснуть. Суперпозиция работает потому, что большинство признаков редко активны одновременно.

    Поэтому отдельные нейроны — отдельные числа в широком среднем слое MLP — часто трудно интерпретировать: один нейрон участвует во многих признаках, а один признак размазан по многим нейронам. Исследователи интерпретируемости обучают разреженные автоэнкодеры (sparse autoencoders — небольшие сети, которые переписывают поток как набор из немногих активных признаков), чтобы снова разделить признаки, и нашли их миллионы в рабочих моделях — от «моста Золотые Ворота» до «кода с уязвимостью». Если усилить или ослабить такой признак, поведение модели заметно меняется.

    Насколько он большой?

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

    Рисунок 6.6 · Считаем параметры
    124,4 млнпараметров (124 439 808)0,2 ГБчтобы хранить по 16 бит на параметр3 072ширина скрытого слоя MLP
    • Эмбеддинги 31,6% 39,4 млн
    • Внимание 22,8% 28,3 млн
    • MLP 45,5% 56,7 млн
    • Нормализация 0,0% 38,4 тыс.

    На слой: внимание 4d² + 4d, MLP 8d² + 5d, две LayerNorm 4d. Плюс таблицы токенов и позиций (таблица токенов повторно используется как выходной слой).

    Выберите пресет, затем меняйте глубину, ширину и размер словаря. GPT-2 small даёт ровно 124 439 808 параметров, а Llama 2 7B — 6 738 415 616. Посмотрите, как MLP начинает доминировать с ростом ширины и какую долю маленькой модели занимает одна только таблица эмбеддингов.

    Из формул следуют два практических правила. В каждом слое около 12 dmodel212\, d_\text{model}^2 параметров, так что удвоение ширины учетверяет стоимость слоя. А при 16 битах на параметр модели нужно около 2 байт памяти на параметр, просто чтобы загрузиться: модели на 7B нужно около 14 ГБ ещё до обработки первого токена. Новые модели урезают часть этого, например групповыми запросами (глава 10) и квантизацией (глава 13).

    Итоги

    • Блок — это две остаточные поправки: внимание (между токенами), затем MLP (внутри каждого токена), каждая применяется к нормализованной копии.
    • Остаточный поток несёт вектор каждого токена вверх через модель; блоки только прибавляют к нему, и поэтому глубокие модели остаются обучаемыми.
    • RMSNorm держит векторы стабильного размера; GELU и SwiGLU дают MLP нелинейность.
    • Вся модель: токены → эмбеддинги → стопка блоков → финальная нормализация → обратный эмбеддинг → softmax по словарю.
    • Финальный вектор превращается в логиты матрицей обратного эмбеддинга; логит-линза применяет её раньше, чтобы увидеть, как ответ формируется слой за слоем.
    • MLP отчасти работают как память «ключ — значение», а благодаря суперпозиции модели упаковывают больше признаков, чем у них измерений.

    Это вся архитектура. Всё, что делает её умной, — значения параметров, а они берутся из обучения.