Содержание курса 21 / 37

21 / 37 · Предобученные языковые модели

GPT и авторегрессионное языковое моделирование

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

На этой странице 12

Энкодер из предыдущей заметки заполняет пропуски и не может продолжить текст. Для порождения нужно разложение из n-граммной заметки, P(w1:T)=∏tP(wt∣w<t)P(w_{1:T}) = \prod_t P(w_t \mid w_{<t}), с моделью, в условии которой стоит весь префикс или та его часть, которая помещается в контекстное окно. Декодер трансформера с каузальной маской и есть такая модель, а обучение его на большом корпусе — то, что сделала серия GPT (Radford et al., 2018, 2019; Brown et al., 2020). Заметка разбирает цель обучения, архитектуру в двух конкретных размерах, поведение получившейся базовой модели и шаг декодирования, через который проходит любое её использование.

Обозначения. Токены w1:Tw_{1:T}; логиты zt∈R∣V∣z_t \in \mathbb R^{|V|} в позиции tt; P(w∣w<t)=softmax⁡(zt)wP(w \mid w_{<t}) = \operatorname{softmax}(z_t)_w. Температура τ\tau.

Отправная точка: рекуррентная языковая модель#

Заметка о RNN уже обучает предсказатель следующего токена через teacher forcing. Её контекст — весь префикс, но через забывающее состояние, и позиции она обрабатывает одну за другой. Замена рекурсии каузальным self-attention сохраняет цель обучения и снимает оба ограничения ценой фиксированного контекстного окна (1024 позиции у GPT-2 small): внимание напрямую читает каждую более раннюю позицию внутри окна, но история не бесконечна.

Цель обучения#

L=−1T∑t=1Tlog⁡P(wt∣w<t),\mathcal L = -\frac1T\sum_{t=1}^{T} \log P(w_t \mid w_{<t}),

кросс-энтропия на токен, экспонента которой — перплексия. Вход — последовательность, цель — та же последовательность, сдвинутая влево на один, и работают два механизма вместе. Teacher forcing подаёт на вход эталонный префикс: предсказание в позиции tt обусловлено истинным w<tw_{<t}, а не собственными более ранними выходами модели, как и в рекуррентной модели. Каузальная маска делает более поздние эталонные токены недоступными: позиция tt не может обратиться к wt+1w_{t+1} и всему, что после, поэтому один прямой проход по всей эталонной последовательности вычисляет все предсказания сразу и без утечки.

Разобранный пример (три позиции). Для последовательности the cat sat down вход — the cat sat, а цель — cat sat down:

ПозицияВходной токенМожет обращаться кПредсказывает
1thethecat
2catthe catsat
3satthe cat satdown

Каждая строка читает только эталонные токены (teacher forcing), и ни одна не читает свою цель или то, что после неё (маска).

Поэтому все позиции обучаются параллельно в одном прямом проходе. Это то практическое преимущество над рекуррентной моделью, которое обещала заметка о трансформере: цена обучения на последовательности — один проход по TT позициям параллельно, а не TT последовательных шагов.

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

Две модели в числах#

Архитектуру делают конкретной две модели из одного декодера разных поколений.

GPT-2 small (Radford et al., 2019): байтовый словарь BPE на 50 257 записей, выученные позиции до 1024, 12 блоков pre-norm с d=768d = 768, 12 головами и dff=3 072d_{\text{ff}} = 3\,072. Проекции внимания слиты в одну матрицу 768×2 304768 \times 2\,304, дающую Q,K,VQ, K, V вместе. Параметры: 12×12×7682≈8512 \times 12 \times 768^2 \approx 85 млн в блоках плюс 50 257×768≈38.650\,257 \times 768 \approx 38.6 млн в эмбеддинге, который одновременно служит выходной матрицей (связанные веса), плюс 1 024×7681\,024 \times 768 позиций: всего 124 млн — число, с которого начинает заметка о дообучении.

Llama 3.2 1B: словарь на 128 256 записей; 16 блоков pre-norm с d=2 048d = 2\,048; RMSNorm; ротационные позиции; FFN с гейтом и тремя матрицами 2 048×8 1922\,048 \times 8\,192; и внимание с группировкой запросов (grouped-query attention, GQA) с проекцией запросов 2 048×2 0482\,048 \times 2\,048 рядом с проекциями ключей и значений 2 048×5122\,048 \times 512: 32 головы запросов ширины 64 делят 8 голов ключей и значений, что вчетверо сокращает память на кэш ключей и значений при порождении. На блок: 10.5 млн во внимании + 50.3 млн в FFN ≈ 60.8 млн; 16 блоков ≈ 973 млн; эмбеддинги 128 256×2 048≈263128\,256 \times 2\,048 \approx 263 млн, связанные с выходом; всего около 1.24 млрд. У модели 1B в десять раз больше параметров, чем у GPT-2 small, и словарь в 2.5 раза больше, а изменения в устройстве (pre-norm, RMSNorm, RoPE, FFN с гейтом, GQA) — те, что заметка об архитектуре перечисляла как современные решения по умолчанию.

Что делает базовая модель#

Предобученный декодер — продолжатель текста. Получив Find the value of n in the equation n + 2 = 6., базовая модель на 1 млрд параметров выдаёт правдоподобное продолжение веб-страницы с этим предложением: повторяет задачу, блуждает по не относящимся к делу правилам алгебры, находит n = 4, а затем продолжает: «If n is an integer, what is the value of n? n = 4», «n = 5», «n = 6» и так далее, пока не кончится бюджет токенов, потому что именно такие списки следуют за такими предложениями в её обучающих данных. Если записать ту же задачу как текст для дополнения, … Answer: n = , она выдаёт 4, а затем продолжает пронумерованным списком уравнений. Знание у модели есть; нет поведения «ответить и остановиться». Это поведение добавляет заметка об обучении на инструкциях, и базовая и дообученная контрольные точки там имеют одинаковую архитектуру.

Декодирование: как превратить вероятности в текст#

На каждом шаге модель выдаёт распределение; кто-то должен выбрать из него токен, дописать его и повторить. Этот выбор формирует текст не меньше, чем сама модель.

Рисунок

Цикл порождения и где действуют настройки декодирования

Один шаг порождения модели из одного декодераЦикл слева направо: префикс, декодер с каузальной маской и KV-кэшем, логиты по словарю, преобразование распределения температурой, штрафами и усечением top-k или top-p, выбор токена через argmax или сэмплирование. Стрелка снизу возвращается к префиксу: выбранный токен дописывается, и шаг повторяется до символа конца.префиксw₁ … wₜ₋₁декодеркаузальный, KV-кэшлогиты zₜпо словарюпреобразоватьτ, штрафы, top-k/pвыбратьargmax / сэмплдописать wₜ и повторить до [EOS]Один шаг порождения модели из одного декодераЦикл слева направо: префикс, декодер с каузальной маской и KV-кэшем, логиты по словарю, преобразование распределения температурой, штрафами и усечением top-k или top-p, выбор токена через argmax или сэмплирование. Стрелка снизу возвращается к префиксу: выбранный токен дописывается, и шаг повторяется до символа конца.префиксw₁ … wₜ₋₁декодеркаузальный, KV-кэшлогиты zₜпо словарюпреобразоватьτ, штрафы, top-k / top-pвыбратьargmax или сэмплдописатьи повторить
Один шаг порождения и место каждой настройки декодирования. Декодер читает префикс (с KV-кэшем вычисляется только новая позиция) и выдаёт логиты по словарю. Температура, штрафы за повтор и усечение top-k или top-p меняют это распределение; затем жадное декодирование берёт argmax, сэмплирование вытягивает токен из распределения, а лучевой поиск держит в живых не один префикс, а несколько. Выбранный токен дописывается, и цикл повторяется до символа конца или предела длины. Спекулятивное декодирование меняет то, кто предлагает токены, но в точной арифметике не меняет выход этого цикла.

Жадное декодирование берёт arg⁡max⁡wP(w∣w<t)\arg\max_w P(w \mid w_{<t}). Оно детерминировано и дёшево, а на открытых промптах зацикливается: модель на 135 млн параметров, которую просят продолжить историю, выдаёт «Lily’s mom, Mrs. Jenkins, was very kind and helpful», а затем повторяет предложение, потому что однажды сгенерированная фраза — самое вероятное продолжение самой себя. Лучевой поиск (заметка о переводе) находит последовательности с большей вероятностью и для открытого текста делает проблему хуже: самый вероятный длинный текст пресен и повторяется (Holtzman et al., 2020). Он остаётся правильным инструментом, когда существует верный выход, как в переводе.

Температура#

Разделить логиты на τ\tau перед softmax:

Pτ(w)=exp⁡(zw/τ)∑w′exp⁡(zw′/τ).P_\tau(w) = \frac{\exp(z_w / \tau)}{\sum_{w'} \exp(z_{w'} / \tau)}.

τ=1\tau = 1 — распределение модели; при τ→0\tau \to 0 оно приближается к жадному выбору; τ>1\tau > 1 его сплющивает. Для трёх логитов (2,1,0)(2, 1, 0):

τ\tauPτP_\tau
0.5(0.867,0.117,0.016)(0.867, 0.117, 0.016)
1(0.665,0.245,0.090)(0.665, 0.245, 0.090)
2(0.506,0.307,0.186)(0.506, 0.307, 0.186)

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

Усечённое сэмплирование: top-kk и top-pp#

Сэмплировать, но только из головы распределения. Top-kk оставляет kk самых вероятных токенов и перенормирует; он предсказуем и не учитывает, насколько распределение острое, поэтому k=40k = 40 — слишком много, когда у одного токена 95% массы, и слишком мало, когда распределение плоское. Top-pp (nucleus sampling, Holtzman et al., 2020) оставляет наименьшее множество SS с ∑w∈SP(w)≥p\sum_{w \in S} P(w) \ge p; множество подстраивается под форму распределения, поэтому p≈0.9p \approx 0.9 — обычный выбор по умолчанию для открытого порождения. Оба метода отрезают длинный хвост, который одна температура иногда бы сэмплировала.

Штрафы и контраст#

Штраф за повтор (repetition penalty) ρ>1\rho > 1 делит логит каждого токена, уже стоящего в контексте, на ρ\rho, если логит положителен, и умножает, если отрицателен (Keskar et al., 2019); штрафы частоты и присутствия в стиле OpenAI вместо этого вычитают член, пропорциональный числу вхождений токена. Оба подавляют циклы ценой того, что иногда подавляют токен, который должен повториться (имя).

Контрастный поиск (contrastive search; Su et al., 2022) оценивает кандидатов величиной λlog⁡P(w)−(1−λ)max⁡j<tcos⁡(hw,hj)\lambda \log P(w) - (1 - \lambda)\max_{j<t}\cos(h_w, h_j): вероятность минус сходство скрытого состояния кандидата с предыдущими, так что штрафуется повтор представления, а не только токенов. Типичное сэмплирование (typical sampling; Meister et al., 2023) оставляет токены, неожиданность которых −log⁡P(w)-\log P(w) близка к энтропии распределения, отбрасывая и предсказуемое, и странное. DoLa (Chuang et al., 2024) декодирует по разности логитов позднего и раннего слоя, исходя из гипотезы, что ранние слои несут общие предсказания, а поздние — конкретные; на той же модели в 135 млн параметров и том же промпте с историей, что и выше, без штрафа за повтор, который рекомендует документация метода, он вырождается в «Max is 11 and 1 and 1 and 1…».

МетодПараметрДетерминированТипичное применение
Жадный—ДаКороткие фактические ответы; зацикливается на длинном тексте
ЛучевойBB, α\alphaДаПеревод, суммаризация с эталонами
Температураτ\tauНетВместе с усечением
Top-kkkkНетПрежнее значение по умолчанию
Top-ppppНетОткрытое порождение
Штраф за повторρ\rho—Добавляется к любому из выше
Контрастный поискλ\lambda или α\alpha, kkДаСвязный длинный текст без сэмплирования

Как ускорить порождение#

Каждый порождённый токен требует прямого прохода по префиксу. Два механизма возвращают бо́льшую часть потерь.

KV-кэш. Ключи и значения прежних позиций не меняются, когда дописывается токен; их можно кэшировать и вычислять только запрос, ключ и значение новой позиции. Память на токен — 2×L×dkv2 \times L \times d_{kv} чисел, поэтому внимание с группировкой запросов, уменьшающее dkvd_{kv}, важно для обслуживания модели.

Спекулятивное декодирование (speculative decoding; Leviathan, Kalman and Matias, 2023). Небольшая черновая модель предлагает kk токенов; большая целевая модель проверяет их за один прямой проход по удлинённому префиксу; принятые токены сохраняются, а первый отвергнутый заменяется собственным выбором целевой модели. При жадном декодировании выход совпадает с выходом целевой модели; при сэмплировании правило принятия делает совпадающим распределение выхода. Целевая модель на 1.7 млрд с черновой на 135 млн порождает 128 жадных токенов за 41 с вместо 101 с на том же оборудовании. Тексты, порождённые с черновой моделью и без неё, совпадают в первом предложении, а затем расходятся. В точной арифметике они были бы одинаковы; вероятная причина в том, что проверочный проход оценивает несколько токенов сразу в 16-битной арифметике с плавающей точкой, его логиты немного отличаются от логитов пошаговых проходов, и почти-равенства двух продолжений хватает, чтобы изменить жадный выбор. Движки для обслуживания добавляют непрерывный батчинг (continuous batching: запросы входят в работающий батч и выходят из него), страничную память KV (paged KV) и кэширование префиксов (общий длинный промпт кодируется один раз), что ещё повышает пропускную способность, не меняя модель.

Что изменилось#

Рекуррентная ЯМТрансформер из одного декодера
КонтекстВесь префикс, через забывающее состояниеКаждая более ранняя позиция в контекстном окне, через внимание
Обучение на последовательностиTT последовательных шаговОдин параллельный проход с каузальной маской
Достигнутый масштабДесятки миллионов параметровОт 10810^8 до 101210^{12}
Использование предобученной моделиПерплексия, сэмплированиеДополнение, few-shot-промптинг, затем дообучение

Ограничения#

  • Только слева направо. Представление токена tt никогда не видит t+1t + 1; для задач понимания двунаправленный вектор энкодера — лучший признак. Сравнивает их заметка о семействах моделей.
  • Гладко — не значит верно. Цель обучения вознаграждает правдоподобные продолжения, поэтому базовая модель выдумывает с той же уверенностью, с какой излагает факты.
  • Продолжатель, а не ассистент. Без дальнейшего обучения модель не следует инструкциям, не останавливается и не отказывает.
  • Порождение последовательно и при инференсе упирается в память, хотя обучение параллельно.
  • Выбор декодирования — часть системы. Одна и та же модель даёт разный текст при разных сэмплерах; оценки должны их фиксировать.

Что нужно запомнить#

  • Цель обучения: −1T∑tlog⁡P(wt∣w<t)-\frac1T\sum_t \log P(w_t \mid w_{<t}) по каждому токену; каузальная маска обучает все позиции за один проход.
  • GPT-2 small: 12 блоков, d=768d = 768, 124 млн, связанные эмбеддинги. Llama 3.2 1B: 16 блоков, d=2 048d = 2\,048, GQA, RoPE, FFN с гейтом, ≈ 1.24 млрд.
  • Базовая модель продолжает текст; промпт в виде текста для дополнения работает лучше, чем вопрос.
  • Декодирование: жадное зацикливается, лучевой поиск — для задач с эталоном, температура перемасштабирует, top-pp адаптивно усекает, штрафы и контрастный поиск борются с повторами.
  • KV-кэш и спекулятивное декодирование ускоряют порождение, не меняя выход, с точностью до эффектов арифметики с плавающей точкой.

Ноутбук#

Три ноутбука. Номера ячеек считают все ячейки, включая текстовые, начиная с 1. Приведённые числа взяты из прогона, сохранённого в курсе; у ячеек, изменённых с тех пор под текущие версии библиотек, сохранённого выхода нет.

week08_modern_LLM.ipynb: ячейки 6–11 загружают базовую контрольную точку Llama 3.2 1B в конвейер text-generation с не более чем 512 новыми токенами и запускают промпт с уравнением как вопрос и как текст для дополнения; ячейки 18–20 печатают деревья модулей базовой и дообученной на инструкциях контрольных точек, по которым прочитаны приведённые выше числа Llama 3.2 1B, и подтверждают, что как строки они совпадают.

week10_PEFT.ipynb: ячейки 11–14 загружают GPT-2 small, добавляют токен [PAD], печатают дерево модулей, по которому прочитаны приведённые выше числа GPT-2 small, и число параметров 124 442 112: 124 439 808 у GPT-2 small, плюс 768 на эмбеддинг нового токена и 1536 на выходной слой для двух классов.

week11_pt0_Decoding_and_Sampling.ipynb:

  • Ячейки 4–7 приводят формулу температуры и определяют generate_once с параметрами max_new_tokens, temperature, top_k, top_p, typical_p и repetition_penalty, передаваемыми в generate.
  • Ячейки 9–12 запускают жадное декодирование (цикл с Mrs. Jenkins), τ=0.7\tau = 0.7, top-kk = 40 и top-pp = 0.9 на промпте «Continue the story: Once upon a time» с моделью на 135 млн параметров, обученной на инструкциях, и печатают тексты.
  • Ячейки 13–15 объясняют и запускают типичное сэмплирование (p=0.2p = 0.2) и top-pp со штрафом за повтор 1.2.
  • Ячейки 16–19 запускают контрастный поиск (penalty_alpha=0.6, top_k=4) и DoLa (dola_layers="low"), оба через репозитории пользовательского порождения; DoLa запускается без штрафа за повтор и выдаёт цикл, приведённый выше.
  • Ячейки 20–23 соединяют целевую модель на 1.7 млрд с черновой на 135 млн через assistant_model и замеряют 128 жадных токенов: 101.38 с без черновой модели (ячейка 22) и 40.79 с с ней (ячейка 23) при одном и том же seed и промпте. Тексты расходятся после первого предложения, как сказано выше; у ячейки 21, которая загружает модели и делает первый замер, нет сохранённого выхода.
  • Ячейки 24–33 описывают vLLM (страничное внимание, непрерывный батчинг, кэширование префиксов) и запускают модель на 360 млн параметров с общим длинным промптом и без него; замеров времени для этих ячеек в сохранённых выходах нет.

Дальше#

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

Литература#