cbx-hallucination-detector-68M
Finds the parts of an AI answer that its context does not support. Give it the context the answer should be based on (retrieved passages, a document, or a structured record such as JSON), the question and the answer. It returns the unsupported spans of the answer, each with a type and a score. 68M parameters, about 14 ms per 1,000 tokens on a GPU and 230 ms on a CPU.
The most accurate size: best of ours on HaluBench, RAGTruth and our own test set. Fine-tuned from jhu-clsp/ettin-encoder-68m. Current version: v0.1 (use
--revision v0.1 to pin it). Also available in the 32M size.
What it flags
The model marks answer text that the context does not support:
- conflicts with the context: a wrong number, date, name, place, attribute or cause, or a changed meaning;
- additions the context does not contain, even if they may be true in the world: invented details, events, features, quotes or figures.
Each span has a type:
factual: a conflict or an invented fact;soft: tone, praise or interpretation the context does not support ("a hidden gem", "known for its friendly staff").
Two modes come from the same model:
lenient(default): factual spans only. It flags fewer correct answers.strict: factual and soft spans.
Not flagged: correct paraphrases and summaries, reasonable readings of the context, hedges, and statements that the context does not mention something.
It covers three kinds of input: question answering over passages, summaries, and descriptions written from structured records (data-to-text).
How to use
1. Download and install
pip install -U huggingface_hub
hf download CobuildX-AI/cbx-hallucination-detector-68M --revision v0.1 --local-dir cbx-hallucination-detector-68M
cd cbx-hallucination-detector-68M
pip install -r requirements.txt
2. Use it in your code
HallucinationDetector (in cbx_hallucination.py, part of this repo) loads the model once:
from cbx_hallucination import HallucinationDetector
det = HallucinationDetector() # uses a GPU if one is available; mode="lenient" by default
res = det.detect(context, answer, question="What are the opening hours?")
res["hallucinated"] # True if any span was found
for s in res["spans"]:
print(s["start"], s["end"], s["text"], s["type"], s["score"])
det.detect(context, answer, mode="strict") # factual and soft spans
det.detect_batch([{"context": c, "question": q, "answer": a}, ...])
contextcan be text, or a JSON record (a string,dictorlist). A record is turned into plain text first, one line per field, as in training: nested keys become paths, true / false / null become yes / no / not given, and times such as17:0-21:0also get a 12-hour form.- Context, question and answer together are read up to 4,096 tokens. When longer, the end of the context is cut,
never the answer (
res["context_cut"]gives the number of context tokens dropped). - The threshold is 0.5. Raise it for fewer false alarms, lower it to catch more.
3. Optional: check your setup
python example.py checks four invented answers in both modes and prints the spans found.
Results
Two other compact detectors are shown for comparison: TinyLettuce (Ettin, same sizes). β marks models trained on RAGTruth, so their RAGTruth numbers are not a held-out comparison. This model was not trained on RAGTruth or on any benchmark below.
1. HaluEval and HaluBench (answer level: is the answer hallucinated?). Independent benchmarks whose wrong answers were written by an LLM: in HaluEval (QA and summaries) ChatGPT wrote wrong answers from HotpotQA questions and CNN / Daily Mail articles; in HaluBench GPT-4o rewrote correct answers into minimally different wrong ones (our subset: DROP, CovidQA, PubMedQA, FinanceBench; its HaluEval and RAGTruth parts are left out as duplicates). F1 of the hallucinated class.
| Model | Mode | HaluEval QA β | HaluEval summaries β | HaluBench β |
|---|---|---|---|---|
| cbx-hallucination-detector-68M | lenient | 0.686 | 0.590 | 0.621 |
| cbx-hallucination-detector-68M | strict | 0.685 | 0.644 | 0.626 |
| cbx-hallucination-detector-32M | lenient | 0.735 | 0.617 | 0.521 |
| cbx-hallucination-detector-32M | strict | 0.746 | 0.650 | 0.522 |
| TinyLettuce 17M β | β | 0.502 | 0.419 | 0.419 |
| TinyLettuce 32M β | β | 0.668 | 0.456 | 0.521 |
2. RAGTruth test (2,700 real model answers with human-annotated spans). Span F1 is over characters; "false alarms" is the share of correct answers that get any span. Spans inside a refusal sentence ("the passages do not say") are not scored as spans, for every model, because RAGTruth labels refusals per answer.
| Model | Mode | Span F1 β | QA / summary / data-to-text span F1 β | Answer F1 β | False alarms β | Data-to-text false alarms β |
|---|---|---|---|---|---|---|
| cbx-hallucination-detector-68M | lenient | 0.315 | 0.357 / 0.221 / 0.323 | 0.616 | 52% | 74% |
| cbx-hallucination-detector-68M | strict | 0.243 | 0.352 / 0.210 / 0.206 | 0.612 | 59% | 95% |
| cbx-hallucination-detector-32M | lenient | 0.280 | 0.363 / 0.236 / 0.224 | 0.597 | 52% | 74% |
| cbx-hallucination-detector-32M | strict | 0.208 | 0.347 / 0.218 / 0.144 | 0.607 | 60% | 95% |
| TinyLettuce 17M β | β | 0.446 | 0.551 / 0.235 / 0.438 | 0.685 | 19% | 31% |
| TinyLettuce 32M β | β | 0.480 | 0.556 / 0.280 / 0.495 | 0.723 | 22% | 33% |
RAGTruth's annotators mark only clear conflicts and clearly invented facts. This model was trained on labels that also mark smaller unsupported details, so it flags more than they do; that difference explains most of the gap to the models trained on RAGTruth.
3. Our test set (543 answers, LLM-labelled by the same judge as the training data; split by context, none seen in training). Lenient mode is scored against factual spans only.
| Model | Mode | Span F1 β | False alarms β |
|---|---|---|---|
| cbx-hallucination-detector-68M | lenient | 0.502 | 30% |
| cbx-hallucination-detector-68M | strict | 0.518 | 32% |
| cbx-hallucination-detector-32M | lenient | 0.434 | 24% |
| cbx-hallucination-detector-32M | strict | 0.468 | 27% |
| TinyLettuce 17M β | β | 0.094 | 47% |
| TinyLettuce 32M β | β | 0.126 | 50% |
Speed (median, batch 1, about 930 tokens per input; NVIDIA TITAN RTX / Intel i7-10700 with 8 threads):
| Model | GPU (ms per 1,000 tokens) | CPU (ms per 1,000 tokens) |
|---|---|---|
| cbx-hallucination-detector-68M | 14 | 230 |
| cbx-hallucination-detector-32M | 9 | 84 |
Training data
Build v0.4 of the CBX hallucination dataset, "natural" mix: 7,390 training answers (2,964 data-to-text, 2,347 QA, 2,079 summary; 62% contain at least one unsupported span).
- Contexts: 2,065 contexts, several answers each.
- 1,717 generated with gpt-5.4-mini (structured records, reviews, articles and passages, all invented; 5,980 answers).
- 181 from RAGBench TAT-QA and CUAD (CC-BY-4.0; 743 answers).
- 84 from PsiloQA (CC-BY-4.0; Wikipedia passages, CC-BY-SA-4.0; 337 answers).
- 83 from HAGRID (Apache-2.0; 330 answers).
- Answers: correct answers, answers with inserted errors, and natural answers from gpt-5.4-mini, Gemma 4 31B and four open models (Phi-3.5-mini, Qwen2.5-7B, Mistral-7B v0.3, OLMo-2 7B).
- Labels: LLM-made. Inserted errors are known by construction. Natural answers were labelled by a gpt-5.4-mini judge, and every span was typed factual or soft by a second gpt-5.4-mini pass. No human labelling.
- No passages with non-commercial or unclear licences were used. RAGTruth was never trained on.
Limitations
- Structured records: it still flags many correct data-to-text answers (lenient: 74% of correct RAGTruth data-to-text answers get a span). In a hand check of 50 such flags from an earlier version, most were misreadings of reworded reviews, opening hours or record fields; opening hours have improved since.
- Stricter than RAGTruth's annotators: it flags more small unsupported details than human annotators of RAGTruth do (false alarms 52% in lenient mode). Use strict mode only when every unsupported word matters.
- Spans follow tokens: a span can start or end inside a word, or cover only part of a claim.
- English only, three tasks (QA, summaries, data-to-text). Code, tool output and agent traces are not covered.
- Only the given context counts. A claim that is true but not in the context is flagged; the model does not check facts against the world.
Licence
Apache-2.0 for the model weights and code. The training contexts come from the sources above under their own licences; CC-BY-4.0 and CC-BY-SA-4.0 sources are credited here.
- Downloads last month
- 11
Model tree for CobuildX-AI/cbx-hallucination-detector-68M
Base model
jhu-clsp/ettin-encoder-68m