PaddleOCR vs Claude Vision: Which Should Read Your Documents?
← All posts
GuideOct 18, 2026· 10 min read

PaddleOCR vs Claude Vision: Which Should Read Your Documents?

If you searched for PaddleOCR vs Claude Vision, you probably have a folder of scans or screenshots and two very different options on the table: an open-source OCR toolkit you run yourself, or a general multimodal model you call over an API. Some of those searches ask for a YouTube walkthrough. This is the written version, with a script you can run. Short answer: PaddleOCR is the better default for high-volume, repeatable transcription. It runs on your own hardware, costs no per-page fee, and returns text lines with bounding boxes and confidence scores you can audit. Claude vision is the better tool when the page needs interpretation: a messy layout, a question about what the document means, or a low volume where a few cents per page does not matter. It returns whatever you ask for, but without per-line confidence, and Anthropic documents that its coordinates are approximate. At real volume, the practical answer is often both: PaddleOCR on every page, Claude on the exceptions.

This post compares the two head to head. If you are still deciding between whole families of models (classic engines, document VLMs, general vision models), start with the OCR model guide. If your question is whether Claude does OCR at all, Does Claude Have OCR? covers that.

The comparison at a glance

PaddleOCR Claude vision
What it is Open-source OCR and document parsing toolkit from Baidu’s PaddlePaddle team, Apache 2.0 Image understanding inside Anthropic’s Claude models, used through the Messages API or claude.ai
Where it runs Your CPU or GPU, offline if needed Anthropic’s API, Amazon Bedrock, Google Cloud, Microsoft Foundry
Default output Text lines with polygons, boxes, and a recognition score per line (PP-OCRv6), or Markdown and JSON (PaddleOCR-VL) Whatever your prompt or tool schema asks for: plain text, Markdown, JSON
Confidence scores Yes, per text line No per-line score in the response
Coordinates Pixel boxes from the detector; PP-StructureV3 adds table cell coordinates Can return coordinates on request; documented as approximate
Public document benchmarks PaddleOCR-VL-1.6 scores 96.34 Overall on OmniDocBench v1.6 No row in the OmniDocBench or olmOCR-Bench tables
Cost model No license fee; you pay for hardware and operations Per token: about 28×28 pixels per visual token, plus output tokens
Typical failure Loses table structure or misreads a character; per-line scores help you triage Fluent output that can paraphrase, skip, or invent text on poor images
Best fit Bulk transcription, offline or regulated data, audit trails Judgment, mixed content, low volume, follow-up questions

The rest of this post explains each row and ends with a way to test both on your pages instead of trusting the table.

What PaddleOCR gives you

PaddleOCR is a toolkit, not one model, so “PaddleOCR” in a comparison can mean three different things. The project README describes them:

  1. PP-OCR (now PP-OCRv6). The classic two-stage pipeline: a detector finds text lines, a recognizer reads each one. PaddleOCR 3.7.0 (June 2026) made PP-OCRv6 the default. It comes in tiny (1.5M parameters), small (7.7M), and medium (34.5M) tiers, and a single model covers 50 languages: Chinese, English, Japanese, and 46 Latin-script languages. The release notes report a 5.2× CPU speedup with OpenVINO and 0.13 s inference on an A100 GPU. Those are the project’s own numbers.
  2. PaddleOCR-VL. A 0.9B document vision language model that writes a whole page as Markdown or JSON, including tables, formulas, and charts. Version 1.6 (May 2026) scores 96.34 Overall in the OmniDocBench v1.6 table, third behind TeleOCR (96.91) and OvisOCR2 (96.47) when we read it in October 2026. Its pipeline can also merge tables that continue across pages and rebuild heading levels for multipage PDFs.
  3. PP-StructureV3. A layout pipeline that also outputs Markdown or JSON, with finer coordinates than the VL models, including table cell and text positions.

The models are released under Apache 2.0 (the Hugging Face cards for PaddleOCR-VL-1.6 and the PP-OCRv6 medium recognizer carry that license), so you can run them commercially and offline.

For the basic pipeline, the general OCR docs show the whole integration in a few lines:

from paddleocr import PaddleOCR

ocr = PaddleOCR(
    use_doc_orientation_classify=False,
    use_doc_unwarping=False,
    use_textline_orientation=False,
)
for res in ocr.predict("delivery-note.png"):
    res.print()
    res.save_to_json("output")

Each result holds rec_texts (the recognized lines), rec_scores (one confidence value per line), and rec_boxes (an [x_min, y_min, x_max, y_max] box per line). That trio is the main practical difference from a vision LLM. You can sort by score, send the bottom few percent to review, and point a reviewer at the exact pixels that produced a value.

What PaddleOCR does not do is decide anything. It will not tell you whether a form is complete, which of two dates is the due date, or that a stamp says “VOID”. You write those rules on top of the text.

Running it is also your job. PP-OCR runs fine on a CPU. PaddleOCR-VL is heavier: its docs say the quick-start path is for validation, recommend a dedicated VLM inference service for production, and list vLLM serving as needing an NVIDIA GPU with compute capability 8.0 or higher (RTX 30 series, A10, A100 and newer).

What Claude vision gives you

Claude has no separate OCR model. Text reading is part of image understanding in every current Claude model, and you reach it by sending an image block to the Messages API with an instruction. Anthropic’s vision guide sets the ground rules:

  • Formats and limits. JPEG, PNG, GIF (first frame only), and WebP. Up to 8000×8000 px per image and 10 MB per base64 image on the Claude API. Up to 600 images per request (100 for models with a 200k context window), but once a request holds more than 20 images, keep each one at or below 2000 px per side.
  • Token cost. An image costs ⌈width / 28⌉ × ⌈height / 28⌉ visual tokens. Claude 4.7 and later models use a high-resolution tier with a 2576 px long edge and a 4,784-token cap per image. Older models cap at 1568 px and 1,568 tokens. Larger images are downscaled to fit, which can make small print illegible.
  • Documented weak spots. Claude “might hallucinate or make mistakes when interpreting low-quality, rotated, or very small images under 200 pixels”, and its coordinate outputs are approximate. Anthropic’s advice is to verify outputs before relying on them for high-stakes work.

The strengths are the mirror image of PaddleOCR’s limits. Claude reads a page and can answer questions about it in the same call: is this invoice overdue, which box is ticked, what does this chart show, does page 3 contradict page 1. It handles screenshots, mixed photos and text, and odd layouts without a layout model, and it can return JSON that matches a tool schema you define. For request shapes in curl and Python, see Claude OCR API.

The catch is that fluent output is not the same as faithful output. A pipeline OCR engine that misreads a word gives you wrong characters plus a line score you can filter on, though a high score is no guarantee. A language model that cannot read a word may return a plausible one instead. On a clean page that rarely matters. On a faded delivery note with a handwritten quantity, it is the whole risk.

Cost: hardware you run versus tokens you pay

PaddleOCR has no per-page price. Your cost is the machine, the engineer who keeps the pipeline running, and the GPU if you use PaddleOCR-VL at volume. At a few hundred pages a month that is mostly setup time. At hundreds of thousands of pages, compare your hardware and staff cost per page with the token figures below. Only you can price those.

Claude’s cost is easier to estimate up front. Take a US letter page scanned at 200 DPI: 1700×2200 px. That works out to 61 × 79 = 4,819 patches, just over the 4,784-token cap, so a current high-resolution model sees about 4,784 visual tokens per page. The output depends on how much text the page holds. The figures below assume 1,000 output tokens per page, which is an assumption for a fairly dense page, not a measurement. Prices are from Anthropic’s pricing page as of October 2026:

Model Input per 1,000 pages Output per 1,000 pages Total With Batch API (50% off)
Claude Sonnet 5.5 ($2 in / $10 out per MTok) $9.57 $10.00 about $19.57 about $9.78
Claude Haiku 5.5 ($0.10 in / $0.50 out per MTok, prompts under 100k tokens) $0.48 $0.50 about $0.98 about $0.49

Three things move that number. Downscaling the scan before upload cuts input tokens (at the risk of legibility). Thinking tokens, if the model reasons before answering, bill as output. And Claude 4.7 and later models use a tokenizer that Anthropic says produces about 30% more tokens for the same text, so older per-page estimates run low. The response’s usage field reports real counts, and the script below prints them for every page.

Accuracy: what public numbers can and cannot tell you

There is no published head-to-head score for PaddleOCR versus Claude on documents. PaddleOCR-VL-1.6 is near the top of the OmniDocBench v1.6 table at 96.34, and the olmOCR 2 report lists the original PaddleOCR-VL at 80.0 on olmOCR-Bench (a figure reported by the PaddleOCR authors, not rerun by Ai2). Claude appears in neither table. The olmOCR 2 report does use claude-sonnet-4 inside its synthetic data pipeline, to rewrite sample pages as HTML that later become unit tests, but it never scores Claude as an OCR system.

The general models that are on OmniDocBench sit a few points below the specialized ones: Gemini 3 Pro at 92.91 and GPT-5.2 at 86.59, against 96.34 for PaddleOCR-VL-1.6. That suggests a pattern, but it is not a Claude result, and you should not treat it as one. The OCR model guide has the wider tables and their caveats.

The more useful point is that the two tools fail differently, so a single accuracy number hides what matters. Character error rate punishes PaddleOCR for every split line and rewards Claude for tidy Markdown, while the one wrong digit in an invoice number is what actually costs you money.

Run both on your own pages

The script below sends every image in a folder through PaddleOCR (PP-OCRv6) and through Claude, writes one output file per page per engine, prints PaddleOCR lines below a confidence threshold, and prints Claude’s token usage. The folder layout matches the scoring harness in the OCR model guide, so you can score both engines against hand-checked text right after.

"""Run PaddleOCR and Claude vision over the same page images.

Writes preds/paddleocr/<page>.txt and preds/claude/<page>.md, prints
low-confidence PaddleOCR lines and Claude token usage per page.

  pip install paddleocr anthropic   # plus a PaddlePaddle build, see PaddleOCR docs
  export ANTHROPIC_API_KEY=...
  python compare.py pages/            # both engines
  python compare.py pages/ --paddle-only
"""
import argparse
import base64
import mimetypes
from pathlib import Path

PROMPT = (
    "Transcribe all visible text in this image as Markdown. Keep the reading "
    "order, headings, and tables. Do not correct, summarize, or add anything "
    "that is not in the image. Write [illegible] where you cannot read a word."
)
IMAGE_TYPES = {"image/png", "image/jpeg", "image/webp", "image/gif"}


def run_paddle(ocr, page: Path, out_dir: Path, min_score: float) -> list[str]:
    lines, flagged = [], []
    for res in ocr.predict(str(page)):
        data = res.json.get("res", res.json)
        for text, score in zip(data["rec_texts"], data["rec_scores"]):
            lines.append(text)
            if score < min_score:
                flagged.append(f"{score:.2f}  {text}")
    (out_dir / f"{page.stem}.txt").write_text("\n".join(lines) + "\n")
    return flagged


def run_claude(client, model: str, page: Path, out_dir: Path) -> tuple[int, int]:
    media_type = mimetypes.guess_type(page.name)[0]
    data = base64.standard_b64encode(page.read_bytes()).decode()
    msg = client.messages.create(
        model=model,
        max_tokens=4096,
        messages=[{
            "role": "user",
            "content": [
                {"type": "image",
                 "source": {"type": "base64", "media_type": media_type, "data": data}},
                {"type": "text", "text": PROMPT},
            ],
        }],
    )
    text = "".join(block.text for block in msg.content if block.type == "text")
    (out_dir / f"{page.stem}.md").write_text(text)
    return msg.usage.input_tokens, msg.usage.output_tokens


def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("pages", type=Path)
    ap.add_argument("--model", default="claude-sonnet-5-5")
    ap.add_argument("--min-score", type=float, default=0.80)
    ap.add_argument("--paddle-only", action="store_true")
    args = ap.parse_args()

    pages = sorted(p for p in args.pages.iterdir()
                   if mimetypes.guess_type(p.name)[0] in IMAGE_TYPES)

    from paddleocr import PaddleOCR
    ocr = PaddleOCR(
        lang="en",
        use_doc_orientation_classify=False,
        use_doc_unwarping=False,
        use_textline_orientation=False,
    )
    paddle_dir = Path("preds/paddleocr")
    paddle_dir.mkdir(parents=True, exist_ok=True)

    client = None
    if not args.paddle_only:
        import anthropic
        client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY
        claude_dir = Path("preds/claude")
        claude_dir.mkdir(parents=True, exist_ok=True)

    for page in pages:
        flagged = run_paddle(ocr, page, paddle_dir, args.min_score)
        print(f"{page.name}: paddleocr wrote {page.stem}.txt, "
              f"{len(flagged)} line(s) below {args.min_score}")
        for line in flagged:
            print(f"    {line}")
        if client:
            tokens_in, tokens_out = run_claude(client, args.model, page, claude_dir)
            print(f"{page.name}: claude wrote {page.stem}.md, "
                  f"{tokens_in} input / {tokens_out} output tokens")


if __name__ == "__main__":
    main()

A few notes on the design. The script only takes images, because Claude’s image block accepts JPEG, PNG, GIF, and WebP; split PDFs into page images first, or switch Claude to a document block. The prompt tells Claude to mark unreadable words instead of guessing, which reduces invented text but does not eliminate it. And --paddle-only lets you run the free half before you spend any tokens.

We ran the PaddleOCR half on a synthetic delivery note created for this post, with PaddleOCR 3.7.0 on a CPU (the first run downloads the PP-OCRv6 medium detection and recognition models). It read every line correctly, including the note number, PO reference, and a Romanian place name. It also returned the item table’s header as two separate lines, “Item” and “Qty Unit”, because the basic pipeline reports text lines and boxes, not table structure. On a blurred, heavily compressed half-size copy of the same page, every line still read correctly and the lowest line score was 0.93. That is the lesson in miniature: confidence scores tell you when characters are uncertain, not when structure is lost. If you need tables back as tables, use PaddleOCR-VL or PP-StructureV3 for those pages, or ask Claude for Markdown.

To score both engines, hand-correct the text of 50 to 200 real pages into a truth/ folder, list the values that must be exact (invoice numbers, totals, dates) in .fields.json files, and run the harness from the model guide. Watch the field column more than the error rate.

When to choose PaddleOCR, Claude, or both

Choose PaddleOCR when:

  • you process thousands of pages and want cost to scale with hardware, not tokens
  • pages cannot leave your network, or you need to run offline
  • reviewers need a confidence score and a pixel box for every extracted line
  • the documents are mostly printed text in the languages PP-OCRv6 or PaddleOCR-VL cover

Choose Claude vision when:

  • the job is a judgment about the page, not only a transcript
  • volume is low and the per-page cost is noise in your budget
  • layouts vary so much that you would otherwise maintain rules per template
  • you want to ask follow-up questions about the same document

Use both when you have volume and messy exceptions. Run PaddleOCR on every page, validate the values you care about in code (formats, check digits, totals that must add up), and send only the pages that fail validation or have low-scoring lines to Claude with a specific question. Claude can also work on PaddleOCR’s text instead of the image when the task is classification or summarizing, which costs text tokens rather than visual tokens.

Where OCRskill fits

There is a third option if you want neither GPUs to manage nor vision prompts to maintain. OCRskill is a hosted OCR API: you send a file to POST /ocr and get Markdown back, or call POST /ocr.json?fields=... and get the named fields as typed JSON, with a 400 when a required field is missing. Uploads are limited to 20 MB, and the structured JSON API reference lists the supported fields.

To add it to the comparison above, save its output in a third folder and score all three:

export API_KEY="sk-your-key-here"   # free key: curl https://api.ocrskill.com/get-key.json
mkdir -p preds/ocrskill

for f in pages/*.png; do
  curl -s https://api.ocrskill.com/ocr \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: image/png" \
    --data-binary "@$f" > "preds/ocrskill/$(basename "${f%.png}").md"
done

OCRskill does not replace Claude for questions about meaning, and it is not an offline option like PaddleOCR. It belongs in the test when your real goal is clean text or fields without running a model yourself.

Limitations of this comparison

  • Both sides move fast. PaddleOCR shipped PP-OCRv6 in June 2026 and PaddleOCR-VL-1.6 in May 2026, and Anthropic’s model lineup and prices change too. Recheck versions and prices before you commit.
  • The cost table rests on an assumption. Output tokens per page vary widely with text density. Use the usage numbers from your own run.
  • Vendor numbers are vendor numbers. PP-OCRv6 speed claims come from the PaddleOCR project, and the olmOCR-Bench figure for PaddleOCR-VL was reported by its authors. Benchmark tables reflect the pages in the benchmark, which lean toward PDFs, papers, and books.
  • Our test page was synthetic and small, and only the PaddleOCR half was run. It shows how PaddleOCR’s output is shaped, not which engine is more accurate on your documents.
  • Neither tool removes verification. IDs, amounts, and dates need checks in code or a human review step, whichever engine produced them.

Conclusion

PaddleOCR and Claude vision are not competing for the same job as often as the “vs” suggests. PaddleOCR is a transcription engine you own: cheap at volume, auditable line by line, and blind to meaning. Claude is a reader that understands the page and charges per token for it, with no confidence score to tell you when it guessed. There is no public benchmark that ranks them against each other on documents, so the decision comes down to your pages. Run the free PaddleOCR half of the script first, look at where its scores drop and where structure breaks, then send those pages to Claude and compare the token bill with the review time you saved. Whatever wins that test on your documents is the right answer.