Опубликовано: 08.04.2026
Это не цельная статья, а перечень отдельных заметок, которые я писал в ходе изучения архитектуры.
Смотрите также:
Общий вид механизма self-attention
Механизм self-attention — это способ каждому токену посмотреть на каждого, чтобы увидеть «что он может означать относительно меня».
Обозначения:
- K (Key) — это «ключ», «на что я откликаюсь».
- V (Value) — это «значение», «что я могу дать».
- Q (Query) — это «запрос», «что меня интересует».
Принцип работы:
- Имеется набор входных векторов x(1)…x(n).
- Каждый этот вектор умножается на матрицы Wq, Wk, Wv, и получаются векторы q(1)…q(n), k(1)…k(n), v(1)…v(n).
- Для каждой позиции i выполняется скалярное умножение q(i) на вектора k всех позиций. В результате получается последовательность чисел, описывающая “смысловую похожесть” рассматриваемого вектора ко всем векторам.
- Значения делятся на корень из размерности векторов ключа, вычисляется softmax, чтобы получить эти же значения как “доли влияния”.
- Вычисляется средневзвешенное значение v используя указанные доли и значения v(1)…v(n). Оно и является финальным вектором, “обогащенным” через внимание.
Учитывая, что обычно мы имеем дело с decoder-only трансформером, используемым для генерации текста, то:
- В этом случае на шаге 3 учитываются только позиции “уже увиденные из текущей”, так как “будущее мы еще не знаем”. (Для каждого q(i) учитываются только такие k(j), где j <= i.)
- При инференсе нас интересует только “внимание” для последнего токена последовательности, чтобы использовать эту информацию для предсказания следующего токена, таким образом вычисление “обогащенного значения” выполняется для позиции токена i (используя кэшированный массив значений k и v от предыдущих шагов - KV-cache), затем на следующем шаге (после того как новый токен предсказан) - позицию i+1, i+2 и так далее.
Общий вид классического пайплайна трансформера
- Входные токены репрезентуются как векторы (эмбеддинги).
- Эти векторы дополняются позиционным кодированием. Один из ранних вариантов: кодирование представляет собой вектор из множества синусоидальных значений с разными частотами, который суммируются к вектору токена, что даёт модели “ощущение последовательности токенов как движения векторов в пространстве”. В настоящее время во многих моделях часто используется RoPE - не суммирование, а поворот в пространстве, при чем поворачивается не исходный эмбеддинг, а вектора Q и K внутри каждого слоя внимания, что делает общую структуру трансформера несколько концептуально сложнее для понимания. RoPE математически позволяет модели учитывать не просто позицию, а разность позиций между токенами, так как в скалярном произведении непосредственно отражается эта разность.
- При инференсе, как уже было сказано выше, мы производим вычисления, находясь в текущей позиции i, а обогащение “смысла” вектора осуществляется через учёт внимания относительно всех предыдущих позиций, как было описано ранее.
- Вычисление проходит через несколько структурно идентичных слоёв, от пары десятков у компактных моделей, до многих десятков или 100+ у крупных.
- На каждом слое:
- Описанный выше механизм внимания дублирован несколько раз и работает параллельно по отдельным наборам матриц Wq, Wk, Wv. Это позволяет модели “обогащать смыслы” разными путями независимо. Это называется multi-head attention.
- Каждая такая голова работает только с частью общей размерности эмбеддинга. (Например, общая размерность эмбеддинга 768, используется 12 голов, размерность субвектора для каждой головы будет равна 768 / 12 = 64.)
- В результате получается не один вектор, обогащенный вниманием, а совокупность векторов меньшей размерности, которые конкатенируются в общий вектор.
- Далее производится вычисление финального вектора через умножение на еще одну обучаемую матрицу.
- Полученное значение нормируется и смешивается со входным значением слоя. Это позволяет передавать далее как исходную информацию, так и полученную в результате работы внимания. В ранних GPT использовался Post-Norm. Сейчас обычно используется Pre-Norm.
- Далее значение проходит через перцептрон (FFN), который трансформирует вектор из предыдущего шага в вектор той же размерности. Перцептрон использует нелинейные функции активации (ReLU, GELU в ранних работах; SwiGLU в современных моделях), это позволяет внести нелинейность в работу трансформера, что необходимо для формирования “богатой и сложной” модели в его весах.
- Полученное значение также нормализуется и смешивается со значением до перцептрона.
- Пройдя через фиксированное для конкретной модели количество слоёв, мы получаем в остаточном потоке финальный “вектор смысла”, на основе которого производится предсказание следующего токена.
- Финальный вектор умножается на матрицу Unembedding (транспонированная матрица входных эмбеддингов). Результатом становится вектор размера словаря модели (например, 128k чисел для словаря в 128k токенов), который называется логитами. Затем к ним применяется softmax (чтобы получить вероятности от 0 до 1). И затем алгоритм, который “бросит кубик” и выберет одно из вероятных продолжений. На этом финальном этапе выбора применяются параметры Temperature, Top-K, Top-P.
Также следует заметить, что единственное место, где токены как последовательные единицы смысла “влияют друг на друга” - это непосредственно механизм self-attention, в котором текущая позиция обогащается информаций ото всех предыдущих. Таких обогащений происходит “число слоёв * число голов” раз, но все они алгоритмически устроены одинаково.
Прочие операции, такие как получение одиночного вектора из совокупности частичных векторов мультиголового внимания, вычисление значения перцептрона, выбор следующего токена - работают относительно обработки одиночного вектора остаточного потока, а не совокупности векторов.
Описанный выше процесс прибавления значения к значению вектора предыдущего шага формирует понятие остаточный поток (residual stream):
- Это вектор, который «протягивается» сквозь все слои трансформера и представляет собой сумму эмбеддинга токена и выходов всех промежуточных вычислений. Все операции внимания и FFN читают из этого потока и дописывают в него, а не перезаписывают его.
- Остаточный поток — это линейный канал: все слои просто прибавляют к нему свои выходы. Поэтому его можно мыслить как «память» или «шину данных», через которую слои обмениваются сигналами. (Именно поэтому используется не Post-Norm, а Pre-Norm, как было отмечено ранее.)
- Остаточный поток — это векторное пространство; его координаты не имеют фиксированного смысла. Можно повернуть всё пространство (и все матрицы модели), и поведение модели не изменится. Смысл имеют только направления относительно друг друга, а не абсолютные координаты.
- Ограниченная «пропускная способность»: у каждого слоя гораздо больше «вычислительных размерностей» (нейронов FFN, голов внимания), поэтому слои вынуждены сжимать информацию и передавать её в суперпозиции в этом относительно узком канале.
- В mechanistic interpretability используется подход Logit Lens: поскольку информация в остаточном потоке линейна и просто аддитивно накапливается, мы можем взять вектор из середины сети (например, после 10-го слоя из 40) и применить к нему финальную матрицу предсказания, чтобы посмотреть, о чем модель «думает» прямо сейчас.
- В некоторых исследованиях указывается, что перцептрон работает как “ассоциативная память” модели: перцептрон видит в остаточном потоке некоторый ключ и дополняет к нему сохранённое в весах перцептрона значение.
Архитектура GLM
- GLM это попытка скрестить GPT-архитектуру с элементами BERT-архитектуры.
- Модель на этапе обучения учится заполнять пропуски, которые могут быть как короткими (один или несколько токенов), так и длинными (несколько предложений).
- Для этого используется двумерное позиционное кодирование. Кодируется как последовательность токенов контеста, так и последовательность токенов внутри заполняемого окна.
- Подобно GPT, модель последовательно заполняет окно токенами один за другим. Однако при этом она имеет информацию о том, “чем всё закончится” (контекст после заполняемого окна).
- Современные версии GLM от Z.ai используют разновидность RoPE для позиционного кодирования, доработанный, чтобы модель видела кодирование по обеим смысловым координатам, как в оригинальном дизайне. Задача на претрейнинге решается та же: авторегрессивное заполнение пропусков.
При использовании GLM в качестве генеративной модели (чат-бота, кодинг агента и т.п.), она работает подобно классической GPT архитектуре, авторегрессивно кодируя ответ токен за токеном.
Значимость отличий GLM проявляется не в процессе генерации, а в качестве скрытых состояний, которые модель выучила. Поскольку GLM на этапе предобучения обучалась восстанавливать текст, глядя на контекст с обеих сторон, это даёт следующие теоретические предпосылки для повышения качества, которых не хватало классическим GPT:
- Глубокое понимание структуры (особенно кода): Когда GLM предсказывала середину функции, имея доступ к ее концу (в предобучении), она лучше выучила долгосрочные зависимости. В коде это дает преимущество: модель лучше “чувствует”, как закроется скобка или цикл в конце, даже если генерирует код в начале.
- Меньше “галлюцинаций формата”. GLM лучше соблюдает структуру, потому что в pretraining она училась заполнять вырезанные куски фиксированной/предсказуемой структуры. Это учит модель “чувствовать” границы и объем генерируемого текста.
- Устойчивость к “сдвигу окна”: GPT-модели часто теряют фокус, если ответ должен опираться на информацию, находящуюся в самом конце длинного промпта. GLM исторически лучше справляется с извлечением фактов из середины или конца контекста, потому что ее механизм внимания изначально не был заблокирован направо.
Остаётся открытым вопрос, насколько здесь важна архитектура модели, а насколько технология обучения, поскольку и классические трансформеры постепенно совершенствуются.
MoE (Mixture of Experts)
- При использовании MoE только перцептрон “делится на части”. Слой внимания остаётся плотным (dense).
- Берётся значение x в состаточном потоке после работы слоя внимания и вычисляется вектор логитов размерностью равной числу экспертов: logits = W_gate * x. (Выполняется маршрутизация к экспертам.)
- Далее выбираются top-k экспертов, например, два эксперта для k = 2.
- Некоторые архитектуры (DeepSeek, Qwen) добавляют общего эксперта, который активируется для всех токенов дополнительно к top-k.
- Сейчас идёт движение от топологии “несколько крупных экспертов” с малой величиной top-k (например, Mixtral 8x22b) к “много мелких экспертов” и большим значением top-k.
- Вычисляется значение с учётом весов выбранных экспертов: MoE(x) = SharedExpert(x) + Σᵢ∈TopK (w_i * Expert_i(x)). Оно добавляется в остаточный поток.
- Обучение модели MoE требует особых техник, чтобы избежать коллапса экспертов.
PLE (Per-Layer Embeddings), архитектура моделей gemma3n:e4b и gemma4:e4b:
В стандартном трансформере каждый токен получает один вектор эмбеддинга на входе, и этот вектор проходит через все слои декодера в качестве основы для вычислений.
PLE добавляет параллельный путь к основному остаточному потоку.
Для каждого токена и для каждого слоя:
- Вычисляется малый специализированный вектор (например, 256 измерений)
- Этот вектор - комбинация двух сигналов:
- token-identity component: lookup из отдельной таблицы эмбеддингов
- context-aware component: проекция основных эмбеддингов через обучаемый слой
- На каждом слое этот вектор используется для модуляции скрытых состояний ПОСЛЕ блока внимания и FFN.
Таблица PLE — это большая, но «пассивная» память: она хранит специализированные сигналы для каждого токена на каждом слое, но не увеличивает вычислительную сложность инференса, так как:
- Доступ к ней — это простой lookup (
O(1)на токен) - Модуляция скрытых состояний происходит через элементное умножение и проекцию низкой размерности.
PLE добавляется как третий остаточный блок в каждом декодере после FFN. Это позволяет каждому слою получать токен-специфичную информацию именно тогда, когда она релевантна, вместо того чтобы «упаковывать всё» в один начальный эмбеддинг.
Преимущества:
- Главное преимущество - экономия памяти при инференсе. Для gemma4:e4b только основной трансформер (~4.5 млрд) должен находиться в быстрой памяти (VRAM). PLE-таблицу (~3.5 млрд) можно хранить в более медленной памяти или подгружать по требованию, так как доступ к ней — это простой индексный поиск.
- Улучшение качества без роста вычислений: модель получает выразительность, близкую к 8B, но с вычислительной стоимостью ~4.5B модели. По способности “срезать угол” это напоминает MoE, но архитектурно подход используется иной.
- Основной трансформер можно квантовать (INT4/INT8), а PLE-таблицу оставить в более высокой точности, так как она не участвует в тяжёлых матричных операциях.
Что касается конкретно gemma4:e4b, она показывает существенный рост результатов в тестах относительно gemma3n:e4b, а семейство gemma4 в целом показывает заметный рост относительно gemma3. Но это уже касается и технологий обучения, а не просто математики модели.
Mamba-2
В архитектуре Mamba-2 вместо блоков self-attention используются блоки, построенные согласно концепции State Space Models.
SSM в данном случае можно представить как:
h(i) = A*h(i-1) + B*x(i)
y(i) = C*h(i)
Где:
i - обрабатываемая позиция
h(i) - скрытое состояние
x(i) - входная информация (то, что читаем из остаточного потока)
y(i) - выходная информация (то, что добавляем в остаточный поток)
таким образом вместо KV-кэша, который де-факто хранит состояние между токенами, в блоках Mamba используется скрытое состояние h фиксированной размерности. Таким образом при инференсе размер памяти и вычислений не растёт вместе с ростом обработанного контекста, и количество операций на токен остаётся константным (O(1)).
В отличие от классической SSM, где обучаемые матрицы A, B и C постоянны, в архитектурах Mamba и Mamba-2 учитывается вычисляемая на каждом шаге “степень важности” входного значения x, которая влияет на то, как сильно входные данные модифицируют скрытое состояние. Это позволяет модели “запоминать важные токены” и “игнорировать несущественные”.
Подробности процесса этого алгоритма важности мне неизвестны.
Mamba (не 2) использовала ряд ухищрений, чтобы “втиснуть” алгоритмы этапа обучения в быструю локальную память вычислительных ядер.
Благодаря тому, что для особых частных случаев была открыта и доказана математическая эквивалентность данного алгоритма и механизма внимания, это позволило обучать модель с использованием доступного для GPT-архитектур аппаратного обеспечения, а затем запускать их при инфересне с вычислительной сложностью O(1) на токен. (O(n) от длины генерации.) Это по сути и есть Mamba-2. Опять же, математические подробности мне не известны.
Пример архитектуры Nemotron-H от NVIDIA:
Nemotron-H-8B:
(Mamba-2 -> FFN)x3 ->
(Mamba-2 -> Attention -> FFN -> (Mamba-2 -> FFN)x4)x4 ->
(Mamba-2 -> FFN)
Nemotron-H-56B:
(Mamba-2 -> FFN)x3 ->
(Mamba-2 -> Attention -> FFN -> (Mamba-2 -> FFN)x4)x10 ->
(Mamba-2 -> FFN)
Примерно 8% от общего числа слоев в модели составляют слои self-attention. Эти слои равномерно распределены по всей модели. Остальная часть модели состоит из чередующихся слоев Mamba-2 и FFN.
С Nemotron-H я на практике не имел дела, только читал в статьях.
С чем я сталкивался на практике, это Granite 4 H Tiny от IBM - MoE модель 7B A1B, у которой 4 слоя внимания и 32 слоя Mamba-2. Детали топологии не помню, да это и не особо важно. Модель показывала впечатляющую скорость работы, а также относительно неплохое качество ответов для своего размера, но была весьма неусточива - на каких-то промптах отвечала хорошо, на каких-то просто ломалась.
Новейшая Qwen3.5 использует Gated DeltaNet, которая имеет какое-то отношение к Mamba-2, но тут уже мои знания заканчиваются.
Qwen 3.5 models feature a hybrid architecture combining GDN (Gated DeltaNet) layers with standard attention layers, SwiGLU activations, and RMSNorm.
Qwen 3.5 релизнулась широким классом открытых моделей, включая как Dense, так и MoE варианты, начиная от 0.8B и вплоть до 397B-A17B, и показывает достойные результаты в каждой из размерных категорий в сочетании с высокой скоростью инференса. Я активно “щупаю” её на практике, а вот с деталями внутреннего устройства еще не ознакомился.