Spaces:
Running
A newer version of the Gradio SDK is available: 6.20.0
Data & Extraction Specification
1. Datasets
All free, all on Hugging Face and/or Kaggle. data.gov.sg is not a source β it publishes statistical open data, not document images. The set below is chosen to cover every required input modality and to provide ground-truth labels, which the evaluation harness needs.
| Dataset | What it is | Modality covered | Labels | Where |
|---|---|---|---|---|
| SROIE (ICDAR 2019) | ~1,000 real scanned receipts from shops/restaurants; variable print & scan quality | Scans | company, address, date, total | HF: Voxel51/scanned_receipts; also priyank-m/SROIE_2019_text_recognition |
| CORD | ~11,000 Indonesian receipts captured in the wild; noisy, low quality; multi-level labels (store/menu/subtotal/total + subclasses) | Scans / in-the-wild | rich key-value + line items | HF: search CORD (naver-clova-ix) |
| MC-OCR | 2,436 receipts captured on mobile devices | Phone photos | quality + key fields | Search "MC-OCR RIVF 2021" (HF mirrors / challenge page) |
| High Quality Invoice Images for OCR | ~6,700 synthetic but realistic invoices | Native-style invoices | invoice fields | Kaggle: osamahosamabdellatif/high-quality-invoice-images-for-ocr; HF: Voxel51/high-quality-invoice-images-for-ocr |
| invoices-and-receipts_ocr_v1 | Mixed invoices + receipts with OCR/structure | Mixed | structured | HF: mychen76/invoices-and-receipts_ocr_v1 |
| invoice-ocr-json | Invoices with structured JSON ground truth | Native invoices | JSON key-values | HF: GokulRajaR/invoice-ocr-json |
| FUNSD | 199 noisy scanned forms | Messy scans/forms | entities + relations | HF: search funsd |
| DocILE (optional, large) | Large invoice benchmark for key-info localization & extraction | Native invoices | KILE/LIR | DocILE project (HF/registration) |
Recommended working split
- Messy real receipts: SROIE (baseline real) + CORD (noisy in-the-wild).
- Phone photos: MC-OCR.
- Native invoices: High Quality Invoice Images +
invoice-ocr-json(has clean JSON labels, convenient for the eval harness). - Messy forms (stretch): FUNSD.
Hold out a fixed evaluation slice per source and never tune against it.
Licensing note
These are research/benchmark datasets with their own terms; several invoice sets are synthetic. Use them for development, evaluation, and demo only, and keep real/sensitive documents off the public demo and off free hosted backends (see NFR-2). Confirm each dataset's license before any redistribution.
2. Output schema
A single unified schema spans receipts and invoices; fields not present in a
given document are null. Define with Pydantic so the same model enforces
structured output, validates types, and serializes to storage.
class LineItem(BaseModel):
description: str | None
quantity: float | None
unit_price: float | None
amount: float | None
class Document(BaseModel):
doc_type: Literal["receipt", "invoice", "other"]
vendor_name: str | None
vendor_address: str | None
invoice_number: str | None # critical
document_date: date | None # ISO 8601
due_date: date | None
currency: str | None # ISO 4217 where detectable
line_items: list[LineItem]
subtotal: float | None
tax: float | None # critical
total: float | None # critical
# populated by the pipeline, not the model:
field_confidence: dict[str, float] = {}
validation: dict = {}
decision: Literal["accept", "review"] | None = None
Field requirements
- Always attempt:
doc_type,vendor_name,document_date,total. - Critical (precision-prioritised):
total,tax,invoice_number. - Monetary fields are numbers (no currency symbols/thousands separators); normalize during extraction.
- Dates are ISO 8601 (
YYYY-MM-DD); store raw string alongside if parsing is ambiguous.
3. Validation rules
Validation is pure functions over the parsed Document β a report. Two
classes of rule:
Hard rules (a failure forces review):
H1All critical fields parse to the correct type when present.H2Arithmetic reconciliation, when the inputs exist:subtotal + tax β totalwithin a small epsilon (rounding tolerance).H3Line-item reconciliation, when line items exist:sum(line_items.amount) β subtotal(ortotalif no subtotal).H4totalis present and non-negative.
Soft rules (reduce confidence, do not force review):
S1document_datepresent and plausible (not in the far future).S2currencyresolves to a known code.S3vendor_namenon-empty.S4Per-line arithmetic:quantity * unit_price β amount.
Epsilon for monetary comparisons accommodates rounding (e.g. Β±0.02 absolute or a small relative tolerance, whichever is larger).
4. Confidence scoring
Document confidence β [0, 1] blends:
- Model signal (weighted) β backend field/token confidence where exposed; neutral (0.5) when unavailable.
- Validation β start from model signal; subtract penalties for each soft
failure; any hard failure short-circuits to
review. - Completeness β penalty proportional to missing required fields.
Exact weights live in config and are set empirically via the eval harness. Keep the function pure and unit-tested with hand-built cases.
5. Routing
decision = review if any hard rule fails
= accept if confidence >= THRESHOLD
= review otherwise
THRESHOLD is one constant, tuned in evaluation.
6. Evaluation methodology
This is what turns "seems to work" into evidence, and it is how the precision/recall question is answered concretely.
Definitions (field level, against ground truth):
- Precision = correct extracted values / all values the system produced (and auto-accepted).
- Recall = correct extracted values / all values present in ground truth.
- F1 = harmonic mean.
Procedure:
- Run the core over each held-out dataset slice.
- Normalize predicted and gold values (numbers, dates, casing/whitespace) before comparison.
- Compute precision, recall, F1 per field and per critical field.
- Compute document-level routing stats: % auto-accepted, % to review, and β crucially β precision on the auto-accepted subset for critical fields.
- Sweep
THRESHOLDand report the precision/recall trade-off curve.
Target / operating point:
- Optimize so auto-accept precision on
total,tax,invoice_numberβ₯ 0.98, then report recall at that point. Recall "lost" to the threshold is simply review-queue volume β acceptable, because the asymmetric cost favours not writing wrong numbers. Arithmetic cross-checks (H2/H3) are the lever that raises precision without collapsing recall, since they let confident, internally-consistent values through while catching the inconsistent ones.
Report a small table per dataset (precision/recall/F1 per field, plus routing stats) in the project README β this is the portfolio's evidence of rigor.
7. Modality handling summary
- Native PDF: Docling β text/layout β backend (text or vision).
- Scan: vision-direct (Gemini reads the image) or OCR β text β backend.
- Phone photo: same as scan; vision-direct is more robust to skew/lighting, which is why the Gemini path is preferred for the demo.