Buckets:

2.31 MB
182 files
Updated about 1 month ago
Name
Size
extractions
ground_truth
invoices
target
README.md8.33 kB
xet
README.md

Lumen Analytics invoices — an extraction evaluation set

Fictional. Every company, person, address, VAT id and IBAN here is invented; every page says so along its edge. Generated for the Docling × Confluent Cloud demo (example 04, examples/04-invoice-extraction in docling-project/docling-confluent-cloud), and usable on its own to evaluate structured extraction from invoices.

174 supplier invoices of a fictional Munich company, Lumen Analytics GmbH, dated 2025-12-01 to 2026-06-19: 17 vendors, 7 layouts, 139 in EUR, 21 in USD, 7 in GBP, 7 in CHF; 10 scans (rasterized, tilted, noisy, no text layer) and 8 two-page invoices; 749 line items in all. Each comes with its ground truth — what is printed on it, field by field and line by line — because the generator drew it from that.

Files

path what
invoices/<doc_id>.pdf the invoices
ground_truth/manifest.jsonl one line per invoice: layout, scanned, pages, and truth
target/extraction_target.json the extraction target the demo sends to Docling: JSON Schema + example + instructions
target/invoice.schema.json its output_schema alone
extractions/docling/<run>/results.jsonl Docling's answer per invoice, verbatim (ExtractionDocumentResult)
extractions/docling/<run>/scores.jsonl per invoice and field: predicted, expected, match
extractions/docling/<run>/run.json, SCORES.md how the run was made; its summary

This is a private Hugging Face Storage Bucket, docling-project/docling-confluent-ex04:

hf buckets sync hf://buckets/docling-project/docling-confluent-ex04 ./lumen-invoices

The invoices

layout n what it looks like
de_classic 96 German DIN-style business letter: Rechnung, 1.234,56 €, zzgl. 19 % USt., dates 09.01.2026
de_modern 31 German, modern single-column variant of the above
us_saas 21 US SaaS bill on Letter paper: $1,234.56, Jan 5, 2026 (or 01/05/2026), metered lines
eu_saas 10 EU SaaS invoice on A4, reverse-charge VAT note, unit column
uk_legal 7 UK solicitors' fee note: narrative time entries, hours × rate, 30 December 2025
ch_qr 7 Swiss invoice with a QR payment part: CHF 1'234.50
hotel_folio 2 Portuguese hotel folio: per-night lines, three IVA rates, tourist tax

The variety is the point: the same fields printed seven ways — German and Swiss number formats, US and European dates, net/tax/total blocks with one, two or three VAT rates, a two-page cloud bill whose metered lines spill over, a hotel folio whose lines are nights. One template seventeen times would be template matching, not extraction.

Ground truth

ground_truth/manifest.jsonl, one JSON object per invoice:

{"doc_id": "lumen-inv-0001", "file": "invoices/lumen-inv-0001.pdf", "layout": "uk_legal",
 "vendor_key": "kestrel", "scanned": false, "pages": 1,
 "department": "Finance", "category": "Professional Services", "submitted_at": "2026-01-05T08:20:51Z",
 "truth": {"vendor_name": "Kestrel & Finch LLP", "invoice_number": "KF/2025/0351",
           "invoice_date": "2025-12-30", "currency": "GBP", "total_amount": 7510.5, "…": "…",
           "line_items": [{"description": "…", "quantity": 6.3, "unit_price": 395.0, "amount": 2488.5,
                           "page": 1}]}}

truth holds vendor_name, vendor_vat_id, vendor_address, customer_name, invoice_number, invoice_date, due_date, currency, subtotal, tax_amount, total_amount, iban and line_items (description, quantity, unit_price, amount, and the page it is printed on). Amounts are numbers in the invoice's currency, dates ISO. department, category and submitted_at are the demo's (who submitted the invoice, when); they are not on the page.

What is asked: the extraction target

target/extraction_target.json is a Docling ExtractionTarget (docling-project/docling#4218): output_schema (the contract, validated per page), template (an example_json: one made-up invoice shown as an example answer) and instructions. It asks for a subset of the truth:

field type required description
vendor_name string yes Legal name of the company that issued the invoice (the seller, not the customer)
vendor_vat_id string or null The seller VAT or tax registration number
invoice_number string yes The invoice identifier, copied exactly
invoice_date string, date yes Date of issue
currency string, ^[A-Z]{3}$ yes ISO 4217 code of the invoice currency
subtotal number or null Net amount before tax
tax_amount number or null Total VAT or sales tax
total_amount number yes Final amount due, including tax
line_items array of LineItem One entry per billed line

LineItem:

field type required
description string yes
quantity number or null
unit_price number or null
amount number yes

Evaluating

Per invoice, the pages' answers are merged — header fields from the first page that has them, totals from the last, line items from all — and compared with truth:

field matches when
vendor_name exact after case-folding and collapsing whitespace
invoice_number exact, same normalisation
invoice_date ISO date after parsing (local formats accepted; a slash date is month-first on USD invoices)
currency exact ISO 4217 code
subtotal within 0.01
tax_amount within 0.01
total_amount within 0.01
line_item_count number of line items, all pages merged

ok is the demo pipeline's own verdict on the merged record: vendor, date, currency and total present, and subtotal + tax = total. The reference implementation is scripts/extract.py score with invoice_udf.invoice.build. Line items are counted, not matched line by line — scores.jsonl and results.jsonl have what is needed for a finer measure.

Runs

2026-10-05_granite-vision-v4

174 invoices, Docling for IBM watsonx (staging), POST /v1/extract/source/async, preset granite_vision_v4_kserve, extracted 2026-10-05; median 10.34 s per invoice. Files: extractions/docling/2026-10-05_granite-vision-v4/.

n ok vendor name invoice number invoice date currency subtotal tax amount total amount line item count
all 174 159 85% 100% 95% 100% 99% 95% 100% 95%
ch_qr 7 7 100% 100% 100% 100% 100% 100% 100% 100%
de_classic 96 90 93% 100% 98% 100% 100% 95% 100% 99%
de_modern 31 31 84% 100% 100% 100% 100% 100% 100% 100%
eu_saas 10 10 100% 100% 100% 100% 100% 100% 100% 100%
hotel_folio 2 0 100% 100% 100% 100% 100% 0% 100% 100%
uk_legal 7 7 100% 100% 100% 100% 86% 86% 100% 100%
us_saas 21 14 33% 100% 67% 100% 100% 100% 100% 67%
scanned 10 9 100% 100% 90% 100% 100% 90% 100% 100%
single-page 166 159 84% 100% 99% 100% 99% 95% 100% 100%
multi-page 8 0 100% 100% 0% 100% 100% 100% 100% 0%

Things worth knowing about these runs:

  • Multi-page invoices: page 1 of each carries 20+ line items, and the service's model server timed out on it (20 s) on every attempt — the page has an error and no data, so dates and line counts miss. A service limit at the time, not the model's answer.
  • Vendor names miss where the model "corrects" a name (Volterra for Voltara, Biurebedarf for Bürobedarf) or drops a suffix (, Inc.).
  • Dates come back as printed (20.02.2026, 30 December 2025), despite the schema's format: date and the instructions; Docling does not validate format. They are scored after parsing.
  • A page whose answer breaks the schema has extracted_data: null in Docling's result and the answer only in raw_text; the scoring reads it from there.

Generated by scripts/dataset.py on 2026-10-05; edit that, not this file.

Total size
2.31 MB
Files
182
Last updated
Oct 5
Pre-warmed CDN
US EU US EU

Contributors