English translation is not available yet. Showing Russian content.

Как вы генерируете synthetic данные для instruction tuning?

Краткий тезис

Synthetic data (синтетические данные) для instruction tuning (дообучения по инструкциям) создаются с помощью LLM, которая сама генерирует пары «инструкция — ответ». Основные методы: Self-Instruct (генерация инструкций и ответов одной моделью), Evol-Instruct (мутация инструкций для усложнения) и Magpie (диалоги модели с собой). Ключевой этап — фильтрация качества через LLM-as-judge, чтобы отсеять нерелевантные или некорректные примеры. Оптимальный объём — 10k–100k инструкций, достаточный для большинства задач.


1. Что такое synthetic data и зачем он нужен для instruction tuning

Synthetic data — это искусственно сгенерированные данные, имитирующие реальные примеры. В контексте instruction tuning (дообучение LLM на наборе инструкций и ожидаемых ответов) синтетические данные позволяют:

  • Расширить обучающий набор без ручной разметки, которая дорога и медленна.
  • Покрыть редкие сценарии и краевые случаи, которые сложно собрать из реальных диалогов.
  • Контролировать распределение тем, сложности и стилей ответов.

Instruction tuning превращает базовую LLM в ассистента, способного следовать инструкциям. Без качественных данных модель будет плохо понимать, что от неё хотят.


2. Self-Instruct: генерация инструкций и ответов одной моделью

Self-Instruct — метод, предложенный в одноимённой статье (2022). Процесс:

  1. Seed-инструкции — небольшой набор (например, 175) вручную написанных примеров.
  2. Генерация инструкций — LLM получает seed-примеры и генерирует новые инструкции (например, «Напиши рецепт борща»).
  3. Генерация ответов — для каждой инструкции LLM генерирует ответ.
  4. Фильтрация — удаляются дубликаты, инструкции без смысла, слишком короткие ответы.
  5. Итерация — процесс повторяется, пока не наберётся нужное количество.

Пример кода (упрощённый):

import openai

def generate_instruction(seed_examples):
    prompt = "Сгенерируй новую инструкцию, похожую на эти:\n" + "\n".join(seed_examples)
    response = openai.ChatCompletion.create(model="gpt-4", messages=[{"role": "user", "content": prompt}])
    return response.choices[0].message.content

def generate_response(instruction):
    response = openai.ChatCompletion.create(model="gpt-4", messages=[{"role": "user", "content": instruction}])
    return response.choices[0].message.content

Проблемы Self-Instruct

  • Модель может генерировать тривиальные или повторяющиеся инструкции.
  • Качество ответов ограничено возможностями самой модели.

3. Evol-Instruct: мутация инструкций для усложнения

Evol-Instruct (из WizardLM) решает проблему однообразия. Вместо генерации с нуля, он мутирует существующие инструкции:

  • Усложнение — добавляет ограничения (например, «используй не более 50 слов»).
  • Конкретизация — заменяет общие слова на конкретные (например, «животное» → «собака породы хаски»).
  • Добавление constraint — требует определённого формата ответа (таблица, JSON, список).

Этапы

  1. Берётся базовая инструкция.
  2. LLM получает промпт: «Усложни эту инструкцию, добавив дополнительное требование».
  3. Генерируется новая инструкция.
  4. Для неё генерируется ответ.
  5. Фильтрация: проверяется, что новая инструкция действительно сложнее (LLM-as-judge).

Пример мутации

  • Исходная: «Напиши стихотворение о зиме».
  • Мутированная: «Напиши стихотворение о зиме в стиле хайку, используя только слова, начинающиеся на букву "с"».

Преимущество данные становятся более разнообразными и сложными, что улучшает способность модели следовать сложным инструкциям.


4. Magpie: диалоги модели с собой

Magpie (2024) — метод, при котором модель генерирует диалоги между пользователем и ассистентом, играя обе роли. Процесс:

  1. Модели даётся системный промпт: «Ты — пользователь, который задаёт вопросы ассистенту».
  2. Модель генерирует сообщение пользователя.
  3. Затем модель переключается на роль ассистента и генерирует ответ.
  4. Шаги повторяются, создавая многошаговый диалог.

Пример:

User: Как приготовить пасту карбонара?
Assistant: Для этого вам понадобятся: спагетти, яйца, бекон, пармезан...
User: А можно без бекона?
Assistant: Да, можно заменить на грибы или тофу...

Преимущество диалоги более естественны, чем изолированные инструкции, и лучше учат модель контексту.


5. Другие методы генерации synthetic data

  • Обратная инструкция (Reverse Instruction): из текста (например, статьи) генерируется инструкция, на которую этот текст является ответом.
  • Генерация на основе seed-тем: задаётся список тем, для каждой LLM генерирует инструкцию и ответ.
  • Data Augmentation через парафраз: существующие инструкции переписываются с сохранением смысла.

6. Проверка качества: LLM-as-judge и фильтрация

Сгенерированные данные содержат шум. Обязательный этап — фильтрация с помощью LLM-as-judge (другая LLM, оценивающая качество).

Критерии оценки

  • Инструкция понятна (чёткая, однозначная)
  • Ответ корректен (фактически верен, релевантен)
  • Ответ полный (не слишком короткий, не уходит в сторону)
  • Нет токсичности или предвзятости

Пример промпта для judge

Оцени инструкцию и ответ по шкале от 0 до 1 по трём критериям:
1. Ясность инструкции
2. Корректность ответа
3. Полнота ответа
Верни JSON: {"clarity": 0.9, "correctness": 0.8, "completeness": 0.7}

Фильтрация оставляем только примеры со средним баллом >0.8. Можно также использовать rule-based фильтры (длина, наличие ключевых слов).


7. Объём данных: сколько нужно?

ОбъёмПрименимость
1k–5kМинимальный набор для экспериментов, но модель может не обобщать.
10k–50kДостаточно для большинства задач (чат-боты, QA, суммаризация).
50k–100kХорошо для сложных сценариев (многошаговые диалоги, инструменты).
>100kИзбыточно, если данные однообразны; лучше сфокусироваться на качестве.

Правило 10k–100k инструкций — золотая середина. Качество важнее количества: 10k отфильтрованных примеров лучше 100k сырых.


8. Инструменты и библиотеки

  • datasets (Hugging Face) — хранение и загрузка synthetic data.
  • trl (Transformer Reinforcement Learning) — обучение с SFT (supervised fine-tuning).
  • Axolotl — фреймворк для fine-tuning, поддерживает synthetic data.
  • OpenAI / Anthropic API — генерация данных (осторожно с затратами).
  • LangChain — пайплайны генерации и фильтрации.

Пример пайплайна

from datasets import Dataset
import openai

# Генерация 1000 инструкций через Self-Instruct
instructions = []
for _ in range(1000):
    instr = generate_instruction(seed_examples)
    resp = generate_response(instr)
    instructions.append({"instruction": instr, "response": resp})

# Фильтрация через judge
filtered = []
for item in instructions:
    score = judge(item["instruction"], item["response"])
    if score > 0.8:
        filtered.append(item)

dataset = Dataset.from_list(filtered)
dataset.save_to_disk("synthetic_data")

9. Best practices

  • Итеративное улучшение: сгенерируйте первую партию, обучите модель, протестируйте на реальных запросах, донастройте промпты генерации.
  • Баланс разнообразия: следите, чтобы не было перекоса в одну тему (например, только кулинария). Используйте seed-темы из разных доменов.
  • Контроль сложности: смешивайте простые и сложные инструкции, чтобы модель училась на всём спектре.
  • Избегайте галлюцинаций: если ответ содержит факты, проверяйте их через внешние источники (например, Wikipedia API).
  • Документируйте процесс: фиксируйте промпты, версии моделей, параметры фильтрации — это упростит воспроизводимость.

10. Ограничения и риски

  • Галлюцинации в ответах: модель может генерировать неверные факты, которые затем будут усилены при обучении.
  • Bias (предвзятость): если seed-данные содержат стереотипы, synthetic data их унаследует.
  • Переобучение на стиль генерации: модель может научиться имитировать «синтетический» стиль, а не реальные диалоги.
  • Затраты: генерация 100k примеров через GPT-4 может стоить сотни долларов.
  • Отсутствие обратной связи: synthetic data не содержит информации о том, был ли ответ полезен пользователю (как в RLHF).

Пет-проект для закрепления

Задача Создать датасет synthetic data для дообучения модели-ассистента, специализирующегося на помощи в написании кода на Python.

Инструменты Python, OpenAI API, Hugging Face datasets, trl.

Шаги:

  1. Соберите 50 seed-примеров: пары «инструкция — код» (например, «Напиши функцию для сортировки списка» → код).
  2. Реализуйте Self-Instruct: используйте GPT-4 для генерации новых инструкций и ответов (кода). Ограничьте темы: алгоритмы, работа с файлами, API.
  3. Примените Evol-Instruct: для каждой инструкции попросите GPT-4 усложнить её (добавить обработку ошибок, оптимизацию).
  4. Отфильтруйте через LLM-as-judge: проверьте, что код компилируется (запустите в песочнице) и соответствует инструкции.
  5. Сохраните датасет в формате Hugging Face Datasets.
  6. Обучите небольшую модель (например, Phi-3) на 5000 примерах с помощью SFT.
  7. Протестируйте: задайте модели 10 новых вопросов по коду и оцените качество ответов.

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


Связь с другими вопросами

ВопросТема
515Как оценивать качество synthetic data?
516Как fine-tune LLM на synthetic data?
517Какие методы data augmentation для LLM существуют?
518В чём разница между instruction tuning и RLHF?
519Как работает Self-Instruct на практике?

Навигация