Механизм внимания (attention)
Идея, которая сделала возможными GPT и всю современную эру LLM: вместо того чтобы сжимать текст в один вектор, дадим каждому токену смотреть на все остальные — с разными весами.
Интуиция: что было не так с RNN
Рекуррентная сеть (RNN) читает предложение слово за словом и тащит всё понятое в одном скрытом векторе фиксированного размера. Это бутылочное горлышко (bottleneck): к концу длинного предложения начало уже «забыто», а увеличить вектор нельзя — он один на любую длину. Механизм внимания (attention) переворачивает подход: на каждом шаге модель может заново посмотреть на все токены сразу и сама решить, какие из них сейчас важны. Ничего не нужно запоминать «на потом» — вся последовательность всегда перед глазами, вопрос только в весах.
Как это работает: Q, K, V и «мягкий словарь»
Представь словарь (dictionary/hash map): по запросу находим ключ и забираем значение. Внимание — тот же словарь, но «мягкий»: вместо точного совпадения — степень похожести, и вместо одного значения — взвешенная смесь всех. Каждый токен тремя линейными проекциями превращается в три вектора:
- Q (query, запрос) — «что я ищу»: например, токен «она» ищет, к кому относится;
- K (key, ключ) — «как меня можно найти»: метка, по которой токен откликается на чужие запросы;
- V (value, значение) — «что я отдаю»: содержимое, которое токен вносит в ответ.
Скалярное произведение Q·K даёт скор похожести запроса и ключа, softmax превращает скоры в веса (неотрицательные, в сумме 1), и результат — взвешенная сумма значений:
Зачем делить на √dk? При большой размерности dk скалярные произведения случайных векторов растут как √dk. Большие скоры загоняют softmax в насыщение: почти весь вес достаётся одному токену, градиенты через остальных исчезают, обучение буксует. Деление возвращает скоры в «рабочую зону» softmax — это по сути регулировка температуры.
Self-attention и causal mask
В трансформере запросы, ключи и значения делаются из одних и тех же токенов — это самовнимание (self-attention). Каждый токен строит своё новое представление из всех остальных: «она» подмешивает к себе «кошку» и перестаёт быть безликим местоимением. Именно это ты видишь в интерактиве: Q токена «она» даёт большое скалярное произведение с K токена «кошка», и почти весь вес уходит туда.
В декодере (модели, которая генерирует текст слева направо) есть жёсткое правило: токен не имеет права смотреть на токены правее себя. Иначе при обучении, где вся фраза известна заранее, модель просто «подглядит» ответ — а на генерации, где будущего ещё нет, окажется беспомощной. Каузальная маска (causal mask) ставит −∞ в скоры всех «будущих» позиций до softmax: их веса становятся нулями, а остальные перенормируются.
Multi-head: несколько взглядов параллельно
Одного набора весов внимания мало: в предложении одновременно есть синтаксические связи (подлежащее—сказуемое), кореференции («она» → «кошка»), позиционные закономерности (смотри на предыдущий токен). Многоголовое внимание (multi-head attention) запускает h независимых «голов»: каждая — со своими проекциями Q, K, V меньшей размерности d/h, со своей матрицей весов. Результаты голов конкатенируются и смешиваются ещё одной линейной проекцией. Разные головы на практике действительно специализируются — одни следят за синтаксисом, другие за совпадающими словами, третьи почти всегда смотрят на соседний токен.
Цена всей этой роскоши — квадрат: скоры считаются для каждой пары токенов, то есть память и вычисления растут как O(n²) по длине последовательности n. Для контекста в 100 тысяч токенов это главная боль — про способы её лечить смотри тему про современные архитектуры.
- «Зачем делить на √d?» — без деления скоры растут с размерностью, softmax насыщается, градиенты почти нулевые. Проверь в интерактиве: маленький делитель ⇒ веса схлопываются в один токен.
- «Что такое Q, K, V своими словами?» — мягкий словарь: запрос, ключ, значение; ответ — взвешенная сумма значений по похожести запроса на ключи.
- «Почему в декодере нужна маска?» — при обучении «следующий токен» уже есть в данных; без маски модель читерит и не учится предсказывать.
- «Какая сложность у self-attention?» — O(n²·d) по времени и O(n²) по памяти на матрицу весов; отсюда FlashAttention, GQA, скользящие окна.