Reading the Math in AI Papers · Часть 1 из 1

Как читать математику в статьях по AI на arXiv: практическое руководство

Автоматический перевод

Эта статья была автоматически переведена с оригинальной английской версии.

Умение читать математику в статьях по AI полезно инженеру, которому нужно разобраться в модели, воспроизвести метод или оценить заявленный экспериментальный результат. В этом руководстве разбирается, как расшифровывать нотацию, проверять уравнение на маленьких числах и связывать его с остальным текстом статьи и с реализацией. Предполагается, что вы умеете читать код, но не обязаны знать научную нотацию.

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

Начните с разбора аттеншна: в нём одно уравнение связывается с формами массивов, маленькими числами и работающим кодом на Python. Справочник по нотации объясняет выражения, которые встретятся в других статьях. В остальных частях серии тот же метод применяется к уравнениям из конкретных статей: уравнениям архитектуры, таким как RoPE, MLA и LoRA; целевым функциям обучения, таким как DPO и GRPO; генеративным моделям и метрикам, таким как ELBO, диффузия и pass@k. Эти части ещё не вышли, поэтому разборы, на которые ссылается эта часть, пока без ссылок. За более подробным изложением основ обратитесь к книге Tianhua Chen The Little Book of Generative AI Foundations: в ней развиваются линейная алгебра и теория вероятностей, лежащие в основе генеративных моделей.

Аттеншн: читаем по одному символу

Аттеншн получает выходной вектор как взвешенное среднее векторов значений (value). Веса он находит, сравнивая вектор запроса (query) для выходной позиции с вектором ключа (key) каждой доступной входной позиции. Матрицы QQ, KK и VV собирают векторы запросов, ключей и значений. Scaled dot-product attention объединяет эти шаги в уравнении (1) из §3.2.1 (§ означает «раздел») статьи Attention Is All You Need:

Attention⁡(Q,K,V)=softmax⁡(QK⊤dk)V.\operatorname{Attention}(Q,K,V)=\operatorname{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V.

Определения находятся в тексте, а не в уравнении. В абзаце перед уравнением (1) сказано, что у запросов и ключей размерность dkd_k, а у значений — dvd_v. Метод берёт скалярное произведение каждого запроса со всеми ключами, делит каждое на dk\sqrt{d_k} и применяет softmax, «чтобы получить веса значений». Запросы «собраны в матрицу QQ», а ключи и значения — в KK и VV. Значит, каждая строка этих матриц — вектор одного токена, а softmax выдаёт по одному набору весов на каждый запрос. Обучаемые матрицы, которые превращают векторы токенов в QQ, KK и VV, появляются позже, в §3.2.2.

Формы и роли. Attention head (далее — head) выполняет одно такое вычисление со своими векторами запросов, ключей и значений. Прежде чем читать операторы, запишите их формы. Для одного head с nn запросами и mm ключами:

СимволФормаЧто этоОткуда берётся
QQn×dkn\times d_kодна строка запроса на каждую выходную позициювекторы токенов, умноженные на обучаемую матрицу
KKm×dkm\times d_kодна строка ключа на каждую позицию, доступную headвекторы токенов, умноженные на обучаемую матрицу
VVm×dvm\times d_vодна строка значения на каждый ключвекторы токенов, умноженные на обучаемую матрицу
K⊤K^\topdk×md_k\times mKK транспонированная: строки становятся столбцамите же числа, что и в KK
dkd_kчислоширина каждого запроса и ключафиксированная настройка: 64 в базовом Transformer

Форму в статьях задают, указывая множество, которому принадлежит матрица: Q∈Rn×dkQ\in\mathbb R^{n\times d_k} означает матрицу вещественных чисел с nn строками и dkd_k столбцами, то есть массив формы [n, dk].

Читайте изнутри наружу.

  1. QK⊤QK^\top умножает матрицу n×dkn\times d_k на матрицу dk×md_k\times m. Общая размерность dkd_k сворачивается суммой, и получается таблица оценок n×mn\times m. Элемент (i,j)(i,j) — это скалярное произведение запроса ii и ключа jj: перемножьте соответствующие элементы, затем сложите произведения. При фиксированных длинах векторов эта оценка тем больше, чем ближе направления векторов.

  2. Деление на dk\sqrt{d_k} не даёт оценкам расти вместе с шириной вектора. Почему ненормированные скалярные произведения растут, показывает сноска 4 статьи. Допустим, компоненты запроса и ключа независимы друг от друга (знание одних ничего не говорит о других), и у каждой среднее 0 и дисперсия 1 (средний квадрат отклонения от среднего). Тогда:

    one product qiki:variance 1q⊤k=∑i=1dkqiki:variance dk, standard deviation dkq⊤k/dk:standard deviation 1\begin{aligned} \text{one product }q_ik_i:&\quad\text{variance }1\\ q^\top k=\textstyle\sum_{i=1}^{d_k}q_ik_i:&\quad\text{variance }d_k,\ \text{standard deviation }\sqrt{d_k}\\ q^\top k/\sqrt{d_k}:&\quad\text{standard deviation }1 \end{aligned}

    В этих строках использованы два правила про независимые числа. Первое: произведение двух независимых чисел, у каждого из которых среднее 0 и дисперсия 1, тоже имеет дисперсию 1. Второе: при сложении независимых чисел их дисперсии складываются, поэтому dkd_k произведений дают дисперсию dkd_k. Стандартное отклонение — квадратный корень из дисперсии, dk\sqrt{d_k}. Деление каждой оценки на dk\sqrt{d_k} уменьшает разброс в то же число раз, обратно до 1.

    Почему эти два правила верны

    Дисперсия при нулевом среднем. Дисперсия — это средний квадрат отклонения от среднего. Когда среднее равно 0, квадрат отклонения от среднего — просто квадрат самого числа, так что дисперсия равна среднему значению квадрата. Поэтому у компоненты qiq_i со средним 0 и дисперсией 1 величина qi2q_i^2 в среднем равна 1.

    Среднее произведения. Для независимых чисел среднее произведения равно произведению средних. Возьмём число aa, которое с равной вероятностью равно 1 или 3, то есть в среднем 2, и число bb, которое с равной вероятностью равно 1 или 5, то есть в среднем 3. Независимость означает, что bb принимает каждое из своих значений одинаково часто, каким бы ни оказалось aa, поэтому все четыре пары равновероятны. При a=1a=1 произведения равны 1 и 5, их среднее 3=1×33=1\times3. При a=3a=3 они равны 3 и 15, среднее 9=3×39=3\times3. В обоих случаях среднее равно a×3a\times3, поэтому по обоим значениям aa оно составляет (3+9)/2=6(3+9)/2=6, то есть 2×32\times3. Без независимости правило ломается: если бы bb равнялось 5 всякий раз, когда aa равно 3, и 1, когда aa равно 1, встречались бы только произведения 1 и 15, а их среднее — 8. Википедия формулирует это правило для любых независимых случайных величин, называя среднее «математическим ожиданием» («expected value»): independence and expectation.

    Правило 1: у одного произведения дисперсия 1. Возьмём одно произведение qikiq_ik_i. Его среднее равно произведению средних, 0×0=00\times0=0, поэтому его дисперсия — среднее значение (qiki)2=qi2ki2(q_ik_i)^2=q_i^2k_i^2. Квадраты независимы, потому что независимы qiq_i и kik_i, и каждый в среднем равен 1, так что дисперсия равна 1×1=11\times1=1. Общая формула — variance of a product of independent variables.

    Правило 2: дисперсии независимых слагаемых складываются. Обозначим произведения xi=qikix_i=q_ik_i, тогда скалярное произведение — это сумма x1+⋯+xdkx_1+\cdots+x_{d_k}. Слагаемые независимы, потому что каждое использует свои компоненты, и у каждого среднее 0 и дисперсия 1. У суммы среднее тоже 0, поэтому её дисперсия — среднее значение её квадрата. Если умножить сумму саму на себя, получится по одному произведению xixjx_ix_j на каждую пару слагаемых, то есть сетка dk×dkd_k\times d_k:

    Сетка четыре на четыре для квадрата суммы x1 + x2 + x3 + x4, по одной клетке на каждое произведение двух слагаемых. Четыре диагональные клетки, от x1 в квадрате до x4 в квадрате, выделены: каждая в среднем равна 1, вместе они дают 4. Остальные двенадцать клеток перемножают два разных независимых слагаемых, и каждая в среднем равна 0 умножить на 0, то есть вместе они дают 0. Квадрат суммы в среднем равен 4: дисперсия 4, стандартное отклонение 2. При 64 слагаемых тот же подсчёт даёт дисперсию 64 и стандартное отклонение 8.Сетка четыре на четыре для квадрата суммы x1 + x2 + x3 + x4, по одной клетке на каждое произведение двух слагаемых. Четыре диагональные клетки, от x1 в квадрате до x4 в квадрате, выделены: каждая в среднем равна 1, вместе они дают 4. Остальные двенадцать клеток перемножают два разных независимых слагаемых, и каждая в среднем равна 0 умножить на 0, то есть вместе они дают 0. Квадрат суммы в среднем равен 4: дисперсия 4, стандартное отклонение 2. При 64 слагаемых тот же подсчёт даёт дисперсию 64 и стандартное отклонение 8.

    Диагональные клетки — это квадраты xi2x_i^2, и каждая в среднем равна 1. Любая другая клетка перемножает два разных независимых слагаемых, поэтому её среднее равно произведению их средних, 0×0=00\times0=0: положительные и отрицательные значения взаимно сокращаются. Остаются только dkd_k диагональных клеток, поэтому дисперсия суммы равна dkd_k, а стандартное отклонение — dk\sqrt{d_k}. Разброс растёт как квадратный корень из ширины, потому что почти вся сетка сокращается. Общую формулировку Википедия приводит как variance of a sum of uncorrelated variables; независимые величины всегда некоррелированы, поэтому правило охватывает и их.

    При dk=64d_k=64 сырые оценки обычно разбросаны примерно в пределах ±8\pm8; после масштабирования — примерно в пределах ±1\pm1 при любой ширине.

    Сильно разбросанные оценки насыщают softmax (шаг 3), и его градиенты исчезают. Если одна оценка в строке намного выше остальных, softmax даёт этому ключу вес, близкий к 1, а всем остальным — близкий к 0. Небольшое изменение любой оценки тогда почти не двигает веса, поэтому градиент, доходящий до запросов и ключей, близок к нулю, и обучению почти нечем их подстраивать. Статья предлагает это как вероятное объяснение более раннего результата: без масштабирования dot-product attention при большом dkd_k работал хуже additive attention, более старой формы, где оценка запроса и ключа считается небольшой сетью (Britz et al., 2017). Сами градиенты статья не измеряет.

  3. Softmax превращает каждую строку оценок в веса. Пусть z=(z1,…,zm)z=(z_1,\ldots,z_m) — одна строка масштабированных оценок. Экспонента eae^a, которую пишут и как exp⁡(a)\exp(a), использует константу e≈2.718e\approx2.718. Тогда softmax⁡(z)j=ezj/∑j′ezj′\operatorname{softmax}(z)_j=e^{z_j}/\sum_{j'}e^{z_{j'}}, где j′j' — просто второе имя индекса, так что сумма идёт по всем ключам строки. Веса положительны, и каждая строка в сумме даёт 1.

  4. Умножение весов n×mn\times m на значения m×dvm\times d_v сворачивает ось ключей. Строка ii выхода n×dvn\times d_v — это взвешенное среднее строк значений, где вес показывает, насколько хорошо каждый ключ подошёл запросу ii.

Один attention head в виде таблиц чисел: три запроса, четыре ключа, ширина ключа два и ширина значения три. Q, три на два, умноженная на K транспонированную, два на четыре, даёт таблицу оценок три на четыре. Softmax сохраняет эту форму и делает сумму каждой строки равной единице. Веса, три на четыре, умноженные на V, четыре на три, дают выход три на три, и вторая строка выхода — это взвешенное среднее строк значений с весами второй строки весов.Один attention head в виде таблиц чисел: три запроса, четыре ключа, ширина ключа два и ширина значения три. Q, три на два, умноженная на K транспонированную, два на четыре, даёт таблицу оценок три на четыре. Softmax сохраняет эту форму и делает сумму каждой строки равной единице. Веса, три на четыре, умноженные на V, четыре на три, дают выход три на три, и вторая строка выхода — это взвешенное среднее строк значений с весами второй строки весов.

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

Проверьте на двух числах. Возьмём один запрос и два ключа с масштабированными оценками (0,log⁡3)(0,\log3), выбранными так, чтобы экспоненты получились 1 и 3, и значения v1=(2,0)v_1=(2,0) и v2=(0,4)v_2=(0,4). На рисунке это разобрано по одной операции на столбец:

Таблица с одной строкой на ключ. Ключ 1: масштабированная оценка 0, экспонента 1, вес 1/4, значение (2, 0), взвешенное значение (0.5, 0). Ключ 2: масштабированная оценка log 3, экспонента 3, вес 3/4, значение (0, 4), взвешенное значение (0, 3). Экспоненты в сумме дают 4, веса — 1, а взвешенные значения — выход (0.5, 3).Таблица с одной строкой на ключ. Ключ 1: масштабированная оценка 0, экспонента 1, вес 1/4, значение (2, 0), взвешенное значение (0.5, 0). Ключ 2: масштабированная оценка log 3, экспонента 3, вес 3/4, значение (0, 4), взвешенное значение (0, 3). Экспоненты в сумме дают 4, веса — 1, а взвешенные значения — выход (0.5, 3).

Аттеншн смешал оба значения; он не выбрал токен, который подошёл лучше.

Сравните с кодом. Функция на NumPy ниже реализует один head. k.T — транспонирование. axis=1 — ось ключей, поэтому строка каждого запроса нормируется отдельно. Максимум строки вычитается перед np.exp: если прибавить одно и то же число ко всем оценкам строки, оно сократится в отношении softmax, и результат не изменится, но большие оценки перестанут вызывать переполнение. Необязательная маска задаёт заблокированным оценкам значение −∞-\infty, из-за чего их веса становятся ровно нулевыми. Декодер использует такую маску, чтобы каждый токен не смотрел на более поздние токены (§3.2.3 статьи).

Сохраните блок как attention_example.py и выполните uv run --with numpy python attention_example.py. Проверки проходят молча.

import numpy as np

def attention(q, k, v, allowed=None):
    """One head. q: [n, dk], k: [m, dk], v: [m, dv], allowed: bool [n, m]."""
    scores = q @ k.T / np.sqrt(q.shape[1])  # [n, m]
    if allowed is not None:
        if not allowed.any(axis=1).all():
            raise ValueError("every query needs at least one allowed key")
        scores = np.where(allowed, scores, -np.inf)
    scores = scores - scores.max(axis=1, keepdims=True)
    weights = np.exp(scores)
    weights = weights / weights.sum(axis=1, keepdims=True)  # rows sum to 1
    return weights @ v, weights  # [n, dv], [n, m]

# The two-key example from the text.
out, w = attention(
    np.array([[1.0]]),
    np.array([[0.0], [np.log(3.0)]]),
    np.array([[2.0, 0.0], [0.0, 4.0]]),
)
np.testing.assert_allclose(w, [[0.25, 0.75]])
np.testing.assert_allclose(out, [[0.5, 3.0]])

# A causal mask: query i may attend only to keys 0..i.
x = np.random.default_rng(0).normal(size=(3, 4))
out, w = attention(x, x, x, allowed=np.tril(np.ones((3, 3), dtype=bool)))
assert out.shape == (3, 4)
np.testing.assert_allclose(w.sum(axis=1), 1.0)
assert np.all(w[np.triu_indices(3, k=1)] == 0)

Запрос, у которого все ключи заблокированы, — случай, который уравнение оставляет открытым: каждый вес в его строке был бы равен 0/00/0. Функция выбрасывает ошибку вместо того, чтобы вернуть NaN.

От одного head к нескольким. Базовый Transformer запускает параллельно восемь head, у каждого свои обучаемые матрицы для получения QQ, KK и VV и dk=dv=64d_k=d_v=64. Он конкатенирует их выходы и умножает результат на ещё одну обучаемую матрицу, WOW^O (Attention Is All You Need, §3.2.2).

Реализация может также обрабатывать батч: несколько входных последовательностей сразу. Например, scaled dot-product attention в PyTorch принимает тензор запросов Q формы [batch, heads, n, d_k]. Первые два измерения выбирают последовательность и head; Q[b, h] — матрица [n, d_k] для этой пары. Формула аттеншна применяется к каждой паре отдельно. Функция на NumPy здесь обрабатывает только одну такую пару: её операции .T и axis=1 рассчитаны на двумерные входы.

Шесть вопросов к любому уравнению

ВопросОтвет для аттеншна
Что возвращает уравнение и какой формы результат?Матрицу n×dvn\times d_v: одна строка выхода на каждый запрос
Чем является каждый символ: данными, обученным весом, замороженной моделью, настройкой или выборкой?QQ, KK и VV вычисляются из токенов обучаемыми матрицами; dkd_k — фиксированная настройка; выборки нет
По какому индексу или оси выполняется каждая операция?Softmax идёт по mm ключам в строке каждого запроса; произведение весов на VV суммирует по ключам
Где находятся определения?Абзац перед уравнением (1), сноска 4 и §3.2.2 для обучаемых проекций
Что даёт проверка на двух-трёх числах?Веса (1/4,3/4)(1/4,3/4) и выход (0.5,3)(0.5,3)
Что пришлось решать коду, чего уравнение не определяет?Вычитание максимума строки, значение для замаскированных оценок, строка без единого разрешённого ключа

Какое утверждение делает уравнение

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

ВидПример в этой серииЧто проверить
ВычислениеВыход аттеншна; сжатый вектор MLAФорму каждого промежуточного результата
ОпределениеОценка GRPO относительно других ответовЧто означает новое имя, чтобы можно было подставить его обратно
Целевая функция: потери для минимизации или оценка для максимизацииПотери DPOМинимизируется она или максимизируется и по каким данным усредняется
Правило обновленияГрадиентный спуск; память в Gated DeltaNetЧто меняется на каждом шаге и что остаётся фиксированным
Ограничение, или множество допустимых значенийДопустимые матрицы смешивания в mHCКак статья получает значение, удовлетворяющее ограничению
Оценка границы: верхний или нижний предел величиныEvidence lower bound (ELBO)Разность между двумя сторонами и когда она равна нулю
Оценщик (estimator) или метрикаpass@kЧто подсчитывается и по скольким сэмплам
Эмпирическая подгонкаЗакон масштабирования DeepSeek LLMДиапазон данных, на котором подогнана кривая

Ограничение утверждает свойство, которым должен обладать результат. Для весов аттеншна это свойство такое: каждый вес неотрицателен, и каждая строка в сумме даёт 1. Softmax — вычисление, которое выдаёт веса с этим свойством. Одно требование ещё не говорит, что нужно использовать именно softmax.

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

Например, Evaluating Large Language Models Trained on Code, статья, в которой представили модель генерации кода Codex, использует :=:= для определения оценщика pass@k (уравнение 1). Эта метрика измеряет вероятность того, что хотя бы одна из kk сгенерированных программ пройдёт тесты. В техническом отчёте DeepSeek-V4 уравнение (2) объединяет два утверждения: M:={…}\mathcal M:=\{\ldots\} определяет множество допустимых матриц, а Bl∈MB_l\in\mathcal M требует, чтобы матрица смешивания модели BlB_l принадлежала этому множеству. Определение использует :=:=, ограничение — ∈\in, то есть «принадлежит». Разделы про pass@k и mHC разбирают эти примеры.

Как найти новое уравнение, его определения и его код

Раздел методов статьи описывает, как работает её модель или алгоритм обучения. Заголовок может быть «Method», «Architecture» или более конкретным. Авторы часто сначала объясняют существующий метод, а потом показывают, что изменили. Чтобы определить заявленный вклад, начните с описания новизны во введении. Например, DeepSeekMath, §1.1 называет Group Relative Policy Optimization (GRPO) — свой метод обучения моделей по оценённым ответам. Номера разделов и уравнений здесь относятся к статье по ссылке.

Затем сравните предлагаемый метод с более ранним, который он меняет. Это иллюстрируют две статьи:

  • Изменение архитектуры. DeepSeek-V2 описывает стандартный multi-head attention в §2.1.1 и вводит multi-head latent attention (MLA) в §2.1.2. Стандартный аттеншн хранит ключи и значения каждого предыдущего токена. MLA хранит сжатый вектор, из которого их можно восстановить. Сравнение этих уравнений показывает, что модель хранит иначе; разбор MLA выводит выигрыш в памяти.
  • Изменение обучения. DeepSeekMath, §4.1.1 приводит целевую функцию Proximal Policy Optimization (PPO) как уравнение (1), а GRPO — как уравнение (3). Обе используют преимущество (advantage): число, которое говорит, был ли ответ лучше или хуже ожидаемого. PPO оценивает его второй обучаемой сетью, value model, которая предсказывает награду, которую ещё предстоит получить после частичного ответа. GRPO вместо этого сравнивает награду за ответ с наградами за другие ответы на тот же вопрос. Разбор GRPO сравнивает эти слагаемые, используя нотацию целого ответа из DeepSeek-R1.

Найдите определения вокруг уравнения. Посмотрите предыдущий абзац, любое предложение вида «где …» после него, сноски и приложения. В Attention Is All You Need абзац перед уравнением (1) определяет размерности, а сноска 4 объясняет масштабирующий множитель. DeepSeek-V3 определяет большинство символов роутинга сразу после уравнения (15), а смещение bib_i — прямо перед уравнением (16). DeepSeek-V2 выводит MLA в уравнениях (9)–(19), а затем собирает вычисление в Приложении C.

Проверьте алгоритм и код. Блок алгоритма — это пронумерованный листинг псевдокода, задающий порядок операций. Algorithm 1 в DeepSeekMath показывает, когда генерировать ответы, а когда обновлять модель. Algorithm 1 в Denoising Diffusion Probabilistic Models (DDPM) определяет, как выбирать обучающее изображение, уровень шума и сам шум. Остальные детали решает реализация: по умолчанию np.std делит сумму квадратов отклонений на nn, а torch.std — на n−1n-1. Пример с GRPO показывает, как этот выбор меняет значения преимущества, вычисленные по одним и тем же наградам.

Версии arXiv могут переставлять разделы и повторять уравнения под новыми номерами, поэтому указывайте версию. В DeepSeek-R1 v1 целевая функция GRPO находится в §2.2.1, уравнения (1)–(3). В v2, опубликованной в январе 2026 года, это §2.1, а те же уравнения повторяются как (11)–(13) в Supplementary A.3. Ссылка без версии открывает последнюю, поэтому каждая ссылка на arXiv в этой серии содержит версию, по которой её проверяли.

Проверка прочтения с помощью LLM

Чат-модель может набросать таблицу символов, индекс каждой суммы и проверку на маленьких числах, если дать ей определения и попросить указать, чего не хватает. Текст, скопированный из PDF, сплющивает нижние и верхние индексы и дроби в одну строку; ссылки «HTML (experimental)» и «TeX Source» на странице аннотации arXiv дают чистый текст для вставки. Вставьте уравнение и окружающие его абзацы с таким промптом:

Below is equation (N) from <paper title, arXiv ID and version>, followed by
the paragraphs that define its symbols.

1. Make a table with one row per symbol: shape or type, meaning, and whether
   it is input data, a trained weight, a frozen model, a fixed setting or a
   random sample. Quote the sentence that defines it.
2. List every symbol the pasted text does not define. Do not guess them.
3. For every sum, mean, softmax, min or expectation, name the index or the
   distribution it runs over.
4. Work through the equation with the smallest numbers that use every term.
5. Say which kind of statement it is: a computation, definition, objective,
   update rule, constraint, bound, estimator or empirical fit.

Без шага 2 ничто не мешает модели заполнить недостающее определение привычным значением буквы, например прочесть σ\sigma в DPO как стандартное отклонение вместо сигмоиды. Цитаты из шага 1 делают таблицу проверяемой: найдите в PDF каждую из них, а строку, цитату из которой найти не удаётся, считайте догадкой.

Та же процедура в виде agent skills. paper-math-skills упаковывает этот раздел и справочник по нотации ниже в два skills, написанных для Claude Code; другие агенты, которые загружают файлы SKILL.md, тоже могут ими пользоваться. read-paper-math берёт зафиксированную версию arXiv, цитирует предложение, определяющее каждый символ, читает уравнение изнутри наружу и запускает проверку на маленьких числах. check-paper-math проверяет такое прочтение по статье: ищет каждую цитату, перезапускает числа и отмечает утверждения сильнее или слабее, чем в статье. В paper-math-readings лежат прочтения этих skills для частей 2–4, по одному на каждый из 15 разделов со строкой Source:.

Справочник по нотации

Если греческая буква незнакома, откройте справочник греческих букв в этой статье (Приложение A): там её название и типичные значения. Для дальнейшей практики с математикой в Stanford CS229 есть обзоры по теории вероятностей и линейной алгебре с упражнениями; Preliminaries в Dive into Deep Learning объясняют основы вместе с кодом.

Индексы, пометки и знаки отношений

Буквы — локальные имена переменных: каждая статья определяет свои. Нижние индексы обычно обозначают номера. xix_i может быть координатой ii вектора или примером ii в датасете, а hth_t — вектор модели для токена tt, его скрытое состояние (hidden state).

Верхние индексы в статьях о моделях часто служат метками. В ht(ℓ)h_t^{(\ell)} верхний индекс в скобках — это, как правило, номер слоя, а не степень; в FFN⁡i(s)\operatorname{FFN}^{(s)}_i и FFN⁡i(r)\operatorname{FFN}^{(r)}_i из DeepSeek-V3 он отмечает общих и маршрутизируемых экспертов: тех, которыми пользуется каждый токен, и тех, которых выбирает роутер (см. пример роутинга в MoE). В DeepSeek-V2 WDKVW^{DKV} и ktCk_t^C несут метки, а не показатели степени; пример с MLA определяет эти метки. W⊤W^\top — транспонирование, а x2x^2 — квадрат.

x1:Tx_{1:T} означает позиции с 1 по TT, включая TT, в отличие от среза в Python; статьи обычно считают с 1. x<tx_{<t} означает все позиции до tt. Xt,:X_{t,:} выбирает строку tt, как срез в NumPy.

Пометки над буквой обычно меняют её смысл одним из следующих способов:

ПометкаОбычное прочтениеПример или исключение
y^\hat yПредсказание или оценкаПример: A^i,t\hat A_{i,t} в DeepSeekMath оценивает, насколько ответ оказался лучше ожидаемого
xˉ\bar xСреднееИсключение: в DDPM αˉt\bar\alpha_t перемножает множители расписания шума с шага 1 по tt
x~\tilde xВозмущённая или неограниченная версияПример: в DeepSeek-V4 B~l\tilde B_l — матрица до нормализации, которая навязывает ей ограничения
x∗x^\astОптимумИсключение: в DPO r∗r^\ast — истинная награда, которую метод никогда не наблюдает
x′x'Новое значение или промежуточноеПример: в DeepSeek-V3 gi,t′g'_{i,t} — вес эксперта до нормализации
A−1A^{-1}Обратная матрицаНе поэлементное обратное число: A−1A^{-1} отменяет AA, A−1A=IA^{-1}A=I (единичная матрица), и в общем случае (A−1)ij≠1/Aij(A^{-1})_{ij}\neq1/A_{ij}

Некоторые символы, кроме греческих букв, тоже выполняют несколько ролей:

СимволЗначения
∣\midУсловие в p(y∣x)p(y\mid x); «такой, что» внутри множества
∣x∣\vert x\vertМодуль числа; длина последовательности, как в ∣oi∣\vert o_i\vert, числе токенов в ответе oio_i в GRPO; размер множества
∼\sim«Выбирается из» в x∼px\sim p; «примерно» в неформальном тексте
TTДлина последовательности; температура softmax; число шагов диффузии
qqВектор запроса (аттеншн); вопрос (GRPO); модель-студент qθq_\theta (дистилляция); энкодер qϕq_\phi (ELBO)

Пять знаков показывают, как соотносятся две стороны. :=:=, иногда ≜\triangleq, определяет новое имя. ≈\approx отмечает приближение, как среднее по выборке в разделе Математическое ожидание и откуда берутся сэмплы. ∝\propto означает «пропорционально», с опущенной нормировочной константой: pi∝ezip_i\propto e^{z_i} становится распределением только после деления на ∑jezj\sum_j e^{z_j}. ≪\ll означает «намного меньше», как в dc≪dhnhd_c\ll d_hn_h из DeepSeek-V2: сжатая ширина намного меньше суммарной ширины всех head. ←\leftarrow — присваивание, как в правиле обновления.

Суммы, подсчёты, интервалы и логарифмы

Крупный ∑\sum складывает слагаемые, а ∏\prod перемножает их. Индекс под оператором здесь начинается с 1 и идёт до верхней границы NN:

∑i=1Nxi=x1+⋯+xN,∏i=1Nxi=x1⋯xN.\sum_{i=1}^{N}x_i=x_1+\cdots+x_N,\qquad\prod_{i=1}^{N}x_i=x_1\cdots x_N.

Индекс принадлежит оператору, как переменная цикла принадлежит своему циклу. В yi=∑j=1dWijxjy_i=\sum_{j=1}^{d}W_{ij}x_j сумма идёт по jj, а ii определяет элемент выхода. Результат — вектор с одним элементом на каждое ii: записанное в развёрнутом виде произведение матрицы на вектор WxWx. Индексы в левой части говорят, какой формы выход.

Множитель перед суммой решает, что получает равный вес. Батч с ответом из 2 токенов и ответом из 8 токенов, где ℓit\ell_{it} — потери на токене tt ответа ii (в GRPO ℓ\ell — слагаемое, которое нужно максимизировать), можно усреднить двумя способами:

Lanswers=12(12∑t=12ℓ1t+18∑t=18ℓ2t)Ltokens=110(∑t=12ℓ1t+∑t=18ℓ2t)\begin{aligned} L_{\text{answers}}&=\frac12\left(\frac12\sum_{t=1}^{2}\ell_{1t}+\frac18\sum_{t=1}^{8}\ell_{2t}\right)\\ L_{\text{tokens}}&=\frac1{10}\left(\sum_{t=1}^{2}\ell_{1t}+\sum_{t=1}^{8}\ell_{2t}\right) \end{aligned}

В первом каждый ответ получает вес 12\tfrac12, который делится между его токенами:

short answer, each token:12×12=14long answer, each token:12×18=116\begin{aligned} \text{short answer, each token:}&\quad\tfrac12\times\tfrac12=\tfrac14\\ \text{long answer, each token:}&\quad\tfrac12\times\tfrac18=\tfrac1{16} \end{aligned}

Во втором у каждого токена вес 1/101/10. GRPO выбирает GG ответов o1,…,oGo_1,\ldots,o_G на каждый вопрос, а ∣oi∣\vert o_i\vert — число токенов в ответе ii. Тогда два усреднения записываются так, для GRPO из DeepSeekMath и для DAPO, более позднего варианта GRPO:

DeepSeekMath’s GRPO, per answer:1G∑i=1G1∣oi∣∑t=1∣oi∣ℓitDAPO, per token:1∑i∣oi∣∑i=1G∑t=1∣oi∣ℓit\begin{aligned} \text{DeepSeekMath's GRPO, per answer:}&\quad\frac1G\sum_{i=1}^{G}\frac1{\vert o_i\vert}\sum_{t=1}^{\vert o_i\vert}\ell_{it}\\ \text{DAPO, per token:}&\quad\frac1{\sum_i\vert o_i\vert}\sum_{i=1}^{G}\sum_{t=1}^{\vert o_i\vert}\ell_{it} \end{aligned}

При G=2G=2 это LanswersL_{\text{answers}} и LtokensL_{\text{tokens}} выше. DAPO перешёл на усреднение по токенам (§3.3), потому что усреднение по ответам придавало токенам длинных ответов слишком малый вес: модель слишком мало училась на длинных хороших ответах и недостаточно штрафовала длинные повторяющиеся плохие.

Сумма может и считать. Статьи делают это с помощью индикатора: жирной единицы с условием, 1[C]\mathbf 1[C], которая равна 1, когда условие CC истинно, и 0, когда ложно. Некоторые статьи ставят условие в скобки или печатают вместо жирной единицы двойную; смысл тот же. Поэтому сумма индикаторов считает, сколько раз условие выполнилось. Типичный пример — accuracy. Если y^i\hat y_i — предсказанный класс, а yiy_i — правильный класс для примера ii, то ∑i1[y^i=yi]\sum_i\mathbf 1[\hat y_i=y_i] — число верных предсказаний. Предсказания (кошка, собака, собака) при правильных метках (кошка, кошка, собака) дают индикаторы 1, 0 и 1, так что счёт равен 2, а accuracy — 2/3. В слое mixture-of-experts (MoE) роутер отправляет каждый токен в несколько из множества feed-forward подсетей, которые называют экспертами. В балансирующей функции потерь DeepSeek-V3 (уравнение 18) индикатор равен 1, когда оценка эксперта для токена входит в KrK_r наибольших оценок для этого токена, где KrK_r — число экспертов, в которые направляется каждый токен. Его сумма по токенам последовательности считает, как часто это случалось. Оценка здесь не включает смещение, которое добавляет роутинг, поэтому счёт может отличаться от экспертов, которых роутер выбирает на самом деле (роутинг в MoE).

Биномиальный коэффициент (nk)\binom nk, читается «nn по kk», считает способы выбрать kk различных элементов из nn без учёта порядка. Для целых 0≤k≤n0\leq k\leq n он равен n!/(k! (n−k)!)n!/(k!\,(n-k)!). Восклицательный знак означает факториал: n!=1×2×⋯×nn!=1\times2\times\cdots\times n, при 0!=10!=1. Например, (52)=5!/(2! 3!)=10\binom52=5!/(2!\,3!)=10: из пяти элементов получается десять различных пар. DeepSeekMoE использует биномиальные коэффициенты для подсчёта комбинаций экспертов, а оценщик pass@k — для подсчёта наборов сэмплов.

Интервалы используют скобки для включённых концов: [a,b][a,b] включает оба, (a,b)(a,b) — ни одного. В Gated DeltaNet αt∈(0,1)\alpha_t\in(0,1) означает строго между 0 и 1. В других местах (a,b)(a,b) — пара.

Натуральный логарифм обращает возведение в степень: log⁡(ea)=a\log(e^a)=a. Логарифмы превращают произведения в суммы, а частные — в разности: log⁡(ab)=log⁡a+log⁡b\log(ab)=\log a+\log b и log⁡(a/b)=log⁡a−log⁡b\log(a/b)=\log a-\log b, но log⁡(a+b)\log(a+b) не раскладывается. Поэтому статьи работают с лог-вероятностями. Логарифм произведения вероятностей токенов — сумма, а логарифм отношения вероятностей двух моделей — разность, именно такая форма используется в целевых функциях DPO и GRPO. Статьи по ML подразумевают натуральный логарифм, если не сказано иное; результат измеряется в натах (nats), а логарифмы по основанию 2 дают биты. Для вероятности p≤1p\leq1 величина −log⁡p≥0-\log p\geq0 и неограниченно растёт по мере приближения pp к 0, поэтому уверенное неверное предсказание обходится дорого.

Log-sum-exp означает: возведите в экспоненту каждую оценку ziz_i, сложите результаты, затем возьмите логарифм. Прямое вычисление log⁡∑iezi\log\sum_i e^{z_i} может переполниться, если оценка велика. Вместо этого найдите наибольшую оценку и назовите её mm. Запись m=max⁡izim=\max_i z_i означает «сравнить все элементы ziz_i и взять наибольший»; в NumPy это m = z.max().

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

log⁡∑iezi=m+log⁡∑iezi−m.\log\sum_i e^{z_i}=m+\log\sum_i e^{z_i-m}.

Для z=(1000,1001)z=(1000,1001) наибольшая оценка m=1001m=1001. Сдвинутые оценки равны (−1,0)(-1,0), так что вычисление превращается в 1001+log⁡(e−1+1)≈1001.3131001+\log(e^{-1}+1)\approx1001.313. Ни одна экспонента не больше 1. Код аттеншна делает то же вычитание перед softmax; там общий множитель сокращается при делении, поэтому ничего прибавлять обратно не нужно.

Условная вероятность и вероятность текста

pθ(y∣x)p_\theta(y\mid x) — вероятность, которую модель с параметрами θ\theta назначает выходу yy при входе xx. Нижний индекс называет параметры; некоторые статьи пишут p(y∣x;θ)p(y\mid x;\theta), где точка с запятой тоже отмечает параметры, а не условие. Если вместо выхода поставить точку, pθ(⋅∣x)p_\theta(\cdot\mid x) — это всё распределение по выходам, а не одно число. В статьях по RL тот же объект записывают как πθ(o∣q)\pi_\theta(o\mid q), вероятность того, что модель напишет ответ oo на вопрос qq, и называют модель политикой (policy).

Если поменять местами событие и условие, получится другое число. Допустим, есть 100 ответов модели: 60 верны, 50 являются корректным JSON и 40 — и то и другое. Тогда

P(correct∣valid JSON)=40/50=0.8,P(valid JSON∣correct)=40/60≈0.67.\begin{aligned} P(\text{correct}\mid\text{valid JSON})&=40/50=0.8,\\ P(\text{valid JSON}\mid\text{correct})&=40/60\approx0.67. \end{aligned}

Пусть AA означает «ответ верен», а BB — «ответ является корректным JSON». Условная вероятность ограничивает подсчёт ответами, удовлетворяющими условию: P(A∣B)=P(A∩B)/P(B)P(A\mid B)=P(A\cap B)/P(B), при условии P(B)>0P(B)>0. Символ ∩\cap означает «происходят оба события». Здесь дробь равна 0.4/0.5=0.80.4/0.5=0.8, то же самое, что 40 верных ответов среди 50 с корректным JSON.

Два события независимы, когда знание о том, что одно из них произошло, не меняет вероятность другого. Для этого требуется P(A∩B)=P(A)P(B)P(A\cap B)=P(A)P(B). В этой выборке P(both)=0.4P(\text{both})=0.4, тогда как P(correct)P(valid JSON)=0.6×0.5=0.3P(\text{correct})P(\text{valid JSON})=0.6\times0.5=0.3, так что в наблюдаемых долях независимости нет.

Теорема Байеса, или правило Байеса, связывает два направления условия: P(A∣B)=P(B∣A)P(A)/P(B)P(A\mid B)=P(B\mid A)P(A)/P(B). Она позволяет вычислить вероятность AA при BB по вероятности BB при AA и вероятностям двух событий. Пример с ELBO использует её, чтобы найти вероятность скрытого кода при наблюдаемом изображении.

Языковая модель оценивает последовательность по одному токену. По цепному правилу вероятности

pθ(y1:T∣x)=∏t=1Tpθ(yt∣x,y<t)log⁡pθ(y1:T∣x)=∑t=1Tlog⁡pθ(yt∣x,y<t)\begin{aligned} p_\theta(y_{1:T}\mid x)&=\prod_{t=1}^{T}p_\theta(y_t\mid x,y_{<t})\\ \log p_\theta(y_{1:T}\mid x)&=\sum_{t=1}^{T}\log p_\theta(y_t\mid x,y_{<t}) \end{aligned}

Каждый множитель зависит от всех предыдущих токенов, поэтому формула не предполагает независимости токенов. Если у трёх токенов условные вероятности 0.5, 0.2 и 0.1:

p=0.5×0.2×0.1=0.01log⁡p=log⁡0.5+log⁡0.2+log⁡0.1≈−0.693−1.609−2.303≈−4.61\begin{aligned} p&=0.5\times0.2\times0.1=0.01\\ \log p&=\log0.5+\log0.2+\log0.1\approx-0.693-1.609-2.303\approx-4.61 \end{aligned}

Обычные потери при обучении — это эта сумма с обратным знаком, делённая на длину:

L(θ)=−1T∑t=1Tlog⁡pθ(yt∣x,y<t).\mathcal L(\theta)=-\frac1T\sum_{t=1}^{T}\log p_\theta(y_t\mid x,y_{<t}).

Во время обучения предыдущие токены y<ty_{<t} берутся из датасета. Во время генерации это собственные предыдущие выборы модели.

Математическое ожидание и откуда берутся сэмплы

Математическое ожидание — это среднее, взвешенное вероятностями:

Ex∼p[f(x)]=∑xp(x)f(x).\mathbb E_{x\sim p}[f(x)]=\sum_x p(x)f(x).

Читайте Ex∼p[f(x)]\mathbb E_{x\sim p}[f(x)] как «среднее значение f(x)f(x), когда xx берётся из pp». Запись ∑x\sum_x суммирует по всем возможным дискретным значениям xx. Без нижнего индекса E[X]\mathbb E[X] усредняет случайную величину XX по её собственному распределению: если XX равно 1 с вероятностью 0.75 и 3 с вероятностью 0.25, то E[X]=1×0.75+3×0.25=1.5\mathbb E[X]=1\times0.75+3\times0.25=1.5.

Когда у переменной есть плотность p(x)p(x), то есть вероятность на единицу xx, взвешенное среднее становится интегралом, ∫f(x)p(x) dx\int f(x)p(x)\,dx. Символ dxdx показывает, что интегрируется по xx; если пределы не записаны, интеграл берётся по всему диапазону. Пример с плотностью объясняет вероятность на единицу и показывает интеграл как площадь под кривой.

Код обучения не может суммировать по всем возможным входам, поэтому он берёт выборку и усредняет: Ex∼p[f(x)]≈1N∑i=1Nf(xi)\mathbb E_{x\sim p}[f(x)]\approx\frac1N\sum_{i=1}^{N}f(x_i), где каждый xix_i независимо берётся из pp, что статьи пишут как xi∼iidpx_i\overset{\text{iid}}{\sim}p. Статьи называют это оценкой Монте-Карло (Monte Carlo estimate), а в коде это loss.mean() по батчу. Среднее по батчу оценивает математическое ожидание, только если батч берётся из распределения, указанного в нижнем индексе E\mathbb E, поэтому нижний индекс говорит, как порождаются обучающие данные:

  • DPO усредняет по сохранённым примерам (x,yw,yl)∼D(x,y_w,y_l)\sim\mathcal D: промпту, предпочтённому ответу и отвергнутому ответу. Ответы собирают и размечают до этого этапа обучения; они могут происходить из более ранней генерации модели. На каждом шаге обучения модель вычисляет вероятности для этих готовых ответов и обновляет веса. Свежих ответов для этого шага она не генерирует.
  • GRPO в DeepSeek-R1: сгенерировать ответы, затем сравнить их награды. Обучение берёт вопрос из датасета, генерирует несколько ответов и оценивает их функцией награды, например проверкой математического результата или запуском юнит-тестов. Обновление поощряет ответы, получившие оценку выше среднего по группе. Запись q∼P(Q)q\sim P(Q) означает «выбрать вопрос qq из распределения вопросов». Запись {oi}∼πθold(O∣q)\{o_i\}\sim\pi_{\theta_{old}}(O\mid q) означает «выбрать ответы oio_i на этот вопрос из копии модели πθold\pi_{\theta_{old}}». Нижний индекс old отмечает копию, сгенерировавшую эти ответы; она остаётся фиксированной, пока батч используется для обновлений. Разбор GRPO объясняет сравнение наград и обновления.
  • On-policy distillation в MiniLLM и DeepSeek-V4: сгенерировать текст, затем учиться по вероятностям учителя. Обучаемая модель — студент (student). Он генерирует текст; замороженный учитель (teacher) выдаёт вероятности следующего токена для тех же префиксов, и обучение подстраивает вероятности студента под вероятности учителя. Именно эти вероятности служат сигналом обучения, а не оценка награды за ответ, как в GRPO. MiniLLM записывает текст, сгенерированный студентом, как y∼qθy\sim q_\theta: yy — это текст, а qθq_\theta называет модель-студента. DeepSeek-V4 называет своего студента πθ\pi_\theta и использует нескольких специализированных учителей. Реальная процедура выборки в MiniLLM к тому же подмешивает токены, взятые у учителя. Разбор дистилляции объясняет целевые функции и это различие в выборке.

Порядок показывает, что оптимизирует обучение. Допустим, модель назначает вероятности 0.9 и 0.1 правильным выходам двух равновзвешенных обучающих примеров. Усреднить их лог-вероятности значит сначала взять каждый логарифм, а потом усреднить: np.log(probs).mean(). Взять логарифм их среднего — np.log(probs.mean()). Если XX — вероятность, назначенная правильному выходу случайно выбранного примера:

E[log⁡X]=12(log⁡0.9+log⁡0.1)≈−1.20log⁡E[X]=log⁡((0.9+0.1)/2)=log⁡0.5≈−0.69\begin{aligned} \mathbb E[\log X]&=\tfrac12(\log0.9+\log0.1)\approx-1.20\\ \log\mathbb E[X]&=\log\bigl((0.9+0.1)/2\bigr)=\log0.5\approx-0.69 \end{aligned}

Если поменять знак, получатся потери 1.20 и 0.69. Вторая модель, которая назначает 0.5 каждому правильному выходу, получает 0.69 при любом из двух вычислений. Значит, усреднение вероятностей до логарифма считает две модели одинаково хорошими, а обычное среднее отрицательных лог-вероятностей сильнее штрафует первую модель за низкую вероятность на втором правильном выходе. Переводя функцию потерь в код, сохраняйте порядок логарифма и усреднения.

Неравенство Йенсена формулирует общее соотношение для положительного XX: E[log⁡X]≤log⁡E[X]\mathbb E[\log X]\leq\log\mathbb E[X]. Оно же помогает строить альтернативные целевые функции обучения. Когда вероятность данных в модели требует дорогого усреднения по скрытым переменным, среднее логарифмических слагаемых может дать нижнюю границу, которую легче оценить. Разбор ELBO объясняет эту задачу обучения; ELBO расшифровывается как evidence lower bound. В разделе 2.4 книги Tianhua Chen The Little Book of Generative AI Foundations граница выводится с помощью неравенства Йенсена.

Плотности, дисперсия и планки погрешностей

У p(x)p(x) два распространённых смысла. Для дискретных исходов, таких как токены или классы, оно даёт вероятность исхода xx: число от 0 до 1, причём вероятности по всем исходам в сумме дают 1.

Чтобы понять другой смысл, допустим, что XX выбирается равномерно между 0 и 0.5. Интервалы одинаковой длины имеют одинаковые вероятности. Интервал от 0.1 до 0.2 занимает одну пятую всего диапазона, поэтому

P(0.1≤X≤0.2)=0.2−0.10.5=0.2.P(0.1\leq X\leq0.2)=\frac{0.2-0.1}{0.5}=0.2.

В этом диапазоне вероятность — это ширина интервала, умноженная на 2. Этот множитель и есть плотность вероятности: p(x)=2p(x)=2 при 0≤x≤0.50\leq x\leq0.5 и ноль вне этого отрезка. Плотность описывает вероятность на единицу переменной, а не вероятность одного точного значения.

Нулевая вероятность точки не означает, что ничего не выбирается. Сужайте интервал вокруг 0.15: его вероятность вдвое больше его ширины, поэтому она стремится к нулю вместе с шириной. Значит, у одной точной точки вероятность нулевая. Но выборка всё равно даёт какое-то значение в [0,0.5][0,0.5], а вероятность всего этого интервала равна 1. Если записать результат, округлив до двух знаков после запятой, записанное значение 0.15 представляет интервал от 0.145 до 0.155, вероятность которого 2×0.01=0.022\times0.01=0.02.

Для неравномерной плотности множитель меняется с xx. Интеграл складывает вклады по интервалу:

P(a≤X≤b)=∫abp(x) dx.P(a\leq X\leq b)=\int_a^bp(x)\,dx.

Геометрически это площадь под кривой плотности между aa и bb; площадь по всему диапазону равна 1. В равномерном примере площадь — это просто высота 2, умноженная на ширину 0.5. Поэтому плотность может превышать 1, а её логарифм — быть положительным, как здесь log⁡2≈0.69\log2\approx0.69. Вероятность никогда не превышает 1.

Гауссово распределение, которое в DDPM используется для шума, имеет плотность такого рода. Не у каждого непрерывного распределения есть обычная плотность: распределение Кантора — математический контрпример, не относящийся к обсуждаемым здесь моделям. Хранение вещественных значений тоже не означает непрерывного распределения: переменная, ограниченная значениями 0.0 и 1.0, по-прежнему имеет два дискретных исхода.

Статьи часто обозначают вероятности и плотности одной и той же буквой. Проверьте, как статья определяет распределение переменной и по какой переменной ведётся суммирование или интегрирование. Интеграл по скрытой переменной zz, такой как латентный код в ELBO в части 4, не говорит, дискретна наблюдаемая xx или непрерывна. Некоторые статьи пишут заглавное PP для вероятностей и строчное pp для плотностей, но во многих pp используют для обеих.

Чтобы описать, насколько распределение разбросано вокруг среднего, статьи используют дисперсию (variance): средний квадрат отклонения от среднего, Var⁡(X)=E[(X−μ)2]\operatorname{Var}(X)=\mathbb E[(X-\mu)^2], где μ=E[X]\mu=\mathbb E[X]. Стандартное отклонение (standard deviation) — её квадратный корень, поэтому оно измеряется в тех же единицах, что и XX.

Эти величины присутствуют и в названиях распределений. Гауссово распределение, или нормальное, записывается N(μ,σ2)\mathcal N(\mu,\sigma^2): μ\mu — его среднее, а σ2\sigma^2 — дисперсия. Для вектора N(μ,Σ)\mathcal N(\mu,\Sigma) использует ковариационную матрицу Σ\Sigma: элемент (i,j)(i,j) измеряет, как вместе меняются координаты ii и jj, а на диагонали стоят их дисперсии. N(0,I)\mathcal N(0,I) описывает вектор независимых стандартных нормальных чисел, у каждого из которых среднее 0 и дисперсия 1; II — единичная матрица.

Таблицы бенчмарков часто приводят средний результат вместе с мерой изменчивости. Разброс отдельных запусков отличается от неопределённости их среднего: для NN независимых запусков со стандартным отклонением σ\sigma стандартная ошибка среднего равна σ/N\sigma/\sqrt N.

Прежде чем сравнивать две записи вроде 82.3±0.482.3\pm0.4 и 81.5±0.481.5\pm0.4, выясните по подписи, является ли 0.4 стандартным отклонением по запускам, стандартной ошибкой или полушириной доверительного интервала. Чтобы сравнить средние, вычислите интервал для их разности. Процедура 95%-го доверительного интервала даёт диапазоны, которые содержат истинную разность в 95% повторных экспериментов при своих допущениях.

В этом примере предположим четыре независимых запуска на модель, приблизительно нормальные результаты запусков и равные дисперсии генеральных совокупностей. Если запуски парные, например две модели оцениваются на одних и тех же независимо выбранных задачах, анализируйте разности внутри пар. Эти случаи объясняет руководство NIST по двум выборкам.

Для независимых средних дисперсия их разности равна сумме их дисперсий. Стандартная нормальная величина попадает между −1.96-1.96 и 1.961.96 с вероятностью около 0.95, что даёт множитель для нормального приближения 95%-го интервала. Если 0.4 — стандартное отклонение по четырём запускам, то первый расчёт даёт:

standard error of each mean=0.4/4=0.2standard error of the gap=0.22+0.22≈0.28gap=82.3−81.5=0.8normal approximation=0.8±1.96×0.28≈0.8±0.55=from 0.25 to 1.35\begin{aligned} \text{standard error of each mean}&=0.4/\sqrt4=0.2\\ \text{standard error of the gap}&=\sqrt{0.2^2+0.2^2}\approx0.28\\ \text{gap}&=82.3-81.5=0.8\\ \text{normal approximation}&=0.8\pm1.96\times0.28\approx0.8\pm0.55\\ &=\text{from }0.25\text{ to }1.35 \end{aligned}

Множитель 1.96 считает оценённый разброс известным. При всего четырёх запусках на модель используйте t-распределение Стьюдента, чтобы учесть неопределённость разброса. При перечисленных допущениях число степеней свободы равно 4+4−2=64+4-2=6 (восемь запусков минус две оценённые средние). scipy.stats.t.ppf(0.975, 6) даёт около 2.447 вместо 1.96; 0.975 оставляет по 2.5% за каждым концом 95%-го интервала. Если допущение о равных дисперсиях не подходит, используйте интервал Уэлча (Welch), у которого степени свободы считаются иначе.

Теперь рассмотрим другое прочтение подписи: 0.4 — уже стандартная ошибка каждого среднего, оценённая по этим четырём запускам. Делить на 4\sqrt4 ничего не нужно, и стандартная ошибка разности равна примерно 0.566. Множитель Стьюдента по-прежнему нужен. Два прочтения дают:

0.4 a standard deviation, t interval:0.8±2.4470.22+0.22≈0.8±0.69from 0.11 to 1.490.4 a standard error, t interval:0.8±2.4470.42+0.42≈0.8±1.38from −0.58 to 2.18\begin{aligned} \text{0.4 a standard deviation, t interval:}&\quad0.8\pm2.447\sqrt{0.2^2+0.2^2}\approx0.8\pm0.69\\ &\quad\text{from }0.11\text{ to }1.49\\ \text{0.4 a standard error, t interval:}&\quad0.8\pm2.447\sqrt{0.4^2+0.4^2}\approx0.8\pm1.38\\ &\quad\text{from }-0.58\text{ to }2.18 \end{aligned}

На рисунке начальное нормальное приближение сравнивается с двумя t-интервалами:

Три интервала для одной и той же разности 0.8 при допущении о четырёх независимых приблизительно нормальных запусках на модель и равных дисперсиях генеральных совокупностей. Если 0.4 — стандартное отклонение, нормальное приближение даёт от 0.25 до 1.35, а t-интервал — от 0.11 до 1.49. Если 0.4 — оценённая стандартная ошибка, t-интервал даёт от минус 0.58 до 2.18 и содержит ноль.Три интервала для одной и той же разности 0.8 при допущении о четырёх независимых приблизительно нормальных запусках на модель и равных дисперсиях генеральных совокупностей. Если 0.4 — стандартное отклонение, нормальное приближение даёт от 0.25 до 1.35, а t-интервал — от 0.11 до 1.49. Если 0.4 — оценённая стандартная ошибка, t-интервал даёт от минус 0.58 до 2.18 и содержит ноль.

Когда 0.4 — стандартное отклонение, t-интервал исключает ноль: при этих допущениях результаты поддерживают положительную разность. Когда 0.4 — оценённая стандартная ошибка, интервал содержит ноль, поэтому результаты не позволяют установить, у какой модели средний результат выше.

Кросс-энтропия и KL-дивергенция

При обучении модели нужна числовая функция потерь (loss), которая измеряет, насколько предсказанные вероятности согласуются с обучающей целью. Алгоритм обучения меняет параметры модели, чтобы уменьшить эти потери. Кросс-энтропия даёт такие потери для размеченных примеров или вероятностей модели-учителя. Дивергенция Кульбака — Лейблера (KL) измеряет расхождение между двумя распределениями. Статьи используют её, чтобы научить студента имитировать учителя или чтобы штрафовать отклонения от фиксированной эталонной модели.

Здесь исходы дискретны, например токены или классы. Обозначим целевое распределение pp, а предсказанное моделью распределение по тем же исходам — qq. Начнём с одного наблюдаемого исхода ii: если модель дала ему вероятность qiq_i, потери равны −log⁡qi-\log q_i. Они равны 0 при qi=1q_i=1, около 0.69 при qi=0.5q_i=0.5, около 2.3 при qi=0.1q_i=0.1 и бесконечны при qi=0q_i=0.

Кросс-энтропия усредняет эти потери по исходам, выбранным из цели:

H(p,q)=Ei∼p[−log⁡qi]=−∑ipilog⁡qi.H(p,q)=\mathbb E_{i\sim p}[-\log q_i]=-\sum_i p_i\log q_i.

Для one-hot метки pp, равной 1 для правильного класса yy и 0 для остальных, считается только правильный класс, и H(p,q)=−log⁡qyH(p,q)=-\log q_y: обычные потери классификации. nn.CrossEntropyLoss в PyTorch вычисляет это по сырым оценкам модели, логитам (logits), и сам применяет log-softmax; на вход ему подаётся не вектор вероятностей qq. Если pp — мягкое распределение модели-учителя, каждый класс учитывается пропорционально вероятности учителя. Классическая дистилляция обучает небольшую модель на вероятностях большой именно так. Для цели p=(0.9,0.1)p=(0.9,0.1) у двух моделей такие кросс-энтропии H(p,q)H(p,q):

q=(0.5,0.5):−0.9log⁡0.5−0.1log⁡0.5≈0.693q=(0.9,0.1):−0.9log⁡0.9−0.1log⁡0.1≈0.095+0.230=0.325\begin{aligned} q=(0.5,0.5):&\quad -0.9\log0.5-0.1\log0.5\approx0.693\\ q=(0.9,0.1):&\quad -0.9\log0.9-0.1\log0.1\approx0.095+0.230=0.325 \end{aligned}

Вторая модель совпадает с целью, и лучше не может быть ни одна модель. Этот минимум, здесь 0.325, равен H(p)=−∑ipilog⁡piH(p)=-\sum_ip_i\log p_i, энтропии (entropy) pp. Он равен 0 только для one-hot цели: когда сама цель неопределённа, остаются потери, которые не может убрать никакая модель.

KL-дивергенция вычитает этот минимум и оставляет только потери, вызванные отличием qq от pp. Её записывают с двойной чертой ∥\Vert, которая лишь разделяет два аргумента; это не вертикальная черта условной вероятности ∣\mid из раздела Условная вероятность и вероятность текста и не знак длины ∥x∥\Vert x\Vert из справочника по векторам. Статьи используют её вместо запятой, чтобы показать, что порядок важен: усреднение идёт по исходам, выбранным из первого аргумента.

DKL(p ∥ q)=H(p,q)−H(p)=∑ipilog⁡piqi=Ei∼p[log⁡piqi].D_{\mathrm{KL}}(p\,\Vert\,q)=H(p,q)-H(p)=\sum_i p_i\log\frac{p_i}{q_i}=\mathbb E_{i\sim p}\Bigl[\log\frac{p_i}{q_i}\Bigr].

Для первой модели выше 0.693−0.325≈0.370.693-0.325\approx0.37. KL равна 0, когда два распределения совпадают, и положительна в остальных случаях.

Порядок меняет то, какие несовпадения штрафуются. Слагаемое с pi>0p_i>0 и qi=0q_i=0 бесконечен, поэтому DKL(p∥q)D_{\mathrm{KL}}(p\Vert q) штрафует qq за нулевую вероятность чего-либо, что может выдать pp. Исходы с pi=0p_i=0 ничего не добавляют (по соглашению 0log⁡0=00\log0=0), поэтому прямого штрафа они не несут, даже если qi>0q_i>0. Если поменять аргументы местами, получится DKL(q∥p)D_{\mathrm{KL}}(q\Vert p), которая бесконечна всюду, где qi>0q_i>0 и pi=0p_i=0. Исходы с qi=0q_i=0 теперь ничего не добавляют, даже если pi>0p_i>0. Если pp — цель, то DKL(p∥q)D_{\mathrm{KL}}(p\Vert q) называют прямой (forward) KL, а DKL(q∥p)D_{\mathrm{KL}}(q\Vert p) — обратной (reverse) KL.

Для p=(0.5,0.5)p=(0.5,0.5) и q=(1,0)q=(1,0) прямая KL бесконечна, потому что qq упускает исход, который выдаёт pp, а обратная KL равна всего 1×log⁡(1/0.5)+0=log⁡21\times\log(1/0.5)+0=\log2: исход, который qq пропускает, ничего не добавляет. Для p=(0.9,0.1)p=(0.9,0.1) и q=(0.5,0.5)q=(0.5,0.5) прямая KL — это найденные выше 0.37, здесь вычисленные по слагаемым, а обратная KL отличается:

DKL(p∥q)=0.9log⁡0.90.5+0.1log⁡0.10.5≈0.53−0.16=0.37DKL(q∥p)=0.5log⁡0.50.9+0.5log⁡0.50.1≈−0.29+0.80=0.51\begin{aligned} D_{\mathrm{KL}}(p\Vert q)&=0.9\log\tfrac{0.9}{0.5}+0.1\log\tfrac{0.1}{0.5}\approx0.53-0.16=0.37\\ D_{\mathrm{KL}}(q\Vert p)&=0.5\log\tfrac{0.5}{0.9}+0.5\log\tfrac{0.5}{0.1}\approx-0.29+0.80=0.51 \end{aligned}

Из-за этой асимметрии KL называют дивергенцией, а не расстоянием.

Поскольку H(p,q)=H(p)+DKL(p∥q)H(p,q)=H(p)+D_{\mathrm{KL}}(p\Vert q), а энтропия фиксированного учителя H(p)H(p) не зависит от студента, кросс-энтропия относительно фиксированного учителя даёт студенту те же градиенты, что и DKL(p∥q)D_{\mathrm{KL}}(p\Vert q). Изменение параметра студента меняет обе функции потерь на одну и ту же величину, поэтому их производные, используемые при обучении, равны; вычисление объясняет раздел Градиенты и оптимизация. Благодаря этому код классификации и классической дистилляции может использовать кросс-энтропию. Такая замена работает только при учителе на первом месте. Если студент стоит первым, DKL(q∥p)=H(q,p)−H(q)D_{\mathrm{KL}}(q\Vert p)=H(q,p)-H(q), а собственная энтропия студента H(q)H(q) меняется по ходу обучения, поэтому градиенты у них уже не совпадают.

Векторы и матрицы

Уравнения архитектуры описывают вычисления над массивами чисел. Форма (shape) массива говорит, как расположены его числа, какие операции допустимы и что они дают. Вектор — упорядоченный список чисел. Матрица располагает числа по строкам и столбцам. В коде ML тензор (tensor) — общий термин для таких числовых массивов, в том числе с более чем двумя осями. Ось (axis) — измерение, по которому индексируется массив: у матрицы есть ось строк и ось столбцов.

Скрытое состояние (hidden state) токена — вектор чисел, вычисленный внутри модели для представления этого токена. Допустим, мы обрабатываем вместе батч из BB последовательностей, в каждой TT позиций токенов, а каждое скрытое состояние содержит dd чисел. Массив скрытых состояний имеет форму [B, T, d], которую статьи пишут и как B×T×dB\times T\times d. Его три оси выбирают последовательность, позицию токена и число внутри вектора этого токена. Например, [2, 3, 4] содержит две последовательности, по три вектора токенов в каждой и по четыре числа в векторе: всего 24 числа. Здесь dd — ширина вектора. Форма перечисляет три размера; их произведение даёт число элементов.

Статьи часто записывают формы как принадлежность множеству: a∈Rda\in\mathbb R^d означает, что aa — вектор из dd вещественных чисел, а A∈Rm×nA\in\mathbb R^{m\times n} — что AA — матрица с mm строками и nn столбцами. Жирные буквы иногда отмечают векторы или тензоры, но форму определяет определение в статье.

В таблице ниже aa и bb — векторы-столбцы: их числа расположены вертикально. Верхний индекс ⊤\top означает транспонирование: обмен строк и столбцов. Так a⊤a^\top — строка с теми же числами, что и столбец aa. Заглавные AA и BB здесь называют матрицы; BB больше не означает размер батча.

ВыражениеИспользуемые значенияЧто делает операцияРезультат
a⊤ba^\top b — скалярное произведениеДва вектора-столбца, в каждом по dd элементовПеремножить соответствующие элементы, затем сложить произведения: ∑iaibi\sum_i a_i b_iОдно число
ab⊤ab^\top — внешнее произведениеСтолбец aa с mm элементами и столбец bb с nn элементамиУмножить каждый элемент aa на каждый элемент bbМатрица m×nm\times n; элемент (i,j)(i,j) равен aibja_i b_j
ABAB — матричное произведениеAA с mm строками и kk столбцами; BB с kk строками и nn столбцамиДля элемента (i,j)(i,j) перемножить соответствующие числа строки ii матрицы AA и столбца jj матрицы BB, затем сложитьМатрица m×nm\times n; число столбцов AA должно равняться числу строк BB
A⊙BA\odot B — поэлементное произведениеДва массива одной формыПеремножить элементы на совпадающих позициях, не складывая ихМассив той же формы
[a;b][a;b] — конкатенацияСтолбцы aa и bb с mm и nn элементамиПоставить элементы bb после элементов aaОдин столбец с m+nm+n элементами; проверьте в статье соглашение об оси склейки

Для конкретного сравнения возьмём a=(12)a=\begin{pmatrix}1\\2\end{pmatrix} и b=(34)b=\begin{pmatrix}3\\4\end{pmatrix}. Перенос транспонирования меняет и вычисление, и результат:

a⊤b=1×3+2×4=11ab⊤=(1×31×42×32×4)=(3468).\begin{aligned} a^\top b&=1\times3+2\times4=11\\ ab^\top&=\begin{pmatrix}1\times3&1\times4\\2\times3&2\times4\end{pmatrix}=\begin{pmatrix}3&4\\6&8\end{pmatrix}. \end{aligned}

Скалярное произведение даёт одну оценку, как при сравнении запроса и ключа в аттеншне. Внешнее произведение сохраняет отдельное значение для каждой пары элементов; обновление в Gated DeltaNet использует его, чтобы построить матричное обновление из двух векторов.

Матричное произведение можно перегруппировать, (AB)C=A(BC)(AB)C=A(BC), но нельзя переставить множители; вывод MLA использует перегруппировку, чтобы не восстанавливать ключи. NumPy записывает матричное умножение как @, а поэлементное произведение как *. Статьи не наследуют правила broadcasting из NumPy: чтобы прибавить вектор к матрице, нужно указать ось. Статьи расходятся и в том, строка вектор или столбец: аттеншн складывает токены в строки QQ, тогда как MLA, Gated DeltaNet и LoRA пишут WhWh с векторами-столбцами, а nn.Linear в PyTorch вычисляет x @ W.T над строками.

Уравнение архитектуры может также описывать размер вектора, ограничивать допустимые матрицы или перестраивать произведение:

ЗаписьЗначение
∥x∥2=∑ixi2\Vert x\Vert_2=\sqrt{\sum_i x_i^2}Евклидова длина; ∥x∥2\Vert x\Vert^2, без корня, встречается в потерях DDPM
∥x∥1=∑i∣xi∣\Vert x\Vert_1=\sum_i\vert x_i\vertСумма модулей
∥A∥2\Vert A\Vert_2Спектральная норма: наибольший множитель, на который AA увеличивает длину вектора; mHC удерживает её не выше 1
rank⁡(A)\operatorname{rank}(A)Число независимых столбцов; у обновления LoRA ранг не выше rr
det⁡A\det AОпределитель: ∣det⁡A∣\vert\det A\vert — множитель, на который AA масштабирует объём, а знак показывает, меняет ли AA ориентацию; пример замены переменных в Приложении B этой статьи использует его
A≥0A\geq0Каждый элемент неотрицателен, как в mHC; A⪰0A\succeq0 — другое условие, положительная полуопределённость: x⊤Ax≥0x^\top Ax\geq0 для каждого xx
II, 1n\mathbf 1_nЕдиничная матрица (1 на диагонали, 0 в остальных местах, так что Ix=xIx=x); вектор из nn единиц
(AB)⊤=B⊤A⊤(AB)^\top=B^\top A^\topТранспонирование произведения меняет порядок на обратный; им пользуются разделы про RoPE и MLA в части 2

Градиенты и оптимизация

Обучение использует производные, чтобы решить, как менять параметры модели. Пусть L\mathcal L — одна скалярная функция потерь, а θ\theta — вектор всех параметров; θi\theta_i — один элемент этого вектора.

Частная производная ∂L/∂θi\partial\mathcal L/\partial\theta_i — одно число, вычисленное при текущих значениях параметров. Она измеряет скорость изменения потерь, когда меняется только θi\theta_i, а остальные параметры остаются фиксированными. Читайте её как «частная производная потерь по параметру θi\theta_i».

Градиент ∇θL\nabla_\theta\mathcal L собирает эти числа для всех параметров в один вектор. Его ii-й элемент равен ∂L/∂θi\partial\mathcal L/\partial\theta_i. Символ ∇\nabla называется набла; здесь он означает «взять градиент». При единственном параметре у градиента один элемент, равный обычной производной.

Например, возьмём L(θ1,θ2)=θ12+3θ22\mathcal L(\theta_1,\theta_2)=\theta_1^2+3\theta_2^2. При θ1=2\theta_1=2 и θ2=1\theta_2=1:

∂L∂θ1=2θ1=4∂L∂θ2=6θ2=6∇θL=(46).\begin{aligned} \frac{\partial\mathcal L}{\partial\theta_1}&=2\theta_1=4\\ \frac{\partial\mathcal L}{\partial\theta_2}&=6\theta_2=6\\ \nabla_\theta\mathcal L&=\begin{pmatrix}4\\6\end{pmatrix}. \end{aligned}

Первая частная производная, 4, означает, что увеличение θ1\theta_1 на 0.01 повышает потери примерно на 0.04, пока θ2\theta_2 фиксировано. Градиент содержит эту информацию для обоих параметров. Градиентный спуск вычитает производную каждого параметра, умноженную на положительную скорость обучения (learning rate) η\eta, которая задаёт размер шага:

θ←θ−η∇θL,η>0.\theta\leftarrow\theta-\eta\nabla_\theta\mathcal L,\qquad\eta>0.

При η=0.1\eta=0.1 пример переходит от (2,1)(2,1) к (1.6,0.4)(1.6,0.4), а потери падают с 7 до 3.04. Для дифференцируемой функции потерь с ненулевым градиентом достаточно малый шаг уменьшает потери. Нулевой градиент обновления не даёт.

Нижний индекс у ∇\nabla говорит, что меняется. ∇θlog⁡pθ(x)\nabla_\theta\log p_\theta(x) варьирует параметры; ∇xlog⁡pθ(x)\nabla_x\log p_\theta(x) варьирует вход, и в статьях по диффузии его называют score, что не имеет отношения к оценке на бенчмарке.

Якобиан записывает производные для нескольких выходов. Слой нейросети может выдавать много чисел, например компоненты скрытого состояния токена. Чтобы описать, как каждый выход реагирует на каждый вход, частные производные собирают в матрицу, которую называют якобианом (Jacobian). Для y=f(x)y=f(x) с nn входными и mm выходными числами его форма m×nm\times n: строки соответствуют выходам, столбцы — входам, а элемент Jij=∂yi/∂xjJ_{ij}=\partial y_i/\partial x_j измеряет, как меняется выход ii при изменении входа jj.

Например, пусть функция принимает два числа и возвращает y1=x1+2x2y_1=x_1+2x_2 и y2=3x1−x2y_2=3x_1-x_2. Её якобиан равен

J=(∂y1/∂x1∂y1/∂x2∂y2/∂x1∂y2/∂x2)=(123−1).\begin{aligned} J&=\begin{pmatrix} \partial y_1/\partial x_1 & \partial y_1/\partial x_2\\ \partial y_2/\partial x_1 & \partial y_2/\partial x_2 \end{pmatrix}\\ &=\begin{pmatrix}1&2\\3&-1\end{pmatrix}. \end{aligned}

Второй столбец говорит, что увеличение x2x_2 на 0.1 при фиксированном x1x_1 увеличивает y1y_1 на 0.2 и уменьшает y2y_2 на 0.1. Этот пример линеен, поэтому его якобиан постоянен. У нелинейной функции элементы могут зависеть от текущего входа и описывают малые изменения локально. При единственном скалярном выходе у якобиана одна строка: те же производные, что и в градиенте, только транспонированные при нашем соглашении о векторах-столбцах. Общие определения даёт Deep Learning, §4.3.

Обратное распространение ошибки (backpropagation) использует эти производные, чтобы вычислить градиент потерь через последовательные слои. Пример замены переменных в Приложении B этой статьи использует другое свойство: абсолютное значение определителя квадратного якобиана даёт локальный коэффициент масштабирования объёма, который нужен для пересчёта плотности вероятности.

В обучении производные описывают локальные изменения; оптимизационная цель говорит, что обновления должны минимизировать или максимизировать. Статьи различают наилучшее значение цели и параметры, которые его достигают: min⁡θf(θ)\min_\theta f(\theta) — наименьшее значение ff, а arg min⁡θf(θ)\operatorname*{arg\,min}_\theta f(\theta) даёт значения параметров, при которых оно достигается. Для f(θ)=(θ−3)2f(\theta)=(\theta-3)^2 минимум равен 0, а argmin равен 3. Argmin задаёт желаемый результат, но не определяет алгоритм обновления.

Например, MiniLLM записывает свою цель как θ=arg min⁡θDKL(qθ∥p)\theta=\operatorname*{arg\,min}_\theta D_{\mathrm{KL}}(q_\theta\Vert p) (уравнение 1), где qθq_\theta — модель-студент, а pp — учитель, у которого она учится. Затем в разделе 2.2 выводится градиент, который затем изменяется, чтобы сделать обучение устойчивее; уравнение (7) — градиент, который используется для обновлений. Пример с on-policy distillation объясняет эти изменения. Если прочесть только argmin, их можно пропустить.

Stop-gradient, sg⁡(x)\operatorname{sg}(x), пропускает xx вперёд без изменений, но блокирует градиенты через себя, как .detach() в PyTorch. Два выражения с одинаковым значением в прямом проходе могут обучаться по-разному, если одно из них отсоединено. В примере с GRPO Hugging Face TRL считает лог-вероятность старой модели фиксированной. В упрощении дистилляции, которое обсуждает DeepSeek-V4, отсоединённое лог-отношение учителя и студента даёт фиксированный вес для обновления.

Множества и ограничения

Ограничение (constraint) говорит, какие значения допустимы. Статьи часто выражают ограничения через множества: наборы различных элементов, записываемые в фигурных скобках, например {1,2,3}\{1,2,3\}. Порядок не важен, поэтому {3,1,2}\{3,1,2\} — то же множество. Повторяющиеся элементы считаются один раз. Для сравнения, круглые скобки в векторе вроде (1,2,3)(1,2,3) описывают упорядоченный список: (3,1,2)(3,1,2) — уже другой вектор.

Когда статья определила множество, она может проверять принадлежность, объединять множества, считать их элементы или формулировать на них условие. Возьмём A={1,2,3}A=\{1,2,3\} и B={3,4}B=\{3,4\}:

ЗаписьЗначениеПример и как его читать
x∈Ax\in AПринадлежность: xx принадлежит AA2∈A2\in A: 2 — элемент AA
A∪BA\cup BОбъединение: включить каждый элемент любого из множествA∪B={1,2,3,4}A\cup B=\{1,2,3,4\}; 3 включается только один раз
A∩BA\cap BПересечение: оставить только общие элементы обоих множествA∩B={3}A\cap B=\{3\}
∣A∣\vert A\vertЧисло различных элементов∣A∣=3\vert A\vert=3
∀\forall«Для каждого»: условие должно выполняться для всех названных элементов∀x∈A: x>0\forall x\in A:\ x>0: каждый элемент AA положителен
∃\exists«Существует»: хотя бы один элемент должен удовлетворять условию∃x∈A: x>2\exists x\in A:\ x>2: в AA есть элемент больше 2, а именно 3

Нотация форм из раздела Векторы и матрицы тоже называет множества: Rd\mathbb R^d — множество всех векторов из dd вещественных чисел, а Rn×d\mathbb R^{n\times d} — множество всех вещественных матриц с nn строками и dd столбцами. Таким образом, Q∈Rn×dkQ\in\mathbb R^{n\times d_k} указывает, какую форму должна иметь QQ.

Set-builder-нотация задаёт множество условием: {x∈S∣condition}\{x\in S\mid\text{condition}\} читается «элементы SS, удовлетворяющие условию», как set comprehension в Python {x for x in S if condition(x)}. Черта здесь означает «такой, что», а не условную вероятность; некоторые статьи вместо неё используют двоеточие. Примеры в этой серии — допустимые матрицы в mHC, выбранные эксперты в MoE и выбранные токены в разреженном аттеншне.

DAPO, метод обучения, фильтрующий группы сгенерированных ответов, оставляет вопрос, только если часть ответов верна, а часть неверна. Для GG выбранных ответов o1,…,oGo_1,\ldots,o_G и эталонного ответа aa запишем множество индексов верных ответов как

C={i∈{1,…,G}∣is_equivalent⁡(a,oi)}.C=\{i\in\{1,\ldots,G\}\mid\operatorname{is\_equivalent}(a,o_i)\}.

Фильтр — это 0<∣C∣<G0<\vert C\vert<G. Индексы делают подсчёт явным: два сэмпла с одинаковым текстом по-прежнему считаются двумя ответами. Статья DAPO записывает множество через сами ответы oio_i; если читать это буквально как множество текстов, два одинаковых ответа посчитаются один раз.

Упражнения

  1. Формы. QQ имеет форму 4×84\times8, KK — 6×86\times8, VV — 6×36\times3. Какие формы у оценок и у выхода? По какой оси идёт softmax?
  2. Softmax. Вычислите softmax от (0,log⁡4)(0,\log4). Изменится ли результат, если прибавить 100 к обоим входам?
  3. Средние. У одного ответа один токен с потерями 4; у другого три токена с потерями 0. Вычислите среднее по токенам и среднее по ответам.
  4. Условие. Из 200 ответов 120 верны, 80 проходят проверку формата и 60 — и то и другое. Найдите P(correct∣valid)P(\text{correct}\mid\text{valid}) и P(valid∣correct)P(\text{valid}\mid\text{correct}).
  5. KL. Для учителя p=(1,0)p=(1,0) и студента q=(0.5,0.5)q=(0.5,0.5) вычислите оба направления KL.
  6. Множества. DAPO оставляет вопрос, только если 0<∣C∣<G0<\vert C\vert<G, где CC содержит индексы верных ответов среди GG сэмплов. При G=4G=4 оставит ли он вопрос, ответы на который набрали оценки (1,1,1,1)(1,1,1,1)? А вопрос с оценками (1,0,1,1)(1,0,1,1)? Изменится ли первый ответ, если все четыре сэмпла содержат одинаковый верный текст?

Ответы:

  1. Оценки имеют форму 4×64\times6, а выход — 4×34\times3. Softmax идёт по шести ключам в строке каждого запроса.

  2. (1/5,4/5)(1/5,4/5). Прибавление одного и того же числа ко всем входам не меняет softmax, но прямое вычисление e100e^{100} переполняет 32-битные float.

  3. Два средних:

    per token:(4+0+0+0)/4=1per answer:(4/1+0/3)/2=(4+0)/2=2\begin{aligned} \text{per token:}&\quad(4+0+0+0)/4=1\\ \text{per answer:}&\quad(4/1+0/3)/2=(4+0)/2=2 \end{aligned}
  4. 60/80=0.7560/80=0.75 и 60/120=0.560/120=0.5.

  5. DKL(p∥q)=log⁡2≈0.69D_{\mathrm{KL}}(p\Vert q)=\log2\approx0.69, а DKL(q∥p)=∞D_{\mathrm{KL}}(q\Vert p)=\infty, потому что студент назначает вероятность исходу, который учитель исключает.

  6. Нет: C={1,2,3,4}C=\{1,2,3,4\} содержит четыре элемента, что равно GG. Да: C={1,3,4}C=\{1,3,4\} содержит три элемента, между 0 и 4. Одинаковый текст первый ответ не меняет: это четыре отдельных сэмпла, поэтому их четыре индекса по-прежнему считаются.

Приложение A. Греческие буквы

Перечислены типичные роли; каждая статья всё равно сама определяет свои символы.

БукваНазваниеТипичные роли в статьях по ML
α\alphaальфаВес смешивания или масштаб; затухание (Gated DeltaNet); расписание шума (DDPM)
β\betaбетаСила штрафа (DPO, GRPO); сила записи (Gated DeltaNet); расписание шума (DDPM)
γ\gammaгаммаКоэффициент дисконтирования в RL; размер шага (обновление смещения в DeepSeek-V3)
δ,Δ\delta,\DeltaдельтаРазность или изменение
ϵ,ε\epsilon,\varepsilonэпсилонШум (DDPM); диапазон клиппинга (GRPO); малая стабилизирующая добавка
η\etaэтаСкорость обучения
θ,Θ\theta,\ThetaтетаПараметры модели; углы поворота в RoPE
λ,Λ\lambda,\LambdaлямбдаВес регуляризации; собственное значение
μ\muмюСреднее; число градиентных шагов на батч в Algorithm 1 из DeepSeekMath
π,Π\pi,\PiпиПолитика; ∏\prod — оператор произведения
ρ\rhoроОтношение вероятностей, как в разделе про GRPO в части 3; корреляция
σ,Σ\sigma,\SigmaсигмаСигмоида (DPO); стандартное отклонение; ковариация; ∑\sum — оператор суммы
τ\tauтауТемпература; порог; траектория в RL
ϕ,φ,Φ\phi,\varphi,\PhiфиПараметры второй сети, например энкодера; признаки; угол
ψ,Ψ\psi,\PsiпсиПараметры другой сети, например value model VψV_\psi в PPO из DeepSeekMath
ω,Ω\omega,\OmegaомегаЧастота; Ω\Omega также означает нижнюю оценку в теории сложности или множество исходов

Варианты вроде ϕ/φ\phi/\varphi и ϵ/ε\epsilon/\varepsilon обычно — одна и та же буква в другом начертании, но статья может использовать обе для разных переменных.

Приложение B. Другие семейства уравнений

Формы уравнений, которые эта серия не разбирает, с определениями, нужными каждой:

Selective state-space models. Модель пространства состояний (state-space model) обрабатывает последовательность, обновляя хранимое состояние на каждом шаге. Обновление вида ht=Aˉtht−1+Bˉtxth_t=\bar A_th_{t-1}+\bar B_tx_t, yt=Cthty_t=C_th_t объединяет предыдущее состояние с текущим входом, а затем вычисляет выход. Здесь xtx_t — текущий вход, hth_t — хранимое состояние, а yty_t — выход. Матрицы Aˉt\bar A_t, Bˉt\bar B_t и CtC_t соответственно преобразуют предыдущее состояние, добавляют вклад входа и порождают выход. Черта отмечает параметры, преобразованные из модели с непрерывным временем в дискретные шаги; средних она не означает. В Mamba параметры обновления зависят от текущего входа, что и значит «selective».

Стохастические дифференциальные уравнения. dx/dt=f(x,t)dx/dt=f(x,t) описывает, как состояние xx меняется со временем tt: ff — скорость его изменения. Стохастическое дифференциальное уравнение (SDE) добавляет случайные изменения, dXt=f(Xt,t) dt+g(Xt,t) dWtdX_t=f(X_t,t)\,dt+g(X_t,t)\,dW_t. Здесь ff описывает детерминированное изменение, gg задаёт масштаб шума, а dWtdW_t — приращение броуновского движения. Чтобы приблизить его в коде, метод Эйлера — Маруямы использует малый шаг по времени Δt\Delta t и заменяет dWtdW_t гауссовым шумом с дисперсией Δt\Delta t. Раздел 5.1 книги Tianhua Chen The Little Book of Generative AI Foundations приводит такое обновление; в §6.4 той же книги SDE используются для описания диффузионных моделей.

Замена переменных. Преобразование случайной величины меняет её плотность в зависимости от того, как преобразование меняет локальный объём. Допустим, y=f(x)y=f(x) отображает между пространствами одной размерности, а ff и обратное к ней f−1f^{-1} дифференцируемы. Плотности до и после преобразования, pXp_X и pYp_Y, удовлетворяют pY(y)=pX(f−1(y)) ∣det⁡Jf−1(y)∣p_Y(y)=p_X\bigl(f^{-1}(y)\bigr)\,\bigl\vert\det J_{f^{-1}}(y)\bigr\vert. Обратное преобразование f−1f^{-1} восстанавливает xx по yy. Его якобиан Jf−1J_{f^{-1}} — квадратная матрица первых производных; абсолютное значение её определителя поправляет локальное изменение объёма. Например, если y=2xy=2x в одном измерении, плотность становится pY(y)=pX(y/2)/2p_Y(y)=p_X(y/2)/2: удвоение ширины вдвое снижает плотность. Нормализующие потоки (normalizing flows) используют такие обратимые преобразования для моделирования плотностей; метод объясняет книга Tianhua Chen, §7.1.

Min–max-цели. В генеративно-состязательных сетях (GAN) генератор GG порождает примеры, а дискриминатор DD пытается отличить их от реальных данных. Целевая функция V(D,G)V(D,G) измеряет успех дискриминатора: DD максимизирует её, а GG минимизирует. Цель min⁡Gmax⁡DV(D,G)\min_G\max_DV(D,G) (уравнение 1) говорит: для каждого возможного генератора рассмотрите лучшего против него дискриминатора, затем выберите генератор с наименьшим получившимся значением цели. Обучение не решает эту внутреннюю максимизацию точно. Algorithm 1 в статье чередует kk шагов градиентного подъёма по DD с одним шагом градиентного спуска по GG; в экспериментах использовалось k=1k=1.

Вероятностный симплекс. У вектора вероятностей неотрицательные элементы, дающие в сумме 1. Множество всех таких векторов с KK элементами называется вероятностным симплексом (probability simplex) и записывается ΔK−1={p∈RK∣pi≥0, ∑ipi=1}\Delta^{K-1}=\{p\in\mathbb R^K\mid p_i\geq0,\ \sum_ip_i=1\}. Каждый выход softmax лежит в нём. Здесь Δ\Delta называет множество, а верхний индекс K−1K-1 — его размерность, а не степень: после того как выбраны K−1K-1 вероятностей, последняя должна довести сумму до 1. При двух вариантах каждое распределение имеет вид (a,1−a)(a,1-a) при 0≤a≤10\leq a\leq1, так что свободно только одно число.

Нормализация. Нормализация перемасштабирует значения по среднему и разбросу выбранной группы. Распространённая форма — x^=(x−μ)/σ2+ϵ\hat x=(x-\mu)/\sqrt{\sigma^2+\epsilon}, где μ\mu — среднее, σ2\sigma^2 — дисперсия, а ϵ\epsilon — малое положительное число, не допускающее деления на ноль. Само уравнение не говорит, по каким элементам считаются среднее и дисперсия. Для батча векторов признаков batch normalization считает их отдельно для каждого признака по примерам. Layer normalization в Transformer считает их отдельно для каждого токена по его признакам. При сравнении реализаций проверяйте указанные оси.

Источники и версии

Номера разделов и уравнений относятся к версиям, на которые даны ссылки.

  1. Tianhua Chen. The Little Book of Generative AI Foundations: An Intuitive Mathematical Primer. 2026. Версия 2; §2.4 и §3.2 охватывают неравенство Йенсена и ELBO, §5.1 и §6.4 — шум в непрерывном времени.
  2. Vaswani et al. Attention Is All You Need. 2017. Версия 7, §3.2.1, уравнение (1) и сноска 4.
  3. Dai et al. DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models. 2024. Мелкозернистая сегментация экспертов и подсчёт комбинаций, §3.1; абляция, §4.4 и Figure 3.
  4. Shao et al. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. 2024. Версия 3, §1.1, §4.1.1, уравнения (1)–(4) и Algorithm 1.
  5. DeepSeek-AI. DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model. 2024. Версия 5, §2.1.1–2.1.3, уравнения (9)–(19) и Appendix C.
  6. DeepSeek-AI. DeepSeek-V3 Technical Report. 2024–2025. Версия 2, §2.1.2, уравнения (12)–(18).
  7. DeepSeek-AI. DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning. 2025. Версия 1: §2.2.1, уравнения (1)–(3). Версия 2, 2026: §2.1 и Supplementary A.3.
  8. DeepSeek-AI. DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligence. 2026. Версия 1: §2.2, уравнения (1)–(8); §5.1.2, уравнение (29).
  9. Rafailov et al. Direct Preference Optimization: Your Language Model is Secretly a Reward Model. 2023–2024. Версия 3, §4, уравнение (7).
  10. Gu et al. MiniLLM: Knowledge Distillation of Large Language Models. 2023–2024. Версия 4, §2.1, уравнение (1) и §2.2, уравнения (2) и (7).
  11. Yu et al. DAPO: An Open-Source LLM Reinforcement Learning System at Scale. 2025. Версия 2, §3.2–3.3, уравнения (11)–(12).
  12. Gu and Dao. Mamba: Linear-Time Sequence Modeling with Selective State Spaces. 2023–2024.
  13. Yang et al. Gated Delta Networks: Improving Mamba2 with Delta Rule. 2024–2025. Версия 3, §3.1, уравнение (10) и §3.3–3.4.
  14. Ho, Jain and Abbeel. Denoising Diffusion Probabilistic Models. 2020. Версия 2, §2, уравнения (4)–(5); §3.2, уравнение (12); §3.4, уравнение (14) и Algorithms 1–2.
  15. Goodfellow et al. Generative Adversarial Nets. 2014. Уравнение (1) и Algorithm 1.
  16. Chen et al. Evaluating Large Language Models Trained on Code. 2021. Версия 2, §2.1, уравнение (1) и Figure 3.
  17. Hugging Face TRL. GRPOTrainer и GRPOConfig на коммите c6eac19, октябрь 2026 года.
  18. Stanford CS229. Probability Theory Review и Linear Algebra Review and Reference.
  19. Dive into Deep Learning. Preliminaries.
  20. Britz, Goldie, Luong and Le. Massive Exploration of Neural Machine Translation Architectures. 2017. Версия 2, Table 5; цитируется в Attention Is All You Need для сравнения dot-product и additive attention.