← Усі статті

Датасет для 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); застаріла версія
Ескалація Коли до людини? Клас ризику «високий»; конфлікт двох документів
Мова uk / 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": "uk",
    "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 фіксований, зберігайте одну версію на маніфест або дублюйте те саме поле свідомо. П’ять конфліктуючих 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).