Оценка качества дообученной модели: Метрики и бенчмарки
Введение: Иллюзия снижения Loss-функции
Добро пожаловать на один из самых критически важных этапов работы с LLM. Вы успешно запустили процесс файн-тюнинга, потратили вычислительные ресурсы, и на дашборде видите красивый график: кривая функции потерь (Loss) стремительно падает вниз. Интуиция подсказывает: «Отлично, модель обучается!».
Но здесь кроется главная ловушка инженера машинного обучения. Низкий Loss не гарантирует, что модель стала лучше решать вашу бизнес-задачу. Он лишь означает, что модель стала лучше предсказывать следующий токен в вашем конкретном датасете. Это может означать две вещи:
- Модель действительно усвоила стиль и знания (хорошо).
- Модель просто «зазубрила» примеры и потеряла способность к обобщению или «сломалась» в других аспектах (плохо, оверфиттинг).
В этом уроке мы отойдем от абстрактных графиков обучения и перейдем к жесткой эмпирике. Как доказать бизнесу или самому себе, что кастомная Gemini 3 работает лучше базовой? Мы разберем иерархию метрик: от простых n-gram сравнений до использования одной нейросети для оценки другой (LLM-as-a-Judge) и проверки агентских способностей.
Уровень 1: Классические метрики (NLP Legacy)
Прежде чем переходить к продвинутым методам, нужно понимать базу. Эти метрики пришли к нам из эпохи машинного перевода до трансформеров. Они быстрые, дешевые, но «глупые».
ROUGE (Recall-Oriented Understudy for Gisting Evaluation)
Используется преимущественно для задач саммаризации (summarization). Сравнивает n-граммы (последовательности из n слов) в сгенерированном тексте и в эталонном (reference).
- ROUGE-N: Совпадение N-грамм.
- ROUGE-L: Самая длинная общая подпоследовательность (учитывает структуру предложения).
BLEU (Bilingual Evaluation Understudy)
Стандарт де-факто для машинного перевода. Фокусируется на точности (Precision) — сколько слов из генерации действительно присутствуют в эталоне.
Проблема классики в эру LLM: Представьте, что эталонный ответ — «Клиент недоволен сервисом». Модель сгенерировала: «Пользователь в ярости от обслуживания». Смысл идентичен, но пересечение по словам минимально. ROUGE и BLEU покажут низкий балл, хотя модель отработала идеально. Поэтому для задач генерации контента, чат-ботов и креатива эти метрики используются всё реже.
# Пример использования библиотеки rouge-score для быстрой оценки
# Это полезно для задач экстракции, где важна точность формулировок
from rouge_score import rouge_scorer
def calculate_rouge(reference: str, candidate: str):
"""
Вычисляет ROUGE метрики между эталоном и генерацией.
"""
scorer = rouge_scorer.RougeScorer(['rouge1', 'rougeL'], use_stemmer=True)
scores = scorer.score(reference, candidate)
print(f"Reference: {reference}")
print(f"Candidate: {candidate}")
print(f"ROUGE-1 (Unigram): {scores['rouge1'].fmeasure:.4f}")
print(f"ROUGE-L (LCS): {scores['rougeL'].fmeasure:.4f}")
# Пример, где метрика работает хорошо (экстракция)
ref_extraction = "ID заказа: 12345"
cand_extraction = "Заказ: 12345"
calculate_rouge(ref_extraction, cand_extraction)
# Пример, где метрика может обмануть (синонимия)
ref_chat = "Я очень рад вас видеть."
cand_chat = "Какое счастье лицезреть вас!"
calculate_rouge(ref_chat, cand_chat)
# Результат будет низким, хотя смысл сохранен.
Уровень 2: Семантическая близость (Embeddings)
Чтобы решить проблему синонимов, мы используем Embedding Distance. Мы превращаем и эталон, и ответ модели в векторы (используя, например, модель text-embedding-004 от Google) и измеряем косинусное сходство (Cosine Similarity) между ними.
Если вектор ответа модели смотрит в ту же сторону, что и вектор эталона, значит, смысл сохранен, даже если слова разные. Это «золотая середина» для задач Retrieval Augmented Generation (RAG) и вопросно-ответных систем.
Уровень 3: LLM-as-a-Judge (Судья с искусственным интеллектом)
Это современный стандарт (State-of-the-Art) для оценки качества Gemini 3. Идея проста: кто лучше оценит текст, написанный нейросетью? Другая, более мощная нейросеть.
В этом подходе мы используем сильную модель (например, Gemini 1.5 Pro или Ultra) в роли «Судьи». Мы скармливаем ей:
- Вопрос пользователя (Prompt).
- Эталонный ответ (если есть).
- Ответ нашей дообученной модели.
- Рубрику оценки (Evaluation Rubric).
Судья должен выставить оценку (например, от 1 до 5) и, что самое важное, объяснить своё решение.
Почему это работает?
LLM отлично понимают нюансы, тон, стиль и логические ошибки. Они могут оценить такие критерии, как «Полезность», «Безопасность», «Сарказм» или «Соответствие бренд-войсу».
Риски метода (Bias)
- Position Bias: Судья часто предпочитает первый из двух представленных вариантов. Решение: менять местами ответы (swapping) и усреднять результат.
- Verbosity Bias: Судьи любят более длинные ответы, даже если они водянистые.
- Self-Preference: Модели от Google могут ставить более высокие оценки текстам, сгенерированным моделями Google (из-за схожести паттернов обучения).
import google.generativeai as genai
import json
# Предполагается, что API ключ уже настроен
# genai.configure(api_key="YOUR_KEY")
def llm_judge_evaluate(query, response, criteria):
"""
Использует Gemini Pro как судью для оценки ответа файн-тюненой модели.
"""
judge_model = genai.GenerativeModel('gemini-1.5-pro-latest')
evaluation_prompt = f"""
Ты - экспертный судья по оценке качества AI-ассистентов.
ЗАДАЧА:
Оцени ответ AI-модели на вопрос пользователя по шкале от 1 до 5.
КРИТЕРИЙ ОЦЕНКИ: {criteria}
ВХОДНЫЕ ДАННЫЕ:
[Вопрос пользователя]: {query}
[Ответ модели]: {response}
ФОРМАТ ВЫВОДА (JSON):
{{
"score": int,
"reasoning": "строка с объяснением"
}}
"""
try:
result = judge_model.generate_content(
evaluation_prompt,
generation_config={"response_mime_type": "application/json"}
)
return json.loads(result.text)
except Exception as e:
return {"error": str(e)}
# Пример использования
user_q = "Объясни квантовую запутанность пятилетнему ребенку."
model_ans = "Это когда две частицы ведут себя как близнецы, чувствующие друг друга на расстоянии. Если пощекотать одну, вторая засмеется, даже если она на Луне."
crit = "Доступность объяснения и точность аналогии."
score = llm_judge_evaluate(user_q, model_ans, crit)
print(json.dumps(score, indent=2, ensure_ascii=False))
Оценка Агентов и Структурированного вывода
В контексте Gemini 3 API мы часто дообучаем модели не просто «болтать», а выполнять действия (Function Calling) или возвращать строгий JSON. Здесь метрики меняются с «качества текста» на «работоспособность».
Метрики для Агентов:
- Ssyntactic Correctness (Валидность синтаксиса): Если модель должна вернуть JSON, парсится ли он `json.loads()`? Если нет — это провал (score 0).
- Schema Adherence (Соответствие схеме): Соответствует ли JSON заданной схеме (поля, типы данных)?
- Argument Hallucination Rate: Как часто модель придумывает аргументы функции, которых нет в документации?
- Success Rate (Коэффициент успеха): Смог ли агент выполнить конечную цель (например, забронировать билет), используя цепочку вызовов?
Для оценки таких моделей мы используем тестовый набор (Unit Tests), где проверяем не текст, а именно вызовы API.
Катастрофическое забывание (Catastrophic Forgetting)
Частая проблема: вы дообучили Gemini идеально отвечать на вопросы техподдержки по вашему продукту, но модель разучилась здороваться или писать Python-код.
Чтобы контролировать это, всегда добавляйте в свой Evaluation Set (набор для оценки) Generic Questions — общие вопросы, не связанные с вашей темой. Если качество ответов на общие темы резко упало, значит, вы «пережарили» модель (overfitting). В этом случае нужно уменьшить количество эпох обучения или снизить Learning Rate Multiplier.
Создание плана оценки для модели техподдержки
Вы дообучили модель Gemini для генерации JSON-отчетов из неструктурированного текста. Какая метрика будет наиболее критичной и первичной для оценки качества?