Generative Pretrained Transformer: общий взгляд на архитектуру

Опубликовано: 08.04.2026

Введение

Цель этой статьи — познакомить читателя с архитектурой Generative Pretrained Transformer, лежащей в основе современных языковых моделей.

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

В этой статье я постараюсь дать достаточно подробное описание, что собой представляет «пайплайн» трансформера: как данные со входа проходят по этапам модели и приходят на выход. Я опишу упрощенную схему decoder-only трансформера, пропуская или сокращая те части, которые не принципиальны для понимания общего вида.

Некоторый базовый глоссарий:

Общий вид модели

Языковая модель читает входной поток токен за токеном. На рисунке слева показан этот поток токенов, направленный снизу вверх. Языковая модель как бы проматывает мимо себя ленту, на которой находятся токены. Несколько токенов модель «уже увидела» и в данный момент видит очередной токен — для неё он является «текущим», «последним», «актуальным».

Текущий увиденный токен посредством входной матрицы преобразуется в векторное представление, называемое эмбеддинг.

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

Совокупность из блока Self-attention и блока FFN называется одиночным слоем трансформера. Языковая модель состоит из множества таких слоёв. Типично в компактных моделях, доступных для запуска на потребительском оборудовании, — порядка пары десятков слоёв; в крупных облачных моделях — многие десятки или 100+.

Таким образом проходя по слоям, вектор обогащается «смыслом» и из вектора текущего токена в начале этой цепи превращается в векторное представление следующего токена к концу этой цепи.

После всех слоёв вектор попадает на матрицу Unembedding, которая конвертирует этот «смысловой вектор» в массив чисел, описывающих уровень сходства вектора для всех возможных токенов модели. Затем тот массив чисел нормализуется функцией Softmax, чтобы получить вероятности относительно единицы.

Если модель в данный момент генерирует текст, то далее используется механизм выборки токена (Sampling), чтобы выбрать один из наиболее вероятных токенов в качестве следующего. На этом этапе в генерацию текста вносится элемент случайности, используя генератор случайных чисел, а также параметры Temperature, Top-k и Top-p. Регулируя эти параметры, можно получать более стабильные или более «креативные» и изменчивые результаты. После этого выбранный токен подаётся модели на вход и становится её текущим токеном. Так пошагово модель генерирует токены один за другим.

Если же модель не генерирует текст, а просто читает уже существующий текст перед тем как начать отвечать (читает промпт), то всё, что выше было сказано относительно матрицы Unembedding и далее — не актуально. Модель читает информацию токен за токеном и пропускает через свои слои, чтобы заполнить KV-cache. (Подробнее про кэш будет ниже.) Когда модель прочитала текст, она начинает генерировать его продолжение.

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

Residual stream (остаточный поток)

Описанный выше процесс прибавления значения к значению вектора предыдущего шага формирует понятие остаточный поток (residual stream). На рисунке этот поток обозначен утолщенной линией. Это понятие — весьма важное для понимания архитектуры LLM.

Почему в этом потоке чередуются блоки Self-attention и FFN:

Можно сказать, что модель чередует фазы «оглянись и сравни новую информацию с уже увиденной» и «обдумай, что это означает».

Self-attention

Механизм self-attention (самовнимание) - это ключевая инновация, после которой начался бум развития ИИ. Не буду лишний раз углубляться в истоки этого прорыва. Думаю, все знают, что поворотной точкой стала публикация работы «Attention Is All You Need» исследовательского центра Google.

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

Когда очередной вектор поступает в блок Self-attention, внутри него используются предобученные матрицы Wq, Wk и Wv, чтобы получить из входного вектора векторы Q, K и V. Значение Q нам требуется только на данном шаге вычислений, а вот значения K и V потребуются не только для текущего, но и для всех последующих. Поэтому они записываются в блок, обозначенный на рисунке как KV-cache.

Таким образом в этот кэш записывается информация о каждом значении остаточного потока, которые «увидел» блок самовнимания, но не напрямую, а в виде векторов K и V.

Исходя из всех увиденных значений K и V и текущего значения Q, блок формирует своё выходное значение. Именно таким образом модель учитывает весь увиденный ранее контекст, а не просто текущий токен.

Точная математика, как я уже говорил, за пределами данного обзора, но я кратко опишу, что это означает структурно:

На каждом новом шаге блок Self-attention формирует очередной запрос Q, чтобы посмотреть, насколько предыдущие шаги работы модели, сохраненные в KV-кэше, «откликаются» на этот запрос через их ключи. А затем использует предоставленные значения V пропорционально силе «отклика» каждого.

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

FFN (Feedforward Network)

Feedforward Network, также известная как MLP: многослойный перцептрон. Это собственно то, что вы можете увидеть в любой базовой статье на тему того, «что такое искусственная нейросеть»: en.wikipedia.org/wiki/Feedforward neural network.

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

Position Encoding

Чтобы модель учитывала порядок, в котором идут токены, информация о порядке и дистанциях между токенами должна как-то кодироваться. В настоящее время во многих моделях используется RoPE — Rotary Positional Embedding. Его суть в том, что векторы Q и K поворачиваются на угол, пропорциональный порядковому номеру токена. Это происходит непосредственно внутри каждого блока Self-attention. С каждым следующим токеном векторы текущего токена поворачиваются всё дальше. Это позволяет модели «чувствовать расстояние» между токенами.

Чтобы отобразить это на схеме, я нарисовал там блок Position Encoding, который подаёт информацию на вход каждого блока Self-attention. По сути в нашей диаграмме его можно осмыслить как простой счётчик, который указывает насколько нужно повернуть векторы. Если этот блок не рисовать, то нужно держать в уме, что блоки Self-attention хранят внутри себя изменяемое на каждом шаге состояние — число пройденных шагов. А так мы это состояние вынесли на схеме в отдельный видимый блок.

Итого

Также важно упомянуть оценки времени работы и затрат памяти:

Что важное упущено в схеме, но потребуется, если вы захотите погрузиться далее

Смотрите также: