Skip to content

Add --no-ocr for the fastest possible PDF path (embedded text only) - #21

Merged
artiz merged 2 commits into
masterfrom
claude/focused-curie-zkkv2p
Jul 1, 2026
Merged

Add --no-ocr for the fastest possible PDF path (embedded text only)#21
artiz merged 2 commits into
masterfrom
claude/focused-curie-zkkv2p

Conversation

@artiz

@artiz artiz commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a no_ocr option that skips layout detection, OCR, and TableFormer entirely — no ML model load, no inference of any kind. Regions come purely from the PDF's embedded text cells via the existing orphan-region mechanism (normally used to rescue text the layout detector missed; here it rescues all of it), grouped by line and emitted as flat paragraphs in reading order.

This is the fastest possible PDF path, at the cost of structure: no headings, lists, tables, code blocks, or pictures, since that classification comes from the layout model. no_ocr implies no_table_former. Pages with no embedded text layer (scanned/image-only PDFs) come back empty rather than erroring, so a caller can detect that and re-convert without the flag.

Benchmarked on amt_handbook_sample.pdf: default ≈4.8s, --no-table-former ≈1.8s, --no-ocr ≈0.55s.

Key Changes

  • PDF Pipeline (fleischwolf-pdf):

    • Worker gains a no_ocr flag; when set, the layout model isn't even loaded, and process() short-circuits to build regions straight from add_orphan_regions on an empty region list
    • Pipeline gains a .no_ocr(bool) builder method (mirrors .no_table_former)
    • _with_options free functions (convert_with_options, convert_image_with_options, convert_pages_with_options, convert_mets_gbs_with_options) take a new no_ocr parameter
  • Document Converter (fleischwolf):

    • DocumentConverter gains a .no_ocr(bool) builder method, threaded through both the buffered convert() path and the streaming path
  • CLI (fleischwolf-cli):

    • New --no-ocr flag, documented in the module doc, usage string, and benchmark warm-up path
  • Documentation (README.md):

    • Documents --no-ocr's behavior and the scanned-PDF fallback caveat

Testing

  • cargo build --workspace --all-targets, cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings, and cargo test -p fleischwolf -p fleischwolf-pdf --lib all pass
  • Manually verified against a text-layer PDF (flat paragraph output, correct reading order) and a mostly-graphic PDF (no crash, only text cells extracted)

https://claude.ai/code/session_01StCE48TQ4sw2kQ2zxveNa2


Generated by Claude Code

claude added 2 commits July 1, 2026 21:04
Adds the fastest possible PDF path: no model load, no inference at
all. Regions come purely from the PDF's embedded text cells via the
existing orphan-region mechanism (normally used to rescue text the
layout detector missed; here it rescues all of it), grouped by line
and emitted as flat paragraphs in reading order. No headings, lists,
tables, code blocks, or pictures, since that structure requires the
layout model.

Implies --no-table-former. Pages with no embedded text layer
(scanned/image-only PDFs) come back empty rather than erroring, so
callers can detect that and re-convert without the flag.
--no-ocr's per-page time was ~90% wasted: extract_page always
rasterized the full page bitmap (render + CatmullRom downsample) for
layout/OCR/TableFormer, none of which no_ocr ever runs. Thread
render_image through for_each_page/extract_page, driven by
Pipeline::no_ocr, so the fast path skips rendering outright.

Separately, extract_page always ran pdfium's FFI text extraction and
then discarded it whenever the Rust parser's prose/word/code cells
were non-empty (the common case, in every mode) — that pdfium call is
now lazy, only running when the parser's per-channel output is
actually missing.

Net effect on a representative single-page PDF: --no-ocr's per-stage
time drops from ~336ms to ~21ms (textparse + assemble only). Verified
byte-identical output for both --no-ocr and the default pipeline, and
scripts/pdf_conformance.sh: 91/91 exact, 0 drift.
@artiz
artiz merged commit cb7ed00 into master Jul 1, 2026
3 checks passed
@artiz
artiz deleted the claude/focused-curie-zkkv2p branch July 1, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants