• Русский
  • Смесь экспертов, квантизация, LoRA

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

    • Смесь экспертов: параметров много, но на каждый токен работает лишь малая их часть.
    • Квантизация: хранить каждый параметр в 4 или 8 битах вместо 16.
    • LoRA: чтобы адаптировать модель, обучать крошечную надстройку, а не всю модель.
    • Дистилляция: научить маленькую модель подражать большой.

    Другие способы сэкономить описаны в соседних главах: ускорение генерации за счёт KV-кэша и спекулятивного декодирования — в главе 10, повторное использование кэша — в главе 11, а архитектурные изменения вроде латентного внимания (MLA) и предсказания нескольких токенов сразу — в главе 14.

    Смесь экспертов

    Чем больше параметров, тем больше знаний может хранить модель, но в обычном трансформере каждый токен платит за каждый параметр. Большая их часть сидит в полносвязной сети (MLP из главы 6) — в больших моделях около двух третей, — и каждый токен проходит её целиком. Смесь экспертов разрывает эту связь между размером и стоимостью.

    Блок смеси экспертов (mixture of experts, MoE) заменяет один MLP множеством сетей поменьше — экспертов — и добавляет крошечный маршрутизатор (router): небольшую обученную матрицу, которая превращает вектор токена в одну оценку для каждого эксперта. Для каждого токена маршрутизатор оставляет несколько лучших экспертов (часто 2, иногда 8 из сотен) и запускает только их. Выход для токена — это выходы выбранных экспертов, смешанные с весами маршрутизатора:

    y=∑i∈top-kgi(x) Ei(x),g=softmax⁡(оценки маршрутизатора по выбранным i)y = \sum_{i \in \text{top-}k} g_i(x)\, E_i(x), \qquad g = \operatorname{softmax}(\text{оценки маршрутизатора по выбранным } i)

    Здесь Ei(x)E_i(x) — то, что эксперт ii выдаёт для вектора токена xx, а gi(x)g_i(x) — вес этого эксперта при смешивании. Если два лучших эксперта — 3 и 6 с весами 0,7 и 0,3, то выход равен 0,7 × (выход эксперта 3) + 0,3 × (выход эксперта 6), а остальные эксперты для этого токена вообще не запускаются.

    Рисунок 13.1 · Маршрутизатор отправляет каждый токен к 2 из 8 экспертов
    токеныэксперты (FFN)Кот·решил·этот·интеграл·на·Python·самE14%E269%E31%E43%E53%E62%E79%E89%
    2 / 8экспертов на токен1токенов у самого загруженного6экспертов ещё без работы
    1/7

    Кот → маршрутизатор оставляет двух лучших, эксперта 2 и эксперта 7, и пересчитывает их оценки в веса смешивания 88% и 12%. Работают только эти двое; остальные 6 для этого токена простаивают.

    Пройдите предложение по шагам. Процент у каждого эксперта — оценка маршрутизатора для текущего токена, а толщина линии — вес смешивания двух оставленных экспертов; оранжевая полоска под экспертом считает, сколько токенов он уже обработал. Переключитесь на «Без неё», чтобы увидеть коллапс маршрутизации: несколько экспертов получают всё, а остальные параметры простаивают зря.

    Выигрыш — в разнице между полным и активным числом параметров. Mixtral 8x7B хранит около 47 млрд параметров, но на каждый токен использует около 13 млрд; DeepSeek-V3 хранит 671 млрд и активирует около 37 млрд. Модель знает столько же, сколько большая, а работает со скоростью гораздо меньшей. Платить приходится памятью: все эксперты должны лежать в памяти GPU, хотя большинство из них в каждый момент простаивает.

    Три практические детали:

    • Балансировка нагрузки. Если маршрутизатор предоставить самому себе, он начинает отдавать предпочтение нескольким экспертам; те больше обучаются, становятся лучше и выбираются ещё чаще. Поэтому при обучении добавляют вспомогательную функцию потерь — дополнительное слагаемое к основной (а в некоторых новых моделях — поправку-смещение для каждого эксперта, которую подстраивает обучающий код), подталкивающую маршрутизатор распределять токены равномерно.
    • Эксперты — это не темы. Заманчиво представить «эксперта по математике» и «эксперта по Python». На деле эксперты специализируются на более размытых закономерностях, часто на уровне синтаксиса и типов токенов, и один эксперт обслуживает множество тем.
    • Мелкие и общие эксперты. Новые MoE-модели используют много маленьких экспертов (от десятков до сотен) и выбирают по несколько на токен, а ещё одного-двух общих экспертов (shared experts), через которых проходит каждый токен и которые хранят общие знания.

    Квантизация

    Веса модели обычно обучают в 16-битном формате с плавающей точкой: 2 байта на параметр, так что модели на 7 млрд параметров нужно около 14 ГБ только на хранение весов. Это бьёт дважды. Такая модель не влезает в обычную игровую видеокарту на 8–12 ГБ. И она медленная: чтобы выдать каждый токен, нужно прочитать из памяти все веса, так что скорость определяется тем, сколько байт приходится перекачать (глава 10). Квантизация хранит каждый вес меньшим числом бит. При 4 битах вместо 16 модель занимает вчетверо меньше памяти, и на каждый токен читается вчетверо меньше байт.

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

    scale=max⁡i∣wi∣2b−1−1,qi=round⁡ ⁣(wiscale),w^i=qi⋅scale\text{scale} = \frac{\max_i |w_i|}{2^{b-1}-1}, \qquad q_i = \operatorname{round}\!\left(\frac{w_i}{\text{scale}}\right), \qquad \hat w_i = q_i \cdot \text{scale}

    Здесь bb — число бит. При b=4b = 4 целые числа идут от −7 до +7 (одна из 16 комбинаций бит не используется, чтобы сетка была симметрична относительно 0). Хранятся целые числа qiq_i и один масштаб на группу. Во время инференса модель вычисляет с w^i\hat w_i.

    Небольшой пример. Возьмём группу 0,5, −1,2, 0,3, 2,0 и b=4b = 4. Наибольший модуль — 2,0, поэтому масштаб равен 2,0 / 7 ≈ 0,286. Делим на него и округляем — получаем целые 2, −4, 1, 7; умножаем обратно — 0,57, −1,14, 0,29, 2,0. Ни один вес не сдвинулся больше чем на 0,07. Теперь добавим в ту же группу один большой вес, 6,0: масштаб вырастет втрое, примерно до 0,86, и 0,3 округлится до 0. Один выброс стёр маленький вес — ровно это и показывает группа 3 на рисунке.

    Рисунок 13.2 · Веса притягиваются к сетке
    Бит на вес
    0группа 1группа 2группа 3выброс →группа 4

    исходный вес хранимое значение ошибка округления допустимые уровни

    15целых уровней18%средняя ошибка / средний вес4,4 ГБмодель на 7 млрд параметров
    Каждая дорожка — группа из 16 весов; вертикальные штрихи — значения, которые группа может хранить, а короткие оранжевые линии показывают, насколько округление сдвинуло каждый вес. Уменьшите число бит — и сетка станет грубой. В группе 3 спрятан выброс: с одним масштабом на весь тензор этот единственный вес растягивает сетку для всех, и ошибка резко растёт. Масштаб на группу держит ущерб локальным.

    Рисунок показывает всю суть практической квантизации:

    • 8 бит почти бесплатны: качество почти не меняется.
    • 4 бита — популярная золотая середина для запуска моделей на своём компьютере; с хорошими методами потери качества невелики.
    • 3 и 2 бита уже заметно вредят, если только модель не обучали с расчётом на квантизацию.
    • Выбросы — главный враг. В настоящих LLM есть немногие веса и активации, которые гораздо больше остальных. С ними борются маленькими группами (32–128 весов на масштаб), хранением выбросов в повышенной точности или поворотом весов перед квантизацией, чтобы «размазать» выбросы.

    Методы вроде GPTQ и AWQ выбирают округление умнее, используя немного калибровочных данных, чтобы понять, какие веса важнее. Форматы вроде GGUF (формат файлов llama.cpp — популярной программы для запуска моделей на обычных компьютерах) и 8- и 4-битные форматы с плавающей точкой на новых GPU (FP8, FP4) — вариации той же идеи. Квантизация проникает и в обучение: например, DeepSeek-V3 выполнял большую часть матричных умножений при обучении в 8-битном формате с плавающей точкой (FP8), экономя время и память.

    LoRA: дообучение на бюджете

    Дообучение (fine-tuning) — это продолжение обучения модели на ваших данных, например на диалогах вашей службы поддержки. Чтобы обновить каждый вес, нужна память под сами веса, их градиенты и скользящие средние оптимизатора для каждого из них (глава 7). С обычным оптимизатором Adam и смешанной точностью это около 16 байт на параметр: больше 100 ГБ для модели на 7 млрд — гораздо больше, чем вмещает одна обычная GPU.

    LoRA (low-rank adaptation, низкоранговая адаптация) замораживает исходную матрицу весов WW и обучает небольшую поправку в виде произведения двух узких матриц:

    W′=W+BA,B∈Rd×r,  A∈Rr×d,  r≪dW' = W + B A, \qquad B \in \mathbb{R}^{d \times r},\; A \in \mathbb{R}^{r \times d},\; r \ll d

    Здесь BB — таблица чисел размером dd на rr, AA — размером rr на dd, а r≪dr \ll d означает, что rr намного меньше dd. Число rr называют рангом. Чтобы понять, что он даёт, возьмём r=1r = 1: BB — один столбец, AA — одна строка, а их произведение — полная таблица, в которой каждая строка кратна одной и той же строке:

    (123)(20−1)=(20−140−260−3)\begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} \begin{pmatrix} 2 & 0 & -1 \end{pmatrix} = \begin{pmatrix} 2 & 0 & -1 \\ 4 & 0 & -2 \\ 6 & 0 & -3 \end{pmatrix}

    Шесть чисел описывают девять. В настоящем слое с d=4096d = 4096 ранг 1 описывает изменение 16,8 млн чисел с помощью 8192; ранг rr складывает rr таких таблиц. Ставка в том, что нужное дообучению изменение имеет низкий ранг: его можно описать несколькими направлениями вместо d2d^2 независимых чисел. И эта ставка работает удивительно хорошо.

    Рисунок 13.3 · LoRA приближает обновление двумя узкими матрицами
    W заморожена
    +
    B 8×1
    ×
    A 1×8
    = W′, адаптированный слой
    ΔW полное дообучение
    ≈
    B·A ранг 1
    29%обновления упущено16 из 64обучаемых чисел здесь

    В настоящем слое 4096×4096 ранг 1 обучает 8 192 чисел вместо 16 777 216: 0,05% от полного дообучения.

    Нижний ряд сравнивает обновление, которое сделало бы полное дообучение (ΔW), с тем, что LoRA может выразить при ранге r. Это обновление — в основном два направления плюс шум, поэтому уже ранг 2 даёт ошибку около 10%, а более высокие ранги лишь подбирают шум. В игрушечном слое 8×8 экономия мала; в настоящем слое — огромна. (Упрощение: рисунок сразу вычисляет лучшее приближение ранга r, а настоящая LoRA находит B и A градиентным спуском.)

    На практике:

    • Типичные ранги — от 8 до 64, так что LoRA обучает гораздо меньше 1% параметров.
    • BB начинается с нуля, поэтому BA=0BA = 0 и обучение стартует ровно с исходной модели.
    • После обучения BABA можно прибавить к WW — и при инференсе нет никаких лишних затрат. А можно хранить адаптеры отдельно и подключать разные для разных клиентов или задач поверх одной общей базовой модели.
    • QLoRA объединяет две идеи этой главы: замороженная базовая модель хранится в 4 битах, а в повышенной точности обучаются только маленькие матрицы LoRA. Это делает дообучение довольно больших моделей посильным для одной GPU.

    Дистилляция: большая модель учит маленькую

    Обученная модель знает больше, чем то, какой токен правильный. Предсказывая слово после «Кот сел на», она отдаёт «коврик» большую часть вероятности, но при этом сообщает, что «ковёр» и «пол» тоже разумны, а «банан» — абсурд. Дистилляция знаний обучает маленькую модель-ученика на этих полных распределениях большой модели-учителя, а не только на одном правильном токене (Hinton и др., 2015):

    L=T2⋅KL(softmax⁡(zучитель/T) ∥ softmax⁡(zученик/T))\mathcal{L} = T^2 \cdot \mathrm{KL}\big(\operatorname{softmax}(z_\text{учитель}/T) \,\big\|\, \operatorname{softmax}(z_\text{ученик}/T)\big)

    Здесь zz — сырые оценки (логиты), которые каждая модель даёт всем возможным токенам до softmax. KL — это расхождение Кульбака–Лейблера, мера того, насколько различаются два распределения вероятностей: 0, если они совпадают, и тем больше, чем сильнее они расходятся. Температура TT (та же ручка, что и в главе 9) сглаживает оба распределения, чтобы малые вероятности — «тёмное знание» — имели вес в функции потерь. Множитель T2T^2 нужен лишь для того, чтобы сила обучающего сигнала почти не зависела от выбранной TT.

    Рисунок 13.4 · Жёсткие метки против мягких целей

    Кот сел на …

    Учитель при T = 2.0
    коврик34.2%
    ковёр22.9%
    пол18.8%
    диван13.9%
    крышу8.4%
    банан1.7%
    Цель обучения
    коврик34.2%
    ковёр22.9%
    пол18.8%
    диван13.9%
    крышу8.4%
    банан1.7%
    Ученик при T = 1
    коврик50.9%
    ковёр22.4%
    пол14.8%
    диван8.0%
    крышу3.2%
    банан0.7%
    0.004отличие от учителя (KL)32.5×P(ковёр) ÷ P(банан)

    Мягкие цели говорят: «коврик, но ковёр и пол тоже возможны, а банан — абсурд». Один пример передаёт весь порядок учителя. Высокая T усиливает малые вероятности, чтобы ученик их заметил.

    Обучите ученика с нуля на одном примере. С жёсткой меткой он узнаёт лишь, что «коврик» правильный: «ковёр» и «банан» остаются для него одинаково маловероятными. С мягкими целями учителя тот же единственный пример передаёт весь порядок вариантов, и отличие от учителя (KL) сокращается гораздо сильнее. Поднимите T и посмотрите, как растут маленькие столбики учителя: это и есть дополнительные сведения, которые получает ученик.

    Так сегодня делают большинство маленьких, но способных моделей. Иногда ученик подгоняет свои вероятности прямо к вероятностям учителя (для этого нужен доступ к логитам учителя, которыми закрытые модели обычно не делятся); чаще он просто обучается на тексте, который написал учитель. Это называют синтетическими данными или дистилляцией на уровне последовательностей. Маленькие модели, умеющие рассуждать, обычно дистиллируют из длинных цепочек рассуждений больших моделей (глава 15).

    Прунинг

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

    Итоги

    • MoE разделяет то, что модель знает (полное число параметров), и то, сколько стоит каждый токен (активные параметры).
    • Квантизация хранит веса как маленькие целые числа плюс масштаб; 8 бит — почти без потерь, 4 бита — обычная золотая середина, главная трудность — выбросы.
    • LoRA замораживает модель и обучает низкоранговую поправку BABA; QLoRA делает это поверх 4-битной базовой модели.
    • Дистилляция обучает маленького ученика на полных распределениях вероятностей большого учителя или на сгенерированном им тексте.
    • Прунинг вырезает части, которые дают меньше всего; удаление целых частей даёт настоящее ускорение.

    Дальше — новые устройства слоёв, выходящие за рамки классического трансформера, в главе 14.