Внимание в LLM · часть 1

Одна операция, на которой стоит весь трансформер: каждое слово оглядывается на остальные и подмешивает в себя то, что важно именно для него. Разберём её по винтикам — и посчитаем на живом примере, кто на кого смотрит.

Раздел 1 · Задача

Слову нужен контекст

Возьмём фразу «кошка лакает молоко, потому что она голодна». Что значит «она»? Само по себе местоимение пусто — его смысл живёт в другом слове фразы, в «кошке». Чтобы понять «она», модель должна дотянуться до нужного слова и втянуть его в себя.

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

Раздел 2 · Три роли

Запрос, ключ, значение

Каждый токен приходит в слой в виде вектора-эмбеддинга x_i. Из него тремя обучаемыми матрицами получают три разные проекции — три роли одного слова:

q_i = x_i W_Q, \quad k_i = x_i W_K, \quad v_i = x_i W_V.

Удобная аналогия — поиск в библиотеке:

  • Запрос q (query) — «что я ищу». У токена «она» это примерно «я местоимение, ищу существительное-подлежащее».
  • Ключ k (key) — «чем я могу быть полезен», ярлык на каждом токене. У «кошки» ключ кричит «я существительное-подлежащее».
  • Значение v (value) — «что я передам», собственно содержимое, которое утечёт к тому, кто на меня посмотрит.
Раздел 3 · Оценки

Похожесть → веса

Насколько запрос токена i подходит к ключу токена j? Мерой служит скалярное произведение: чем сильнее векторы «смотрят в одну сторону», тем оно больше.

\mathrm{score}_{ij} \;=\; \frac{q_i \cdot k_j}{\sqrt{d_k}}.

Делим на \sqrt{d_k} (корень из размерности): иначе с ростом размерности скоры разбухают, и softmax «схлопывается» в одну точку.

Оценки — это ещё не веса: они любого знака и не нормированы. Пропустим строку оценок токена i через softmax — получим распределение \alpha_{i\cdot}, которое неотрицательно и суммируется в единицу:

\alpha_{ij} = \frac{e^{\,\mathrm{score}_{ij}}}{\sum_{j'} e^{\,\mathrm{score}_{ij'}}}, \quad \sum_j \alpha_{ij} = 1.

Наконец, новое представление токена i — это взвешенная сумма значений всех токенов с этими весами. Всё вместе — знаменитая формула внимания:

o_i = \sum_j \alpha_{ij}\, v_j, \quad\Longleftrightarrow\quad \mathrm{Attention}(Q,K,V) = \mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right) V.

Слева — для одного токена, справа — та же операция сразу для всей матрицы.

Раздел 4 · Матрица

Кто на кого смотрит

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

Ползунок «температуры» — это делитель оценок. Стандартное значение \sqrt{d_k}; уменьшите — фокус заострится к одному слову, увеличьте — внимание размажется поровну.

Обратите внимание на строку «она»: сильнее всего она смотрит на «кошку» — модель нашла, к чему относится местоимение, просто сравнив векторы. А «молоко» тянется к «лакает»: объект липнет к своему действию. Никаких правил грамматики — только скалярные произведения и softmax.

Итог

Что мы собрали

Одна голова внимания — это четыре шага:

  1. спроецировать каждый токен в запрос, ключ и значение
  2. оценить пары запрос·ключ скалярным произведением и поделить на \sqrt{d_k}
  3. softmax по строке → веса, суммирующиеся в единицу
  4. сложить значения с этими весами — вот новое представление токена