Add --no-ocr for the fastest possible PDF path (embedded text only) - #21
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
no_ocroption 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_ocrimpliesno_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):Workergains ano_ocrflag; when set, the layout model isn't even loaded, andprocess()short-circuits to build regions straight fromadd_orphan_regionson an empty region listPipelinegains a.no_ocr(bool)builder method (mirrors.no_table_former)_with_optionsfree functions (convert_with_options,convert_image_with_options,convert_pages_with_options,convert_mets_gbs_with_options) take a newno_ocrparameterDocument Converter (
fleischwolf):DocumentConvertergains a.no_ocr(bool)builder method, threaded through both the bufferedconvert()path and the streaming pathCLI (
fleischwolf-cli):--no-ocrflag, documented in the module doc, usage string, and benchmark warm-up pathDocumentation (
README.md):--no-ocr's behavior and the scanned-PDF fallback caveatTesting
cargo build --workspace --all-targets,cargo fmt --check,cargo clippy --workspace --all-targets -- -D warnings, andcargo test -p fleischwolf -p fleischwolf-pdf --liball passhttps://claude.ai/code/session_01StCE48TQ4sw2kQ2zxveNa2
Generated by Claude Code