Линейная алгебра
Линейная алгебра в глубоком обучении
GPT-4 за один forward pass выполняет 1.8 триллиона матричных умножений - не условно, а буквально. Ранг матриц весов, их спектральная норма, число обусловленности - это не теоретические абстракции, а характеристики, определяющие скорость обучения, устойчивость и способность к обобщению.
- LoRA: гипотеза низкого ранга ΔW = BA позволяет fine-tune GPT-3 на одной GPU вместо 8
- Flash Attention: тайловая обработка QKᵀ - O(n) памяти вместо O(n²), контекст 128K токенов
- Spectral Normalization: W/σ₁(W) стабилизирует обучение GAN (Miyato et al. 2018)
- Batch Normalization: центрирование и нормировка активаций - диагональная матричная операция
- Gradient clipping: ограничение нормы градиента - стандарт при обучении трансформеров
**GPT-4 за один forward pass выполняет 1.8 триллиона матричных умножений.** Не "применяет нейронные операции" - именно матричных умножений. Каждый токен проходит через сотни слоёв вида y = Wx + b, каждый attention head вычисляет QKᵀ/sqrt(d), каждый backward pass берёт транспонирование и цепное правило. Линейная алгебра - это не язык описания нейросетей, это и есть нейросети, вид изнутри.
**О чём этот урок на самом деле**: не о том, что нейросети используют матрицы - это известно. О том, почему конкретные свойства матриц (ранг, норма, число обусловленности, транспонирование) определяют, как обучается, обобщает и масштабируется модель. После этого урока GPT, LoRA, Flash Attention перестают быть чёрными ящиками.
Forward pass: матричные умножения на каждом шагу
Линейный слой нейросети - это в точности умножение матрицы на вектор: **y = Wx + b**, где W - матрица весов размером (out, in). GPT-2 имеет FFN слой 768 -> 3072 -> 768: это W1 в R^(3072x768), W2 в R^(768x3072). Обработка батча из 32 последовательностей длиной 1024 - это умножение матриц размером (32x1024) x 768, что требует GEMM-ядра на GPU.
Backprop: транспонирование как основа chain rule
Обратное распространение ошибки - это цепное правило, записанное через транспонирование. Если y = Wx, то градиент по весам: **dL/dW = (dL/dy) * xᵀ**, а градиент по входу: **dL/dx = Wᵀ * (dL/dy)**. Транспонирование появляется не случайно: оно соответствует ~сопряжённому отображению~{adjoint map} в линейной алгебре. Размерности проверяются автоматически - если Wᵀ не подходит, значит где-то ошибка в цепочке.
**Градиентный клиппинг** - это нормирование вектора градиентов. PyTorch делает `torch.nn.utils.clip_grad_norm_(params, max_norm=1.0)`, что эквивалентно: если ||g|| > 1.0, то g = g / ||g||. Операция чисто линейно-алгебраическая - масштабирование вектора до единичной нормы.
Attention: три matmul на каждый head
Scaled dot-product attention - это одна формула с тремя матричными умножениями. **QKᵀ** даёт матрицу схожести (seq x seq), деление на sqrt(d_k) предотвращает насыщение softmax, умножение на **V** взвешивает значения. Сложность O(seq^2 x d_k) - именно квадратичная зависимость от длины последовательности стала главной мотивацией для Flash Attention, который обходится без материализации этой матрицы.
Batch Normalization: матрица центрирования
Batch Normalization выглядит как простая нормализация, но линейно-алгебраически это проецирование на гиперплоскость. Вычитание среднего применяет матрицу **(I - (1/m)11т)** - центрирующую проекцию, которая убирает компоненту вдоль вектора 1. Деление на стандартное отклонение - это диагональное масштабирование. Обучаемые gamma, beta позволяют сети отменить нормализацию, если задаче это выгодно.
LoRA: fine-tuning через матрицы низкого ранга
LoRA (Low-Rank Adaptation) основана на одном наблюдении: **при fine-tuning LLM изменения весов dW имеют низкий ранг**. Вместо обновления полной матрицы W с d^2 параметрами - обучаются две маленькие матрицы B и A, где W_new = W0 + BA. Для GPT-3 с d=12288 и r=4: вместо 150M параметров - 98K. Это rank-decomposition в действии, та же идея что и в SVD.
**Почему B инициализируется нулями**: при старте LoRA должна быть тождественным дополнением, не изменять поведение базовой модели. B=0 гарантирует BA = 0, W_new = W0. Если бы A=0, то градиенты через B не текли бы.
Инициализация весов: Xavier и He через дисперсию
Если инициализировать веса слишком маленькими - сигнал затухнет, если слишком большими - взорвётся. Ключевой вопрос: при каком Var(W) дисперсия активаций остаётся постоянной от слоя к слою? **Xavier** (Glorot, 2010) выводит Var(w) = 2/(n_in + n_out) для tanh/sigmoid. **He** (Kaiming, 2015) выводит Var(w) = 2/n_in для ReLU: коэффициент 2 компенсирует то, что ReLU зануляет ~50% нейронов.
Практика: прямой проход нейросети
Ранг, норма и число обусловленности матриц весов нейросети
Матрица весов $W$ нейросети - это не просто набор чисел. Её **ранг** определяет информационную ёмкость слоя. Её **спектральная норма** $\|W\|_2 = \sigma_1$ (максимальный сингулярный вектор) - это коэффициент Липшица слоя: как сильно он может растягивать входные векторы. **Число обусловленности** $\kappa(W) = \sigma_1/\sigma_{\min}$ влияет на скорость сходимости.
**LoRA (Low-Rank Adaptation)**: вместо обновления всей матрицы $W \in \mathbb{R}^{m \times n}$, параметризуем обновление как $\Delta W = BA$, где $B \in \mathbb{R}^{m \times r}$, $A \in \mathbb{R}^{r \times n}$, $r \ll \min(m,n)$. Параметров: $(m+n)r$ вместо $mn$. Для GPT-3 ($m=n=12288$, $r=8$): $\sim$0.01% параметров. Гипотеза: изменения при fine-tuning имеют низкий ранг.
Spectral Normalization для стабильного обучения GAN
Контроль коэффициента Липшица
GAN страдает от нестабильности: дискриминатор может резко менять свои предсказания. Spectral Normalization (Miyato et al., 2018): делим каждую матрицу весов на её спектральную норму $W \leftarrow W / \sigma_1(W)$. Это гарантирует $\|W\|_2 = 1$ и коэффициент Липшица $\leq 1$ для каждого слоя. $\sigma_1$ вычисляется итерационным power method за 1-2 итерации.
Почему LoRA использует разложение $\Delta W = BA$ с $r \ll n$, а не просто обновляет $W$ напрямую?
При fine-tuning LLM обновление весов $\Delta W$ эмпирически оказывается близко к матрице низкого ранга. LoRA использует это: $\text{rank}(BA) \leq r$. При $m=n=4096$, $r=8$: $16M$ vs $66K$ параметров. Это позволяет fine-tune GPT-3 на одной GPU.
Batch Normalization и Flash Attention через матричную линзу
Batch Normalization нормирует активации по батчу: $\hat{x}_i = (x_i - \mu)/\sigma$, затем $y_i = \gamma \hat{x}_i + \beta$. Матрично - это центрирование и масштабирование: $\hat{X} = (X - \mathbf{1}\mu^\top) \text{diag}(1/\sigma)$. Параметры $\gamma, \beta$ - диагональные матрицы, обученные через backprop.
**Flash Attention** (Dao et al., 2022): стандартный attention вычисляет $S = QK^\top$ - матрицу $n \times n$ полностью в HBM-памяти GPU ($O(n^2)$ памяти). Flash Attention tile-блочно вычисляет то же самое с $O(n)$ GPU SRAM: разбивает $Q,K,V$ на блоки и использует онлайн-softmax. Результат: 2-4x ускорение, $O(n)$ вместо $O(n^2)$ памяти. Именно поэтому GPT-4 работает с контекстом 128K токенов.
Число обусловленности и скорость сходимости
Почему Adam быстрее SGD
Для функции потерь $L(w) = \frac{1}{2}w^\top H w$ (квадратичное приближение), SGD требует $O(\kappa(H) \log(1/\varepsilon))$ итераций, где $\kappa = \lambda_{\max}/\lambda_{\min}$. Adam адаптирует шаг по каждому параметру, по сути приближая $H^{-1}$, что снижает эффективное $\kappa$. Плохое число обусловленности матрицы Гессе - одна из причин, почему простой SGD медленно учит трансформеры.
Flash Attention вычисляет те же результаты, что и стандартный attention, но быстрее. В чём ключевое отличие?
Стандартный attention: вычислить $S = QK^\top/\sqrt{d}$ ($O(n^2)$ элементов), применить softmax к $S$, умножить на $V$. Flash Attention: разбить на блоки, обновлять running max/sum для softmax онлайн. Математически точно то же самое, но $O(n)$ HBM-памяти вместо $O(n^2)$.
Пусть L - скаляр, y = Wx, W in R^(m x n), x in R^n dL/dW = dL/dy * x^T in R^(m x n) [outer product] dL/dx = W^T * dL/dy in R^n [W^T разворачивает действие W] Проверка размерностей: dL/dy in R^m, x in R^n -> dL/dy * x^T in R^(m x n) = форма W OK W^T in R^(n x m), dL/dy in R^m -> W^T * dL/dy in R^n = форма x OK
Q, K, V in R^(seq x d_k) Шаг 1: S = QK^T / sqrt(d_k) in R^(seq x seq) O(seq^2 * d_k) FLOPS Шаг 2: A = softmax(S) in R^(seq x seq) O(seq^2) FLOPS Шаг 3: Out = A * V in R^(seq x d_k) O(seq^2 * d_k) FLOPS GPT-4 (предположительно): seq=32768, d_k=128, 128 heads Память для S: 32768^2 * 4 bytes = 4 GB на один слой(!) -> Flash Attention: не материализует S, блочно по SRAM
Матрица весов: W in R^(d x d), параметров: d^2 LoRA: W_new = W0 + B*A, B in R^(d x r), A in R^(r x d) Параметров LoRA: d*r + r*d = 2dr GPT-3, d=12288, r=4: Полный: 12288^2 = 150,994,944 LoRA: 2 x 12288 x 4 = 98,304 Экономия: 1537x меньше параметров при схожем качестве! Почему это работает: гипотеза intrinsic dimensionality - пространство полезных обновлений весов имеет малую размерность
- **Linear / FFN слой**: Матричное умножение
- **Self-Attention**: QK^T V через три matmul
- **Batch/Layer Normalization**: Проецирование + масштабирование
- **Backpropagation**: Транспонирование + chain rule
- **LoRA fine-tuning**: Низкоранговая декомпозиция
Упражнения
- Почему LoRA работает - почему изменения весов при fine-tuning низкоранговые? — Гипотеза intrinsic dimensionality: большинство полезных обновлений лежит в подпространстве малой размерности; Эмпирически: ранг dW при fine-tuning GPT-3 на конкретную задачу - порядка 4-16; LoRA может плохо работать если задача далека от pretraining distribution - тогда ранг выше; Связь с SVD: малые сингулярные значения W соответствуют неиспользуемым направлениям
- Почему в attention scores делят на sqrt(d_k), а не на d_k? — q*k = sum(q_i * k_i); если q_i, k_i ~ N(0,1), то Var(q*k) = d_k; При большом d_k std(scores) = sqrt(d_k): softmax насыщается, один токен получает вес ~1; Деление на sqrt(d_k) приводит Var(scores) к 1 - softmax работает нормально; При d_k = 64 без нормировки std = 8, softmax - почти one-hot, градиенты исчезают
Нейросеть через линейную алгебру
- Forward pass - последовательность matmul: y = Wx + b; GEMM занимает >90% времени inference
- Backprop - транспонирование: dL/dW = delta * x^T, dL/dx = W^T * delta; размерности самопроверяются
- Attention = QK^T/sqrt(d) + softmax + V; O(seq^2) память; Flash Attention обходит материализацию
- BatchNorm = проекция (I - 11^T/m) + диагональное масштабирование; обучаемые gamma, beta
- LoRA: dW = BA, r << d; 100-1500x меньше параметров; работает из-за низкой intrinsic dim обновлений
- He init: Var(w) = 2/n_in для ReLU; коэффициент 2 компенсирует занулённые нейроны
- Gradient clipping: g = g * c/||g|| - нормирование вектора, не усечение компонент
Связанные темы
Спектральная теория графов применяет те же инструменты к структурированным данным. GNN объединяют matmul и Laplacian в одном forward pass.
- Спектральная теория графов — GNN используют нормализованный Лапласиан как аналог attention для графовых данных
- SVD разложение — LoRA - это SVD-идея низкоранговости; randomized SVD в sklearn использует ту же технику
- Собственные векторы и значения — PCA как предобработка данных для нейросети; spectral features в GNN