AtesiT/qwen2.5-1.5b-ru-hallucination-detector
🔍 Детектор галлюцинаций LLM — русский язык
Текущая версия: v5 · Последнее обновление: 2026-08-14 08:11:28
Эта модель определяет, является ли ответ языковой модели галлюцинацией — то есть содержит ли он информацию, которая противоречит предоставленному контексту или не подтверждается им.
Модель дообучена на основе [Qwen2.5-1.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct) методом QLoRA (4-bit quantization + LoRA адаптеры) с использованием библиотеки [Unsloth](https://github.com/unslothai/unsloth) для ускоренного обучения на GPU.
📋 Описание задачи
Галлюцинации LLM — это когда языковая модель генерирует ответ, который звучит правдоподобно, но не соответствует реальным фактам или противоречит предоставленному источнику (контексту). Это одна из ключевых проблем при использовании LLM в production-системах, особенно в задачах RAG (Retrieval-Augmented Generation).
Постановка задачи
Модель принимает три входных текста:
- Вопрос — то, что пользователь спросил у LLM
- Контекст — документ/фрагмент, который был предоставлен LLM как источник фактов
- Ответ — то, что LLM сгенерировала в ответ на вопрос
И возвращает бинарную метку:
- 0 — ответ соответствует контексту (не галлюцинация)
- 1 — ответ противоречит контексту или содержит неподтверждённые факты (галлюцинация)
Где это применяется
- ✅ RAG-пайплайны — проверка ответов перед показом пользователю
- ✅ Автоматическое тестирование LLM-агентов
- ✅ Мониторинг качества ответов в продакшн-системах
- ✅ Датасеты для обучения других моделей (серебряная разметка)
📊 Метрики качества
Текущая версия (v5, 2026-08-14 08:11:28)
Кривая обучения (Train / Eval Loss)
График показывает динамику функции потерь на обучающей и валидационной выборках по шагам обучения. Снижение eval loss без роста train loss означает, что модель обобщает, а не запоминает данные.
Confusion Matrix
По оси X — предсказанный класс, по оси Y — истинный класс. Диагональ показывает правильные предсказания.
🗂️ Данные для обучения
Источник
Датасет собран полностью автоматически на основе русского QA-корпуса [SberQuAD](https://huggingface.co/datasets/kuznetsoffandrey/sberquad) — русскоязычного аналога Stanford SQuAD (~45 000 пар вопрос-параграф-ответ).
Стратегия генерации примеров
Положительные примеры (label=0, не галлюцинация): Берутся напрямую из SberQuAD — оригинальная тройка (вопрос, контекст, правильный ответ), где ответ гарантированно содержится в контексте.
Отрицательные примеры (label=1, галлюцинация) генерируются тремя способами:
Такой микс позволяет модели научиться выявлять галлюцинации разной степени "правдоподобности" — от очевидных несоответствий до тонких фактических ошибок.
Размер датасета (v5)
🛠️ Технические детали обучения
Архитектура
Гиперпараметры обучения
Формат промпта
<|im_start|>system
Ты — эксперт по проверке фактов. Тебе дан вопрос, контекст (источник фактов) и ответ ассистента.
Определи, является ли ответ галлюцинацией — то есть противоречит контексту или не подтверждён им.
Ответь только цифрой: 1 — если это галлюцинация, 0 — если ответ соответствует контексту.
<|im_end|>
<|im_start|>user
Вопрос: {question}
Контекст: {context}
Ответ: {answer}
<|im_end|>
<|im_start|>assistant
{0 или 1}
<|im_end|>Инфраструктура
💻 Как использовать
Установка
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() из примера выше⚠️ Ограничения и известные проблемы
- Домен данных — модель обучена на энциклопедических текстах (Wikipedia-style, SberQuAD). Качество может быть ниже на специализированных доменах (медицина, право, технические тексты).
- Длина контекста — максимальная длина входной последовательности 512 токенов. Длинные контексты нужно обрезать перед подачей в модель.
- Автоматическая разметка — обучающие данные сгенерированы автоматически без ручной проверки. Часть негативных примеров (особенно perturbation) может содержать "шумные" метки.
- Бинарная классификация — модель не объясняет, почему ответ является галлюцинацией, только детектирует сам факт.
- Только русский язык — модель дообучалась исключительно на русскоязычных данных, для других языков результаты непредсказуемы.
📈 История версий
Каждая версия — результат отдельной сессии дообучения. Модель загружается с предыдущей версии и дообучается на новых данных.
📚 Связанные работы и датасеты
- SberQuAD — базовый датасет
- HaluEval — бенчмарк галлюцинаций (английский)
- Qwen2.5 — базовая модель
- Unsloth — библиотека для ускорения обучения
📄 Лицензия
Apache 2.0 — можно использовать в коммерческих проектах. Базовая модель Qwen2.5 также распространяется под Apache 2.0.
Модель создана в образовательных целях. При использовании в продакшн рекомендуется дополнительная валидация на ваших данных.
