← Все статьи

Датасет для SFT: как спроектировать корпус дообучения

Опорный лонгрид о корпусе для дообучения с учителем: контракт пары «инструкция → ответ», покрытие, отказы, синтетика и эксперты, проверки перед обучением и утечки с оценкой.

Датасет для SFT: как спроектировать корпус дообучения
Содержание

Команда неделю крутит низкоранговую адаптацию (LoRA, Low-Rank Adaptation) на локальном чекпоинте. «Датасет» — шестьсот диалогов, выгруженных из чата: разные системные инструкции, ответы без единого шаблона, ни одного явного отказа, ни среза «устаревший регламент». На отложенной выборке из того же чата метрика растёт. На пилоте юрист ловит уверенный ответ по отменённой версии документа, а оператор — ответ в тоне, которого в проде быть не должно.

Провал почти никогда не в оптимизаторе. Провал в том, что корпус для дообучения с учителем (SFT, Supervised Fine-Tuning) собирали как папку примеров, а не как продукт с контрактом, покрытием и барьером качества. Ниже — опорный лонгрид о дизайне SFT-корпуса: что писать в пару «инструкция → ответ», откуда брать примеры, как не смешать обучение с оценкой и когда синтетика помогает, а когда вредит. Материал продолжает обзор инженерии датасетов и дополняет когда действительно нужно дообучение (решение «нужно ли»), не дублируя кейс классификации на Qwen (узкий эксперимент) и общий контур обучения LLM.

Ключевые выводы

SFT учит поведение на парах «вход → желаемый выход». Это не претрейн на сыром вебе и не набор предпочтений «ответ A лучше B». Путать семейства — получать красивый лосс и странный прод.

Сначала контракт пары, потом объём. Формат ответа, язык, когда отказ, когда эскалация к человеку — фиксируются до разметки и до синтетики.

Покрытие важнее размера. Тысяча однотипных «коротких вежливых ответов» хуже трёхсот стратифицированных кейсов с отказами, граничными классами и реальными формулировками пользователей.

Синтетика — ускоритель черновика, не замена редактора эталонов. Финальный стиль и факты домена утверждает человек с рубрикой.

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

Оценка не должна жить в том же файле, что обучение. Иначе вы подгоняете промпт и набор под метрику, а не проверяете систему. Рамка оценки — в материале про оценку LLM перед запуском.

Чем SFT-корпус отличается от соседних семейств

В одном проекте часто живут четыре семейства. Для SFT критично не перепутать назначение.

Семейство Учит / измеряет Типичная единица Ошибка смешения
SFT-корпус Как отвечать (формат, тон, паттерн) инструкция → ответ Обучение на эталоне оценки без аудита
Данные предпочтений Что выбрать из двух правдоподобных chosen / rejected Стиль без фактов; «нравится» вместо «верно»
Эталонный набор Измерить поведение вход + критерий приёмки Подгонка промпта под видимые кейсы
Буфер сбора Сырые провалы из эксплуатации трасса без финальной метки Оценка по неразмеченным кейсам

SFT-корпус может быть шире и шумнее эталона: цель — научить паттерн, а не зафиксировать регрессионный барьер. Эталон для непрерывной интеграции (CI, Continuous Integration) — уже и строже. Общая таксономия — в опорном обзоре серии; здесь разворачиваем только контур обучения.

Кратко: если запись нельзя описать как «при таком входе желаем такой выход (или отказ)», она ещё не готова для SFT — это заметка или кандидат в буфер сбора.

Сначала контракт пары instruction → output

До разметки зафиксируйте контракт в одном месте (meta.yaml набора или короткий RFC):

Элемент Вопрос Пример для ассистента по регламентам
Вход Что видит модель? Вопрос пользователя; опционально найденные фрагменты
Выход Формат? Короткий ответ + ссылка на пункт; или структурированный JSON
Отказ Когда не отвечать? Нет источника; вне списка контроля доступа (ACL, Access Control List); устаревшая версия
Эскалация Когда к человеку? Класс риска «высокий»; конфликт двух документов
Язык ru / en / mixed? Ответ на языке вопроса
Тон Формальный / операторский? Без сленга; без «уверенности» без источника
Источник истины Что факт? Актуальная версия документа в СЭД, не чат

Контракт — основа рубрики. Без него два эксперта напишут два «правильных» ответа разной длины и структуры, и модель выучит среднее из шума. Согласие между разметчиками падает не из‑за «сложной задачи», а из‑за отсутствия правил.

Связь с решением «нужен ли fine-tuning вообще»: если контракт закрывается поиском по корпусу и жёстким шаблоном ответа, сначала проверьте критерии, когда дообучение оправдано. SFT имеет смысл, когда нужно устойчивое поведение (формат, отказ, тон, доменный жаргон), которое промптом и RAG не удерживается стабильно.

Схема записи и шаблон диалога

Минимальная запись для instruction tuning — не «текст целиком», а поля, которые переживают смену чекпоинта и библиотеки обучения.

{
  "id": "sft-reg-0142",
  "messages": [
    {"role": "system", "content": "…одна версия системной инструкции…"},
    {"role": "user", "content": "Можно ли хранить СИЗ без журнала выдачи?"},
    {"role": "assistant", "content": "По регламенту v3.2, п. 4.1 — нет. …"}
  ],
  "meta": {
    "domain": "ot_pb",
    "intent": "policy_qa",
    "doc_version": "3.2",
    "language": "ru",
    "refusal": false,
    "source": "editor",
    "difficulty": "medium"
  }
}

Правила, которые экономят недели отладки:

  1. Одна версия системной инструкции на манифест набора (или явное поле system_version). Смешивать пять промптов в одном JSONL — обучать модель на конфликте политик.
  2. id стабилен между версиями корпуса: правка ответа не должна плодить «новый» кейс без следа.
  3. Метаданные для срезов: домен, намерение, версия документа, язык, отказ, источник (редактор / синтетика / прод). Без них нельзя ответить, «на каком срезе упали».
  4. Шаблон чата совместим с тем, что будет в проде. Если в проде нет system, не учите на длинном system, которого не будет при вызове.

Для классификации и извлечения структура может быть проще (input / label / spans), но принцип тот же: схема + метаданные + версия манифеста.

Источники: эксперты, прод, синтетика, перепись

Четыре типичных источника — у каждого свой риск.

Источник Плюс Риск Как использовать
Редакторы эталонов Факты и тон домена Дорого, медленно Ядро покрытия и все отказы высокого риска
Логи эксплуатации Реальные формулировки Персональные данные, ACL, шум, устаревшее После фильтра и ревью; не копировать ответ модели как истину
Синтетика (LLM) Объём и вариации Галлюцинации, однообразие стиля Черновик → обязательное ревью; квота «синтетика ≤ N%»
Перепись / транскрипция Эталонный тон организации Узкое покрытие Хорошо для формата; плохо как единственный источник намерений

Практика, которая работает в корпоративных пилотах: ядро 30–40% пишет или утверждает эксперт; периферия расширяется синтетикой по шаблонам намерений; хвост пополняется из буфера провалов после ревью. Синтетика без квоты и без рубрики быстро заполняет корпус «уверенным средним» — модель становится вежливой и пустой.

Не путайте «модель сгенерировала пару» с «пара проверена». Для доменов с ценой ошибки (охрана труда, финансы, смежные с медициной) финальный статус записи — только после человека. Роль редактора эталонов подробнее выйдет в спутнике серии; здесь достаточно правила: синтетика не подписывает манифест.

Объём, покрытие и разнообразие

Вопрос «сколько примеров нужно?» без карты покрытия бессмысленен. Ориентиры из практики (не догма):

Тип задачи Рабочий старт корпуса На что смотреть раньше объёма
Классификация / маршрутизация 1k–20k меток Баланс классов, путаемые классы
Instruction / диалог SFT 500–5k пар Намерения, отказы, длина, язык
Структурированный вывод (JSON) 300–3k Соблюдение схемы, редкие поля
Код / SQL под домен 500–8k Диалекты, схемы БД, опасные запросы

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

Разнообразие формулировок пользователя — отдельная ось. Если все user-реплики написал один редактор «литературным» языком, модель плохо переносит разговорный прод. Смешивайте короткие обрывочные запросы, опечатки (если они есть в проде), и формальные письма — в долях, отражающих поток, а не вкус разметчика.

Для узкой классификации на маленькой модели иногда хватает сотен качественных примеров — как в кейсе дообучения Qwen 0.6B. Для открытого диалога по регламентам без отказов и срезов даже десять тысяч пар не спасут пилот.

Отказы, эскалации и «похожие, но неверные» ответы

Корпус без отказов учит модель всегда отвечать. В корпоративном ассистенте это прямой путь к выдуманным пунктам регламента.

Минимальный набор «негативных» навыков в SFT:

  1. Отказ без источника — «в переданных фрагментах нет ответа; не выдумываю».
  2. Отказ по ACL — нет прав на документ; не пересказывать «из общих знаний».
  3. Отказ по устаревшей версии — явное указание, что документ снят с действия.
  4. Эскалация — конфликт двух норм; просьба передать специалисту по шаблону.
  5. Форматный отказ — запрос вне области (погода, шутки), если продукт это запрещает.

Доля таких кейсов часто 15–30% на старте пилота — иначе позитивный класс задавит поведение. Точная доля зависит от риска домена; важнее не процент, а наличие всех типов отказа из контракта.

«Похожие, но неверные» ответы в SFT обычно не кладут как assistant (это скорее территория предпочтений / DPO). Для SFT полезнее жёстко правильный выход и отдельные записи, где правильный выход — отказ. Если нужно научить выбирать между двумя правдоподобными формулировками, заводите семейство предпочтений отдельно — иначе один корпус будет тянуть модель в разные стороны.

Статические проверки и барьер качества перед обучением

Обучение не должно стартовать с «папки, которую кто‑то положил на диск». Минимальный барьер:

flowchart TB
  sources[Источники: редактор / прод / синтетика] --> normalize[Нормализация схемы и шаблона]
  normalize --> lint[Статические проверки]
  lint --> split[Train / dev / holdout]
  split --> trainJob[Задача SFT]
  split --> evalGate[Оценка на эталоне]
  evalGate --> release{Регрессионный барьер}
  release -->|pass| ship[Релиз адаптера]
  release -->|fail| buffer[Буфер правок корпуса]
  buffer --> sources

Проверки, которые ловят большинство бед до GPU:

  • Схема: обязательные поля, типы, допустимые role.
  • Один system на манифест (или явные версии).
  • Дедупликация по нормализованному user-тексту и по эмбеддингам «почти дублей».
  • Пересечение с эталоном оценки — ноль общих id и ноль почти одинаковых вопросов.
  • Доля отказов в заданном коридоре; пустой коридор — алерт.
  • Длина: обрезки, пустые content, гигантские вставки логов.
  • Персональные данные и секреты: токены, телефоны, внутренние URL — по политике проекта.
  • Язык: метка language совпадает с фактическим текстом на выборке аудита.

Результат барьера — манифест: версия корпуса, хэш файлов, число записей по срезам, автор утверждения, ссылка на рубрику. Без манифеста сравнивать «модель A vs B» бессмысленно: вы сравниваете ещё и разные папки данных.

Разделение с оценкой: утечки и подгонка

Типичная ловушка: взять 10% «с конца файла» в тест. Если файл сортирован по времени или по автору, тест не отражает прод. Хуже — править ответы в train, подглядывая в те же формулировки, что в отчёте для заказчика.

Практические правила:

  1. Скрытая выборка (holdout) — десятки–сотни кейсов, которые команда не открывает при итерациях промпта и корпуса. Отчёт для «мы готовы к пилоту» — только по ней или по отдельному эталону.
  2. Видимая dev-выборка — для отладки; её метрики не продавать бизнесу как финальные.
  3. Эталон оценки версионируется отдельно от train-манифеста. Можно ссылаться друг на друга («train v0.4 оценён на gold v0.3»), но не хранить эталон внутри train JSONL «для удобства».
  4. Парафраз — тоже утечка. Вопрос «Можно ли хранить СИЗ без журнала?» и «Обязателен ли журнал выдачи СИЗ?» не должны оказаться один в обучающей выборке, другой в скрытой (holdout) без явной политики. Ищите почти дубликаты.

Для RAG-оценки эталон строится иначе — см. золотые наборы для RAG. Граница: RAG-эталон проверяет поиск и опору на фрагменты; SFT-корпус учит формулировку и политику ответа. Общие вопросы между ними — кандидат на утечку, если один контур «подглядывает» в другой.

Корпоративный пример: ассистент по регламентам

Контекст: внутренний ассистент отвечает на вопросы сотрудников по актуальным регламентам. RAG уже отдаёт фрагменты; ответы всё равно «плывут» по формату и иногда дописывают пункты, которых нет во фрагментах.

Контракт: ответ только по переданным фрагментам; обязательно doc_id и версия; при отсутствии — отказ; тон формальный.

Корпус v0.2 (пример распределения):

Срез Доля Кто утверждает
Успешный ответ с цитатой 55% Редактор + выборочный аудит
Отказ: нет во фрагментах 15% Редактор
Отказ: устаревший документ 10% Редактор
Конфликт двух норм → эскалация 10% Юрист / соответствие требованиям
Вне области продукта 5% Редактор
Короткий разговорный запрос 5% Из логов после фильтра

Синтетика использовалась только для перефразов успешных и «нет во фрагментах» — с квотой 25% и обязательным ревью. После двух недель пилота в буфер попали провалы «уверенный ответ при пустой выдаче поиска» — их добавили как отказы в v0.3, а не как новые «успешные» фантазии.

Метрика для релиза адаптера: не средний «похоже на эталон», а доля нарушений контракта на holdout (выдуманный пункт, нет версии, ответ при пустом контексте) ниже порога.

Промышленный пример: операторские инструкции

Контекст: киоск или планшет в цехе; модель помогает оператору найти шаг инструкции и допустимые отклонения. Ошибка дороже, чем в офисном чате.

Отличия корпуса:

  • Короткие реплики, шум распознавания речи, смешанный язык (русский + коды оборудования).
  • Жёсткий отказ при «как обойти блокировку» и при запросах вне смены/допуска.
  • Много метаданных: линия, тип станка, версия техкарты, уровень допуска.

Здесь объём SFT часто меньше, чем кажется нужным маркетингу: 800–1500 утверждённых пар с полным покрытием отказов и линий важнее пяти тысяч синтетических «вежливых» диалогов. Связка с реальными бланками и разрывом домена (лабораторный набор ≠ поле) — та же логика, что в разборе OCR рукописных цифр: сначала похожесть на эксплуатацию, потом масштаб.

Связь с LoRA-кейсом и соседними материалами

Узкий эксперимент «классификация вопросов → метка» хорошо показывает, что маленькая модель + чистые метки бьют большой чекпоинт с грязным набором. Не переносите этот успех один в один на открытый диалог: там единица обучения — не класс, а политика ответа, и цена «почти правильного» текста выше.

Карта чтения:

Вопрос Материал
Нужен ли fine-tuning? Когда нужно дообучение
Как устроены семейства данных? Инженерия датасетов
Как мерить до прода? Оценка LLM перед запуском
Эталон только для RAG Эталонный набор для RAG
Кейс классификации Fine-tuning Qwen 0.6B

Этот текст закрывает вопрос: как спроектировать корпус, если решение «дообучаем» уже принято.

Типичные ошибки

Папка из чата без схемы. Разные system, разные форматы, нет id — воспроизводимость нулевая.

Ноль отказов. Модель учится быть полезной всегда; в проде это галлюцинации с уверенным тоном.

Синтетика на 90% без ревью. Красивые графики лосса, пустой пилот.

Обучение на эталоне оценки. Метрики радуют до первого чужого запроса.

Один автор всех user-реплик. Разрыв с реальным языком сотрудников или операторов.

Смешение SFT и предпочтений в одном файле. Модель не понимает, учить ей «единственный правильный ответ» или «что чаще нравится».

Нет манифеста. Нельзя откатить корпус и нельзя объяснить регрессию.

Игнорирование ACL и персональных данных в логах. Юридический долг и долг по безопасности в том же JSONL, что и обучение.

Что сделать сегодня

  1. Запишите контракт пары на одну страницу: вход, выход, отказ, эскалация, тон.
  2. Выпишите карту покрытия намерений × условий и отметьте пустые ячейки — это очередь разметки, не «ещё LoRA».
  3. Добавьте в черновик корпуса не меньше пяти отказов каждого типа из контракта.
  4. Прогоните статический барьер (схема, дедуп, пересечение с оценочным набором) до первого запуска обучения.
  5. Назначьте владельца манифеста SFT-корпуса — человека, без чьей подписи файл не попадает в задачу обучения.

Часто задаваемые вопросы (FAQ)

Сколько примеров нужно для SFT?

Столько, чтобы закрыть карту покрытия и коридор отказов, а не «как у всех в статье». Для узкой классификации часто хватает сотен–пары тысяч качественных меток; для диалога по политикам — обычно сотни–несколько тысяч стратифицированных пар. Лучше 700 утверждённых, чем 7 000 синтетических без редактора.

Можно ли строить весь корпус синтетикой?

Как черновик и для расширения перефразов — да, с квотой и ревью. Как единственный источник истины в домене с ценой ошибки — нет. Синтетика ускоряет, эксперт подписывает.

Нужна ли системная инструкция в каждой записи?

Нужна согласованность с продом. Если в проде системная инструкция фиксирована, храните одну версию на манифест или дублируйте одно и то же поле осознанно. Пять конфликтующих system в одном корпусе — способ научить модель игнорировать политику.

Чем SFT-корпус отличается от эталона для CI?

Эталон для CI маленький, стабильный, с жёсткой рубрикой — им измеряют. SFT-корпус учит и может быть шире; его меняют чаще. Оценивать релиз только на случайной подвыборке train — ошибка методологии.

Когда переходить от SFT к данным предпочтений?

Когда формат и факты в целом держатся, но нужно стабильно выбирать между двумя допустимыми ответами (короче / полнее, с цитатой / без). Это отдельное семейство и отдельная статья серии; не смешивайте пары chosen/rejected с единственным assistant в одном JSONL без политики.

Как не утянуть персональные данные из логов в корпус?

Фильтр до разметки, маскирование по политике, запрет сырых трасс в git без сканера, выборочный аудит. Запись из прода без ревью — не «быстрый SFT», а утечка в обучающую выборку.

Дальше в серии

  • Инженерия датасетов: обзор — рамка семейств и жизненного цикла.
  • Редакторы эталонов — рубрика и согласование (golden-editors-annotation-workflow-2026).
  • Обучение / оценка / скрытая выборка и утечки (dataset-splits-leakage-2026).
  • Данные предпочтений: DPO и пары (preference-dataset-rlhf-2026).
  • Синтетика и гибридный конвейер (synthetic-human-dataset-pipeline-2026).