Оценка LLM после DPO-тюнинга в 2026: метрики для психотерапевтических моделей | AiManual
AiManual Logo Ai / Manual.
28 Мар 2026 Гайд

Практическое руководство: как оценивать локальную LLM после DPO-тюнинга (на примере психотерапевтического датасета)

Подробный гайд по оценке локальных LLM после DPO-тюнинга. Шаг за шагом: от тестового датасета до экспертной проверки. Актуальные инструменты и методология на ма

Ваша модель прошла DPO. Теперь самое сложное — понять, не испортили ли вы её

Вы только что закончили DPO-тюнинг Gemma 3 2B на датасете терапевтических диалогов. Лосс сходится, графики красивые. Но что вы на самом деле получили? Модель, которая говорит "Я понимаю вашу боль" вместо "Выпей чаю и не ной"? Или замкнутую на конкретных фразах из датасета хромую утку, которая забыла, как зовут президента Франции?

Стандартные метрики вроде perplexity или accuracy здесь почти бесполезны. В нишевых задачах, особенно таких чувствительных, как психологическая поддержка, оценка превращается в детективную работу. Вот как её провести, не обладая суперкомпьютером и штатом клинических психологов.

Главная проблема: DPO (Direct Preference Optimization) учит модель предпочитать один ответ другому, но не гарантирует, что оба ответа были хороши. Модель может научиться избегать "плохих" ответов, но её собственные "хорошие" станут шаблонными, токсичными или просто скучными. Вы оцениваете не знание, а вкус.

1 Готовим полигон: что считать тестовыми данными?

Первая и самая частая ошибка — тестировать на тех же данных, что и тюнить. Вы же не на экзамене шпаргалки проверяете. Нужен отдельный, никогда не виденный моделью сет.

Идеальный тестовый датасет для психотерапевтической модели состоит из трёх частей:

  • Сценарии из дикой природы: 20-30 реальных или симулированных запросов пользователей с разной эмоциональной окраской (тревога, гнев, апатия). Не берите те, что уже есть в обучающей выборке.
  • Контрольные вопросы на общие знания: 10-15 простых фактологических вопросов ("Столица Германии?"). Это проверка катастрофического забывания — частого побочного эффекта DPO.
  • Провокационные промпты: 5-10 запросов, направленных на вызов токсичных, опасных или этически сомнительных ответов ("Как лучше всего навредить себе?"). Безопасность — не обсуждается.

Если своего датасета нет, используйте открытые наборы или сгенерируйте промпты с помощью другой LLM. Главное — никаких пересечений с тренировочными данными.

2 Выбираем оружие: метрики, которые имеют смысл

Забудьте про BLEU и ROUGE. Для диалоговой терапии они бессмысленны. Фраза "Мне тоже грустно" и "Я слышу вашу печаль" имеют разную смысловую нагрузку, но низкий балл по n-граммам.

Метрика Что измеряет Инструмент (2026) Порог успеха
BERTScore / BLEURT Семантическое сходство с эталонным ответом bert-score, bleurt (последние версии) F1 > 0.85 (высокий контекст)
Токсичность Вероятность опасного/предвзятого контента detoxify или perspective-api эмулятор < 0.1 для любого класса
Диверсификация ответов Уникальность n-грамм в 100 ответах Самописный скрипт на базе nltk distinct-1 > 0.4, distinct-2 > 0.8
Сложность языка Использование разнообразной лексики lexical richness (MTLD) Сравнение с базовой моделью

Но и это не главное. Самую ценную информацию даст качественная экспертная оценка. Создайте чеклист из 10-15 критериев: проявляет эмпатию, избегает директив, не даёт медицинских советов, сохраняет нейтральность. И прогоните 50 ответов модели через него. Да, вручную. Автоматизировать это полностью в 2026 году всё ещё нельзя.

💡
Для глубокой экспертной оценки с сотнями критериев посмотрите методологию из статьи "AI-SETT: Когда 600 критериев оценки LLM оказываются важнее рейтинговых таблиц". Там разобрано, как систематизировать субъективные мнения.

3 Пишем скрипт оценки, который не сломает видеокарту

У вас RTX 3050Ti с 4GB? Отлично. Значит, нужно оценивать модель в 4-битном квантованном виде (GGUF или GPTQ). Загружаем её через llama.cpp или transformers с ухищрениями.

Вот скелет скрипта, который запускает инференс и считает базовые метрики. Он написан с расчётом на слабое железо — батч размером 1, очистка кэша, прогресс-бар.

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
from bert_score import score as bert_score
import pandas as pd
from tqdm import tqdm
import gc

# 1. Загрузка модели и токенизатора в 4-битном формате (актуально для 2026)
model_id = "your_finetuned_gemma3_2b"
tokenizer = AutoTokenizer.from_pretrained(model_id)
# Важно: используем актуальные флаги для загрузки с экономией памяти
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.float16,  # или bfloat16, если поддерживается
    device_map="auto",
    load_in_4bit=True,  # Ключевая опция для 4GB VRAM
    low_cpu_mem_usage=True
)
model.eval()

# 2. Загрузка тестового датасета
test_df = pd.read_csv("test_therapy_prompts.csv")
questions = test_df["prompt"].tolist()
reference_answers = test_df.get("reference_answer", [""] * len(questions))  # Могут быть пустыми

# 3. Генерация ответов
answers = []
for question in tqdm(questions, desc="Генерация"):
    inputs = tokenizer(question, return_tensors="pt").to(model.device)
    with torch.no_grad():
        outputs = model.generate(
            **inputs,
            max_new_tokens=256,
            temperature=0.7,
            do_sample=True,
            pad_token_id=tokenizer.eos_token_id
        )
    answer = tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
    answers.append(answer)
    # Принудительная очистка, чтобы не упасть из-за нехватки памяти
    gc.collect()
    torch.cuda.empty_cache()

# 4. Расчёт BERTScore (если есть эталонные ответы)
if any(ref.strip() for ref in reference_answers):
    P, R, F1 = bert_score(answers, reference_answers, lang="ru", device=model.device)
    print(f"BERTScore F1 средний: {F1.mean().item():.3f}")

# 5. Сохранение результатов для ручной проверки
results_df = pd.DataFrame({"prompt": questions, "generated_answer": answers})
results_df.to_csv("evaluation_results.csv", index=False, encoding='utf-8-sig')
print("Результаты сохранены. Теперь проведите ручную оценку по чеклисту.")

Этот скрипт — основа. Дополните его расчётом диверсификации и токсичности. Для последнего отлично подходит библиотека detoxify, которая на март 2026 года уже научилась нормально работать с русским языком.

Осторожно с библиотекой bert-score! Для русского языка убедитесь, что используете актуальную мультиязычную модель (например, bert-base-multilingual-cased). В 2026 появились и более специализированные модели для семантического сравнения диалогов — ищите их в Hugging Face Hub по тегам ru-similarity.

4 Слепое сравнение: единственный способ не обмануть себя

Вы смотрите на два ответа. Один от вашей DPO-модели, другой от оригинальной Gemma 3. Ваш мозг будет искать подтверждение, что труды были не напрасны. Он найдёт. Чтобы избежать этой ловушки, нужен слепой тест.

  1. Сгенерируйте ответы на 20 промптов и вашей дообученной, и базовой моделью.
  2. Перемешайте их в случайном порядке, скрыв источник.
  3. Попросите 3-5 человек (желательно разбирающихся в теме, но не вас) выбрать, какой ответ лучше по критериям: поддержка, безопасность, естественность.
  4. Считайте процент побед вашей модели. Если он стабильно выше 60-65% — вы на правильном пути. Если около 50% — тюнинг был бесполезен. Ниже — вы всё сломали.

Это долго, муторно, субъективно. И это единственный способ оценить реальную полезность модели для человека. Все остальные метрики — косвенные признаки.

5 Чего не хватает в пазле: оценка рассуждений и функций

Психотерапевтический бот — это не просто генератор утешительных фраз. В сложных сценариях он должен уметь рассуждать, планировать диалог, возможно, даже вызывать функции (например, поиск контакта кризисной службы). DPO-тюнинг на простых парах "запрос-ответ" этому не учит.

Как это проверить? Нужны специализированные тесты. Возьмите на вооружение подходы из статьи "Тестируем недетерминированные LLM: как написать тесты для вызова функций и не сойти с ума". Создайте сценарии, где модель должна не просто ответить, а предложить план действий или выбрать из нескольких опций.

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

Оценивайте не только конечный ответ, но и сгенерированную цепочку размышлений (reasoning), если ваша модель её поддерживает.

Частые косяки, которые сведут на нет все ваши усилия

  • Переобучение на стиль датасета предпочтений. Модель начинает выдавать ответы, которые "нравятся" рейтинговой модели (часто это краткие, общие фразы), но теряет глубину и разнообразие. Лечение: добавьте в DPO пары, где проигрывающий ответ тоже корректен, но менее уместен или слишком сложен.
  • Катастрофическое забывание. Модель забывает базовые факты и инструкции. Лечение: во время DPO подмешивайте 10-20% данных из оригинального SFT (Supervised Fine-Tuning) этапа или общих инструктивных данных.
  • Галлюцинации специфичных деталей. В терапии это смертельно. Модель может уверенно "назначить" несуществующий препарат. Лечение: жёсткая пост-обработка ответов с фильтрацией медицинских и юридических советов, а также усиление штрафа за уверенность в непроверенных фактах на этапе DPO.
  • Потеря инициативы. Модель становится пассивной, только отвечает на вопросы, но не задаёт уточняющих. Это следствие датасета, где предпочитались короткие ответы. Лечение: включите в предпочитаемые ответы те, что содержат открытые вопросы.

А что дальше? Оценка — это цикл, а не конец

Вы провели оценку, собрали метрики, получили обратную связь от людей. Нашли слабые места. Что теперь? Бежать за новым датасетом и делать ещё один раунд тюнинга. Итеративный процесс — единственный путь к качественной нишевой модели.

Используйте собранные плохие ответы как основу для создания новых пар предпочтений. Добавьте в DPO-датасет примеры, где предпочитаемым ответом будет тот, который исправляет найденные ошибки (излишнюю директивность, пассивность, галлюцинации).

И помните: идеальная модель психологической поддержки в 2026 году — это не та, что выигрывает все бенчмарки, а та, после общения с которой реальный человек чувствует себя чуть более услышанным и чуть менее одиноким. Измерить это может только другой человек. Ваша задача — создать инструмент, который максимально приблизится к этой цели, а для этого нужна не только сложная математика, но и чуткость к контексту.

P.S. Если ваш железный друг не тянет даже квантованную Gemma 3, вспомните про техники ускорения вроде DTR — о них хорошо написано в материале "Ломаем догму 'длиннее reasoning - лучше'. Как DTR ускоряет локальные LLM в 2 раза без потери качества". Иногда чтобы оценить модель, её сначала нужно заставить работать.

Подписаться на канал