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

24 / 37 · Адаптация и эффективные модели

Дообучение

Продолжить обучение предобученной модели на размеченной задаче: что обучать (всё или только новый выходной слой), с каким шагом обучения и чего это стоит по памяти. Модель GPT-2 на задаче тональности даёт 0.890, если обучать всё, 0.737 — только выходной слой, и 0.900, если сначала обучить выходной слой, а затем всё.

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

Заметка о переносе обучения показала, что обучение всего предобученного энкодера на задаче дало на AG News больше, чем считывание его замороженных признаков: 0.949 на отложенной десятой части обучающей выборки против 0.902 на тесте. Отсюда практические вопросы, на которые отвечает эта заметка: какие параметры обучать, с каким шагом обучения, в каком порядке и во что обходится выбор. Эксперименты переходят на модель из одного декодера и новую задачу, чтобы выводы не были привязаны к BERT.

Обозначения. Предобученные параметры θ\theta (тело модели), выходной слой задачи с параметрами ϕ\phi, инициализированными случайно; шаг обучения η\eta; функция потерь L\mathcal L — кросс-энтропия задачи.

Постановка#

Задача: бинарная тональность на Stanford Sentiment Treebank (SST-2), фразы из рецензий на фильмы с метками «положительная» или «отрицательная»; используются 50 000 из 67 349 обучающих фраз, а валидационная часть из 872 фраз служит тестом (официальные тестовые метки скрыты). На обучении 44% отрицательных и 56% положительных — близко к балансу, поэтому приводится доля правильных ответов.

Модель: GPT-2 small (124 млн параметров, из заметки о GPT) с линейным выходным слоем ϕ∈R768×2\phi \in \mathbb R^{768 \times 2} на скрытом состоянии последнего токена без паддинга. В каузальной модели только последняя позиция видела весь вход, поэтому только она может подытожить фразу; соглашение BERT с [CLS] читает первую позицию, потому что там каждая позиция видит всё. В токенизатор добавляется токен [PAD], и таблица эмбеддингов вырастает на одну строку.

Обучение: AdamW, размер батча 128, 1000 шагов (около 2.6 прохода по 50 000 фраз), смешанная точность, оценка каждые 250 шагов.

Отправная точка: обучать всё#

Полное дообучение обновляет θ\theta и ϕ\phi вместе одним оптимизатором:

(θ,ϕ)←(θ,ϕ)−η ∇θ,ϕ L.(\theta, \phi) \leftarrow (\theta, \phi) - \eta\, \nabla_{\theta,\phi}\, \mathcal L .

Шаг обучения — 2×10−62 \times 10^{-6}, на три порядка меньше 10−310^{-3}, с которым небольшой трансформер обучался с нуля в заметке об архитектуре. Предобученные веса уже кодируют то, что модель знает; большой шаг разрушает это прежде, чем выходной слой научится этим пользоваться, — такой провал называется катастрофическим забыванием (catastrophic forgetting). Маленькие шаги сдвигают тело модели ровно настолько, насколько требует задача.

Результат: 0.890 правильных ответов на валидации, функция потерь 0.277.

Цена: оптимизатор хранит две оценки моментов на параметр, а обратный проход — градиент на параметр. В 32-битных числах 124 млн весов занимают 0.5 ГБ, градиенты — ещё 0.5 ГБ, состояния AdamW — 1.0 ГБ, и это без активаций: примерно вчетверо больше памяти самой модели. Для модели на 7 млрд параметров та же арифметика даёт 112 ГБ — больше, чем вмещает один GPU, и именно это число берётся сократить заметка о PEFT.

Линейное зондирование: обучать только выходной слой#

Заморозить θ\theta и обучать только ϕ\phi с бо́льшим шагом (10−410^{-4}: выходной слой начинает со случайных значений, и забывать ему нечего). Выход тела модели — фиксированный признак, а выходной слой — логистическая регрессия поверх него, как в эксперименте с замороженными признаками из предыдущей заметки, только здесь признаки вычисляются на лету.

Результат: 0.737, функция потерь 0.541.

Отставание от полного дообучения — 15 пунктов. Скрытое состояние последнего токена языковой модели обучалось предсказывать следующий токен, а не разделять тональности, и линейное считывание находит лишь часть сигнала. Вектор [CLS] BERT на AG News в похожем режиме дал 0.902, но это сравнение меняет сразу модель, задачу, данные и обучение выходного слоя. По нему нельзя понять, присутствует ли тема в представлении линейнее, чем тональность, или двунаправленный итоговый токен — лучший признак, чем каузальное состояние последней позиции. Обе гипотезы правдоподобны; чтобы проверить любую из них, нужно сравнение, меняющее один фактор: например, одна и та же модель, зондируемая на обеих задачах, или энкодер и декодер близкого размера, зондируемые на SST-2. Линейное зондирование (linear probing) — это измерение того, что содержит представление, и дешёвый, но слабый классификатор.

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

LP-FT: сначала выходной слой, потом всё#

Kumar et al. (2022) показали, что такое двухэтапное расписание (линейное зондирование, затем дообучение) лучше сохраняет предобученные признаки, чем дообучение со случайным выходным слоем, причём сильнее всего выигрыш на данных, отличающихся от распределения дообучения. Здесь полное дообучение начинается с выходного слоя, обученного линейным зондированием выше, и идёт при 2×10−62 \times 10^{-6}.

Результат: 0.900, функция потерь 0.258 — на пункт выше дообучения с нуля при той же цене плюс один прогон зондирования.

РежимОбучаетсяη\etaДоля верных (валидация)Потери (валидация)
Полное дообучение124 млн2×10−62\times10^{-6}0.8900.277
Линейное зондирование153610−410^{-4}0.7370.541
LP-FT1536, затем 124 млн10−410^{-4}, затем 2×10−62\times10^{-6}0.9000.258
Рисунок

Три режима дообучения: что и когда обучается

Режимы дообученияполное дообучение: тело и слой обучаются, η = 2·10⁻⁶; 0.890. линейное зондирование: обучается только слой, η = 10⁻⁴; 0.737. LP-FT: обучается только слой, η = 10⁻⁴ → тело и слой обучаются, η = 2·10⁻⁶; 0.900.полное дообучение0.890выходной слой φ, 1536тело θ, 124 млнη = 2·10⁻⁶линейное зондирование0.737выходной слой φ, 1536тело θ, 124 млнη = 10⁻⁴LP-FT0.900выходной слой φ, 1536тело θ, 124 млнη = 10⁻⁴выходной слой φ, 1536тело θ, 124 млнη = 2·10⁻⁶обучаетсязамороженодоля верныхРежимы дообученияполное дообучение: тело и слой обучаются, η = 2·10⁻⁶; 0.890. линейное зондирование: обучается только слой, η = 10⁻⁴; 0.737. LP-FT: обучается только слой, η = 10⁻⁴ → тело и слой обучаются, η = 2·10⁻⁶; 0.900.полное дообучение0.890слой φтело θη = 2·10⁻⁶линейное зондирование0.737слой φтело θη = 10⁻⁴LP-FT0.900слой φтело θη = 10⁻⁴слой φтело θη = 2·10⁻⁶обучаетсязаморожено
GPT-2 small на SST-2, по 1000 шагов на фазу. Полное дообучение с первого шага обучает и тело модели, и случайно инициализированный выходной слой с маленьким шагом. Линейное зондирование замораживает тело и обучает только выходной слой (1536 весов) с шагом побольше. LP-FT сначала делает линейное зондирование, а затем дообучает всё, начиная с уже обученного выходного слоя, поэтому первые шаги не портят предобученные признаки градиентом от случайного слоя. Справа — доля правильных ответов на валидации SST-2 (872 фразы, одна фраза — 0.11 пункта).

Разница в один пункт между первой и третьей строками — на пределе того, что могут различить 872 примера: это 9 фраз (один пример — 0.11%), а стандартная ошибка одной доли верных около 0.9 на 872 примерах равна 0.9⋅0.1/872≈0.010\sqrt{0.9 \cdot 0.1 / 872} \approx 0.010, то есть одному пункту. Поэтому в этом прогоне наблюдалось 0.900 против 0.890: это согласуется с механизмом выше, но не упорядочивает два режима и не доказывает, что они равноценны.

Гиперпараметры, которые важны#

  • Шаг обучения — главный: от 10−510^{-5} до 5×10−55 \times 10^{-5} для энкодеров, меньше для больших декодеров. Слишком большой — модель забывает; слишком маленький — не сдвигается.
  • Расписание. Линейный прогрев на первых нескольких сотнях шагов, затем затухание — выбор по умолчанию для моделей post-norm и безвредный для pre-norm.
  • Эпохи. Два–четыре прохода по размеченной выборке; больше — переобучение на малых выборках.
  • Затухание весов 0.01 и дропаут на уровне предобучения; оба регуляризуют модель, у которой параметров гораздо больше, чем примеров в задаче.
  • Seed. На малых выборках запуски различаются на пункт и больше в зависимости от seed и порядка данных; решение требует нескольких запусков (Dodge et al., 2020).

Паддинг до длины батча, а не всего набора данных#

Батч — это тензор, поэтому у всех его последовательностей должна быть одна длина: короткие дополняются паддингом, а маска внимания скрывает его (заметка о токенизации). Вопрос в том, до какой длины. Дополнить весь набор данных до одного максимума просто, но вычисления тратятся на позиции, которые всё равно замаскированы. Динамический паддинг (dynamic padding) токенизирует каждый пример один раз, без паддинга, и дополняет только при формировании батча — до самой длинной последовательности этого батча. Батчи перемешиваются заново каждую эпоху, так что их длины заранее неизвестны; паддингу место в функции, которая собирает примеры в батч (collate function).

Разобранный пример (игрушечные длины). Батч из восьми фраз длиной 5, 9, 12, 7, 23, 4, 10 и 6 токенов содержит 76 настоящих токенов. Дополненный до 128, он занимает 1024 позиции, из которых настоящих 7.4%; дополненный до своей самой длинной фразы, 23, — 184 позиции, из которых настоящих 41.3%. Стоимость полносвязных блоков пропорциональна числу позиций — здесь она в 5.6 раза меньше. Self-attention сравнивает каждую пару позиций внутри последовательности: 1282=16 384128^2 = 16\,384 пар против 232=52923^2 = 529, в 31 раз меньше.

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

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

Замороженные признаки + линейная модельДообучение
Обновляемые параметрыВыходной слойВыходной слой и тело
Шаг обученияБольшой (случайный слой)Маленький (предобученное тело)
ПамятьТолько выходной слой≈ 4 × размер модели в fp32
Качество признаковЗафиксировано предобучениемПодстроено под задачу
SST-2, GPT-2 small0.7370.890 / 0.900 (LP-FT)

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

  • Одна полная копия на задачу. Дообученные θ\theta — новый артефакт на 124 млн параметров (или 7 млрд); десять задач — десять копий.
  • Память растёт вместе с моделью: веса, градиенты и состояния оптимизатора.
  • Забывание. Дообученная модель специализирована; её общие способности ухудшаются.
  • Шум. Малые валидационные выборки не различают разницу в пункт.
  • Признаки последнего токена слабы. Представление каузальной модели не предназначено для классификации; энкодер того же размера для этой задачи часто лучше и дешевле, хотя на SST-2 курс их не сравнивает.

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

  • Дообучение: обучать тело и выходной слой вместе с маленьким шагом (здесь порядка 10−610^{-6}–10−510^{-5}); большие шаги стирают предобучение.
  • Линейное зондирование: заморозить тело, обучать выходной слой с бо́льшим шагом; дёшево по памяти, ограничено тем, что представление уже кодирует (здесь 0.737).
  • LP-FT: сначала зондирование, затем дообучение начиная с обученного выходного слоя; здесь 0.900 против 0.890, разница в пределах шума, так что довод в его пользу — механизм и результаты Kumar et al., и проверять его нужно на каждой задаче.
  • Память при полном дообучении — примерно вчетверо больше весов модели в fp32.
  • Каждая задача, дообученная так, даёт полную копию модели.
  • Токенизировать один раз без паддинга и дополнять каждый батч до его собственной самой длинной последовательности; с маской внимания и паддингом справа предсказания не меняются, а вычисления сокращаются вместе с паддингом.

Ноутбук#

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

  • Ячейки 4–7 загружают SST-2 (train[:50000] и validation); ячейка 19 печатает доли классов (0.442 / 0.558 на обучении, 0.491 / 0.509 на валидации).
  • Ячейки 10–14 загружают GPT-2 с выходным слоем для классификации последовательностей, добавляют [PAD], расширяют эмбеддинги и печатают 124 442 112 параметров. Метод forward обёртки Model прогоняет трансформер, выбирает скрытое состояние с индексом attention_mask.sum(-1) - 1 (последний настоящий токен) и применяет слой score.
  • Ячейка 23 определяет цикл обучения (AdamW, кросс-энтропия, torch.autocast во float16, оценка каждые 250 из 1000 шагов с кривыми функции потерь и доли правильных ответов) и evaluate.
  • Ячейки 25–27: полное дообучение при 2×10−62\times10^{-6}, функция потерь на валидации 0.2772 и доля правильных ответов 0.8899.
  • Ячейки 31–34: линейное зондирование (AdamW(model.model.score.parameters(), lr=1e-4)), 0.5412 и 0.7374; выходной слой сохраняется в head.pt.
  • Ячейки 56–60: LP-FT, загрузка head.pt и дообучение всего при 2×10−62\times10^{-6}: 0.2580 и 0.9002.
  • Ячейки 62–64 печатают предсказания с вероятностями для десяти валидационных фраз.

Ячейки 35–54 (LoRA и настройка промпта в той же постановке) относятся к следующей заметке.

Ноутбук о LLM курса HSE-LAMBDA Deep Generative Models, Transformers-LangChain.ipynb, даёт рецепт с Trainer для задачи того же рода в текстовых ячейках 32–35, которые не запускаются (ячейки нумеруются так же). Он дообучает distilbert-base-uncased на предложениях из рецензий на фильмы Rotten Tomatoes с шагом обучения 2⋅10−52 \cdot 10^{-5}, размером батча 8, 2 эпохами и оценкой каждые 500 шагов (значение по умолчанию, когда выбрана стратегия "steps"). Набор данных токенизируется один раз через map(batched=True) без паддинга, а DataCollatorWithPadding(tokenizer=tokenizer) дополняет каждый батч до его самой длинной последовательности — это описанный выше динамический паддинг. Перед запуском нужно поменять две детали: текущие версии Transformers принимают только eval_strategy и отвергают evaluation_strategy, а оценка идёт на тестовой части, хотя в наборе данных есть валидационная — именно за ней следят во время обучения.

Дальше#

Полное дообучение даёт лучшую точность и стоит полной копии модели плюс вчетверо больше памяти при обучении. Следующая заметка оставляет тело замороженным и добавляет немного новых параметров в правильных местах, так что та же задача SST-2 выучивается до той же точности при обучении 0.24% весов.

Литература#