Skip to main content

Find exactly which parts of your LLM output are hallucinated.

Project description

๐Ÿ” FactEval

Find exactly which parts of your LLM output are hallucinated.

Debug hallucinations in RAG and LLM pipelines with claim-level verification.

Input:  "Paris is the capital of Germany."
Output:  Paris is the capital of Germany โŒ
         โ†’ Contradicts evidence: "Paris is the capital of France."

License: MIT Python 3.10+


What is FactEval?

FactEval verifies claims against provided reference context (e.g., retrieved documents in a RAG system). It helps developers debug LLM outputs by:

  • Breaking answers into atomic claims
  • Checking each claim against reference evidence
  • Highlighting hallucinated parts with explanations and diagnostics

โšก Try It Instantly

Live Demo on Hugging Face Spaces โ†’

No setup needed โ€” paste your text and see hallucinations highlighted in seconds.


๐Ÿ“ฆ Install

pip install facteval

For development:

git clone https://github.com/sahilaf/FactEval.git
cd FactEval && pip install -e ".[dev]"

๐Ÿš€ Quick Start

from facteval import check

result = check(
    answer="Paris is the capital of Germany and has 5 million people.",
    contexts=[
        "Paris is the capital of France. Paris has approximately 2.2 million inhabitants.",
        "Germany's capital is Berlin.",
    ],
)

for claim in result["claims"]:
    print(f'{claim["label"]:15s} {claim["claim"]}')
    print(f'                โ†’ {claim["reason"]}')
contradicted    Paris is the capital of Germany.
                โ†’ Contradicts evidence: "Paris is the capital of France."
contradicted    Paris has 5 million people.
                โ†’ Contradicts evidence: "Paris has approximately 2.2 million inhabitants."

Lightweight Mode (up to 10x faster)

Already have claims? Skip extraction entirely:

from facteval import verify

result = verify(
    claims=["Paris is the capital of Germany.", "Paris has 5 million people."],
    contexts=["Paris is the capital of France. Population: 2.2M."],
)
# No Qwen model loaded โ†’ ~0.5 GB VRAM, ~0.3s latency

CLI (Command Line Interface)

# Quick check
facteval check --answer "The earth is flat." --context "The earth is an oblate spheroid."

# From file
facteval check input.json --output results.json

# With calibrator
facteval check input.json --calibrator calibrator.pkl

โœจ Features

  • Claim-level verdicts โ€” each sentence gets โœ… supported, โŒ contradicted, or โ“ unverifiable
  • Highlighted output โ€” color-coded HTML showing exactly which parts are wrong
  • Human-readable reasons โ€” every verdict explains why
  • Pipeline diagnostics โ€” hallucination vs. retrieval gap vs. missing context
  • Calibrated confidence โ€” isotonic regression for trustworthy probability scores
  • Lightweight mode โ€” verify() skips extraction for up to 10x faster results
  • Batch NLI โ€” all claims in a single forward pass
  • CLI โ€” facteval check for scripting and CI/CD

๐Ÿ“‹ Output Format

Short version:

{
  "claims": [
    {
      "claim": "Paris is the capital of Germany.",
      "label": "contradicted",
      "confidence": 0.9971,
      "reason": "Contradicts evidence: \"Paris is the capital of France.\"",
      "diagnostics": {
        "failure_type": "hallucination",
        "retrieval_quality": "strong",
        "suggestion": "Claim directly contradicts the evidence."
      }
    }
  ],
  "summary": {
    "total_claims": 2, "supported": 0, "contradicted": 2,
    "unverifiable": 0, "hallucination_rate": 1.0
  },
  "highlighted_answer": "<mark>Paris is the capital of Germany โŒ</mark>..."
}
Full output includes

Each claim also contains:

  • evidence โ€” the matched reference sentence
  • evidence_score โ€” retrieval similarity (0โ€“1)
  • raw_nli_scores โ€” per-label NLI probabilities (entailment, neutral, contradiction)
  • calibrated_confidence โ€” post-calibration confidence (if calibrator provided)
  • calibration_error โ€” estimated calibration error

Top-level fields:

  • calibrated โ€” whether a fitted calibrator was used
  • pipeline_time_seconds โ€” total processing time

Labels

Label Meaning
โœ… supported Claim is entailed by the evidence
โŒ contradicted Claim contradicts the evidence
โ“ unverifiable No relevant evidence, or evidence is neutral

Diagnostics

failure_type What happened What to do
verified Supported by strong evidence Nothing โ€” it's correct
hallucination Contradicts strong evidence Factual error in LLM output
possible_hallucination Contradicts weak evidence Add better context to confirm
no_evidence No context for this topic Add reference passages
retrieval_gap Evidence too dissimilar Context may not cover this claim
inconclusive Evidence is neutral Cannot confirm or deny

๐Ÿค” When Should You Use FactEval?

Use FactEval if you are:

  • Building a RAG system and need to verify answers against retrieved documents
  • Debugging hallucinations in LLM outputs
  • Evaluating whether generated answers are grounded in context
  • Building CI/CD checks for LLM-powered features

Not intended for:

  • General fact-checking without reference context (FactEval needs ground truth documents)
  • Real-time inference on user-facing APIs (model loading adds latency)

โšก Performance

Mode First run Subsequent runs VRAM
check() (full) ~60s (loads 3 models) ~1.3s ~3.4 GB
verify() (lightweight) ~15s (loads 2 models) ~0.3s ~0.5 GB

First run downloads and loads models from Hugging Face. After that, models are cached in memory. Use verify() when you already have claims and need low-latency evaluation.


๐Ÿงช Built For

  • RAG pipelines โ€” verify that generated answers are grounded in retrieved documents
  • LLM evaluation workflows โ€” measure hallucination rates across test sets
  • AI product debugging โ€” find exactly where your model is making things up

๐Ÿ—๏ธ Architecture

Answer Text โ”€โ”€โ†’ Claim Extractor โ”€โ”€โ†’ Evidence Retriever โ”€โ”€โ†’ NLI Verifier โ”€โ”€โ†’ Calibrator โ”€โ”€โ†’ Output
                (Qwen 1.5B)         (MiniLM + FAISS)      (DeBERTa)        (Isotonic)
                                          โ”‚                                      โ”‚
                                          โ””โ”€โ”€ Semantic Highlighting โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                               (reuses MiniLM embeddings)
Stage Model Size Latency
Claim Extraction Qwen/Qwen2.5-1.5B-Instruct ~3 GB ~1s
Evidence Retrieval all-MiniLM-L6-v2 + FAISS ~90 MB <10ms
NLI Verification DeBERTa-v3-base-mnli-fever-anli ~370 MB <10ms/batch
Calibration Isotonic Regression (sklearn) ~1 KB <1ms

๐Ÿ–ฅ๏ธ Try It Locally

pip install -e ".[demo]"
python demo/app.py

Features:

  • Highlighted answer text with โœ…โŒโ“ annotations
  • Per-claim cards with reasons, diagnostic badges, and suggestions
  • Summary dashboard with hallucination rate
  • 4 built-in examples

Deploy to Hugging Face Spaces

git remote add hf https://huggingface.co/spaces/YOUR_USERNAME/facteval
git push hf main

๐Ÿ“ Project Structure

FactEval/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ ANALYSIS.md                # Development analysis & lessons learned
โ”œโ”€โ”€ LICENSE                    # MIT
โ”œโ”€โ”€ pyproject.toml             # Package config + CLI entry point
โ”œโ”€โ”€ app.py                     # HF Spaces entry point
โ”œโ”€โ”€ requirements.txt           # HF Spaces dependencies
โ”œโ”€โ”€ examples/
โ”‚   โ”œโ”€โ”€ basic.py               # Minimal usage example
โ”‚   โ””โ”€โ”€ rag_debug.py           # RAG pipeline debugging example
โ”œโ”€โ”€ demo/
โ”‚   โ””โ”€โ”€ app.py                 # Gradio interactive demo
โ””โ”€โ”€ facteval/
    โ”œโ”€โ”€ __init__.py            # Public API: check(), verify()
    โ”œโ”€โ”€ config.py              # Model names, prompts, defaults
    โ”œโ”€โ”€ models.py              # Claim, Evidence, ClaimWithEvidence
    โ”œโ”€โ”€ claim_extractor.py     # Qwen2.5-1.5B claim decomposition
    โ”œโ”€โ”€ retriever.py           # FAISS + MiniLM evidence retrieval
    โ”œโ”€โ”€ verifier.py            # DeBERTa batch NLI + reasons
    โ”œโ”€โ”€ calibrator.py          # Isotonic regression calibration
    โ”œโ”€โ”€ core.py                # Pipeline orchestration + diagnostics
    โ””โ”€โ”€ cli.py                 # facteval check CLI

๐Ÿ“„ License

MIT โ€” see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

facteval-0.1.0.tar.gz (22.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

facteval-0.1.0-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file facteval-0.1.0.tar.gz.

File metadata

  • Download URL: facteval-0.1.0.tar.gz
  • Upload date:
  • Size: 22.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for facteval-0.1.0.tar.gz
Algorithm Hash digest
SHA256 37252e7567203f98d171f768e6e54a72358853cd036388e9594b0c0014a41ca6
MD5 211a21dd91b23ee5172ae034561b3f5e
BLAKE2b-256 98a69f1d854c658c2fc0e057cdc38917e51c0d4ffc4113a7ddacb48d37ed1827

See more details on using hashes here.

File details

Details for the file facteval-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: facteval-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for facteval-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdc68476aea9960924d9c004838bb6a0b6a473c2adf5fa88fd4f900da08ad87e
MD5 b83407afc020f76ea24d87112f4dbd90
BLAKE2b-256 c977bb9a38655a1c39932503972f7b83f21b5190d37b9678fc8fe0ac154d503a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page