Після кожної ітерації fine-tuning постає питання: чи стало краще? Без структурованої системи метрик легко потрапити в пастку — модель може перенавчитися, втратити загальні знання або деградувати на крайових випадках. Ми бачили проекти, де команда робила 15+ ітерацій «на око», поки не вибудувала evaluation pipeline. Наш підхід — ієрархія метрик від швидких автоматичних до дорогої людської оцінки — дозволяє зупинитися в потрібний момент і гарантувати якість.
Чому важлива комплексна оцінка донавченої моделі?
Одна метрика не дає повної картини. BLEU може бути високим, а модель — галюцинувати факти. Perplexity може падати, а корисність відповідей — знижуватися. Тільки комбінація автоматичних метрик, LLM-as-judge та людської оцінки показує реальну якість донавченої нейромережі. Ми використовуємо цей підхід у всіх проектах вже понад 5 років — накопичили портфоліо з 50+ fine-tuning проектів.
Ієрархія метрик оцінки
Рівень 1: Автоматичні метрики
Швидкі, дешеві, працюють без людини. Дають грубу оцінку, але незамінні для швидких ітерацій.
Рівень 2: LLM-as-judge
Сильна модель (GPT-4o, Claude 3.5) оцінює відповіді тестованої моделі. Добре корелює з людською оцінкою при правильному промпті.
Рівень 3: Людська оцінка
Золотий стандарт. Дорого, але необхідно для фінальної валідації та калібрування нижніх рівнів. Зазвичай 200–500 прикладів достатньо.
Порівняння типів метрик:
| Тип метрики | Швидкість | Ресурсоємність | Кореляція з людиною |
|---|---|---|---|
| Автоматичні (BLEU, ROUGE, perplexity) | Миттєво | Низька | 50-60% |
| LLM-as-judge | 1-2 дні на 1000 прикладів | Середня | 80-85% |
| Людська оцінка | Тиждень на 200 прикладів | Висока | 95-100% |
Як LLM-as-judge доповнює автоматичні метрики?
Автоматичні метрики (BLEU, ROUGE) вимірюють лише поверхневий збіг з референсом. LLM-as-judge оцінює семантику: точність фактів, повноту, логіку. В одному кейсі базова Llama 3.1 8B показала BLEU-4=0.18, а після fine-tuning — 0.39, але LLM-суддя виявив, що модель почала вигадувати юридичні статті. Без судді це б пропустили. LLM-as-judge корелює з людською оцінкою на 85%, що в 1.5 рази вище, ніж у автоматичних метрик. Крім того, LLM-as-judge важливий для оцінки генерації тексту, де автоматичні метрики безсилі.
Практична реалізація LLM-as-judge
Приклад реалізації LLM-as-judge
from openai import OpenAI
JUDGE_PROMPT = """Ты — строгий эксперт, оценивающий качество ответов AI-ассистента.
Вопрос: {question}
Ответ ассистента: {answer}
Референсный ответ: {reference}
Оцени ответ по критериям (каждый 1–5):
1. Фактическая точность
2. Полнота охвата темы
3. Структурированность
4. Соответствие стилю
Верни JSON: {{"accuracy": X, "completeness": X, "structure": X, "style": X, "overall": X, "reasoning": "..."}}"""
def llm_judge(question: str, answer: str, reference: str, client: OpenAI) -> dict:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": JUDGE_PROMPT.format(question=question, answer=answer, reference=reference)
}],
response_format={"type": "json_object"},
temperature=0.1
)
return json.loads(response.choices[0].message.content)
Автоматичні метрики: реалізація в коді
Нижче — приклад обчислення BLEU та ROUGE для пайплайну оцінки. Код можна використовувати як шаблон.
from nltk.translate.bleu_score import corpus_bleu, SmoothingFunction
from rouge_score import rouge_scorer
references = [[ref.split()] for ref in reference_list]
hypotheses = [hyp.split() for hyp in hypothesis_list]
bleu_4 = corpus_bleu(references, hypotheses,
weights=(0.25, 0.25, 0.25, 0.25),
smoothing_function=SmoothingFunction().method1)
scorer = rouge_scorer.RougeScorer(['rouge1','rouge2','rougeL'], use_stemmer=True)
rouge_scores = [scorer.score(ref, hyp) for ref, hyp in zip(reference_list, hypothesis_list)]
Perplexity — метрика впевненості моделі
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
def compute_perplexity(model, tokenizer, texts: list[str]) -> float:
total_loss = 0
total_tokens = 0
model.eval()
with torch.no_grad():
for text in texts:
encodings = tokenizer(text, return_tensors="pt").to(model.device)
outputs = model(**encodings, labels=encodings["input_ids"])
total_loss += outputs.loss.item() * encodings["input_ids"].shape[1]
total_tokens += encodings["input_ids"].shape[1]
avg_loss = total_loss / total_tokens
return torch.exp(torch.tensor(avg_loss)).item()
Класифікація та вилучення — оцінюємо через F1 і accuracy
from sklearn.metrics import classification_report, f1_score
def evaluate_classification(model_outputs: list, ground_truth: list) -> dict:
predictions = []
for output in model_outputs:
try:
pred = json.loads(output)["category"]
except:
pred = "parse_error"
predictions.append(pred)
report = classification_report(ground_truth, predictions, output_dict=True)
return {
"macro_f1": report["macro avg"]["f1-score"],
"weighted_f1": report["weighted avg"]["f1-score"],
"accuracy": report["accuracy"],
"per_class": {k: v for k, v in report.items() if isinstance(v, dict) and k not in ["macro avg", "weighted avg"]}
}
Практичний приклад: комплексна оцінка fine-tuned моделі
Базова модель: Llama 3.1 8B Instruct. Fine-tuning: QLoRA r=16, 2000 прикладів юридичних документів.
| Метрика | Базова модель | Fine-tuned | Зміна |
|---|---|---|---|
| ROUGE-L | 0.41 | 0.67 | +63% |
| BLEU-4 | 0.18 | 0.39 | +117% |
| Perplexity (домен) | 24.3 | 11.8 | -51% |
| Perplexity (MMLU) | 8.2 | 9.1 | +11% (forgetting) |
| LLM-judge overall | 3.1 | 4.3 | +39% |
| F1 (NER категорії) | 0.61 | 0.89 | +46% |
Perplexity на MMLU зросла на 11% — помірне катастрофічне забування, але для вузького юридичного use-case це прийнятно. Рішення: додати 10% загальних даних у наступний раунд.
Що входить до нашої роботи з оцінки моделі
- Розробка кастомного evaluation pipeline під вашу задачу (включаючи скрипти, конфіги та документацію)
- Налаштування автоматичних метрик (BLEU, ROUGE, perplexity, F1, accuracy)
- Інтеграція LLM-as-judge з вибором моделі-судді та калібруванням промпту
- Проведення людської оцінки (залучення експертів, збір розмітки)
- Побудова дашборду метрик та моніторингу (MLflow, Weights & Biases)
- Фінальний звіт з рекомендаціями щодо покращення моделі
- Навчання вашої команди роботі з пайплайном
Почніть з evaluation pipeline — зв'яжіться з нами для аудиту вашої моделі. Економія на зайвих ітераціях може досягати 40% бюджету проекту.
Терміни та процес оцінки
- Аналіз задачі та метрик — 1–2 дні
- Розробка pipeline та інтеграція — 3–5 днів
- Автоматична оцінка — кілька годин
- LLM-as-judge (до 1000 прикладів) — 1–2 дні
- Людська оцінка — 1 тиждень
- Звіт та рекомендації — 1–2 дні
Разом на одну ітерацію fine-tuning — 1–2 тижні. При комплексному проекті з кількома раундами — від 3 тижнів.
Моніторинг після деплою
import mlflow
def log_inference_quality(prompt, response, user_feedback):
with mlflow.start_run(run_name="production-monitoring"):
mlflow.log_metrics({
"response_length": len(response.split()),
"refusal_detected": int("не могу" in response.lower()),
"user_rating": user_feedback.get("rating", -1),
})
Моніторинг у продакшені обов'язковий — ми гарантуємо, що модель не деградує з часом. Сертифіковані інженери нашої команди супроводжують проект на всьому життєвому циклі. Наша команда має 5+ років досвіду в fine-tuning і виконала понад 50 проектів.
Якщо ви хочете впровадити системну оцінку, зв'яжіться з нами. Ми допоможемо вибудувати пайплайн і зекономити на зайвих ітераціях. Замовте консультацію: оцінимо ваш проект за 2 дні.







