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}, ...])
  • context can be text, or a JSON record (a string, dict or list). 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 as 17:0-21:0 also 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
Safetensors
Model size
68.1M params
Tensor type
F32
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for CobuildX-AI/cbx-hallucination-detector-68M

Finetuned
(37)
this model

Collection including CobuildX-AI/cbx-hallucination-detector-68M