Модуль 7. Гиперпараметры и кривые обучения

Цель модуля: настроить цикл обучения (epochs, learning rate, эффективный батч, warmup, расписание) и читать кривые train/val так, чтобы поймать переобучение до того, как оно испортит модель. После модуля вы выбираете чекпойнт по валидации, а не по последнему шагу.

Перед началом: модуль 2 (обучение — подбор чисел по градиенту), модуль 6 (LoRA-адаптеры), модуль 5 (датасет с val-частью). Инструменты: песочница сайта (сниппет модуля), python3 локально. Трудоёмкость: ~1.5 ч (теория 45 мин · практика 35 мин · квиз 10 мин).

🔥 Loss упал до нуля — и модель стала хуже

Команда выложила графики обучения: train loss плавно съехал с 0.9 до 0.0003. Скриншот в рабочий чат, все довольны. Через день на живых вопросах модель отвечает идеально — на 300 примеров из датасета, слово в слово. И мимо — на всё остальное. Классическое переобучение: сеть с миллиардами параметров запомнила обучающую выборку вместе с опечатками вместо того, чтобы выучить закономерность.

Train loss — не метрика качества; это метрика «как хорошо модель запоминает обучающие данные». Честный сигнал — валидация. И вместо того чтобы верить этому тезису, вы сейчас увидите его в песочнице — на модели из шести чисел.

📖 7.1. Цикл обучения на пальцах

Один шаг оптимизатора устроен так:

text
батч (N примеров)
  → forward: модель предсказывает ответ на каждом примере батча
  → loss: одно число — «насколько неправильно» (среднее по батчу)
  → backward: градиент — в какую сторону крутить каждый вес
  → шаг: каждый вес сдвигается против градиента, с силой learning rate

Epoch — один проход по всему датасету. Если пар 300, а эффективный батч 32, одна эпоха — около 10 шагов оптимизатора, а 3 эпохи — около 30. В тюнинге LLM шагов мало (десятки–сотни), поэтому чувствительность к гиперпараметрам высокая: ошиблись с learning rate — либо ничего не выучите, либо «бред» на первых же шагах. Отсюда и консервативные значения ниже.

📖 7.2. U-кривая валидации: разбираем сниппет

Запустите сниппет модуля. Это полиномиальная регрессия (6 коэффициентов), обучаемая градиентным спуском на 7 точках train; val — другие 7 точек того же закона. Крошечная, но честная копия ситуации «миллиард параметров против сотни примеров». Ключевая часть вывода:

text
шаг  train MSE    val MSE
    20     0.0295     0.0113  ← лучший val на текущий момент
    40     0.0094     0.0051
    80     0.0030     0.0092
   160     0.0020     0.0118
   640     0.0007     0.0129
  6000     0.0000     0.0139

Минимум val MSE = 0.0051 на шаге 39
Финальная модель (шаг 6000): train 0.0000, val 0.0139
«Ранняя остановка» (шаг 39): train 0.0099, val 0.0051

Читаем по столбцам. Train MSE монотонно падает до нуля — модель способна запомнить все 7 точек. Val MSE ведёт себя иначе: 0.0113 → 0.0051 (минимум около шага 39) → 0.0139. Сначала модель ловит закон — падают обе ошибки. После минимума она начинает запоминать шум train-точек: val растёт почти втрое от рекорда. Это и есть U-кривая валидации.

Два практических вывода. Первый: лучший чекпойнт — шаг 39, а не финальный 6000; в сниппете «ранняя остановка» просто сохраняет копию весов (best_w) в момент рекорда val. Второй — про дискретность отчётов: маркер «лучший val» горит только у шага 20, потому что рекорд случился на 39-м, между печатью 20 и печатью 40; на шаге 40 val в округлении такой же (0.0051), но на долю хуже сохранённого рекорда. Лог обучения — выборка из гладкой картины: не верьте «последней строке», ищите экстремум.

📖 7.3. Гиперпараметры тюнинга LLM

  • Epochs: 1–3. Датасет маленький (модуль 5), модель мощная; десять эпох — рецепт запоминания из крючка. Начинайте с 1–2; третью добавляйте, только если val всё ещё улучшается.
  • Learning rate: 1e-4…2e-4 для LoRA. Адаптер маленький и учится с нуля — ему нужны относительно большие шаги. Для полного дообучения (все веса уже обучены) — на порядок меньше, около 1e-5…2e-5: крупные шаги ломают базовые навыки (catastrophic forgetting, модуль 6).
  • Эффективный батч = batch size × gradient accumulation. VRAM хватает на маленький физический батч (4–8), а стабильный шаг нужен больше: градиенты накапливаются несколько микробатчей, затем делается один шаг — как будто батч был 32–64. Пример: физический батч 8 × накопление 4 = эффективный 32.
  • Warmup: первые 5–10% шагов. Learning rate растёт от нуля до целевого. В начале адаптеры «свежие» относительно задачи, и один случайный крупный шаг может испортить обучение с первых батчей — warmup это страхует.
  • Cosine schedule. После warmup LR плавно спадает к нулю по косинусу: крупные шаги в середине (быстрое схождение), мелкие в конце (точная доводка). Мягкая альтернатива — линейный спад.

📖 7.4. Чекпойнты, ранняя остановка, выбор модели

Правило одно: чекпойнт выбирается по val, никогда по train. На практике:

  1. Сохраняйте чекпойнт каждые N шагов или раз в эпоху — это копия весов; для LoRA она весит мегабайты (модуль 6).
  2. После каждой эпохи считайте loss на val. Ещё лучше — метрику по golden set (модуль 8): val loss тоже «не про задачу», он лишь про предсказание датасета.
  3. Ранняя остановка: val не улучшается 2–3 проверки подряд — обучение можно останавливать. Рекордный чекпойнт уже сохранён; в сниппете это best_w с шага 39.
  4. В прод идёт рекордный чекпойнт — под версией и с возможностью отката (модуль 12).

📖 7.5. Компромиссы

  • Больше эпох vs переобучение: каждая эпоха после минимума val — запоминание train; выигрыш возможен, но проверяется только val.
  • LR высокий vs низкий: высокий — быстро, но риск «улететь» и задавить базовые навыки; низкий — надёжно, но можно не сойтись за 1–3 эпохи.
  • Большой физический батч vs накопление: большой батч быстрее по времени, но требует VRAM; накопление экономит память ценой времени и даёт тот же эффективный батч.
  • Остановка по train vs по val: train падает почти всегда и ничего не говорит о задаче; val — единственный честный сигнал, golden set — ещё честнее.
  • Частые чекпойнты vs место: чаще — точнее поймали минимум, но больше места на диске и пауз на сохранение.

💻 Практика

  1. (10 мин) Запустите сниппет в песочнице. Найдите минимум val (0.0051 на шаге 39) и убедитесь: финальная модель хуже рекордной по val почти втрое (0.0139 против 0.0051). Объясните, почему маркер «лучший val» стоит только у шага 20.
  2. (10 мин) Поэкспериментируйте: lr 0.35 → 0.5 и → 0.2, а затем DEGREE 5 → 3. При lr 0.5 минимум наступает раньше (шаг ~27), при 0.2 — позже (~68); при DEGREE 3 train упирается в ~0.0038 — модель проще и физически не может запомнить шум, U-кривая мягче, минимум val глубже.
  3. (10 мин) Спланируйте свой тюнинг: возьмите размер датасета из модуля 5 (например, 300 пар) и заполните: epochs, learning rate, физический батч, накопление, эффективный батч, warmup. Посчитайте число шагов оптимизатора на эпоху и точку конца warmup.
  4. (5 мин) Напишите одной строкой правило выбора чекпойнта в прод — как в 7.4, но своими словами.

🧩 Quiz "Проверь себя"

1. Какой чекпойнт несут в прод?
2. Сколько эпох типично для LoRA-тюнинга LLM?
3. Train loss почти нулевой, val растёт. Диагноз?
4. Физический батч 8, накопление градиентов 4. Каков эффективный батч?
5. Зачем warmup в начале обучения?

✅ Итоги модуля

  • Нарисовать цикл «батч → loss → градиент → шаг LR» и объяснить, что такое epoch.
  • Прочитать U-кривую из сниппета: 0.0113 → 0.0051 (шаг ~39) → 0.0139 при train, ушедшем в 0.
  • Назвать типичные epochs и learning rate для LoRA и отличия от full.
  • Посчитать эффективный батч из физического батча и накопления.
  • Объяснить warmup и cosine schedule.
  • Сформулировать правило выбора чекпойнта по val / golden set.

🔗 Мостик к Модулю 8

Вы научились останавливаться по валидации — но и val loss обманывает: он говорит «модель предсказывает датасет», а не «она полезна задаче». Два тюнинга с одинаковым val loss могут отличаться на живых вопросах: один перестал извиняться, другой начал сочинять несуществующие политики возврата. Следующий модуль — «Оценка качества: golden set, метрики, LLM-as-judge»: как до выката поймать и то, и другое.