Після кожної ітерації 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 дні.







