Подготовка датасета для дообучения LLM

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Подготовка датасета для дообучения LLM
Средняя
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1240
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1167
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    867
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1084
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    829

Подготовка датасета для дообучения LLM

Качество датасета — главный фактор успеха fine-tuning. "Мусор на входе — мусор на выходе" работает вдвойне для LLM: плохо структурированные или нерелевантные примеры не просто не помогают — они активно деградируют модель. 1000 качественных примеров лучше 100,000 плохих.

Форматы датасетов для fine-tuning

Instruction following (Alpaca формат):

{"instruction": "Переведи на английский", "input": "Привет мир", "output": "Hello world"}
{"instruction": "Напиши SQL запрос", "input": "Выбери всех пользователей старше 30", "output": "SELECT * FROM users WHERE age > 30;"}

Chat format (ShareGPT/ChatML):

{
  "conversations": [
    {"from": "system", "value": "Ты помощник по SQL"},
    {"from": "human", "value": "Как выбрать уникальные значения?"},
    {"from": "gpt", "value": "Используй SELECT DISTINCT: `SELECT DISTINCT column FROM table;`"}
  ]
}

Completion format (простой):

{"text": "### Вопрос: Что такое RLHF?\n### Ответ: RLHF (Reinforcement Learning from Human Feedback) — метод..."}

Требования к объёму датасета

Задача Минимум примеров Оптимум
Tone/style transfer 500-1000 2000-5000
Domain adaptation 1000-3000 5000-15000
Task-specific (Q&A) 500-2000 3000-10000
Code generation 2000-5000 10000-50000
Multi-turn dialogue 1000-3000 5000-20000

Структура хорошего примера

from dataclasses import dataclass

@dataclass
class FineTuningExample:
    instruction: str    # Чёткая задача без двусмысленности
    input: str          # Конкретный контекст/данные (опционально)
    output: str         # Идеальный ответ модели

    def validate(self) -> list[str]:
        issues = []
        if len(self.output) < 10:
            issues.append("Output too short")
        if len(self.output) > 2000:
            issues.append("Output may be too long for this task")
        if self.output in ["I don't know", "N/A", ""]:
            issues.append("Uninformative output")
        # Проверка на утечку промпта в ответ
        if self.instruction.lower()[:20] in self.output.lower():
            issues.append("Output contains instruction text")
        return issues

Разделение на train/eval

from sklearn.model_selection import train_test_split

def split_dataset(examples: list, eval_ratio: float = 0.1) -> tuple:
    # Стратифицированное разделение по длине output
    short = [e for e in examples if len(e.output) < 200]
    medium = [e for e in examples if 200 <= len(e.output) < 500]
    long = [e for e in examples if len(e.output) >= 500]

    train, eval = [], []
    for group in [short, medium, long]:
        if len(group) > 1:
            tr, ev = train_test_split(group, test_size=eval_ratio)
            train.extend(tr); eval.extend(ev)

    return train, eval

Дедупликация

import hashlib
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

def deduplicate_exact(examples: list) -> list:
    """Точная дедупликация по хэшу"""
    seen = set()
    unique = []
    for ex in examples:
        h = hashlib.md5(f"{ex.instruction}{ex.input}".encode()).hexdigest()
        if h not in seen:
            seen.add(h)
            unique.append(ex)
    return unique

def deduplicate_semantic(examples: list, threshold: float = 0.95) -> list:
    """Семантическая дедупликация (убирает near-duplicates)"""
    model = SentenceTransformer('all-MiniLM-L6-v2')
    texts = [f"{e.instruction} {e.input}" for e in examples]
    embeddings = model.encode(texts, batch_size=512, show_progress_bar=True)

    keep = [True] * len(examples)
    for i in range(len(examples)):
        if not keep[i]:
            continue
        for j in range(i+1, len(examples)):
            sim = cosine_similarity([embeddings[i]], [embeddings[j]])[0][0]
            if sim > threshold:
                keep[j] = False

    return [ex for ex, k in zip(examples, keep) if k]

Финальный чеклист перед обучением

  • Нет дублей (exact и near-duplicate)
  • Нет PII в датасете (имена, emails, телефоны)
  • Output не содержит ссылок на даты/версии ("по состоянию на 2023")
  • Равномерное распределение по типам задач
  • Eval set не пересекается с train
  • Токенизированные примеры не превышают max_length модели (без truncation)