Как работает attention математически? Выведите формулу scaled dot-product attention.
Краткий тезис
Attention — это механизм, позволяющий модели динамически выбирать, на какие части входных данных обратить внимание при генерации вывода. Математически scaled dot-product attention выражается формулой Attention(Q,K,V) = softmax(QK^T / √d_k) V, где Q (queries), K (keys) и V (values) — матрицы, полученные из входных данных. Ключевая идея: скалярное произведение Q и K измеряет схожесть запроса и ключа, масштабирование на √d_k предотвращает чрезмерно большие значения softmax, а взвешенная сумма V даёт итоговый контекстный вектор.
1. Термин: Attention (внимание)
Attention — это механизм, который позволяет модели «сосредоточиться» на релевантных частях входной последовательности при вычислении выходного представления. В отличие от фиксированного окна или свёртки, attention динамически вычисляет веса для каждого элемента входа в зависимости от текущего запроса.
Интуиция Представьте, что вы ищете ответ на вопрос в книге. Вы пробегаете глазами по страницам (keys), находите наиболее подходящие абзацы (высокие веса attention) и формируете ответ на основе их содержания (values). Механизм attention делает то же самое математически.
2. Компоненты: Queries, Keys, Values
В механизме attention используются три матрицы, полученные из входных данных (обычно через линейные проекции):
- Q (queries) — запросы, размерность n × d_k (n — количество запросов, d_k — размерность ключа/запроса).
- K (keys) — ключи, размерность m × d_k (m — количество ключей/элементов входа).
- V (values) — значения, размерность
m × d_v(d_v — размерность значения, часто равна d_k).
В self-attention n = m (одна и та же последовательность), и Q, K, V получаются из одних и тех же входных векторов через разные линейные слои.
3. Вывод формулы scaled dot-product attention
Формула:
Attention(Q, K, V) = softmax( (Q K^T) / √d_k ) V
Разберём по шагам:
Шаг 1: Вычисление матрицы сходства (scores)
Q K^T — матрица размерности n × m. Элемент (i, j) равен скалярному произведению q_i (i-й запрос) и k_j (j-й ключ):
(Q K^T)_{ij} = q_i · k_j = Σ_{l=1}^{d_k} q_{i,l} * k_{j,l}
Чем больше скалярное произведение, тем сильнее запрос q_i «похож» на ключ k_j, и тем больше внимания будет уделено соответствующему значению.
Шаг 2: Масштабирование (scaling)
Деление на √d_k (где d_k — размерность ключей) предотвращает проблему слишком больших значений скалярного произведения при больших d_k. Если не масштабировать, softmax будет давать очень «острые» распределения (почти 0 или 1), что приводит к исчезающим градиентам.
Почему именно √d_k
Предполагая, что элементы q и k — независимые случайные величины с нулевым средним и единичной дисперсией, скалярное произведение имеет среднее 0 и дисперсию d_k. Деление на √d_k нормализует дисперсию к 1, что стабилизирует градиенты.
Шаг 3: Softmax по строкам
softmax применяется к каждой строке матрицы (Q K^T) / √d_k. Для i-й строки (запроса) получаем вектор весов a_i размерности m:
a_{i,j} = exp(score_{i,j}) / Σ_{l=1}^{m} exp(score_{i,l})
Все веса положительны и в сумме дают 1. Они показывают, какую долю внимания i-й запрос уделяет каждому из m ключей.
Шаг 4: Взвешенная сумма значений
Итоговый выход для i-го запроса — взвешенная сумма столбцов V (значений) с весами a_i:
output_i = Σ_{j=1}^{m} a_{i,j} * v_j
В матричной форме: Attention(Q,K,V) = softmax( (Q K^T) / √d_k ) V, где результат имеет размерность n × d_v.
4. Зачем нужно масштабирование (scaling factor √d_k)
Без масштабирования при больших d_k (например, 512 или 1024) скалярные произведения становятся большими по модулю. Softmax при больших входных значениях даёт распределения, близкие к one-hot (один вес ≈ 1, остальные ≈ 0). Это приводит к:
- Исчезающим градиентам — производные softmax в таких областях малы.
- Нестабильности обучения — модель слишком «уверена» в одном элементе.
Масштабирование на √d_k нормализует дисперсию, делая градиенты более гладкими.
5. Softmax и взвешенное суммирование
Softmax превращает неограниченные scores в вероятностное распределение. Это ключевой шаг, так как он делает attention дифференцируемым и позволяет модели учиться, какие части входа важны.
Взвешенное суммирование V с весами softmax даёт контекстный вектор для каждого запроса. Этот вектор содержит информацию из всех значений, но с акцентом на наиболее релевантные.
6. Вычислительная сложность
Основная операция — умножение матриц Q K^T (размер n × d_k на d_k × m). Сложность: O(n·m·d_k). Для self-attention (n = m) сложность O(n²·d_k) — квадратичная по длине последовательности. Это главный bottleneck трансформеров при работе с длинными контекстами.
Умножение на V (размер n × m на m × d_v) даёт дополнительно O(n·m·d_v). Итоговая сложность: O(n·m·(d_k + d_v)).
7. Сравнение с другими видами attention
| Тип attention | Формула | Особенности |
|---|---|---|
| Scaled dot-product (используется в Transformer) | softmax(QK^T / √d_k) V | Быстрое матричное умножение, масштабирование для стабильности |
| Additive attention (Bahdanau) | softmax(v^T tanh(W_q Q + W_k K)) | Более гибкая функция сходства, но медленнее из-за нелинейности |
| Dot-product attention (без scaling) | softmax(QK^T) V | Проще, но нестабилен при больших d_k |
| Multi-head attention | Concat(head_1,...,head_h) W_O | Несколько параллельных attention, каждый со своими Q,K,V |
Scaled dot-product attention стал стандартом благодаря эффективности (оптимизированные матричные умножения на GPU) и хорошей эмпирической производительности.
8. Multi-head attention как расширение
Multi-head attention запускает scaled dot-product attention несколько раз (h голов) с разными линейными проекциями Q, K, V. Результаты конкатенируются и снова проектируются. Это позволяет модели одновременно учитывать различные типы зависимостей (например, синтаксические и семантические).
Формула:
MultiHead(Q, K, V) = Concat(head_1, ..., head_h) W_O
head_i = Attention(Q W_i^Q, K W_i^K, V W_i^V)
9. Роль attention в Transformer
В архитектуре Transformer attention используется в трёх местах:
- Self-attention в энкодере — каждый токен «смотрит» на все токены входной последовательности.
- Masked self-attention в декодере — каждый токен видит только предыдущие (для авторегрессии).
- Cross-attention — запросы из декодера, ключи и значения из энкодера (связь между encoder и decoder).
В контексте RAG attention используется как в эмбеддерах (Bi-encoder, Cross-encoder), так и в генеративной LLM для обработки контекста из retrieval.
10. Пет-проект для закрепления
Задача Реализовать scaled dot-product attention с нуля на NumPy и проверить на простом примере.
Инструменты Python, NumPy, Matplotlib (для визуализации весов).
Шаги:
- Сгенерируйте случайные матрицы Q (2×4), K (3×4), V (3×5) — например, 2 запроса, 3 ключа, размерность d_k=4, d_v=5.
- Вычислите scores = Q @ K.T / sqrt(d_k).
- Примените softmax по строкам (можно написать свою функцию).
- Получите output = scores @ V.
- Визуализируйте матрицу attention weights (scores после softmax) с помощью heatmap.
- Проверьте, что сумма весов в каждой строке равна 1.
- Сравните результат с реализацией из PyTorch (
torch.nn.functional.scaled_dot_product_attention).
Ожидаемый результат Вы получите матрицу выходных векторов размерности 2×5. Тепловая карта покажет, какой ключ получил наибольший вес для каждого запроса. Вы убедитесь, что ваша реализация численно совпадает с эталонной.
11. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 650 | Архитектура Transformer |
| 652 | Multi-head attention |
| 653 | Positional encoding |
| 654 | Self-attention vs cross-attention |
| 655 | Masked attention в декодере |
| 656 | Attention is all you need (обзор) |
Эти вопросы углубляют понимание attention: как он используется в разных частях Transformer, как комбинируется в multi-head, как учитывается порядок токенов и как маскируется для авторегрессии.
12. Навигация
- Предыдущий: 650
- Следующий: 652
- Индекс: 00. Индекс разборов
Навигация
- Предыдущий: 650
- Следующий: 652
- Индекс: 00. Индекс разборов