← All models

document-question-answering Β· document β†’ answer (VQA) Β· WASM Β· ~215 MB

Donut β€” ask a document a question

Donut reads documents the OCR-free way: there's no separate text-extraction step. A vision transformer looks at the whole page and a decoder writes the answer to your question directly β€” What is the total? β†’ $65.40 β€” entirely on your device.

At a glance

ModelXenova/donut-base-finetuned-docvqa
Task / pipelinedocument-question-answering
ArchitectureSwin Transformer image encoder β†’ BART-style text decoder (VisionEncoderDecoder). No OCR engine.
InputA document image + a natural-language question
OutputA short free-text answer, generated token by token
Quantizationq8 (8-bit) ONNX β€” separate encoder + decoder graphs
BackendWebAssembly (runs anywhere; no WebGPU needed)
Download~215 MB, cached after first load
LicenseMIT (naver-clova-ix/donut-base-finetuned-docvqa)
Web APIsWebAssembly, Web Workers, FileReader β€” all Baseline widely available

Run it

Pick a document, type a question (or tap a preset), and hit Ask. The answer streams in as the decoder generates it β€” that's the real model, not an animation.

Drop a document here, or click to choose
An invoice from Acme Supplies Ltd A shop receipt from The Corner Store A membership form
Selected document preview

See inside β€” the task prompt & the decode

Donut turns "answer this question" into text generation. Your question is wrapped in a fixed task template and fed to the decoder as its starting prompt; the model then generates the answer tokens that come after <s_answer>, each conditioned on the image and everything decoded so far. Below is the exact prompt Donut receives and the answer streaming out, token by token with timing. This is the real output, no OCR step in sight.

Constructed task prompt

Ask a question to see the prompt Donut builds.

Answer tokens as they arrived

Ask a question to see the token-by-token trace.

Why it matters

Most document automation is a brittle chain: OCR the page, then hunt through the raw text with regexes and rules. Donut skips the OCR step β€” you ask for what you want in plain language and it answers, which makes it robust to layout and doing it locally makes it free, private, and offline-capable.

Use cases

Basics

Ask one question about a document and watch the answer stream in.

Practical

Extract a whole field set β€” total, date, number β€” from a receipt or invoice at once.

Wild

Have a back-and-forth "chat" with a document β€” ask follow-ups, build a Q&A log.

Multi-model

Donut answers β†’ M2M100 translates the answer into another language.

How the API works

The base call is a couple of lines with Transformers.js:

import { pipeline } from "@huggingface/transformers";

const docqa = await pipeline(
  "document-question-answering",
  "Xenova/donut-base-finetuned-docvqa",
); // downloads + caches ~215 MB once

const out = await docqa(documentImageURL, "What is the total due?", {
  max_new_tokens: 64,
});
// β†’ [{ answer: "$65.40" }]

Under the hood Donut wraps your question in a task prompt β€” <s_docvqa><s_question>…</s_question><s_answer> β€” and generates the answer that follows. For "See inside", this page passes a TextStreamer into the same call so the answer renders as it forms and each token's arrival time is recorded, all off the main thread in a Web Worker.

References