English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

гость
1 / ?
назад к урокам

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

Три линейных отображения из одного и того же входа

После встраивания (активность 4) каждая позиция несёт 768-мерный вектор x_t. Attention начинается с создания трёх различных проекций x:


Q (query): что эта позиция хочет узнать?


K (ключ): что эта позиция предлагает другим позициям?


V (значение): какой контент эта позиция предоставляет, если на неё обратить внимание?


Каждая проекция получается из матрицы весов, полученной в результате обучения:


Q = x · W_Q     # Форма W_Q: (d_model, d_k)
K = x · W_K     # Форма W_K: (d_model, d_k)
V = x · W_V     # Форма W_V: (d_model, d_k)

Три матрицы, все обучаются через обратное распространение. Модель учится: в этой позиции какая query лучше всего извлекает полезный прошлый контекст? Какой key хорошо рекламирует содержимое этой позиции? Какое value предоставить, если выбрано?


Масштабированное скалярное произведение


Аналогия с библиотекой

Представьте каталог карточек библиотеки. Вы заходите с темой в голове (ваш query). Каждая карточка содержит ключевые слова (key). Когда ваша тема совпадает с ключевыми словами на карточке, вы берёте содержание книги (value). Attention делает это для каждого токена параллельно: каждая позиция запрашивает каждую другую позицию, ранжирует совпадение и извлекает взвешенную комбинацию векторов значений.


Размерности ANDREA-120M


КоличествоЗначениеПримечания
d_model768Размер вектора на каждой позиции
n_head12Параллельные головы внимания
d_k64Размерность на голову (= d_model / n_head)
T1024Длина контекста

d_k = d_model / n_head = 768 / 12 = 64. Каждая голова видит 64-мерный срез полного 768-мерного пространства. Activity 6 (grow_a_language_model_multi_head) подробно разбирает разделение по головам.

Вычислите d_k

Вычислите d_k для двух вариантов ANDREA. (a) ANDREA-12M: d_model = 384, n_head = 12. (b) ANDREA-480M: d_model = 1536, n_head = 24. Покажите вашу формулу d_k = d_model / n_head для каждого.

Почему делить на sqrt(d_k)

Матрица оценок

Как только Q и K существуют (каждый с формой (T, d_k)), внимание вычисляет матрицу оценок:


scores = Q · K^T     # shape: (T, T)

scores[i, j] = насколько сильно запрос позиции i выравнивается с ключом позиции j. Каждая пара (i, j) получает один score: 1024 × 1024 = 1 048 576 scores на attention head за один forward pass.


Почему делим

Скалярные произведения двух случайных единичных векторов размерности d имеют величину порядка sqrt(d). Без масштабирования scores растут с d_k:


- d_k = 64: типичные скалярные произведения порядка 8.

- d_k = 256: типичные скалярные произведения порядка 16.

- d_k = 4096: типичные скалярные произведения порядка 64.


Большие значения приводят к пиковому softmax (одна позиция доминирует, градиенты исчезают в других местах). Обучение останавливается. Масштабирование исправляет величину:


scaled_scores = (Q · K^T) / sqrt(d_k)

Для ANDREA-120M, sqrt(d_k) = sqrt(64) = 8. Каждое значение делится на 8. Величины остаются примерно на единичном масштабе независимо от d_k. Softmax остается хорошо управляемым. Градиенты текут.


Оригинальное обоснование Васвани

Из Attention Is All You Need (2017): «Для больших значений d_k скалярные произведения растут в величине, выталкивая функцию softmax в области, где у неё чрезвычайно малые градиенты.» Делитель sqrt(d_k) противодействует этому росту.


Взгляд на код

Внутри microgpt_cuda.cu это масштабирование появляется как буквальное деление:


scores[i][j] = dot(Q[i], K[j]) * (1.0f / sqrtf(d_k));

Одно умножение float на каждый score. Дёшево. Критично.

Масштабирование при d_model = 4096

Предположим, исследовательская группа создаёт ANDREA-2B с d_model = 4096 и n_head = 32. (a) Вычислите d_k. (b) Вычислите sqrt(d_k). (c) Объясните в одном предложении, что произойдёт, если команда забудет разделить на sqrt(d_k) при этом масштабе.

Почему позиция i не может видеть позицию j > i

Ограничение, рождённое генерацией

ANDREA генерирует один токен за раз. На этапе инференса позиция 0 производит первый токен, затем позиция 1 видит вывод позиции 0 и производит второй токен, и так далее. Модель никогда не имеет доступа к будущим токенам во время генерации.


Обучение должно отражать это. Если во время обучения позиция 5 могла бы обращать внимание на позицию 6, модель выучила бы обходной путь: «предсказывать токен 6, читая токен 6». На этапе инференса этот обходной путь исчезает (токен 6 ещё не существует). Поведение модели во время обучения и инференса катастрофически разойдётся.


Маска

Causal-маска блокирует внимание из любой позиции i на любую позицию j > i. Реализация: устанавливаем scaled_scores[i][j] = -infinity везде, где j > i. После softmax эти значения становятся exp(-inf) = 0. Маска чисто обнуляет внимание к будущим позициям.


for i in range(T):
for j in range(T):
if j > i:
scaled_scores[i][j] = -1e9   # эффективно -inf

После softmax (по строкам) каждая строка суммируется до 1, но только элементы [0, i] несут вероятностную массу. Позиция i смешивает информацию только из прошлых позиций.


Визуализация маски

Матрица оценок формы (T, T) с применённой маской выглядит как нижнетреугольная структура:


scaled_scores после маски, softmax по строкам:

строка 0:  [1.0, 0,   0,   0,   ...]   # видит только себя
строка 1:  [0.4, 0.6, 0,   0,   ...]   # видит позиции 0, 1
строка 2:  [0.2, 0.3, 0.5, 0,   ...]   # видит 0, 1, 2
строка 3:  [0.1, 0.2, 0.3, 0.4, ...]   # видит 0, 1, 2, 3
...

Строго нижнетреугольное распределение вероятностей по строкам. Будущее остаётся невидимым.


Почему трансформеру только с декодером это нужно

Модели только с декодером, такие как ANDREA, GPT и LLaMA, имеют одну общую цель: предсказывать следующий токен на основе предыдущих. Causal mask делает эту цель обучаемой параллельно: каждая позиция вычисляет своё предсказание следующего токена одновременно, и ни одна позиция не жульничает, заглядывая вперёд.

Маска и тип

Активность 2 (введение) охватывала три типа трансформеров: только энкодер, энкодер-декодер, только декодер. (a) Какой тип использует causal mask? (b) Объясните в одном предложении, почему другой тип (только энкодер, как BERT) НЕ использует causal mask. (c) На какую цель обучается немаскированный энкодер вместо этого?

От оценок к выходу

Softmax: От оценок к вероятностям

Маскированные, масштабированные оценки всё ещё принимают значения из области действительных чисел. Softmax преобразует каждую строку в распределение вероятностей:


A[i][j] = exp(scaled_scores[i][j]) / sum_k exp(scaled_scores[i][k])

В результате получаются три свойства:


- A[i][j] >= 0 для всех (i, j).

- sum_j A[i][j] = 1 для каждой строки i.

- Большие сырые оценки производят большие вероятности (монотонно).


Вектор вероятностей строки i говорит модели: насколько сильно позиция i должна учитывать каждую предыдущую позицию при вычислении своего выхода?


Взвешенная сумма V

Итоговый выход внимания для позиции i:


output[i] = sum_j A[i][j] · V[j]

Каждый вектор значений V[j] взвешивается вероятностью внимания A[i][j], затем суммируется. Выход позиции i объединяет векторы значений из каждой предыдущей позиции, взвешенные по релевантности.


В матричном виде, все позиции одновременно:


Attention(Q, K, V) = softmax(mask(Q · K^T / sqrt(d_k))) · V

Одна строка. Весь механизм внимания. Vaswani et al. написали эту строку в 2017 году; трансформеры с тех пор фундаментально не изменились.


Форма выхода на голову

Выход одной головы внимания: форма (T, d_k). Для ANDREA-120M: (1024, 64). Все 12 голов вычисляются параллельно; их выходы конкатенируются в (1024, 768) и подаются в финальную линейную проекцию (W_O), затем в MLP блока трансформера.


Активность 6 (grow_a_language_model_multi_head) охватывает разделение на несколько голов. Активность 7 (grow_a_language_model_transformer_block) охватывает всё, что окружает внимание: остаточные соединения, нормализацию слоёв, MLP.

Синтезируйте конвейер

Синтезируйте полный конвейер внимания своими словами. Опишите, что происходит с одной позицией i (например, позиция 5 в последовательности) от входного вектора x_5 до attention output[5]. Назовите четыре операции по порядку: (1) проекция в Q/K/V, (2) вычисление масштабированных оценок против всех позиций, (3) применение причинной маски + softmax, (4) взвешенная сумма векторов V по вероятностям. Один короткий абзац.