Как работают трансформеры: от узких мест в RNN до механизмов внимания, агентов и окон контекста
Пошаговый обзор трансформера: почему RNN застряли, как работают токены и эмбеддинги, внимание, QKV, головы, позиции, структура блоков, масштабирование и агенты.
Любой, кто использует только инструменты ИИ, может обходиться без понимания того, что находится в их основе. Однако те, кто хочет создавать, отлаживать или совершенствовать такие системы, не могут обойтись без этого знания. Все распространённые большие языковые модели основаны на одной архитектуре, описанной в пятнадцатистраничной статье 2017 года под названием «Attention Is All You Need». Немногие исследовательские работы за последнее десятилетие настолько сильно повлияли на развитие искусственного интеллекта. Идеи, лежащие в основе этой архитектуры, не кажутся настолько сложными, как может показаться, а математические расчёты становятся понятными, если выполнять их в правильном порядке. После этого те же самые идеи встречаются повсюду: в способах планирования агентами, в принципах работы обучения в контексте, в возможности модели переключаться между темами в ходе разговора и в значимости более длинных окон контекста.
В данном обзоре сначала рассматривается старый последовательный подход и причины его неудачи, затем объясняется, как текст преобразуется в числа, далее — концепция внимания и полная структура блоков, и в заключение показано, как эта концепция превратилась в современные языковые модели и агенты.
Почему чтение текста по одному слову за раз столкнулось с трудностями
До появления трансформеров обработкой языка занимались в основном рекуррентные нейронные сети, обычно сокращаемые до RNN. Идея проста: сеть проходит по последовательности слов за словом, передавая дальше скрытое состояние — краткое резюме всего увиденного до этого момента.
Примерно так выглядит процесс: кто-то читает роман, но может оставить себе лишь одну записку, и ему приходится читать страницу за страницей, не пропуская ни одной и не возвращаясь назад. После каждого предложения записка переписывается с тем, что кажется важным, но она мала по размеру. К 300-й странице почти ничего из первой страницы не остается. Также невозможно передать другу вторую главу для одновременного чтения, поскольку сначала нужно закончить записки к первой главе.
Такой строгий порядок приводит к двум отдельным проблемам масштабирования.
Первая — это исчезающий градиент. Обучение происходит с помощью обратного распространения ошибки, которое определяет, насколько каждый параметр повлиял на ошибку. В RNN, читающем длинную последовательность, этот сигнал должен передаваться назад через каждый шаг времени. К моменту достижения самых ранних шагов он часто сильно ослабевает, поэтому сеть фактически не может извлечь информацию из того, что происходило на ранних этапах.
Вторая проблема — последовательное узкое место. Результат на позиции n невозможно вычислить до завершения обработки позиции n-1, поскольку каждый шаг требует использования предыдущего скрытого состояния. Современные GPU разработаны для одновременной обработки огромного количества операций, а RNN практически не предоставляет им возможностей для параллельной работы. Документ из 1 000 слов требует выполнения 1 000 шагов подряд, причем аппаратура в основном находится в состоянии покоя между ними.
На приведённой ниже диаграмме показано сравнение двух способов обработки токенов: с одной стороны — по одному токену с постепенным исчезновением скрытого состояния, а с другой — одновременная обработка каждой пары токенов:
╔══════════════════════════════════════════════════════════════════════════════╗
║ RNN vs TRANSFORMER: HOW TOKENS ARE PROCESSED ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────┐ ║
║ │ RNN ── Sequential (slow, forgets early context) │ ║
║ └─────────────────────────────────────────────────────────────────────┘ ║
║ ║
║ "The" "cat" "sat" "on" "the" "mat" ║
║ │ │ │ │ │ │ ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║
║ │ RNN │──▶│ RNN │─▶│ RNN │▶│ RNN │▶│ RNN │▶│ RNN │ ║
║ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ ║
║ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ ║
║ h₁ ──▶ h₂ ──▶ h₃ ──▶ h₄ ──▶ h₅ ──▶ h₆ ║
║ ║
║ Step 1 Step 2 Step 3 Step 4 Step 5 Step 6 (must wait!) ║
║ ⚠ "The" signal is diluted through 5 hops by the time we reach "mat" ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────┐ ║
║ │ TRANSFORMER ── Parallel (fast, every token sees all others) │ ║
║ └─────────────────────────────────────────────────────────────────────┘ ║
║ ║
║ "The" "cat" "sat" "on" "the" "mat" ◀── ALL AT ONCE ║
║ │╲╲ │╲ ╲╲ │╲╲ ╲ │ ╲╲ │ ╲╲ │ ║
║ │ ╲╲ │ ╲ ╲╲ │ ╲╲ ╲ │ ╲╲ │ ╲╲ │ ║
║ ├───╫──┼───╫───┼───╫───┼────╫──┼────╫───┤ ← every token ║
║ │ ╱╱ │ ╱ ╱╱ │ ╱╱ ╱ │ ╱╱ │ ╱╱ │ attends to ║
║ │╱╱ │╱ ╱╱ │╱╱ ╱ │ ╱╱ │ ╱╱ │ every token ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║
║ │ out │ │ out │ │ out │ │ out │ │ out │ │ out │ ← all computed ║
║ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ simultaneously ║
║ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ ║
║ ✓ "The" has DIRECT connection to "mat" — no information decay ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ LEGEND: ──▶ sequential dependency ╲╱╱ all-pairs attention ║
║ h₁ hidden state ⚠ information bottleneck ║
╚══════════════════════════════════════════════════════════════════════════════╝
Ворота помогли, но не изменили сущность проблемы
Сети долгосрочной и краткосрочной памяти, представленные Хохрайтером и Шмидхубером в 1997 году, ввели концепцию «ворот», позволяющих явно контролировать, что сохранять, что удалять и что генерировать на каждом шаге. Они хорошо справлялись со своей задачей. В течение 2010-х годов они использовались в большинстве практических задач обработки естественного языка, включая ранние системы машинного перевода, анализ настроений и генерацию текста.
Однако они по-прежнему оставались последовательными структурами. Обработка очень дальних зависимостей по-прежнему была сложной, а параллельное оборудование ещё не могло использоваться в полной мере. LSTM потерпели неудачу не потому, что плохо моделировали язык, а потому, что не могли масштабироваться: увеличение вычислительных ресурсов приносило всё меньшую отдачу, а для преодоления этого ограничения требовался совершенно иной стиль обработки данных.
От текста к числам
Нейронные сети обрабатывают числа, а язык состоит из слов, поэтому перед тем, как в игру вступает механизм внимания, необходимо произвести преобразование. Для этого требуется два шага: токенизация и вкладка.
Токенизация
Токенизация преобразует строку в последовательность целочисленных идентификаторов, взятых из фиксированного словаря. Сначала следует понимать, что токены — это не слова. Современные токенизаторы разделяют текст на субслова, обычно с использованием методов Byte-Pair Encoding или WordPiece, и результат выглядит так:
"Hello world" → ["Hello", " world"] → [15496, 995]
"unbelievable" → ["un", "believ", "able"] → [256, 9391, 540]
"ChatGPT" → ["Chat", "G", "PT"] → [14126, 38, 2969]
"antidisestablishmentarianism" → ["ant", "idis", "est", "ablish", "ment", "ari", "an", "ism"]
Часто встречающиеся слова получают собственный токен, в то время как редкие или сложные слова разбиваются на более мелкие части. Это обеспечивает хорошее покрытие текста при умеренном размере словаря, поскольку нет необходимости создавать запись для каждого возможного слова. Размеры словарей варьируются от примерно 30 000 для BERT и 50 257 для GPT-2 до более чем 100 000 в современных моделях.
Удобное преобразование для английского языка: один токен соответствует примерно трём четвертям слова, а одно слово — примерно 1,3 токена. Следовательно, роман из 100 000 слов состоит примерно из 133 000 токенов, что имеет значение при ограничениях по размеру контекстного окна.
Эмбеддинги
Матрица вжимания, состоящая из одной строки на каждую запись словаря и d_model столбцов, преобразует каждый идентификатор токена в плотный вектор. Чтобы найти информацию о токене, достаточно просто выбрать соответствующую строку. Идентификатор токена 995, обозначающий слово «world», указывает на строку 995, и в результате получаются числа d_model — например, 0.24, -0.83, 0.17 и так далее до 0.91.
Эти строки формируются в процессе обучения, и возникает полезное свойство: токены с близкими значениями оказываются с векторами, геометрически близкими друг к другу.
Cosine similarity in embedding space:
similarity("cat", "lion") ≈ 0.89 ← very similar
similarity("cat", "moon") ≈ 0.12 ← not similar
similarity("king", "queen") ≈ 0.91 ← very similar
Одно предостережение относительно известного примера: король минус мужчина плюс женщина равно королева. Эта арифметика основана на технологии Word2Vec 2013 года, а не на эмбеддингах трансформеров. Трансформеры обучают свои эмбеддинги совместно со всеми остальными параметрами, поэтому простая векторная арифметика менее надежна. Однако сохраняется принцип, согласно которому слова с близкими значениями находятся в соседних областях пространства.
Одинаковая ширина везде
Фиксированная размерность d_model присутствует везде в трансформере: в эмбеддингах, результатах механизма внимания, а также во входах и выходах слоев с прямой передачей. Это сделано намеренно. Каждый компонент читает данные и записывает в них из одного потока векторов фиксированной ширины, называемого потоком остатков, который проходит через каждый слой. Поскольку все компоненты работают с вектором одинакового размера и добавляют свои результаты обратно в него, элементы синхронизированно функционируют. Именно поэтому информацию о позиции можно просто добавить к эмбеддингу токена: у них одинаковая структура, и сумма напрямую попадает в поток.
Таким образом, входными данными для первого блока являются эмбеддинг токена и вектор позиции. Поскольку они находятся в одном пространстве, их суммирование не требует дополнительных параметров, а информация о позиции включается в те же векторы, которые несут смысл. Модели в стиле BERT, обрабатывающие два предложения одновременно, например при ответах на вопросы с использованием вопроса и текста, добавляют эмбеддинг сегмента, который указывает, к какому предложению относится каждый токен — 0 для первого и 1 для второго. Модели в стиле GPT этого не делают.
Attention: обучение тому, куда смотреть
Примерно в 2014–2015 годах исследователи, работающие над машинным переводом, заметили недостаток даже в системах LSTM. Модель сжимала всю информацию о входном предложении в один вектор фиксированного размера перед тем, как начать генерировать результат, что становилось ещё одним узким местом. Возник вопрос: может ли модель на каждом этапе генерации заглянуть во всё входное предложение. Ответом на этот вопрос стал механизм внимания, который изменил подход к моделированию последовательностей.
Два повседневных примера помогают интуитивно понять эту идею.
На шумной вечеринке, где идёт десять разговоров одновременно, мозг не придаёт равный вес каждому звуку при прослушивании разговора друга. Он усиливает голос и звук из направления друга, снижая громкость остальных звуков, но не выключая их полностью. Это усиление происходит постепенно, а не путём включения/выключения.
Когда человеку дают классную фотографию и просят найти учителя, он не сканирует каждый пиксель одинаково. Поиск сразу направляется на признаки, указывающие на взрослого человека, такие как рост по сравнению с остальными и пропорции лица. То, что ищут, определяет направление взгляда.
Компьютерное внимание превращает эти интуиции в четыре шага: иметь что-то для поиска, то есть запрос; иметь набор кандидатов, которые могут быть релевантными; присвоить каждому кандидату непрерывную оценку релевантности; и объединить информацию, взвешенную по этим оценкам.
Заблуждение, которое стоит прояснить сразу: внимание не означает, что модель фокусируется на одной вещи и игнорирует всё остальное. Результат — это взвешенная средняя, к которой вносит вклад каждый элемент, причем некоторые из них вносят гораздо больший вклад, чем другие. Это постепенное учитывание факторов, а не двоичная концентрация.
Исходная, простая форма
В своей первоначальной форме механизм внимания был дополнением к моделям RNN и LSTM. На каждом шаге декодирования модель выполняла следующее:
- анализировала все скрытые состояния кодера;
- рассчитывала показатель релевантности между текущим состоянием декодера и каждым состоянием кодера;
- преобразовывала эти показатели в веса с помощью функции softmax;
- брала сумму взвешенных значений состояний кодера в качестве контекста внимания.
Функция softmax заслуживает краткого объяснения. Она преобразует вектор произвольных вещественных чисел в распределение вероятностей. Каждый показатель преобразуется в значение e в степени этого показателя, затем делится на сумму всех таких значений. Все результаты остаются положительными и их сумма равна 1; кроме того, поскольку экспонентная функция увеличивает разницу между большими и малыми показателями, элемент с наивысшим значением получает наибольшую долю веса.
Это стало значительным улучшением, поскольку теперь модель могла в каждом шаге обращаться к любой части входных данных. Затем авторы статьи «Attention Is All You Need» предложили более смелую идею: а что, если убрать рекуррентные механизмы и сделать так, чтобы внимание не было дополнением, а составляло всю модель?
Самовнимание и тройка запроса, ключа и значения
Основной идеей статьи 2017 года является самовнимание. Вместо того чтобы обращаться от одной последовательности к другой, каждый элемент внутри одной и той же последовательности обращается ко всем остальным элементам в ней. Именно так трансформеры создают контекст, и для его понимания требуются три вектора, присутствующих при каждом вычислении внимания: запрос, ключ и значение.
Поисковик видео
При вводе запроса «как приготовить хлеб из закваски» на видео-сайте текст не сравнивается с каждым кадром каждого видео. Каждое видео имеет метаданные в виде меток, которые выполняют роль ключей: название, теги, ключевые слова описания. Сайт сопоставляет запрос с этими метками, чтобы определить степень релевантности, после чего отображаются видео с наивысшими оценками, чтобы можно было получить их фактический контент.
Есть один важный нюанс. Результатом является не одно конкретное видео, а взвешенная смесь всех видео одновременно, причем каждое из них воспроизводится с громкостью, пропорциональной его релевантности. Самое релевантное видео доминирует, а более менее значимые видео добавляют свой вклад в более тихом уровне. Схема соответствия следующая:
| YouTube Concept | Attention Concept | Question it Answers |
|----------------|------------------|---------------------|
| Search query | **Query (Q)** | "What am I looking for?" |
| Video metadata/tags | **Key (K)** | "What do I contain?" |
| Actual video content | **Value (V)** | "What should I contribute?" |
Почему три отдельных вектора
Почему бы не сравнивать эмбеддинги напрямую? Возьмём предложение «Кошка сидела на коврике, потому что устала». Чтобы понять, на кого указывает местоимение «она», слову необходимо обратить внимание на «кошку». Однако в пространстве сырых эмбеддингов местоимение и существительное не являются особенно похожими. Разделение на запросы и ключи позволяет модели понять, что запрос местоимения должен соответствовать ключам существительных, на которые оно может указывать, даже если местоимение и существительное совершенно не похожи в своих базовых эмбеддингах. Полученные проекции создают пространство релевантности, отдельное от пространства сходства сырых эмбеддингов. Релевантность и сходство — это разные вещи, и архитектура QKV позволяет модели кодировать оба аспекта.
Масштабируемое внимание с точечным произведением за четыре шага
Первый шаг — это проекция. Эмбеддинг каждого токена умножается на три выученные матрицы: W_Q, W_K и W_V, в результате чего получаются запрос, ключ и значение для данного токена.
Второй шаг измеряет совместимость. Вопрос заключается в том, насколько хорошо токен a соответствует токену b, а ответом является скалярное произведение запроса токена a и ключа токена b. Высокое значение означает, что токен a должен уделять пристальное внимание токену b. Скалярные произведения увеличиваются с размером вектора и размерностью ключа d_k, а не только с его направлением; поэтому на следующем шаге они масштабируются.
Третий шаг — масштабирование и нормализация. Когда d_k велик, необработанные скалярные произведения становятся большими, что приводит к тому, что функция softmax работает в областях с очень малыми градиентами. Деление на квадратный корень d_k перед применением softmax предотвращает это, отсюда и название метода — масштабированное скалярное произведение внимания. Результатом является набор весов alpha_ab.
Четвертый шаг — агрегация. Результат для токена a представляет собой сумму по всем токенам b из произведения alpha_ab на вектор значений для b.
Все токены можно обрабатывать вместе как матрицы в одной компактной формуле: Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V. На диаграмме показано применение этой формулы к трехсловному выражению «the cat sat»:
╔══════════════════════════════════════════════════════════════════════════════╗
║ SCALED DOT-PRODUCT ATTENTION ── "the cat sat" ║
╚══════════════════════════════════════════════════════════════════════════════╝
STEP 1: Input embeddings - ALL tokens are stacked into one matrix X
┌─────────────────────────────────────────┐
│ "the"→x₁ "cat"→x₂ "sat"→x₃ │ X ∈ ℝⁿˣᵈ
└──────────────────┬──────────────────────┘
│ the SAME X feeds all three projections
STEP 2: Three separate linear projections (each applied to every token)
┌─────────────┴─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ W_Q │ │ W_K │ │ W_V │ ← learned weight matrices
└────┬────┘ └────┬────┘ └────┬────┘
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Q rows │ │ K rows │ │ V rows │
│ q₁ │ │ k₁ │ │ v₁ │
│ q₂ │ │ k₂ │ │ v₂ │
│ q₃ │ │ k₃ │ │ v₃ │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
STEP 3: score = QKᵀ, scale by 1/√dₖ, then softmax row-wise
│ │ │
└──────┬──────┘ │
▼ │
┌─────────────────────┐ │
│ softmax(QKᵀ / √dₖ) │ │
│ the cat sat │ │
│ the[.72 .20 .08] │ │ each row
│ cat[.12 .71 .17] │ │ sums to 1.0
│ sat[.09 .28 .63] │ │
└──────────┬──────────┘ │
│ │
STEP 4: multiply weights by Values V (weighted sum)
└──────────┬─────────┘
▼
┌─────────────────┐
│ output for "cat"│ 0.12·v₁ + 0.71·v₂ + 0.17·v₃
└────────┬────────┘ ← rich context-aware vector
│
OUTPUT: contextualized token representations
┌──────────┐ ┌──────────┐ ┌──────────┐
│"the" │ │"cat" │ │"sat" │
│knows it │ │knows it │ │knows │
│precedes │ │sat, and │ │who was │
│"cat" │ │where │ │sitting │
└──────────┘ └──────────┘ └──────────┘
Пример из практики: словарь слов
Возьмём фразу «Она пошла в банк, чтобы положить деньги». При кодировании слова «банк» трансформером механизм самообратной связи позволяет этому слову одновременно анализировать все остальные слова. Большие веса приходятся на слова «положить» и «деньги», что вносит финансовый смысл в представление слова «банк». Контекст устраняет неоднозначность.
╔══════════════════════════════════════════════════════════════════════════════╗
║ SELF-ATTENTION RESOLVES AMBIGUITY: What does "bank" mean? ║
╚══════════════════════════════════════════════════════════════════════════════╝
Sentence: "I went to the bank to deposit money"
t₁ t₂ t₃ t₄ t₅ t₆ t₇ t₈
ATTENTION WEIGHTS for token "bank" (t₅) attending to all other tokens:
Token │ Weight │ Visualization
──────────┼────────┼───────────────────────────────────────────
"I" │ 0.03 │ ░
"went" │ 0.04 │ ░
"to" │ 0.02 │
"the" │ 0.03 │ ░
"bank" │ 0.08 │ ░░
"to" │ 0.05 │ ░
"deposit" │ 0.38 │ ████████████████████████░░░░░░░░ ← strong!
"money" │ 0.37 │ ████████████████████████░░░░░░░ ← strong!
FULL ATTENTION HEATMAP (rows = query token, columns = key token):
Higher weight → more ░/▒/▓/█
Q\K │ I went to the bank to deposit money
──────────┼──────────────────────────────────────────────
I │ ▓ ░ ░ ░ ░ ░ ░ ░
went │ ░ ▓ ░ ░ ░ ░ ░ ░
bank │ ░ ░ ░ ░ ▒ ░ █ █ ← "bank"→"deposit","money"
deposit │ ░ ░ ░ ░ █ ░ ▓ ▒ ← "deposit"→"bank"
money │ ░ ░ ░ ░ █ ░ ▒ ▓ ← "money"→"bank"
BEFORE attention: "bank" = ambiguous (river bank? financial bank?)
AFTER attention: "bank" ≈ 0.38·v(deposit) + 0.37·v(money) + ...
→ "bank" representation is now strongly financial ✓
The model learned this WITHOUT any explicit disambiguation rules.
Веса на той иллюстрации показаны для наглядности и не соответствуют реальному модели. На самом деле структуры обычно более хаотичны, а исследования того, как веса внимания связаны с процессами «мышления» модели, все еще продолжаются. Практическая польза от этого отличается от той, что показано на рисунке: самовнимание для всех токенов представляет собой умножение матриц, то есть одну операцию на GPU. То, что для RNN требует n последовательных шагов, для трансформера нуждается всего в одной параллельной операции, и именно поэтому трансформеры обладают высокой масштабируемостью.
Множество голов — множество подходов
Один механизм обработки вычисляет один тип релевантности за раз, так что что происходит, когда важны несколько типов связей одновременно? Возьмём пример: «Музыкант, который выступил на фестивале, получил награду». Чтобы понять этот пример, необходимо одновременно учитывать несколько зависимостей: связь «получил» с субъектом и глаголом «музыкант», связь «музыкант» с действием «выступил» через относительное предложение, связь «выступил» с местом проведения — фестивалем, а также связь «награду» с глаголом и объектом «получил».
Одна голова должна была бы поместить всё это в один набор весов. Вместо этого механизм многоголовой атенции выполняет функцию атенции h раз параллельно, причем каждый раз с собственными выученными проекциями для запросов, ключей и значений. Результаты h вычислений соединяются и проходят через ещё одну выученную матрицу W_O, которая возвращает данные в размерность модели. Каждая голова работает в более маленьком подпространстве, причем d_k равно d_model деленному на h, поэтому общая стоимость обработки для всех голов примерно соответствует стоимости обработки одной головы полной ширины.
Представьте рукопись, отправленную в редакционный комитет. Редактор по грамматике проверяет синтаксис, редактор по стилю следит за повествовательным потоком, проверяющий факты ищет семантическую целостность, а редактор по структуре анализирует долгосрочную организацию текста. Все они читают одновременно и независимо, а их замечания объединяются в один отзыв. Многоголовая атенция ведёт себя аналогичным образом.
╔══════════════════════════════════════════════════════════════════════════════╗
║ MULTI-HEAD ATTENTION (3 heads shown) ║
╚══════════════════════════════════════════════════════════════════════════════╝
Input Embedding x ∈ ℝᵈ_model
┌────────────────────────────┐
│ [ x₁ x₂ x₃ ... xₙ ] │
└──────────┬─────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
╔══════════════╗ ╔══════════════╗ ╔══════════════╗
║ HEAD 1 ║ ║ HEAD 2 ║ ║ HEAD 3 ║
║ "Syntax" ║ ║ "Semantics" ║ ║ "Position" ║
║ ║ ║ ║ ║ ║
║ W_Q¹ W_K¹ ║ ║ W_Q² W_K² ║ ║ W_Q³ W_K³ ║
║ W_V¹ ║ ║ W_V² ║ ║ W_V³ ║
║ ║ ║ ║ ║ ║
║ ┌──────────┐ ║ ║ ┌──────────┐ ║ ║ ┌──────────┐ ║
║ │ Scaled │ ║ ║ │ Scaled │ ║ ║ │ Scaled │ ║
║ │ Dot- │ ║ ║ │ Dot- │ ║ ║ │ Dot- │ ║
║ │ Product │ ║ ║ │ Product │ ║ ║ │ Product │ ║
║ │Attention │ ║ ║ │Attention │ ║ ║ │Attention │ ║
║ └────┬─────┘ ║ ║ └────┬─────┘ ║ ║ └────┬─────┘ ║
║ │ ║ ║ │ ║ ║ │ ║
║ learns: ║ ║ learns: ║ ║ learns: ║
║ subject-verb ║ ║ word meaning ║ ║ nearby-word ║
║ agreement ║ ║ similarity ║ ║ relationships║
╚══════╤═══════╝ ╚══════╤═══════╝ ╚══════╤═══════╝
│ head₁ ∈ ℝⁿˣ⁽ᵈ/ʰ⁾ │ head₂ │ head₃
└───────────────────┼───────────────────┘
▼
┌──────────────────────────────┐
│ CONCATENATE all heads │
│ [head₁ ║ head₂ ║ head₃] │ ∈ ℝⁿˣᵈ_model
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Final linear projection W_O │ blends info from all heads
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Multi-Head Attention Output │ ∈ ℝⁿˣᵈ_model (same shape as input)
└──────────────────────────────┘
Чем занимаются отдельные компоненты
Анализы обученных моделей показали наличие специализированных компонентов. Некоторые из них отвечают за анализ синтаксиса, такого как согласование подлежащего и сказуемого и модификаторы, присоединяемые к существительным. Другие обрабатывают информацию на больших расстояниях, связывая местоимения с их антецедентами. Есть ещё компоненты, которые действуют на локальном уровне, уделяя внимание соседним словам и паттернам биграмм. Некоторые из них определяют относительное расстояние между токенами, а другие выявляют тематические роли, то есть определяют, кто что сделал с кем. Никто этого не программирует. Обучение стимулирует точные прогнозы, и сеть сама обнаруживает, что разделение задач между специализированными компонентами эффективно.
Ограничение этого подхода заключается в том, что эти категории в основном проистекают из исследований интерпретируемости более мелких моделей. В крупных моделях многие компоненты невозможно четко проанализировать, и эксперименты показывают, что такие модели часто выдерживают удаление большого количества компонентов с минимальными потерями качества. Архитектура позволяет осуществлять специализацию, но не гарантирует чёткого разделения, понятного человеку.
Присвоение словам адресов
Механизм самообратной связи учитывает каждую пару токенов, но при этом рассматривает последовательность как множество элементов без учета порядка. Оценка взаимосвязи между любыми токенами a и b зависит только от их содержимого, а не от того, какой из них находится первым или насколько они разделены друг от друга. Язык в высокой степени зависим от порядка: фразы «Собака кусает человека» и «Человек кусает собаку» содержат одинаковые слова, но означают противоположные вещи; к тому же выражение «не счастлив» означает совершенно другое, чем «счастлив не». Поскольку трансформер обрабатывает все позиции параллельно, по умолчанию в нем нет механизма кодирования порядка, поэтому позиция должна указываться явно. Именно для этого и существует позиционная кодировка.
Представьте себе добавление метаданных к каждому зданию в городе. Каждому из них необходим адрес, который указывает его местоположение, отражает относительное положение (здание 402 находится рядом с 404) и позволяет работать без знания всей городской схемы заранее. GPS-координаты эффективно решают эту задачу. Кодирование положения — это его лингвистическая версия: математические координаты, добавляемые к представлению каждого слова.
Волны синуса и косинуса
Изначальный трансформатор использовал синусоидальные функции, причем для каждой пары размерностей вкладки существовала своя частота. Для положения pos и индекса размерности k вектор заполняется синусами и косинусами значений pos, деленными на степень числа 10000 и масштабированными с учетом k. Медленные, низкочастотные волны обозначают крупное положение, а быстрые, высокочастотные — тонкое положение; вместе они придают каждому положению уникальный «отпечаток».
╔══════════════════════════════════════════════════════════════════════════╗
║ SINUSOIDAL POSITIONAL ENCODING ║
╚══════════════════════════════════════════════════════════════════════════╝
GRID: exact values for a tiny d_model=8 - positions 0-4, dims 0-7
(frequency denominators are 1, 10, 100, 1000 for dim-pairs 0,1,2,3)
dim→ d=0 d=1 d=2 d=3 d=4 d=5 d=6 d=7
sin cos sin cos sin cos sin cos
pos↓ ──────────────────────────────────────────────────────
pos=0 │ 0.000 1.000 0.000 1.000 0.000 1.000 0.000 1.000 │
pos=1 │ 0.841 0.540 0.100 0.995 0.010 1.000 0.001 1.000 │
pos=2 │ 0.909 -0.416 0.199 0.980 0.020 1.000 0.002 1.000 │
pos=3 │ 0.141 -0.990 0.296 0.955 0.030 1.000 0.003 1.000 │
pos=4 │ -0.757 -0.654 0.389 0.921 0.040 0.999 0.004 1.000 │
↑ fast-changing ↑ medium-changing ↑ very slow
(high frequency) (mid frequency) (low freq)
unique per position gradual shift global structure
WAVE PATTERNS (each row = one dimension across positions):
dim 0 (sin): █ ▇ ▄ ▁ ▂ ▅ ▇ █ ▇ ▄ ▁ ← fast oscillation
dim 2 (sin): █ █ ▇ ▇ ▆ ▅ ▄ ▃ ▂ ▁ ▁ ← medium oscillation
dim 4 (sin): █ █ █ █ █ █ ▇ ▇ ▇ ▇ ▆ ← slow oscillation
dim 6 (sin): █ █ █ █ █ █ █ █ █ █ █ ← very slow oscillation
HOW IT'S USED: Added to the token embedding elementwise
┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Token Embedding│ │ Positional Enc. │ │ Final Input x_t │
│ "cat" │ │ position = 2 │ │ │
│ [0.2, 0.8, │ │ [0.9,-0.4, │ │ [1.1, 0.4, │
│ 0.1, 0.5, │ + │ 0.2, 1.0, │ = │ 0.3, 1.5, │
│ 0.9, 0.3] │ │ 0.0, 1.0] │ │ 0.9, 1.3] │
│ (meaning) │ │ (where in seq) │ │ (meaning+position)│
└─────────────────┘ └─────────────────┘ └──────────────────┘
WHY SINUSOIDS?
✓ Each position gets a unique encoding across all dimensions
✓ Distance between nearby positions is consistent and learnable
✓ Can represent any position mathematically (unlike learned embeddings)
✓ Model can attend to relative positions via linear combinations
Низкие измерения колеблются быстро и фиксируют тонкие детали положения, в то время как высокие измерения изменяются медленно и отражают глобальный порядок. Вектор просто добавляется к эмбеддингу токена.
Фиксированные волны, выученные таблицы и поворот
Синусоидальная схема обладает полезным математическим свойством: кодировка в позиции pos+k является линейной функцией от кодировки в позиции pos. Таким образом, относительные смещения представляются последовательно, что облегчает изучение позиционных связей.
Используемые BERT позиционные эмбеддинги в виде отдельной таблицы с одним элементом на позицию проще в реализации, но не могут экстраполировать данные за пределы позиций, виденных во время обучения, тогда как синусоиды в принципе могут представлять любую позицию. Тем не менее синусоиды также не полностью решают проблему обобщения на длинные контексты. Модели по-прежнему испытывают трудности с последовательностями, значительно длиннее их обучающих данных, поскольку сами шаблоны внимания также должны обобщаться на невиданные расстояния между элементами.
Модели вроде Llama используют технологию Rotary Position Embeddings, или RoPE. Перед вычислением скалярных произведений запросы и ключи поворачиваются на угол, пропорциональный их положению. В произведении запроса, находящегося в одной позиции, и ключа, находящегося в другой, относительный поворот напрямую кодирует смещение. Превращение относительного положения в явный параметр оценки внимания, а не в нечто косвенное, получаемое через матрицы проекции, способствует обработке длинных контекстов.
Полная архитектура
Теперь можно собрать все компоненты. На диаграмме показан современный вариант структуры с предварительной нормализацией слоев:
╔═══════════════════════════════════════════════════════════════════════════════════════╗
║ THE COMPLETE TRANSFORMER ARCHITECTURE (Pre-LayerNorm, modern) ║
╠═══════════════════════════════════════════╦═══════════════════════════════════════════╣
║ ENCODER (×N layers) ║ DECODER (×N layers) ║
╠═══════════════════════════════════════════╬═══════════════════════════════════════════╣
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ Linear → Softmax → P(next token) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ ⊕ Add (residual) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ FFN( LayerNorm(x) ) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ Encoder output → K, V (to decoder) ║ ┌───────────────────────────────────────┐ ║
║ ▲ ║ │ ⊕ Add (residual) │ ║
║ ┌───────────────────────────────────────┐ ║ └───────────────────────────────────────┘ ║
║ │ ⊕ Add (residual) │ ║ ▲ ║
║ └───────────────────────────────────────┘ ║ ┌───────────────────────────────────────┐ ║
║ ▲ ║ │ Cross-Attention │ ║
║ ┌───────────────────────────────────────┐ ║ │ Q ← decoder │ ║
║ │ FFN( LayerNorm(x) ) │ ║ │ K, V ← encoder output │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ ⊕ Add (residual) │ ║ │ ⊕ Add (residual) │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Multi-Head Self-Attention │ ║ │ Masked Multi-Head Self-Attention │ ║
║ │ ( on LayerNorm(x), bidirectional ) │ ║ │ ( on LayerNorm(x), causal ) │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Input Embedding + Positional Enc. │ ║ │ Output Embedding + Positional Enc. │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Source: "The cat sat on the mat" │ ║ │ Target (shifted): <BOS> "Le" "chat"… │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
╠═══════════════════════════════════════════╩═══════════════════════════════════════════╣
║ Data flows UPWARD (▲). Each sub-layer is a residual branch over a ║
║ LayerNorm-ed input: h = x + SubLayer( LayerNorm(x) ) ║
║ The encoder's output (K, V) flows into the decoder's Cross-Attention. ║
╚═══════════════════════════════════════════════════════════════════════════════════════╝
У трансформера есть две основные части — кодер и декодер. В оригинальной статье каждая из них содержала по 6 слоев, с 8 головами внимания и параметром d_model равным 512.
Кодер: понимание в контексте
Кодер считывает входную последовательность и создаёт контекстуализированное представление каждого токена, учитывая не то, что слово означает по отдельности, а то, что оно означает в конкретном предложении. Для этого используется двунаправленное самовнимание, что позволяет каждому токену обращаться ко всем остальным токенам с обеих сторон. Именно так решается вышеупомянутая двусмысленность слова «bank»: модель одновременно видит «deposit» и «money».
Шесть слоев кодировщика работают последовательно, каждый из них улучшая представление данных. Ранние слои сосредотачиваются на синтаксисе, таком как порядок слов и части речи. Средние слои обрабатывают более сложные грамматические структуры. Поздние слои улавливают высокоуровневый смысл, такой как типы сущностей, структура событий и прагматика. Именно такая иерархия слоев объясняет высокую эффективность метода переноса знаний: тонкая настройка в основном влияет на поздние слои, в то время как общие лингвистические закономерности ранних слоев остаются полезными для различных задач.
Декодер: генерация с использованием памяти
Декодер генерирует выходные токены по одному, авторегрессивно. Каждый новый токен зависит от всего, что было сгенерировано ранее, а также от всего закодированного входного данных. У него есть три подслоя.
Первый тип — это маскированное самообращение внимания, также называемое каузальным обращением внимания. Декодер может смотреть только на токены, которые он уже выдал, что обеспечивается каузальной маской. Значения, находящиеся выше диагонали, перед применением функции softmax устанавливаются в значение минус бесконечности, что делает будущие токены невидимыми. Таким образом процесс обучения совпадает с процессом инференса, поскольку модели необходимо предсказывать каждый токен исключительно на основе прошлого контекста.
╔══════════════════════════════════════════════════════════════════════════╗
║ DECODER SELF-ATTENTION: Causal (Autoregressive) Masking ║
║ "Each token can only attend to itself and tokens before it" ║
╚══════════════════════════════════════════════════════════════════════════╝
Tokens: [The] [cat] [sat] [on] [mat]
t₁ t₂ t₃ t₄ t₅
ATTENTION SCORE MATRIX (row = query, col = key)
KEY → t₁ t₂ t₃ t₄ t₅
QUERY ↓ "The" "cat" "sat" "on" "mat"
──────────────────────────────────────
t₁ "The" │ ✓ ✗ ✗ ✗ ✗
t₂ "cat" │ ✓ ✓ ✗ ✗ ✗
t₃ "sat" │ ✓ ✓ ✓ ✗ ✗
t₄ "on" │ ✓ ✓ ✓ ✓ ✗
t₅ "mat" │ ✓ ✓ ✓ ✓ ✓
✓ = ALLOWED (score kept, participates in softmax)
✗ = MASKED (score → −∞, becomes 0 after softmax)
When generating t₃ "sat":
Raw scores: [ 2.1 3.4 1.8 -∞ -∞ ]
After softmax: [ 0.18 0.68 0.14 0 0 ]
↑
future tokens are invisible
WHY IS MASKING NECESSARY?
┌──────────────────────────────────────────────────────────┐
│ TRAINING: We feed the whole target sequence at once │
│ (teacher-forcing). Without masking, t₃ could "cheat" │
│ by looking at t₄ and t₅ - the answers it should │
│ be predicting. │
│ │
│ INFERENCE: We generate one token at a time anyway, │
│ so future tokens literally don't exist yet. Masking │
│ makes training match inference behavior exactly. │
└──────────────────────────────────────────────────────────┘
Второй компонент — это кросс-аттеншн, связующее звено между энкодером и декодером. Запросы поступают от декодера и отражают текущее состояние генерации, в то время как ключи и значения поступают от энкодера и показывают, что было сказано во входных данных. Перевод осуществляется именно таким образом: когда декодер генерирует французское слово «chat», он запрашивает представление всего английского предложения у энкодера, и кросс-аттеншн направляет больший вес на слово «cat».
Третий компонент — это сеть с передачей сигнала вперед, выполняющая ту же функцию, что и сеть в энкодере, о которой рассказано ниже.
Три группы, построенные из одинаковых элементов
Сочетание энкодера и декодера — это лишь один способ использования этих компонентов, причем для разных задач требуются разные их комбинации:
| Model | Architecture | Training Objective | Best For |
|-------|-------------|-------------------|----------|
| **BERT** | Encoder-only | Masked Language Modeling | Understanding: classification, NER, QA |
| **GPT** | Decoder-only | Next token prediction | Generation: writing, coding, conversation |
| **T5** | Encoder-Decoder | Text-to-text seq-to-seq | Transformation: translation, summarization |
╔══════════════════════════════════════════════════════════════════════════════════════╗
║ BERT vs GPT vs T5: Architecture Families ║
╠══════════════════╦═══════════════════════════╦═════════════════════════════════════╣
║ BERT ║ GPT ║ T5 ║
║ Encoder-Only ║ Decoder-Only ║ Encoder + Decoder ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ ATTENTION: ║ ATTENTION: ║ ATTENTION: ║
║ t₁ ● ● ● ● ║ t₁ ● ║ Encoder: ● ● ● ● (bidir) ║
║ t₂ ● ● ● ● ║ t₂ ● ● ║ ● ● ● ● ║
║ t₃ ● ● ● ● ║ t₃ ● ● ● ║ Decoder: causal + ║
║ t₄ ● ● ● ● ║ t₄ ● ● ● ● ║ cross-attn to encoder ║
║ (bidirectional) ║ (causal/left-only) ║ ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ BEST FOR: ║ BEST FOR: ║ BEST FOR: ║
║ ✓ Classification ║ ✓ Text generation ║ ✓ Translation ║
║ ✓ NER / tagging ║ ✓ Completion ║ ✓ Summarization ║
║ ✓ Sentence embeds ║ ✓ Chat / dialogue ║ ✓ Question answering ║
║ ✓ Reading comp. ║ ✓ Code generation ║ ✓ Any seq-to-seq task ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ EXAMPLES: ║ EXAMPLES: ║ EXAMPLES: ║
║ BERT, RoBERTa ║ GPT-4o, Claude 4, ║ T5, BART, ║
║ DeBERTa ║ Llama 4, Gemini 2.5 ║ mT5, FLAN-T5 ║
╚══════════════════╩═══════════════════════════╩═════════════════════════════════════╝
BERT обрабатывает данные в обоих направлениях и подходит для задач понимания текста. GPT генерирует текст слева направо с использованием механизма причинно-следственного маскирования. T5 сохраняет полную архитектуру для структурированного преобразования последовательностей. Выбор между ними зависит от соответствия архитектуры конкретной задаче, а не от того, какой из них лучше. Короче говоря, кодер создаёт двунаправленные контекстуальные представления, декодер генерирует текст авторегрессивно с применением причинно-следственного маскирования и механизма кросс-аттеншн, а разные компоненты архитектуры настраиваются для понимания, генерации и преобразования.
Вспомогательные компоненты
Наибольшее внимание уделяется механизму аттеншн и слою передачи сигнала, но три других элемента предотвращают коллапс моделей типа deep transformer во время обучения: сами сети передачи сигнала, нормализация слоёв и остаточные соединения.
Сети передачи сигнала: время обработки каждого токена
После каждого слоя внимания в каждом блоке следует сеть с прямой передачей данных с учетом позиции. Вектор каждого токена проходит через одну и ту же двухслойную сеть MLP, применяемую отдельно к каждой позиции: сначала происходит умножение на W1, затем добавление смещения, после чего применяется нелинейная функция GeLU, и, наконец, умножение на W2 с добавлением еще одного смещения. W1 преобразует размерность от d_model до четырехкратного значения d_model, а W2 — обратно. При исходных размерах это соответствует переходу от 512 до 2048, а затем обратно до 512, что позволяет сети хранить и преобразовывать информацию, которую не может зафиксировать только механизм внимания.
Ключевой фразой является «с учетом позиции», поскольку этот слой обрабатывает каждый токен независимо. Механизм внимания служит средством обмена информацией, позволяющим токенам взаимодействовать друг с другом, в то время как сеть с прямой передачей данных является механизмом вычислений, при котором каждый токен обрабатывает собранную им информацию.
Гева и его коллеги (2021) обнаружили, что эти слои ведут себя отчасти как память типа «ключ-значение», и можно выделить отдельные нейроны, которые активируются при возникновении определенных семантических концепций. Когда языковая модель «знает», что Париж — столица Франции, эта связь в основном хранится в весах прямой передачи сигналов. Это объясняет две вещи: тонкая настройка позволяет обновлять фактические знания, поскольку она изменяет именно эти веса; кроме того, метод генерации с усилением на основе извлечения информации работает, потому что он помещает факт в окно контекста, куда внимание может обратиться напрямую.
Остаточные связи
Градиенты, движущиеся назад через глубокую сеть, уменьшаются на протяжении многих слоев. Остаточное соединение, также называемое пропускающим соединением, эффективно решает эту проблему: выходной сигнал подслоя представляет собой результат работы этого подслоя плюс его собственный входной сигнал. Таким образом, слою необходимо изучать только изменение, то есть остаток, а не всю функцию отображения. Это создает «автостраду», по которой градиенты могут двигаться прямо назад, обходя любые слои; именно поэтому современные трансформеры могут иметь 96 и более слоев без снижения качества обучения.
Нормализация слоев: контроль масштабов
Нормализация слоя стандартизирует вектор активации каждого токена так, чтобы среднее значение равнялось нулю, а дисперсия — единице, после чего применяются выученные коэффициенты масштабирования gamma и смещения beta. Статистические показатели берутся из характеристик d_model одного токена: среднее значение — это простая сумма его элементов, а дисперсия — среднее квадратичное расстояние от этого среднего значения. Малая константа epsilon, обычно равная 10 в минус 5 степени, включается в выражение под квадратный корень, чтобы избежать деления на ноль. В отличие от нормализации пакета, вычисления выполняются для каждого токена отдельно, а не для всего пакета, что подходит для последовательностей переменной длины.
Современная структура блока
В первоначальной работе после добавления остатка применялся LayerNorm, что называется Post-LN. Почти все современные модели — от GPT-2 и GPT-3 до Llama, а также практически все модели, обученные с 2020 года, — используют Pre-LayerNorm и нормализуют данные перед каждым подслоем. Pre-LN обеспечивает более стабильное обучение и не требует подготовки скорости обучения.
Затем каждый блок добавляет к нормализованным данным ветку внимания и фильтр прямого распространения. Первое промежуточное состояние — это исходные данные плюс результат применения механизма внимания к нормализованным данным, а второе состояние — это предыдущее состояние плюс результат работы сети прямого распространения к её собственной нормализованной версии. При просмотре кода любого современного трансформера можно увидеть, что LayerNorm располагается перед механизмом внимания и перед шагом прямого распространения. Повторив такой блок N раз, причем значение N может быть 6, 12, 24, 96 или больше в зависимости от размера модели, получается полноценный трансформер.
Механизм внимания — это гениальная идея. Эти вспомогательные компоненты представляют собой техническую реализацию, позволяющую этой идее сработать. Слои передачи данных обеспечивают вычисления для каждого токена, сохраняющие фактические связи; остаточные пути дают градиентам маршрут через всю структуру, а функция Pre-LN поддерживает стабильность активаций. Вместе они делают возможным использование десятков блоков.
Путь предложения
Один полный процесс включает: токенизацию, встраивание информации, добавление кодировки позиции, кодирование, декодирование по одному токену за раз, а затем проецирование на словарь. На следующей диаграмме показан процесс перевода фразы «Hello world»:
╔══════════════════════════════════════════════════════════════════════════╗
║ END-TO-END DATA FLOW: "Hello world" → Translation ║
╚══════════════════════════════════════════════════════════════════════════╝
STAGE 1: Tokenization
┌─────────────────────────────────────────────────────────────────┐
│ Raw text: "Hello world" │
│ ↓ Tokenizer (BPE / WordPiece) │
│ Token IDs: [ 7592, 2088 ] ← integers into vocabulary │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 2: Embedding Lookup e_t = E[t] ∈ ℝ^512
┌─────────────────────────────────────────────────────────────────┐
│ 7592 → [0.21, -0.54, 0.88, ...] "Hello" │
│ 2088 → [0.67, 0.12,-0.34, ...] "world" │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 3: Add Positional Encoding x_t = e_t + PE(t)
┌─────────────────────────────────────────────────────────────────┐
│ embedding + PE = input vector carrying BOTH meaning AND order │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 4: Encoder Stack (× N layers)
┌─────────────────────────────────────────────────────────────────┐
│ ╔═══════════════════════════════════╗ │
│ ║ Each Encoder Layer: ║ × 6 │
│ ║ h₁ = x + Attn(LayerNorm(x)) ║ │
│ ║ h₂ = h₁ + FFN(LayerNorm(h₁)) ║ │
│ ╚═══════════════════════════════════╝ │
│ After 6 layers: rich contextual reps - "Hello" knows context │
└──────────────────────┬──────────────────────────────────────────┘
↓ (K, V flow into decoder cross-attention)
STAGE 5: Decoder Stack (generates tokens autoregressively)
┌─────────────────────────────────────────────────────────────────┐
│ Step 1: <BOS> → Decoder → predict "Hola" │
│ Step 2: <BOS> "Hola" → Decoder → predict "mundo" │
│ Step 3: <BOS> "Hola mundo" → Decoder → predict <EOS> │
│ │
│ Each step: ① Masked self-attention on generated tokens │
│ ② Cross-attention: Q←decoder, K,V←encoder │
│ ③ LayerNorm → FFN → residual │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 6: Output Projection & Softmax
┌─────────────────────────────────────────────────────────────────┐
│ hidden state → W_vocab → logits over 50k vocab items │
│ → softmax → probability distribution │
│ → sample or argmax → next token │
└──────────────────────┬──────────────────────────────────────────┘
↓
"Hola mundo" ✓
Как статья о машинном переводе превратилась в языковую модель
В ней описывается полная архитектура, но как проект машинного перевода превратился в системы, способные писать эссе и код и решать сложные задачи? Краткий ответ — масштаб.
Приведенная ниже временная шкала охватывает период от трансформеров 2017 года до современных передовых моделей:
YEAR MODEL PARAMS KEY DEVELOPMENT
────────────────────────────────────────────────────────────────────────────────
2017 Transformer 65M "Attention Is All You Need" published
2018 GPT-1 117M First successful generative pre-training
2019 GPT-2 1.5B Improved fluency; staged release
2020 GPT-3 175B Few-shot in-context learning emerges
2022 ChatGPT 175B+ InstructGPT + RLHF = aligned conversational AI
2023 GPT-4 undisclosed Multimodal input + stronger reasoning
2024 GPT-4o undisclosed Natively multimodal, faster & cheaper (May)
2024 o1 undisclosed "Reasoning" model: thinks before answering (Sep)
2025 o3 / o4-mini undisclosed Stronger reasoning, tool use, long-horizon
2025 Claude 4 undisclosed Anthropic: Opus 4 / Sonnet 4 (May)
2025 Gemini 2.5 undisclosed Google: 1M-token context, multimodal
2025 Llama 4 undisclosed Meta: open weights, up to 10M-token context
2026 GPT-5 series undisclosed OpenAI flagship (GPT-5.4 / 5.5); 272K-1M ctx
2026 Gemini 3.x undisclosed Google: frontier reasoning; 1M context
2026 Claude 5 family undisclosed Anthropic: Opus 4.8, Sonnet 5, Fable 5
2026 Grok 4.x undisclosed xAI frontier line (Grok 4.5, Jul 2026)
(Every one is the same core transformer from 2017 — scaled and refined, not replaced)
Основная архитектура практически не изменилась между GPT-1 и современными передовыми моделями. Изменились следующие аспекты:
- Масштаб, то есть больше параметров, больше данных и больше вычислительных ресурсов.
- Соответствие целям, благодаря обучению с усилением на основе обратной связи от людей модели становятся более полезными и безопасными.
- Настройка под инструкции, которая обучает модели следовать указаниям, а не просто продолжать текст.
- Обучение рассуждениям, при котором применяется масштабированное обучение с усилением к проверяемым задачам. Это основа моделей рассуждения, таких как серия o от OpenAI и режимы расширенного мышления, теперь широко используемые в Claude, Gemini и других моделях, которые тратят дополнительные вычислительные ресурсы на размышления перед ответом.
Способности, которые, кажется, активируются
При увеличении размера моделей происходили неожиданные изменения. Некоторые способности не улучшались постепенно, а, казалось, скачкообразно развивались при достижении определенного размера. Многократные арифметические операции практически отсутствовали при количестве параметров менее 10 миллиардов, но становились надежными при их количестве около 100 миллиардов. Размышления в виде цепочки шагов практически отсутствовали, если только модель не была достаточно большой и не получала соответствующие указания. Генерация кода значительно улучшилась при размере модели выше уровня GPT-3. Все это не было запрограммировано — оно возникло спонтанно.
Вопрос о том, насколько реально велики эти скачки, остается спорным. Широко цитируемый анализ 2023 года, проведённый Шеффером и его коллегами под названием «Являются ли возникающие способности больших языковых моделей миражом?», показал, что некоторые кажущиеся резкие изменения частично обусловлены используемой метрикой. Оценка выполнения задачи как «всё или ничего», как это делается при измерении точности полного совпадения, может превратить постепенный прогресс во что-то, что выглядит как внезапный скачок, тогда как непрерывная метрика отражает реальный поступательный прогресс. Практический аспект остаётся актуальным, поскольку большие модели способны делать то, что невозможно для маленьких, однако конкретные пороговые значения следует рассматривать лишь как приблизительные ориентиры, а не как строгие физические законы.
Цель обучения любой модели в стиле GPT — это одна и та же простая задача: предсказание следующего токена. Расчеты, генерация кода, мультиязычное понимание и творческое письмо никогда не обучаются явно. Они появляются по мере того, как модель становится лучше в предсказании следующего токена, при условии наличия достаточных ресурсов: большого, качественного и разнообразного корпуса текстов, а также модели достаточно большого размера для хранения необходимых закономерностей. Именно поэтому исследователи называют эту цель обманчиво простой. Цель действительно проста, но то, что должна выучить модель, чтобы хорошо справляться с ней, — нет.
Окно контекста как рабочая память
Для модели рабочая память представляет собой окно контекста — максимальное количество токенов, которые она может обработать за один проход. Её объем растет стремительно: GPT-2 в 2019 году обрабатывал 1 024 токена, а GPT-3 в 2020 году — 2 048. GPT-4o в 2024 году достиг уровня 128 000 токенов. К середине 2026 года показатели снова значительно выросли: серия GPT-5 от OpenAI предлагает 272 000 токенов в стандартной конфигурации и около миллиона через API; Claude от Anthropic и Gemini 3 от Google также обеспечивают более миллиона токенов, а открытая модель Llama 4 Scout от Meta заявляет о способности обрабатывать до 10 миллионов токенов, что соответствует примерно 15 000 страницам. Эти цифры продолжают расти с каждым новым поколением моделей.
Большее окно контекста важно, поскольку оно позволяет анализировать целый файл кода, а не только его фрагменты, поддерживать связность диалога на протяжении множества сообщений, создавать краткие изводы целых документов и выполнять многоэтапные расчеты, учитывая множество промежуточных результатов.
Есть нюанс. Вычисление полной матрицы внимания, которая связывает каждый токен с каждым другим, требует при обучении O(n в квадрате) времени и памяти. Удвоение длины контекста приводит к учетверению как времени, так и памяти. При инференсе кэширование KV-значений снижает вычислительные затраты на каждый шаг, но память по-прежнему растет линейно с длиной контекста. Эта квадратичная проблема обучения является активной областью исследований. Редкое внимание, внимание с скользящим окном, используемое в Mistral и других эффективных решениях, Flash Attention (точное внимание с эффективным использованием памяти) и линейные аппроксимации — все они направлены на снижение затрат.
Что лежит поверх основы
Внимание, QKV, несколько голов, позиционное кодирование и структура энкодер-декодер представляют собой инфраструктуру, и причина изучения этих элементов заключается во всем, что строится на их основе.
Генеративный ИИ — это повторяющееся прогнозирование следующего токена
Каждое генеративное приложение по сути представляет собой один и тот же цикл, который выполняется снова и снова:
Prompt: "Write a poem about autumn"
↓
Model predicts most likely next token: "The"
↓
Prompt + "The" → predicts: "leaves"
↓
Prompt + "The leaves" → predicts: "fall"
↓
... continues until <end-of-sequence> token predicted
Такой взгляд развеивает тайну некоторых явлений:
- Галлюцинации. Модель предсказывает вероятные токены и не запрашивает факты из базы данных. Если имеется правдоподобный, но неверный токен, он может быть сгенерирован.
- Почему контекст так важен. На каждом шаге генерации учитывается весь окно контекста, поэтому всё, что указано в запросе, определяет, какие веса внимания будут рассчитаны, а значит, и что будет сгенерировано.
Обучение в контексте: механизм внимания для поиска информации
Одним из самых примечательных возможностей крупных трансформеров является обучение в контексте — способность адаптироваться к новой задаче на основе примеров из запроса без какой-либо дополнительной настройки. Этот механизм соответствует тому, что было рассмотрено выше. Примеры с небольшим количеством случаев занимают определённые позиции в окне. Когда модель обрабатывает тестовый пример, запрос соответствующего токена сравнивается с помощью скалярного произведения с ключами всех предыдущих токенов, включая пары примеров. Поскольку примеры имеют схожую структуру с тестовым примером, их ключи хорошо совпадают, а их значения получают высокие веса. Внимание буквально является механизмом поиска, и именно поэтому структура запроса, влияя на паттерны внимания, изменяет результат вывода.
Агенты: трансформер как механизм рассуждений
Агенты ИИ — это системы, которые сами делят задачи на части, вызывают инструменты, учитывают обратную связь и достигают целей в ходе множества шагов. В 2023 году они считались объектом исследовательского интереса. Сейчас такие продукты, как Claude Code, GitHub Copilot, Cursor и Devin, ежедневно используются разработчиками. Каждый серьезный агент основан на трансформере.
╔══════════════════════════════════════════════════════════════════════════════╗
║ THE CONTEXT WINDOW AS AGENT WORKING MEMORY ║
╚══════════════════════════════════════════════════════════════════════════════╝
TIME ──────────────────────────────────────────────────────────────────────▶
┌──────────────┬──────────────┬────────────────┬────────────┬──────────────┐
│ SYSTEM │ USER │ AGENT │ TOOL │ AGENT │
│ PROMPT │ MESSAGE │ THOUGHT │ RESULT │ RESPONSE │
│ │ │ (reasoning) │ │ │
│ "You are a │ "What is │ <think> │ {"temp": │ "The current │
│ weather │ the weather │ I need to │ 22, │ temperature │
│ assistant │ in Paris │ call the │ "unit": │ in Paris │
│ ..." │ today?" │ weather API │ "C", │ is 22°C and │
│ │ │ for Paris... │ "cond": │ cloudy." │
│ │ │ </think> │ "cloudy"} │ │
│ ~200 tokens │ ~15 tokens │ ~80 tokens │ ~40 tokens │ ~25 tokens │
└──────────────┴──────────────┴────────────────┴────────────┴──────────────┘
▲ ▲ ▲ ▲ ▲
└───────────────┴───────────────┴───────────────┴─────────────┘
│
At each generation step:
Full self-attention runs over the
ENTIRE context simultaneously.
Cost: O(n²) in total context length.
WHAT THIS MEANS FOR AGENTS:
✓ Tool results are just tokens - the model attends to them like any text
✓ Reasoning traces are visible - chain-of-thought shapes next generation
✓ Long task history - "memory" without any separate mechanism
⚠ Context fills up - very long loops need summarization/offload
⚠ O(n²) attention cost - longer context = quadratically more compute
KEY INSIGHT: There is no "working memory" separate from the context.
The context window IS the agent's entire cognitive state.
Для агента окно представляет собой один плоский, упорядоченный буфер токенов, и на каждом шаге генерации обрабатывается вся его содержимое, что позволяет сохранять всё произошедшее в пределах доступа до установленного лимита. Окно является рабочей памятью агента, внимание — его механизмом рассуждения, а цикл обработки следующего токена — его циклом действий. Для агентского ИИ не требовалась новая архитектура; достаточно было понять, что трансформер при достаточно большом масштабе уже может обеспечивать проявление агентности.
На практике агенты, созданные в 2026 году, редко полагаются исключительно на само окно для обработки информации. Чтобы справляться с длительными задачами, они используют внешнюю память: файлы временного хранения, слой поиска или базу знаний, которую агент постоянно обновляет. Это не противоречит вышесказанному, поскольку внешняя память влияет на модель только путем её повторного зачитывания в окно. Она расширяет буфер, не заменяя его, и внимание трансформера к этому контексту по-прежнему остается единственным местом, где происходит обработка информации.
Куда движется исследования
Производительность трансформеров следует предсказуемым законам зависимости от количества параметров, объёма обучающих данных и вычислительных ресурсов, что позволяет исследователям иметь чёткий план действий. Исследования развиваются по нескольким направлениям:
- Эффективные архитектуры, снижающие квадратичные затраты на обработку информации с помощью технологий Flash Attention, редкого внимания и линейного внимания.
Все эти подходы основаны на принципах трансформеров, поэтому знание их позволяет легче понимать эти направления.
В приведенной ниже таблице каждый компонент представлен в одном виде, с указанием решаемой им проблемы, способа работы и основных характеристик:
| Component | Problem it Solves | Core Mechanism | Key Properties |
|-----------|------------------|----------------|----------------|
| **Tokenization** | Text is not natively numeric | Subword BPE/WordPiece splitting | Vocabulary ≈ 30k–100k; subwords handle rare terms |
| **Embeddings** | Discrete IDs have no geometry | $\mathbf{e}_t = E[t] \in \mathbb{R}^{d_{\text{model}}}$ | Semantic similarity → geometric proximity |
| **Positional Encoding** | Parallel attention loses token order | sin/cos at different frequencies (or RoPE) | Multi-scale; encodes absolute and relative position |
| **Self-Attention** | Long-range deps, sequential bottleneck | $\text{softmax}(QK^\top/\sqrt{d_k})V$ | $O(n^2)$ but parallel; dynamic contextual reps |
| **Query/Key/Value** | Separating "what I seek" from "what I offer" | Three separate learned linear projections | Relevance ≠ similarity; flexible dependency modeling |
| **Multi-Head Attention** | Single head captures only one relationship type | $h$ parallel heads, concatenated + $W^O$ | Simultaneously captures syntactic, semantic, positional |
| **Encoder** | Understanding input in full bidirectional context | Full self-attention, no masking | Bidirectional; rich contextualized representations |
| **Decoder** | Generating output autoregressively | Causal self-attention + cross-attention | Predicts one token at a time; teacher-forcing in training |
| **Cross-Attention** | Connecting generation to input understanding | Q from decoder, K/V from encoder | Enables encoder→decoder communication |
| **Feed-Forward Network** | Per-token computation + factual storage | $\text{GeLU}(\mathbf{x}W_1)\,W_2$ per token | Position-wise; stores factual associations in weights |
| **Residual Connections** | Vanishing gradients in deep networks | $\mathbf{h} = \text{SubLayer}(\mathbf{x}) + \mathbf{x}$ | Creates gradient highway; enables 100+ layer models |
| **Pre-LayerNorm** | Unstable activations in deep networks | Normalize before each sublayer | Stable training; standard in all modern transformers |
Что было рассмотрено и куда двигаться дальше
Элементы соединяются следующим образом. Параллельное внимание работает эффективнее, чем пошаговая обработка, и позволяет более точно улавливать отдаленные зависимости, поэтому трансформеры заменили последовательные модели. Данные проходят путь от текста к токенам, затем к эмбеддингам, к позиционному кодированию, к механизму внимания и к слоям с прямой передачей, после чего цикл повторяется. Основной операцией является самовнимание, при котором каждый токен взаимодействует со всеми остальными с помощью выученных проекций Q, K и V, как в формуле Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V. Несколько голов обрабатывают различные паттерны, позиционное кодирование восстанавливает порядок, а архитектура кодер-декодер обеспечивает как понимание, так и генерацию текста. Слои с прямой передачей хранят знания, резидуальные связи позволяют увеличивать глубину модели, а Pre-LayerNorm поддерживает стабильность обучения. Прогнозирование следующего токена в масштабе приводит к появлению новых возможностей, окно контекста служит рабочей памятью агента, а сама архитектура...
Статьи 2017 года лежат в основе современных самых передовых систем.
Чтобы углубиться в тему, хорошо подойдет поэтапный план.
Первые две недели: математика. Просмотрите серию видео Андрея Карпати «Нейронные сети: от нуля до мастерства» на YouTube, особенно видео о создании GPT с нуля. Затем напишите простой слой самообратной связи с использованием NumPy. Понятия усваиваются лучше, когда их рассчитываешь вручную.
Третья и четвертая недели: статьи. Прочитайте статью «Attention Is All You Need» (Vaswani и др., 2017), которая теперь доступна для чтения, а также статью о BERT (Devlin и др., 2018), статью GPT-3 «Language Models are Few-Shot Learners» (Brown и др., 2020) и статью «Scaling Laws for Neural Language Models» (Kaplan и др., 2020).
Второй месяц: практика с библиотеками и API. Библиотека Hugging Face transformers позволяет использовать эти модели в Python с минимальной настройкой. Проведите тонкую настройку модели BERT или небольшой модели с открытыми весами, такой как версия Llama или Qwen, для задач классификации. Затем ознакомьтесь с современными передовыми моделями, будь то Claude Sonnet 5 или одна из моделей GPT-5, с помощью Python SDK от Anthropic или OpenAI. Сочетание обоих подходов связывает теорию с практикой, поскольку одни и те же принципы трансформеров проявляются как в моделях с открытыми весами, так и в передовых API-моделях.
Третий месяц: углубленное изучение одной области. Выберите одну из платформ для создания агентов (LangChain, LlamaIndex) или попрактикуйтесь непосредственно с Claude Code или Cursor, чтобы наблюдать за поведением агентов в реальном производственном инструменте, изучите эффективные трансформеры (Flash Attention, разреженное и линейное внимание) или техники тонкой настройки больших языковых моделей с использованием LoRA и PEFT. Здесь важнее глубина, чем ширина охвата.
Актуально: следите за исследованиями. Разделы arXiv cs.CL и cs.LG, блог Hugging Face, страница с исследованиями Anthropic и форум AI Alignment — отличные источники информации. В этой области всё развивается быстро, но вышеупомянутые ресурсы помогают понимать новые статьи.
Статья о трансформерах состоит примерно из пятнадцати страниц, а описанная в ней архитектура достаточно проста для реализации за один день. То, что она способствовала появлению, а также то, что продолжает возникать благодаря масштабированию и усовершенствованиям, изменило представления людей о том, что могут делать машины.