DEV Community

Cover image for Best Open-Source Structured Data Extraction Models for Financial Reports
Kiell Tampubolon
Kiell Tampubolon

Posted on

Best Open-Source Structured Data Extraction Models for Financial Reports

Quick answer: Among open-weight models with a commercial licence and a size a single team can serve, Qwen3.8-27B is the strongest general extractor, and NuExtract3 is the best purpose-built one. Qwen3.5-4B and Qwen3-4B-Instruct-2507 cover stable, high-volume schemas cheaply, and GLiNER2 and NuNER_Zero tag entities on CPU. SIE serves the document models you put into production, on Cloud or in your cluster, behind one API.

The segment table came back clean. Four operating segments, each with a revenue figure, a period and a unit, and the schema validator passed every row. Then someone added the segments up and got a number larger than consolidated revenue. The model had read the "Intersegment eliminations" row as a positive figure, so the eliminations were added back instead of taken away. JSON validators are the most relaxed reviewers in finance. They check that a number is a number and ask nothing about its sign, its scale or which row it came from.

This ranking covers open-weight models with a licence that permits commercial use, turning report text or page images into fields such as revenue, period, unit, scale and segment. It assumes the text is already available: for EDGAR filings that means the HTML of the filing itself, and OCR only for PDF-only sources, which the companion list of open OCR models covers. Hosted frontier models are not ranked, but they get a direct comparison after the list.

One point before the models. For a US filer's face statements, you may not need a model at all. The SEC's XBRL APIs return tagged facts in base units. What those APIs leave out is where models earn their place: untagged tables in MD&A and EX-99.1 earnings releases, non-US annual reports that exist only as PDF, and the segment detail discussed below.

1. Qwen3.8-27B

Model card: Qwen/Qwen3.8-27B on Hugging Face

Qwen3.8-27B is a 27.8B dense model from Qwen with native vision-language input, licensed Apache-2.0, so commercial use is permitted. It reads page images directly, so a PDF page can go in without a separate OCR step when the layout allows.

It ranks first on evidence and capability together. Its card reports 91.1 on OmniDocBench v1.5, the strongest document-parsing figure among the generative models here. It takes text and images in one request, it can produce structured output under a JSON-schema grammar when the serving layer supports it, and it has a native context of 262,144 tokens, extensible to one million, which fits a full 10-K section with room for the schema. Thinking mode is on by default. For extraction, switch it off per request, or every field pays for reasoning you did not ask for.

The limit is size. Self-hosting a 27B model needs a large GPU, and the card reports no finance-specific extraction score.

Deployment shape: open weights. It is priced on SIE Cloud as Qwen/Qwen3.8-27B-FP8; the self-hosted catalog carries the previous generation, Qwen3.6-27B, also Apache-2.0 at 27.8B. It suits schemas that need judgement: segment tables, footnoted adjustments, and fields that depend on reading two rows together.

2. NuExtract3

Model card: numind/NuExtract3 on Hugging Face

NuExtract3 from NuMind is built for one job: filling a JSON template from a document. It is a 4B-parameter fine-tune of Qwen3.5-4B, released under Apache-2.0, so commercial use is permitted. It reads text and images, handles multilingual documents, and runs with a 131,072-token context in the vLLM configuration its card gives. NuMind also publishes quantised builds, including FP8 and GGUF.

The template language is its strength. You describe the fields, and the model returns null or an empty array when a value is absent. In finance that matters: a model that abstains on a missing segment figure is easier to trust than one that invents a plausible number. It also offers reasoning and non-reasoning modes, and it can convert pages to Markdown with tables as HTML.

The numbers are NuMind's. On its internal benchmark of about 600 documents, described as including invoices, movie posters and floor plans, the card reports 0.651 for NuExtract3 against 0.417 for its base, Qwen3.5-4B. On ExtractBench, the card reports a mean of 82.35. Neither set is described as covering financial filings.

Deployment shape: open weights you serve yourself, for example with vLLM, as the card shows. It suits teams that want template extraction with abstention from a model sized for one GPU.

3. Qwen3.5-4B

Model card: Qwen/Qwen3.5-4B on Hugging Face

Qwen3.5-4B is a small generative model, 4.66B parameters in its weights, licensed Apache-2.0, so commercial use is permitted. It shares the family's 262,144-token context and, like Qwen3.8, thinks by default unless you disable it.

Its place here is cost. For a dozen fields pulled from the same report section each period, a 4B model on a small GPU is often enough, and at volume the saving is the reason to test it. The card also reports an OmniDocBench v1.5 result; the rank here rests on size and cost. Whether it is accurate enough is a question only your evaluation set can answer, so test it on the hardest filers you cover, not the tidiest.

Deployment shape: open weights, in SIE's self-hosted catalog, and runnable locally. On SIE Cloud, priced extraction runs on Qwen3.8-27B (FP8). The 4B runs self-hosted or locally. It suits high-volume, stable schemas.

4. Qwen3-4B-Instruct-2507

Model card: Qwen/Qwen3-4B-Instruct-2507 on Hugging Face

Qwen3-4B-Instruct-2507 is an earlier 4B generation, licensed Apache-2.0, so commercial use is permitted. Its card is plain about the difference that matters: it supports only non-thinking mode. Context is 262,144 tokens natively.

That makes it the predictable choice. With no thinking tokens, latency per field is steady, which suits an extraction service with a response-time budget, and output length is easier to cap. It is older than Qwen3.5-4B, so expect the newer model to edge it on harder pages. Running both on the same evaluation set is cheap and tells you whether the gap matters for your schema.

Deployment shape: open weights, in SIE's self-hosted catalog, and runnable locally. It suits teams that value consistent latency over the last point of accuracy.

5. GLiNER2 Large

Model card: fastino/gliner2-large-v1 on Hugging Face

GLiNER2 from Fastino is an encoder model, 486M parameters in its large weights, licensed Apache-2.0, so commercial use is permitted. Its card describes entity recognition, classification, structured extraction and relation extraction in a single forward pass, and calls it CPU first.

Speed is the draw. For fields that are named things rather than computed ones, such as company name, auditor, segment label or fiscal year-end, a schema-driven encoder is fast and cheap. It does not generate text and does not reason across tables, so a subtotal that must be checked against two rows is beyond it.

Deployment shape: open weights that run on CPU; in SIE's self-hosted catalog; and priced on SIE Cloud at $0.186 per million input tokens, as listed on 2026-09-30. It suits the first pass of a pipeline, tagging entities and routing pages before a generative model handles the numbers.

6. NuNER_Zero

Model card: numind/NuNER_Zero on Hugging Face

NuNER_Zero from NuMind is a 449M zero-shot entity tagger, licensed MIT, so commercial use is permitted. You pass the labels as input, and it finds the spans.

It ranks last because its job is the smallest. It tags spans and nothing more: no schema, and no sense of what a number means. For the simplest fields, such as the company, the auditor or a date, that is enough, and a model this size is cheap to run on every document. Its card has not been updated since February 2025.

Deployment shape: open weights; in SIE's catalog for self-hosting or local use, and on SIE Cloud. It suits a light entity pass before heavier extraction.

How these compare with hosted APIs

Hosted frontier models are a separate serving path from the open weights above. OpenAI Structured Outputs guarantees responses that adhere to a supplied JSON schema, and Gemini and Claude offer schema-constrained output too. Prompt caching and batch pricing, about half the list price, cut the cost of stable prompts.

OpenAI gpt-6.1-sol costs $2 per million input tokens and $10 per million output, and gpt-6-astra $10 and $50. OpenAI also ships open-weight gpt-oss models under Apache-2.0, but the frontier GPT family is hosted only. Google Gemini reads PDFs natively, pages as images, including tables and charts, in documents up to 1,000 pages. Gemini 3.8 Flash is $0.75 and $3.75 at a promotional price through 2026-12-31, and Gemini 3.1 Pro Preview is $2 and $12. Anthropic Claude Sonnet 5.5 costs $2 and $10, with a one-million-token window at standard pricing.

The cost is structural. Documents go to the provider's service. Regional data residency and zero-retention terms exist, and Azure OpenAI, Vertex AI and Bedrock run inside your cloud tenancy, but the model does not run in your own cluster. Per-token cost also scales with volume. Open models run on SIE, on Cloud or in your own cluster, with weights you pin.

Schema adherence, from any provider, still only guarantees the shape. The eliminations row in the opening example would have passed strict JSON-schema output, because the error was a sign, not a type.

How to run these models

Superlinked Inference Engine

Superlinked SIE is an inference layer for task-specific models. It serves the document models you put into production, next to the OCR models and embedders a reporting pipeline also needs. It runs in three modes: managed on SIE Cloud, priced per use with no GPUs to run; self-hosted in your own VPC or Kubernetes cluster, the same engine under Apache 2.0; and locally for development.

On Cloud, as priced on 2026-09-30, Qwen3.8-27B (FP8) backs doc field extraction and structured output at $0.72 per million tokens in and $0.72 out, GLiNER2 Large is $0.186 per million input tokens, and NuNER_Zero is available. Qwen3.6-27B, Qwen3.5-4B and Qwen3-4B-Instruct-2507 sit in the model catalog for self-hosted and local use. The SDK's extract call takes a model ID and a list of labels, and the documentation covers generate for the Qwen models, so comparing two candidates on one evaluation set needs no second serving stack.

Honest take: SIE serves the document models you put into production, on SIE Cloud or in your own cluster, behind one API. OCR, extraction, embeddings and reranking share that client. On Cloud, Qwen3.8-27B (FP8) backs field extraction and structured output, with GLiNER2 and NuNER_Zero beside it, and Superlinked runs the GPUs. Self-host the same Apache 2.0 engine on your own GPUs, and the open weights in the catalog, including the Qwen extractors, run under the same model IDs. You point one SDK at a gold set, swap the model ID, and keep the schema, the labels and the serving path stable.

How we ranked them

No benchmark decides this order, because none of the ranked models publishes a financial-report extraction score. The order rests on four criteria: the range of fields a model can handle, from entity labels to computed figures; fit for schema-bound output, including abstention; the publisher's evidence, such as OmniDocBench v1.5 or template-extraction scores, read as attributed claims; and size and cost to run. Licence was a gate, not a score: every entry permits commercial use. Where a model runs is reported in each entry's deployment line and played no part in the order.

Frequently asked questions

How do we get segment revenue when companyfacts does not have it?

companyfacts, companyconcept and frames include only facts that use a non-custom taxonomy and apply to the entire filing entity, so segment and other dimensional facts are excluded, as are company extension tags. Read them from the filing's own inline XBRL instead: each ix:nonFraction points to a contextRef, and that context carries the axis and member, such as StatementBusinessSegmentsAxis and the segment's member. Extract by axis and member, keep the eliminations member separate with its sign, and check that segments plus eliminations equal the consolidated fact.

How do we stop thousands-versus-millions scale errors?

Make scale a field. Extract the unit and the scale statement ("in thousands", "in millions") as values next to every figure, then normalise in code, never in the prompt. In inline XBRL the scale is markup: a figure displayed as "78,678" carries scale="6" on its ix:nonFraction element, so it means 78,678 million, and decimals (for example -6) states the rounding precision, which is the right tolerance when you match. The JSON APIs return base units with no scale attribute, so compare against those.

Should we fine-tune or prompt?

Prompt first. With a typed schema, a few examples and thinking switched off, the models above often clear the bar on stable sections, and you learn where they fail. Fine-tune only when the evaluation shows a consistent error you cannot prompt away, such as a filer layout the model keeps misreading.

Where to start

Start with the schema, not the model. For fields that need judgement, test Qwen3.8-27B; for strict templates with abstention, NuExtract3; for stable high-volume sections, Qwen3.5-4B; for entity fields, GLiNER2. SIE serves the document models you put into production, on Cloud or in your cluster, behind one API. The SIE Cloud page lists the priced models and a first request you can point at your own reports.

Top comments (1)

Collapse
 
arhancanli profile image
Arhan Canli •

The eliminations example is the right test to build the evaluation around, because it is checkable without any labels: segment revenues plus the eliminations row has to equal the consolidated figure, and that one reconciliation catches sign, scale and wrong-row errors in one go. I'd add it as a hard gate after extraction (and the same for segment assets and operating income), and report per model how often the gate fails rather than field accuracy alone. A model can score 98% per field and still fail the sum on a large share of filings.

Two things that bite on real EDGAR data: in XBRL the eliminations usually sit under a different dimension member and often carry a negative or negated-label presentation, so the "correct" sign in the HTML table and in the tagged fact can legitimately differ; and a restated prior-year number can be re-filed under a different tag, so the same row won't line up across two filings unless you key on the filing, not the concept name. Both are worth including in the eval set as named hard cases.

One question: for the four models you rank without finance-specific scores, did you run any of them on a reconciliation set like this, or are the rankings from the model cards only? If it's the cards, a short table of "gate passes out of N filings" would be the most useful addition.

For the face statements and tagged facts I built canli-mcp, a free MIT MCP server (no key, runs locally) that reads them from EDGAR: npx -y canli-mcp, github.com/arhancanli/canlicapital.