🔍 Детектор галлюцинаций LLM — русский язык

Текущая версия: v5 · Последнее обновление: 2026-08-14 08:11:28

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

Модель дообучена на основе Qwen2.5-1.5B-Instruct методом QLoRA (4-bit quantization + LoRA адаптеры) с использованием библиотеки Unsloth для ускоренного обучения на GPU.


📋 Описание задачи

Галлюцинации LLM — это когда языковая модель генерирует ответ, который звучит правдоподобно, но не соответствует реальным фактам или противоречит предоставленному источнику (контексту). Это одна из ключевых проблем при использовании LLM в production-системах, особенно в задачах RAG (Retrieval-Augmented Generation).

Постановка задачи

Модель принимает три входных текста:

  • Вопрос — то, что пользователь спросил у LLM
  • Контекст — документ/фрагмент, который был предоставлен LLM как источник фактов
  • Ответ — то, что LLM сгенерировала в ответ на вопрос

И возвращает бинарную метку:

  • 0 — ответ соответствует контексту (не галлюцинация)
  • 1 — ответ противоречит контексту или содержит неподтверждённые факты (галлюцинация)

Где это применяется

  • ✅ RAG-пайплайны — проверка ответов перед показом пользователю
  • ✅ Автоматическое тестирование LLM-агентов
  • ✅ Мониторинг качества ответов в продакшн-системах
  • ✅ Датасеты для обучения других моделей (серебряная разметка)

📊 Метрики качества

Текущая версия (v5, 2026-08-14 08:11:28)

Метрика Значение
Accuracy 0.9835
F1-score 0.9833
Precision 0.9793
Recall 0.9874
Размер теста 485 примеров

Кривая обучения (Train / Eval Loss)

Loss curve

График показывает динамику функции потерь на обучающей и валидационной выборках по шагам обучения. Снижение eval loss без роста train loss означает, что модель обобщает, а не запоминает данные.

Confusion Matrix

Confusion Matrix

По оси X — предсказанный класс, по оси Y — истинный класс. Диагональ показывает правильные предсказания.


🗂️ Данные для обучения

Источник

Датасет собран полностью автоматически на основе русского QA-корпуса SberQuAD — русскоязычного аналога Stanford SQuAD (~45 000 пар вопрос-параграф-ответ).

Стратегия генерации примеров

Положительные примеры (label=0, не галлюцинация): Берутся напрямую из SberQuAD — оригинальная тройка (вопрос, контекст, правильный ответ), где ответ гарантированно содержится в контексте.

Отрицательные примеры (label=1, галлюцинация) генерируются тремя способами:

Стратегия Описание Сложность для детектора
Mismatch Ответ от другого вопроса/контекста Лёгкая — ответ явно не связан с контекстом
Perturbation Искажение чисел или слов в правильном ответе Средняя — ответ похож на правду, но неверен
LLM-generated Qwen2.5 генерирует правдоподобный, но неверный ответ (zero-shot) Сложная — похоже на настоящую галлюцинацию

Такой микс позволяет модели научиться выявлять галлюцинации разной степени "правдоподобности" — от очевидных несоответствий до тонких фактических ошибок.

Размер датасета (v5)

Сплит Размер
Train 3877
Val 485
Test 485
Итого 4847

🛠️ Технические детали обучения

Архитектура

Параметр Значение
Базовая модель Qwen/Qwen2.5-1.5B-Instruct
Квантизация 4-bit (QLoRA)
LoRA rank (r) 16
LoRA alpha 16
LoRA dropout 0.1
Target modules q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
Обучаемых параметров ~20M из ~1.5B (≈1.3%)

Гиперпараметры обучения

Параметр Значение
Эпохи 2
Learning rate 2e-4
Warmup ratio 0.05
Batch size (эффективный) 16 (2 × grad_accum 8)
Optimizer AdamW 8-bit
Max sequence length 512
Планировщик LR cosine

Формат промпта

<|im_start|>system
Ты — эксперт по проверке фактов. Тебе дан вопрос, контекст (источник фактов) и ответ ассистента.
Определи, является ли ответ галлюцинацией — то есть противоречит контексту или не подтверждён им.
Ответь только цифрой: 1 — если это галлюцинация, 0 — если ответ соответствует контексту.
<|im_end|>
<|im_start|>user
Вопрос: {question}
Контекст: {context}
Ответ: {answer}
<|im_end|>
<|im_start|>assistant
{0 или 1}
<|im_end|>

Инфраструктура

Параметр Значение
GPU NVIDIA T4 (16 GB VRAM)
Платформа Google Colab
Фреймворк PyTorch + Hugging Face Transformers
Ускорение Unsloth (2-4x быстрее стандартного обучения)
Время обучения ~30-60 минут на T4

💻 Как использовать

Установка

pip install transformers torch accelerate

Код


from transformers import AutoModelForCausalLM, AutoTokenizer
import torch, re

# Загружаем модель с Hugging Face Hub
REPO_ID = "AtesiT/qwen2.5-1.5b-ru-hallucination-detector"
tokenizer = AutoTokenizer.from_pretrained(REPO_ID)
model = AutoModelForCausalLM.from_pretrained(
    REPO_ID,
    torch_dtype=torch.float16,
    device_map="auto"
)
model.eval()

SYSTEM_PROMPT = (
    "Ты — эксперт по проверке фактов. Тебе дан вопрос, контекст (источник фактов) и ответ ассистента. "
    "Определи, является ли ответ галлюцинацией — то есть противоречит контексту или не подтверждён им. "
    "Ответь только цифрой: 1 — если это галлюцинация, 0 — если ответ соответствует контексту."
)

def predict(question: str, context: str, answer: str) -> dict:
    """
    Определяет, является ли ответ галлюцинацией.

    Args:
        question: Вопрос, на который отвечала LLM
        context:  Контекст (источник фактов, справочный текст)
        answer:   Ответ LLM, который нужно проверить

    Returns:
        dict с ключами: label (0/1), verdict (str), raw_output (str)
    """
    prompt = (
        f"<|im_start|>system\n{SYSTEM_PROMPT}<|im_end|>\n"
        f"<|im_start|>user\n"
        f"Вопрос: {question}\n"
        f"Контекст: {context}\n"
        f"Ответ: {answer}"
        f"<|im_end|>\n"
        f"<|im_start|>assistant\n"
    )
    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
    with torch.no_grad():
        out = model.generate(
            **inputs,
            max_new_tokens=3,
            do_sample=False,
            pad_token_id=tokenizer.eos_token_id,
        )
    gen = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
    m = re.search(r"[01]", gen)
    label = int(m.group()) if m else 0
    return {
        "label":      label,
        "verdict":    "Галлюцинация" if label == 1 else "Не галлюцинация",
        "raw_output": gen.strip(),
    }

# ── Пример 1: очевидная галлюцинация ──────────────────────────────────
result = predict(
    question="Столица Франции?",
    context="Франция — государство в Западной Европе. Столица страны — Париж.",
    answer="Столица Франции — Лондон.",
)
print(result)
# {'label': 1, 'verdict': 'Галлюцинация', 'raw_output': '1'}

# ── Пример 2: правильный ответ ─────────────────────────────────────────
result = predict(
    question="Столица Франции?",
    context="Франция — государство в Западной Европе. Столица страны — Париж.",
    answer="Столица Франции — Париж.",
)
print(result)
# {'label': 0, 'verdict': 'Не галлюцинация', 'raw_output': '0'}

# ── Пример 3: тонкая галлюцинация (неверное число) ────────────────────
result = predict(
    question="В каком году основана компания Apple?",
    context="Apple Inc. была основана 1 апреля 1976 года Стивом Джобсом, "
            "Стивом Возняком и Рональдом Уэйном.",
    answer="Apple была основана в 1985 году.",
)
print(result)
# {'label': 1, 'verdict': 'Галлюцинация', 'raw_output': '1'}

Использование с Unsloth (быстрее, если нужна генерация)

from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "AtesiT/qwen2.5-1.5b-ru-hallucination-detector",
    max_seq_length = 512,
    load_in_4bit = True,
)
model.eval()
# Далее используйте predict() из примера выше

⚠️ Ограничения и известные проблемы

  1. Домен данных — модель обучена на энциклопедических текстах (Wikipedia-style, SberQuAD). Качество может быть ниже на специализированных доменах (медицина, право, технические тексты).

  2. Длина контекста — максимальная длина входной последовательности 512 токенов. Длинные контексты нужно обрезать перед подачей в модель.

  3. Автоматическая разметка — обучающие данные сгенерированы автоматически без ручной проверки. Часть негативных примеров (особенно perturbation) может содержать "шумные" метки.

  4. Бинарная классификация — модель не объясняет, почему ответ является галлюцинацией, только детектирует сам факт.

  5. Только русский язык — модель дообучалась исключительно на русскоязычных данных, для других языков результаты непредсказуемы.


📈 История версий

Версия Дата и время Accuracy F1 Precision Recall Train size
v1 2026-08-11 11:27:28 0.9587 0.9573 0.9739 0.9412 3865
v2 2026-08-12 12:05:19 0.9628 0.9615 0.9783 0.9454 3867
v3 2026-08-13 08:18:03 0.9794 0.9792 0.9751 0.9833 3876
v4 2026-08-13 09:16:07 0.9794 0.9792 0.9751 0.9833 3874
v5 2026-08-14 08:11:28 0.9835 0.9833 0.9793 0.9874 3877

Каждая версия — результат отдельной сессии дообучения. Модель загружается с предыдущей версии и дообучается на новых данных.


📚 Связанные работы и датасеты

  • SberQuAD — базовый датасет
  • HaluEval — бенчмарк галлюцинаций (английский)
  • Qwen2.5 — базовая модель
  • Unsloth — библиотека для ускорения обучения

📄 Лицензия

Apache 2.0 — можно использовать в коммерческих проектах. Базовая модель Qwen2.5 также распространяется под Apache 2.0.


Модель создана в образовательных целях. При использовании в продакшн рекомендуется дополнительная валидация на ваших данных.

Downloads last month
67
Safetensors
Model size
2B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for AtesiT/qwen2.5-1.5b-ru-hallucination-detector

Adapter
(1525)
this model

Dataset used to train AtesiT/qwen2.5-1.5b-ru-hallucination-detector