Оценка качества дообученной модели и итеративное улучшение
Введение: Почему fine-tuning — это только начало
Добро пожаловать на урок, который часто отделяет успешные ML-проекты от неудачных экспериментов. Вы уже прошли этап подготовки данных и запустили процесс обучения (fine-tuning) модели Gemini. В консоли Google AI Studio или через API вы видите статус «Succeeded». Казалось бы, можно открывать шампанское?
Не спешите. Тот факт, что модель дообучилась, означает лишь то, что процесс не упал с ошибкой. Это не гарантирует, что модель стала умнее, полезнее или безопаснее. Более того, существует риск «катастрофического забывания» (catastrophic forgetting), когда модель, улучшаясь в одной узкой задаче, теряет общие знания или способность логически рассуждать.
В этом уроке мы отойдем от слепого доверия алгоритмам и перейдем к инженерному подходу. Мы научимся измерять качество модели, выявлять переобучение и, самое главное, выстраивать цикл итеративного улучшения. Мы рассмотрим как количественные метрики (числа), так и качественные (оценка «глазами» и с помощью других моделей).
Количественная оценка: Loss Curves и что они скрывают
Первое, с чем вы сталкиваетесь после обучения — это графики функции потерь (Loss Curves). В контексте Gemini API вы получаете доступ к метрикам обучения. Давайте разберем, как их читать, как кардиограмму пациента.
1. Training Loss (Потери на обучении)
Это показатель того, насколько хорошо модель предсказывает следующий токен на тех данных, которые она видит прямо сейчас. В идеальном мире эта кривая должна плавно стремиться вниз.
- Если не падает: Возможно, данные слишком «грязные», learning rate (скорость обучения) слишком низкий, или данные противоречат друг другу.
- Если падает слишком быстро: Модель может просто «заучивать» примеры, а не учить закономерности.
2. Evaluation/Validation Loss (Потери на валидации)
Это критически важная метрика. Она рассчитывается на отложенной выборке данных, которую модель не видела при обучении. Именно расхождение между Training Loss и Validation Loss говорит нам о качестве.
Классический сценарий переобучения (Overfitting): Training Loss продолжает падать, а Validation Loss начинает расти. Это значит, модель начала «зубрить» ответы из тренировочного сета, но потеряла способность к обобщению на новых данных. В этот момент обучение нужно было остановить.
# Пример того, как можно визуализировать метрики обучения,
# если вы экспортировали их из истории обучения Gemini API (обычно это JSON или CSV).
import matplotlib.pyplot as plt
import pandas as pd
# Представим, что у нас есть данные обучения в DataFrame
data = {
'epoch': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'training_loss': [2.5, 1.8, 1.2, 0.9, 0.7, 0.5, 0.45, 0.4, 0.38, 0.35],
'validation_loss': [2.6, 1.9, 1.4, 1.1, 1.0, 1.2, 1.5, 1.8, 2.2, 2.5]
}
df = pd.DataFrame(data)
plt.figure(figsize=(10, 6))
plt.plot(df['epoch'], df['training_loss'], label='Training Loss', marker='o')
plt.plot(df['epoch'], df['validation_loss'], label='Validation Loss', marker='x', linestyle='--')
plt.title('Анализ кривых обучения: Обнаружение Overfitting')
plt.xlabel('Эпоха (Epoch)')
plt.ylabel('Loss (Функция потерь)')
plt.legend()
plt.grid(True)
# Добавим аннотацию в точку перелома
plt.annotate('Начало переобучения!',
xy=(5, 1.0),
xytext=(6, 1.5),
arrowprops=dict(facecolor='red', shrink=0.05))
plt.show()
# В данном примере видно, что после 5-й эпохи модель перестала учиться
# обобщать и начала просто запоминать тренировочные данные.
Качественная оценка: Методология «LLM-as-a-Judge»
Графики потерь необходимы, но недостаточны. Низкий Loss не гарантирует, что модель не галлюцинирует или соблюдает нужный Tone of Voice (TOV). Для языковых моделей «золотым стандартом» оценки сейчас является использование более мощной модели для проверки работы дообученной.
Этот метод называется LLM-as-a-Judge (LLM как судья). Суть проста: вы берете тестовый набор (промпты), прогоняете их через вашу fine-tuned модель, а затем просите более мощную модель (например, Gemini 1.5 Pro или Ultra) оценить ответ по заданным критериям.
Критерии оценки могут включать:
- Фактическая точность: Противоречит ли ответ предоставленному контексту?
- Форматирование: Соблюден ли требуемый JSON/XML/Markdown формат?
- Стиль: Соответствует ли ответ заданной персоне (например, «дружелюбный саппорт» или «строгий юрист»)?
Ниже приведен пример скрипта для автоматизированной оценки.
import google.generativeai as genai
import time
# Настройка API (предполагаем, что ключи уже настроены)
# genai.configure(api_key="YOUR_API_KEY")
# 1. Ваша дообученная модель
finetuned_model_name = "tunedModels/my-special-assistant-v1"
finetuned_model = genai.GenerativeModel(model_name=finetuned_model_name)
# 2. Модель-судья (используем самую мощную доступную версию)
judge_model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest")
# Тестовый набор данных: [Prompt, Ideal_Answer (Ground Truth)]
test_cases = [
("Как сбросить пароль?", "Зайдите в настройки -> Безопасность -> Сменить пароль."),
("Где находится офис?", "Наш офис расположен по адресу: ул. Пушкина, д. 10.")
]
def evaluate_response(user_prompt, model_response, ground_truth):
"""
Функция просит судью оценить ответ по шкале 1-5.
"""
judge_prompt = f"""
Ты - строгий критик AI-ассистентов.
Оцени ответ модели по шкале от 1 до 5, где 5 - идеальное совпадение по смыслу и стилю.
Вопрос пользователя: {user_prompt}
Эталонный ответ (Ground Truth): {ground_truth}
Ответ модели: {model_response}
Выведи ТОЛЬКО число от 1 до 5.
"""
try:
evaluation = judge_model.generate_content(judge_prompt)
return evaluation.text.strip()
except Exception as e:
return "Error"
print("--- Запуск оценки ---")
for prompt, ground_truth in test_cases:
# Генерация ответа дообученной моделью
response = finetuned_model.generate_content(prompt)
model_output = response.text
# Оценка судьей
score = evaluate_response(prompt, model_output, ground_truth)
print(f"Вопрос: {prompt}")
print(f"Ответ модели: {model_output}")
print(f"Оценка судьи: {score}/5")
print("-" * 30)
# Пауза, чтобы не упереться в лимиты API
time.sleep(1)
Типология ошибок и итеративное улучшение
Получив результаты оценки, вы неизбежно столкнетесь с ошибками. Ключ к улучшению — правильная классификация этих ошибок. Просто добавить «больше данных» не всегда помогает, а иногда и вредит.
Категории ошибок и методы лечения:
- Галлюцинации (Hallucinations): Модель придумывает факты, которых не было в обучающей выборке.
Решение: Проверьте обучающие данные на наличие противоречий. Если модель должна отвечать «Я не знаю» на неизвестные вопросы, убедитесь, что в датасете есть примеры с ответом «Я не знаю», а не выдуманные факты. - Нарушение формата (Format Drift): Вы просили JSON, а получили текст с JSON внутри.
Решение: Увеличьте количество примеров (Over-sampling) именно с жесткой структурой формата в датасете. Добавьте negative examples (примеры того, как НЕ надо делать, хотя в fine-tuning лучше работают позитивные примеры). - Потеря тональности (Tone Mismatch): Модель отвечает сухо, хотя вы учили ее быть эмпатичной.
Решение: Пересмотрите System Instructions, которые вы добавляете при инференсе. Fine-tuning задает стиль, но системный промпт все еще имеет огромный вес. Также проверьте, не слишком ли много «сухих» данных в датасете. - Катастрофическое забывание: Модель разучилась делать базовые вещи (например, переводить текст), сосредоточившись на вашей узкой задаче.
Решение: Смешайте ваш специфический датасет с небольшим количеством общих инструкций (General Purpose Data). Это напомнит модели о ее базовых возможностях.
Представьте, что вы дообучили модель для технической поддержки интернет-провайдера. <br>Ниже приведены три неудачных ответа модели на тестовой выборке.<br>Для каждого случая определите тип ошибки и предложите конкретное действие для следующей итерации обучения.<br><br>1. Вопрос: "У меня нет интернета, горит красная лампа LOS". <br> Ответ модели: "Попробуйте испечь пирог, это успокаивает."<br><br>2. Вопрос: "Какая скорость на тарифе 'Геймер'?"<br> Ответ модели: "Скорость составляет 500 Мбит/с. (Примечание: на самом деле 800 Мбит/с в текущих тарифах)".<br><br>3. Вопрос: "Верните JSON со статусом заявки 12345".<br> Ответ модели: "Конечно! Вот ваш статус: {status: 'active'}. Надеюсь, я помог!"
Стратегия итераций: Цикл улучшения
Разработка агентов на базе LLM — это не водопадная модель (Waterfall), это чистый Agile. Ваш процесс должен выглядеть так:
- Базовый Fine-tuning: Запуск на небольшом наборе (50-100 примеров) высокого качества.
- Оценка (Eval): Прогон на тестовом сете, использование LLM-судьи.
- Анализ ошибок: Ручной просмотр 20-50 неудачных ответов.
- Корректировка данных (Data Curation): Исправление ошибок в данных, добавление новых примеров для покрытия edge-cases (граничных случаев).
- Повторный Fine-tuning: Обучение новой версии модели.
Совет эксперта: Не меняйте гиперпараметры (эпохи, learning rate) в первых 2-3 итерациях. 90% проблем решаются улучшением качества данных, а не настройкой параметров обучения. Только когда данные вычищены до блеска, можно экспериментировать с увеличением количества эпох для лучшего запоминания.
Вы анализируете графики обучения вашей модели Gemini. Вы заметили, что Training Loss упал почти до нуля, а Validation Loss начал резко расти вверх после 5-й эпохи. О чем это говорит и что нужно сделать?