Математика глубокого обучения
Многоголовость и маски
Головы как блочная структура, причинная маска как −∞ — и почему она именно так
Головы — это блочная структура
Многоголовое внимание не добавляет вычислений. Оно делит существующую ширину на части и считает внимание в каждой независимо.
Из прошлого урока: стоимость равна и не содержит . Двадцать четыре головы по и двенадцать по стоят одинаково — меняется только то, как ширина поделена.
В нотации индексов
Именно поэтому einops удобнее, чем view и permute: здесь видно, что и — это
разложение одной оси, а не две независимые. Порядок множителей в скобках важен, и перепутать
(h d) с (d h) — распространённая ошибка, которая не падает.
Зачем несколько голов
Если стоимость та же, что даёт разбиение? Одна голова может внимать только «в одном направлении»: её распределение по ключам одно. Несколько голов дают несколько распределений одновременно.
Ограничение, из которого это следует: у одной головы результат — выпуклая комбинация значений, то есть точка внутри их выпуклой оболочки, с одним набором весов. Чтобы собрать информацию из двух разных мест по разным правилам, нужны два набора весов.
Цена — размер головы. При :
| что происходит | ||
|---|---|---|
| одно распределение, максимум выразительности внутри него | ||
| стандартный компромисс | ||
| оценки почти вырождены: по восьми компонентам очень шумно |
Последняя строка — реальное ограничение. При очень малом скалярное произведение вычисляется по нескольким числам, и его дисперсия относительно велика: внимание становится шумным. Отсюда и практический диапазон почти во всех моделях.
Причинная маска
Для авторегрессионной модели токен не должен видеть будущее. Реализуется это прибавлением к запрещённым оценкам до softmax:
Почему именно , а не удаление или ноль:
- ноль не подходит: нулевая оценка даёт вес , то есть не запрет, а средний вес. Маскировать нужно до softmax, а не после;
- даёт ровно нуль после softmax: , и знаменатель тоже не включает это слагаемое. Нормировка остаётся корректной автоматически;
- удаление не подходит технически: тензор должен остаться прямоугольным, чтобы операции оставались батчевыми.
На практике вместо берут большое отрицательное число (например или
минимальное значение типа), потому что в арифметике может дать nan при умножении
на нуль. Но с точки зрения математики это именно .
Включите маску в виджете: верхний треугольник заштрихован, и первая строка имеет единственный ненулевой вес — первый токен видит только себя.
Обратите внимание на первую строку: у неё энтропия равна нулю независимо от оценок. Первый токен имеет ровно один допустимый ключ — себя, — и после нормировки его вес равен единице принудительно. Никакой информации в этой строке нет, и это не дефект: так устроена авторегрессия.
Сколько работы экономит маска
Наивная реализация считает всю матрицу, а потом половину выбрасывает. Экономии нет вовсе — только трата.
| используется | доля | |
|---|---|---|
| из | ||
| из | ||
| из |
Доля равна и стремится к половине сверху. То есть при честной реализации причинное внимание должно быть примерно вдвое дешевле полного — и FlashAttention с блочными ядрами эту экономию действительно получает, просто не вычисляя запрещённые блоки.
Другие маски
| маска | что запрещает | где |
|---|---|---|
| причинная | будущее | декодеры, языковые модели |
| padding | заполнитель в коротких последовательностях | батчи переменной длины |
| скользящее окно | всё дальше токенов | Longformer, Mistral |
| блочно-разреженная | всё вне выбранных блоков | длинный контекст |
Padding-маска стоит отдельного упоминания как источник ошибок: если её забыть, модель будет внимать заполнителям, и результат станет зависеть от того, как батч был собран. Ошибка не падает — просто качество на коротких последовательностях оказывается хуже, чем на длинных, и причина неочевидна.
Вариации по числу наборов ключей
Из урока про KV-кэш (140) станет понятно, зачем это нужно, но структура относится сюда:
| схема | запросов | ключей и значений |
|---|---|---|
| MHA | наборов | наборов |
| MQA | наборов | один набор на все головы |
| GQA | наборов | групп, |
Вычислений это почти не меняет, а вот размер кэша делит на (для MQA) — и именно кэш, а не арифметика, ограничивает генерацию. Поэтому современные модели почти все используют GQA: компромисс между выразительностью MHA и памятью MQA.
Источники
- Vaswani и др. — Attention Is All You Need — Multi-head attention, раздел 3.2.2
- Shazeer — Fast Transformer Decoding — Multi-query attention и почему головы делят ключи
Проверки
0 из 2Головы и маски
Отметьте все верные утверждения о многоголовом внимании и масках.
Маска, головы и размер кэша
Реализуйте
mask_facts(n, heads, model_dim, kv_groups)— верните[allowed_fraction, head_dim, kv_cache_ratio, masked_cells]:allowed_fraction— доля матрицы оценок, разрешённая причинной маской. Разрешено ячеек из ;head_dim= ;kv_cache_ratio= — во сколько раз кэш ключей и значений меньше, чем при полном MHA. При это единица (обычное MHA), при — MQA;masked_cells— сколько ячеек замаскировано, то есть .
Проверить себя можно двумя тождествами:
allowed_fractionобязана равняться , аmasked_cells— числу . Оба следуют из того, что разрешённая часть — треугольник с диагональю, а запрещённая — треугольник без неё.Загрузка редактора…
Ctrl/⌘ + Enter