Дообучение Laya на своих собственных решениях
На бенчмарке typed-decisions базовые чекпойнты дают почти случайный результат zero-shot — 0.36 и 0.35 против случайного базового уровня 0.318 — тогда как дообученный чекпойнт достигает 0.766 на тех же 2,000 решениях, выше опубликованного 0.727 у TypeSafe Jev и выше потолка самосогласованности учителя 0.735. Дообучение — это то, где заключена большая часть ценности, и публичный ноутбук для дообучения прогоняет весь цикл на бесплатных GPU 2xT4 в Kaggle: построить набор данных, обучить с RLCD, подобрать температуры калибровки, оценить и загрузить результат в Hub. Эта страница проходит по тому ноутбуку и указывает на части, которые остаются несущими, когда вы заменяете данные на свои.
Другой разобранный пример — голова принятия решений для браузерного агента на одной GPU на 16 GB без платного API — находится в разделе Дообучение Laya как головы принятия решений для браузерного агента.
Что делает ноутбук, по порядку
| # | шаг | что происходит |
|---|---|---|
| 1 | Окружение | проверяет, что обе GPU T4 видны и выделены |
| 2 | Установка | laya, transformers, datasets и зависимости для обучения |
| 3 | Предобработка | 1,200 обучающих случаев (6,000 типизированных решений) превращаются в токенизированные элементы с мягкими целями, записанные на диск для обоих рангов DDP |
| 4 | Обучение | train_ddp.py под torchrun --nproc_per_node=2, четыре эпохи |
| 5 | Калибровка | одна температура на тип, подобранная на срезе, отложенном до обучения (внутри обучающего скрипта, после последней эпохи) |
| 6 | Оценка | официальный сплит test, отвеченный дообученным чекпойнтом — 400 случаев, 2,000 решений — с задержкой на каждый случай |
| 7 | Метрики | точность, мягкая точность, Brier, ECE, score MAE, within-one-level, KL/TV и процентили задержки; таблица очного сравнения с Jev и потолком учителя |
| 8 | Публикация | (необязательно) карточка модели, построенная по собственным числам запуска, папка загружена в Hub |
| 9 | Отчёт | benchmark_report.json с таблицей метрик и точностью по каждому рабочему процессу |
Настройки Kaggle: Accelerator GPU T4 x2, Internet On. Выходные данные попадают в
/kaggle/working/laya_finetuned_typed_decisions.
Рецепт обучения
RLCD обучается на золотых распределениях бенчмарка, а не на жёстких метках: каждый элемент несёт вероятность, которую учитель назначил каждому варианту, и обе половины функции потерь читают эту цель —
- терм градиента политики по выборочным шумным проекциям логитов (в стиле GRPO: четыре выборки на элемент, шум исследования затухает 0.4 → 0.1), вознаграждаемый собственными правилами оценки (сферическая 0.75, ranked probability 1.0);
- терм мягкой кросс-энтропии с полным весом против того же распределения.
Параметры, которые ноутбук задаёт для карты на 16 GB:
| эпохи | 4 |
| эффективный батч | 64 последовательности (8 на микро-батч, 2 GPU, 4 шага накопления) |
| скорости обучения | энкодер 2.5e-5, голова 1e-4 — AdamW, косинусное расписание |
| память | fp16 autocast, gradient checkpointing на энкодере и голове, обрезка нормы градиента 1.0 |
| бюджет последовательности | max_len 1024, head_max_len 256, max_tokens_per_batch 4096 |
Время выполнения на 2xT4 — минуты для демо и часы для реальных данных: около 4–6 минут для 6,000 решений демо и примерно 4–5 часов для четырёх эпох на ~30k вопросах.
Чтобы направить его на свои данные, замените два вызова load_dataset и сохраните схему строки:
каждый случай несёт state, questions и gold (вероятности учителя по каждому вопросу), и
препроцессор превращает их в элементы. Типы вопросов — choice, score и noul; всё, что вы
можете выразить ими над состоянием, годится.
Калибровка — часть запуска
Это шаг, который чаще всего опускают при копировании цикла, и он становится несущим в тот момент, когда кто-либо применяет gating по уверенности.
Ноутбук берёт калибровочный срез из обучающих данных до того, как разбить их по рангам (до 400 элементов, или 10%, при фиксированном seed, одинаковом на каждом ранге). Подбор температур на элементах, на которых запуск уже обучался, измеряет подгонку, а не калибровку — модель почти уверена и почти права на них, поэтому оптимизатору нечего смягчать и он возвращает вырожденный масштаб.
После последней эпохи ранг 0 подбирает одну температуру на тип вопроса (choice, score,
noul) методом LBFGS по логарифму температуры, ограниченную [0.1, 10] (1.0 для среза менее
десяти элементов, 1.2 если подбор вызывает исключение). Значения попадают в rl_agent_config.json
как temperature, и ноутбук удаляет любой унаследованный temperature_by_options в той же
записи: те старые значения по корзинам имеют приоритет при инференсе и молча маскировали бы новый
подбор.
Масштабирование по температуре оставляет argmax — и точность — без изменений; меняется уверенность. Чекпойнты в поставляемом виде переуверены, поэтому подбирайте до того, как полагаться на любой порог, и оценивайте результат на отложенных данных, прежде чем заявлять об улучшении. Регрессия сохранения конфигурации запускается без загрузок и обучения:
python tests/test_calibration_persistence.py
Оценка до того, как доверять
Оценка — это полный проход по официальному тестовому сплиту: 400 случаев, 2,000 решений по
Agent Trace Observability, Customer Service, Invoice Processing и Security Incidents. Она вычисляет
точность, мягкую точность, Brier, ECE (через laya.common.ece_score), score MAE, within-one-level и
процентили задержки, затем строит таблицу очного сравнения, опорные строки которой фиксированы:
| модель | вид | точность | ECE |
|---|---|---|---|
| TypeSafe Jev 1.13.0 | общего назначения | 0.727 | 0.144 |
| ModernBERT-base (149M) | специализированная | 0.646 | 0.179 |
| Teacher Self-Agreement | потолок | 0.735 | — |
| Laya (опубликованный чекпойнт) | дообученный | 0.766 | — |
Строка Laya вашего собственного запуска вычисляется так же — ноутбук перестраивает таблицу по
собственным числам запуска. Две привычки, которые стоит скопировать: держите срезы, которые вам
важны (язык, рабочий процесс), внутри отложенных данных, и сообщайте калибровку рядом с точностью,
потому что обучающий сигнал — это распределение, а не только метка. Когда у вас появятся числа,
сообщение в Discussions репозитория — место, где
ими поделиться; бенчмарки и известные ограничения живут в BENCHMARKS.md в корне репозитория.
Публикация в Hub
Ячейка публикации — последняя миля цикла, и она намеренно скучная:
- Поместите
HF_TOKENс правом записи в Kaggle (Add-ons → Secrets). Ячейка вызывает исключение с точными инструкциями, если его нет. - Задайте целевой репозиторий — поставляемая ячейка по умолчанию использует имя в собственном пространстве имён проекта, поэтому измените его перед запуском.
- Запустите её. Она записывает карточку модели, числа которой берутся из таблицы сравнения этого
запуска, затем загружает
model.safetensors,encoder/,tokenizer/,rl_agent_config.json, карточку и отчёт бенчмарка.
Результат загружается как любой другой чекпойнт — нет никакого API, специфичного для дообучения:
import laya
agent = laya.load("your-org/your-checkpoint") # the repo you just pushed
result = agent.predict(state, questions)
Скользящий checkpoint_latest/ перезаписывается после каждой эпохи, поэтому таймаут или OOM в
Kaggle стоит одной эпохи, а не всего запуска.
За чем следить
- Цикл хорош ровно настолько, насколько хороши цели. RLCD имитирует распределение учителя на ваших вопросах; собирайте уверенности учителя до (или вместе с) обучением и относитесь к их качеству как к потолку.
- Калибровочный срез намеренно мал. До 400 элементов или 10% — достаточно для трёх скаляров на тип, недостаточно для валидации. Откладывайте собственные данные для оценки.
- Ваши метки должны укладываться в три примитива. Если ваше решение — не choice, не шкала и не вероятность да/нет, сначала придайте ему такую форму. Два острых края уже задокументированы: большое число вариантов ухудшает выбор по уверенности (#394), а отрицание при принудительном выборе может следовать за вопросом, а не за состоянием (#377).
- Поставляйте конфигурацию, а не только веса. Удалённый
temperature_by_options— это та часть, которая молча сбивает калибровку, если он выживет в скопированной конфигурации.