Files
qwen2.5-1.5b-ru-hallucinati…/README.md
ModelHub XC d009ed4b2a 初始化项目,由ModelHub XC社区提供模型
Model: AtesiT/qwen2.5-1.5b-ru-hallucination-detector
Source: Original Platform
2026-10-21 18:32:18 +08:00

354 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
language: ru
license: apache-2.0
base_model: Qwen/Qwen2.5-1.5B-Instruct
tags:
- hallucination-detection
- fact-checking
- qwen2.5
- lora
- unsloth
- russian
- nlp
- classification
pipeline_tag: text-generation
datasets:
- kuznetsoffandrey/sberquad
metrics:
- accuracy
- f1
---
# 🔍 Детектор галлюцинаций 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)
| Метрика | Значение |
|---------|----------|
| **Accuracy** | **0.9835** |
| **F1-score** | **0.9833** |
| Precision | 0.9793 |
| Recall | 0.9874 |
| Размер теста | 485 примеров |
### Кривая обучения (Train / Eval Loss)
![Loss curve](loss_curve.png)
*График показывает динамику функции потерь на обучающей и валидационной выборках
по шагам обучения. Снижение eval loss без роста train loss означает, что модель
обобщает, а не запоминает данные.*
### Confusion Matrix
![Confusion Matrix](confusion_matrix.png)
*По оси X — предсказанный класс, по оси Y — истинный класс.
Диагональ показывает правильные предсказания.*
---
## 🗂️ Данные для обучения
### Источник
Датасет собран **полностью автоматически** на основе русского QA-корпуса
**[SberQuAD](https://huggingface.co/datasets/kuznetsoffandrey/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 |
---
## 💻 Как использовать
### Установка
```bash
pip install transformers torch accelerate
```
### Код
```python
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 (быстрее, если нужна генерация)
```python
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](https://huggingface.co/datasets/kuznetsoffandrey/sberquad) — базовый датасет
- [HaluEval](https://github.com/RUCAIBox/HaluEval) — бенчмарк галлюцинаций (английский)
- [Qwen2.5](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct) — базовая модель
- [Unsloth](https://github.com/unslothai/unsloth) — библиотека для ускорения обучения
---
## 📄 Лицензия
Apache 2.0 — можно использовать в коммерческих проектах.
Базовая модель Qwen2.5 также распространяется под Apache 2.0.
---
*Модель создана в образовательных целях.
При использовании в продакшн рекомендуется дополнительная валидация на ваших данных.*