Как разработчику быстро углубиться в тему LLM? Часть 2
Часть 1.
2. Механизм внимания (self-attention)
❓Вопрос на разминку: как во фразе «Data visualization empowers users to» понять, что слово empowers относится к visualization? В трансформерах за такие зависимости отвечают механизмы внимания.
Сами трансформеры разберём в следующей части, а пока достаточно знать следующее: это нейросеть для работы с последовательностями (текст, аудио, ДНК и т.д.), которая обновляет представление каждого токена слоями. В обучении/обработке готовой последовательности это делается параллельно по всем токенам; в генерации текста новые токены добавляются шаг за шагом (autoregressive), но внутри каждого шага операции параллельные.
Ключевая операция внутри слоя — self-attention: способ «взвесить» для каждого токена, какие другие токены в контексте ему сейчас важны, и собрать из них непосредственно контекст. Для каждого токена линейными преобразованиями вычисляются три вектора:
• Query (Q): «что я сейчас ищу в контексте?»
• Key (K): «по каким признакам меня можно найти/со мной сопоставиться?»
• Value (V): «какую информацию я передаю, если на меня "посмотрят"?»
Как считается self-attention, по шагам:
1️⃣ Dot product (оценка совместимости): для каждого токена берут его Query и считают скалярные произведения со всеми Key остальных токенов. Получается матрица «оценок внимания» размера n×n (n — длина последовательности).
2️⃣ Scaling (масштабирование): оценки делят на √dₖ, где √dₖ — размерность Key/Query в одной голове внимания.
Зачем это нужно: без деления разброс значений Q·Kᵀ растёт с dₖ softmax начинает «насыщаться» (почти 0/1), и обучение/градиенты становятся менее стабильными.
3️⃣ Mask (маскирование): перед softmax часто запрещают некоторые связи, выставляя им очень большие отрицательные числа (эквивалент −∞), чтобы после него они получили почти нулевой вес. Два самых частых случая:
• padding mask: игнорировать токены-паддинги;
• causal mask: в генерации текста запретить смотреть в будущее (токен i видит только позиции ≤ i).
4️⃣ Softmax (и иногда dropout): превращает оценки в нормированные веса (распределение внимания), которые суммируются в 1 по строке — для каждого «смотрящего» токена.
5️⃣ Взвешенная сумма Values: веса умножают на V и суммируют — получается контекстный вектор для каждого токена: он содержит информацию о других токенах пропорционально их важности.
Формально:
Attention(Q,K,V) = softmax(Q·Kᵀ / √dₖ) · V,
где T — транспонирование (чтобы Q·Kᵀ дало матрицу n×n).
❓ Зачем вниманию несколько голов (multi-head)?
Одна голова — это один «взгляд» на последовательность: свои матрицы проекций для Q/K/V и свои веса внимания. Multi-head attention делает такие «взгляды» параллельно: каждая голова считает attention независимо, затем выходы голов конкатенируются и проходят через выходную линейную проекцию (W^O). Практический смысл: разные головы могут подхватывать разные типы зависимостей (локальные, дальние, синтаксические/семантические шаблоны), и итоговый контекст получается богаче.
Наивная реализация self-attention опирается на матрицу n×n, поэтому вычислительная природа операции квадратичная по длине контекста. По памяти квадрат возникает, когда мы явно материализуем/храним attention-матрицу (веса). В продакшене часто используют оптимизированные подходы (например, FlashAttention), которые уменьшают пиковую память за счёт того, что не пишут всю матрицу внимания n×n в глобальную память. В autoregressive inference LLM обычно кэшируют K и V для уже сгенерированных токенов (KV-cache), чтобы не пересчитывать их на каждом шаге. Этот кэш растёт линейно с длиной контекста и на больших окнах часто становится главным потребителем памяти на инференсе. Как прикинуть потребление памяти KV-cache для заданной модели и длины контекста хорошо описано здесь.
✍️ На правах домашнего задания стоит изучить следующие материалы:
• The Annotated Transformer
• Attention? Attention!
• FlashAttention
• Краткая история механизма внимания в NLP
... и обязательно поиграться с левой частью интерактивной визуализации 🦄
Часть 3.
#LLM #гайд
Post #64
431

- ❤ 6
- 👍 1
- 💯 1