Подготовка и очистка датасетов для обучения Gemini 3
Введение: Почему данные важнее алгоритмов
Приветствую в пятом модуле. Если вы здесь, значит, вы уже переросли базовые промпты и готовы адаптировать Gemini 3 под свои уникальные задачи. Но прежде чем мы нажмем кнопку «Start Tuning», нам предстоит, пожалуй, самая кропотливая, но критически важная работа — подготовка данных.
В сообществе ML-инженеров есть поговорка: «Garbage In, Garbage Out» (Мусор на входе — мусор на выходе). Для Gemini 3 это справедливо вдвойне. Модель уже обладает колоссальными знаниями. Ваша задача при файн-тюнинге — не научить её «говорить» (она это уже умеет), а скорректировать стиль, формат или область экспертизы.
Если ваш датасет содержит противоречия, ошибки форматирования или «шум», модель не просто не выучит нужное — она может начать галлюцинировать или потерять свои базовые способности (феномен, известный как catastrophic forgetting). В этом уроке мы научимся превращать разрозненные логи в «золотой стандарт» для обучения.
Анатомия идеального датасета для Gemini 3
Для начала разберемся с форматом. Gemini 3, как и её предшественники, ожидает данные в формате JSONL (JSON Lines), где каждая строка — это отдельный валидный JSON-объект, представляющий один обучающий пример.
Ключевой паттерн для чат-моделей — это структура диалога. В отличие от старых моделей автодополнения текста, здесь мы работаем с ролями:
- system (опционально, но рекомендуется): Задает глобальный контекст или персону агента.
- user: Вводные данные, запрос или вопрос.
- model: Желаемый эталонный ответ.
Важный нюанс: Качество важнее количества. Для успешного файн-тюнинга Gemini 3 часто достаточно 500–1000 идеальных примеров, чем 50 000 «грязных». Что значит идеальный пример? Это пример, где ответ модели демонстрирует именно то поведение (тон, структуру JSON, использование инструментов), которое вы хотите закрепить.
// Пример одной строки в файле training_data.jsonl
// Обратите внимание: весь объект должен быть на одной строке, здесь разбито для читаемости
{
"messages": [
{
"role": "system",
"content": "Ты — эксперт по кибербезопасности, специализирующийся на анализе логов. Твоя задача — классифицировать инцидент и предложить решение в формате JSON."
},
{
"role": "user",
"content": "Log entry: 2024-10-25 14:02:11 Failed password for root from 192.168.1.55 port 22 ssh2"
},
{
"role": "model",
"content": "{\n \"severity\": \"high\",\n \"type\": \"brute_force_attempt\",\n \"action\": \"block_ip\",\n \"reasoning\": \"Попытка прямого входа под root является критической угрозой безопасности.\"\n}"
}
]
}
Этапы очистки данных: От сырья к золоту
Представим, что вы выгрузили историю переписки службы поддержки за год. Это «сырые» данные. Использовать их сразу нельзя. Вот чек-лист того, что необходимо сделать:
- Удаление PII (Personal Identifiable Information): Это критично. Если вы случайно обучите модель на реальных именах, адресах или кредитных картах клиентов, модель может начать выдавать их случайным пользователям.
- Дедупликация: Повторяющиеся примеры приводят к оверфиттингу (переобучению). Модель просто заучит этот конкретный ответ, вместо того чтобы понять принцип.
- Чистка «системного шума»: Фразы вроде «Как языковая модель, я не могу...», «Нажмите кнопку ниже» или HTML-теги из веб-скрейпинга должны быть удалены. Они не несут смысла для логики ответов.
- Балансировка длины: Gemini 3 имеет огромное контекстное окно, но обучение на сверхдлинных диалогах дорого и не всегда эффективно. Старайтесь держать примеры сфокусированными.
- Консистентность форматирования: Если в 50% примеров вы используете дату в формате DD/MM/YYYY, а в других — YYYY-MM-DD, модель запутается. Приведите всё к стандарту.
import json
import re
import pandas as pd
# Пример скрипта для базовой очистки датасета перед файн-тюнингом
def clean_text(text):
# 1. Удаление лишних пробелов
text = re.sub(r'\s+', ' ', text).strip()
# 2. Анонимизация email-адресов (простой пример)
text = re.sub(r'[\w\.-]+@[\w\.-]+\.\w+', '<EMAIL_REDACTED>', text)
return text
def validate_example(example):
# Проверка структуры для Gemini API
if 'messages' not in example:
return False
roles = [m['role'] for m in example['messages']]
# Диалог должен заканчиваться ответом модели
if roles[-1] != 'model':
return False
# Проверка на пустые сообщения
if any(not m.get('content') for m in example['messages']):
return False
return True
# Загрузка сырых данных
raw_data = [
{"messages": [{"role": "user", "content": "Привет! Мой email: boss@company.com"}, {"role": "model", "content": "Привет!"}]},
{"messages": [{"role": "user", "content": ""}, {"role": "model", "content": "Пустой запрос?"}]} # Этот будет удален
]
cleaned_data = []
for entry in raw_data:
# Валидация структуры
if not validate_example(entry):
continue
# Очистка контента внутри сообщений
for msg in entry['messages']:
msg['content'] = clean_text(msg['content'])
cleaned_data.append(entry)
print(f"Осталось валидных примеров: {len(cleaned_data)}")
print(json.dumps(cleaned_data[0], ensure_ascii=False, indent=2))
Стратегия разделения данных (Train / Validation / Test)
Частая ошибка новичков — загружать все имеющиеся данные в обучение. Это лишает вас возможности объективно оценить результат.
Золотое правило 80/10/10:
- 80% Training Set: На этом модель учится весам.
- 10% Validation Set: Используется во время процесса обучения. Платформа Gemini использует его для вычисления метрик потерь (Loss) на данных, которые модель еще не видела. Это помогает вовремя остановить обучение и предотвратить переобучение.
- 10% Test Set (Holdout): Эти данные вы вообще не загружаете на платформу. Вы используете их после завершения обучения, чтобы вручную или автоматически проверить, как новая модель справляется с реальными задачами.
Совет эксперта: Убедитесь, что распределение типов задач в этих сетах одинаковое. Если в Training Set у вас только вопросы про Python, а в Validation — про JavaScript, метрики будут ужасными, даже если модель обучилась нормально.
Вам предоставлен фрагмент «грязного» датасета в формате JSONL. Ваша задача — найти в нем 3 критические ошибки, которые помешают качественному обучению Gemini 3, и предложить исправленный вариант.
Использование синтетических данных
Что делать, если у вас нет 1000 диалогов? Здесь на сцену выходит генерация синтетических данных. Это одна из самых мощных техник современной инженерии данных.
Идея проста: используйте самую мощную модель (например, Gemini 1.5 Pro или Ultra) для генерации примеров обучения для более компактной и быстрой модели (например, Gemini Flash), которую вы хотите зафайнтюнить.
Пайплайн выглядит так:
- Создайте 10–20 идеальных примеров вручную (Few-Shot Prompting).
- Подайте их в Gemini Pro с промптом: «На основе этих примеров сгенерируй еще 50 аналогичных сценариев, сохраняя JSON-структуру и тональность».
- Проведите валидацию (человеком или скриптом), чтобы отсеять галлюцинации.
- Используйте полученный dataset для обучения.
Этот метод называется Model Distillation (дистилляция знаний). Он позволяет получить качественную специализированную модель за копейки.
Какая проблема наиболее вероятна, если в вашем обучающем датасете много дублирующихся примеров?