PDF extraction at DevRev
We built a page-level PDF extraction gate that sends safe text pages to a CPU path and everything else to visual OCR. Here is what failed and what changed.
12 min read

Ex-MTS Intern @ DevRev
Anirudh Jayakishan
12 min read

Ex-MTS Intern @ DevRev
Anirudh Jayakishan
A lot of the PDFs that flow through an enterprise are straightforward: a report exported from Google Docs, a contract generated by a CRM, a spec sheet saved from Word. The text is right there in the file, fully addressable, ready to be read out in microseconds. Yet production OCR systems routinely spend GPU time running a vision model over these pages, “reading” an image of text that was never an image to begin with. It is the equivalent of taking a photograph of a book and then asking someone to transcribe it, when the book is already open in front of you.
At DevRev, we deployed a production document extraction pipeline based on GLM-OCR, a vision-language model for document understanding. This post describes the hybrid document-extraction pipeline we developed and use. Its smart routing directs each page to native text extraction or GLM-OCR, avoiding GPU work for pages that do not need it. In our original evaluation, fast-only requests had about 240× lower mean latency than VLM-only requests; these are different request cohorts, not paired runs of the same pages.
The baseline pipeline
Before describing our optimization, it is important to understand the baseline system that we are improving upon.
The GLM-OCR pipeline has two stages. First, a layout detector (PP-DocLayoutV3 running on CPU) processes each page and identifies regions: text blocks, titles, tables, formulas, images, and other structural elements, returning their bounding boxes and type labels. Second, each detected region is cropped and sent to GLM-OCR, a vision-language model served on a GPU, which reads the cropped image and produces structured text (markdown for text regions, formatted tables for table regions, LaTeX for formulas, and so on.).

This baseline is accurate across the full spectrum of PDFs: it handles born-digital text, scans, tables, and formulas uniformly because the VLM sees each region as an image and interprets it visually. However, it is also uniformly expensive: every region on every page, regardless of difficulty, requires a GPU inference call. Each call carries the cost of queuing (which under load can add significant wait time) and autoregressive decoding (the model generates the region’s text token by token, so processing time scales with output length). In practice, a single request, including queue wait and decoding, can take anywhere from seconds to as long as ten minutes under heavy load. For born-digital PDF pages, where the content is already fully embedded in the file and could be extracted in milliseconds, we are paying this cost to “read” an image of something that was never an image to begin with.
This is the inefficiency we set out to address.
The hybrid architecture
We augmented the baseline with a fast path: native text extraction using LiteParse. When a PDF page is born-digital, the characters and their coordinates are already in the file, so LiteParse reads them out directly. There is no model inference, no GPU, and the latency is dominated by PDF parsing. It is essentially free.
The resulting hybrid architecture has three components:
- Layout detector (PP-DocLayoutV3, CPU): detects regions on every page and returns their bounding boxes and type labels. This runs unconditionally, because we need the region structure both to drive the VLM with targeted crops and to determine whether a page is eligible for the fast path.
- Fast path (LiteParse, CPU): extracts text natively from the PDF structure for eligible pages. Zero GPU cost.
- VLM path (GLM-OCR, GPU): performs visual reading on cropped region images for all pages that are not eligible for native extraction.
The key question is: how do we determine which pages are eligible for the fast path without compromising accuracy?

The hybrid pipeline: layout detection runs on every page, then each page is routed to either the native fast path or the VLM based on page-level eligibility checks.
The routing decision
First attempt: routing per region
The natural first design is fine-grained routing. Since the layout detector already identifies regions and labels their types, we attempted to route each region independently: text regions to the fast path, and tables, formulas, and images to the VLM. In principle, this maximizes savings: on a page that is mostly text with one table, only the table region would go to the VLM while the rest is resolved natively.
However, this approach did not produce acceptable results.
The problem is that layout-detector bounding boxes are approximate. They can overlap or clip neighbouring content. A box drawn around one paragraph may capture a line or two from the paragraph above or below, and nested boxes (such as a title inside a larger text block) can share the same words. The VLM is robust to this: it processes the cropped image and is capable of ignoring stray content at the edges, reading only what is semantically relevant. Native text extraction has no such capability. When native extraction is constrained by an imperfect bounding box, it returns exactly the characters whose coordinates fall inside that box, including clipped fragments from neighbouring regions and excluding words whose coordinates fall just outside the boundary. The result is duplicated lines, dropped words, and incorrect reading order at region boundaries.
The core asymmetry: the VLM is robust to noisy region boundaries; native extraction is not. Per-region routing therefore forces native extraction to rely on the layout detector’s approximate bounding boxes, which are not always reliable: a slightly incorrect crop can duplicate text, drop words, or disrupt reading order.

Per-region routing fails because detector boxes are approximate. The VLM tolerates noisy crops; native extraction takes bounding-box coordinates literally and produces corrupted output at region boundaries.
The solution: routing per page
We moved the routing decision up to the page level. We use the fast path on the entire page only when a page is unambiguously safe for native extraction. A page qualifies only when it passes all five checks:
- Every relevant detected region on the page is a text region. Tables and formulas require structured markdown formatting (e.g. pipe-delimited tables, LaTeX) that native extraction cannot produce reliably. If any retained region is not text, the entire page is routed to the VLM.
- The page does not contain a full-page image. Some scanned PDFs contain a full-page image plus a hidden, low-quality OCR text layer. Whenever LiteParse detects a full-page image, we route the page to GLM-OCR, even if the text layer otherwise appears usable.
- LiteParse considers the native text usable. We use LiteParse's page-level analysis to reject pages whose native text is unsuitable for direct extraction and route them to the VLM.
- The page has a substantial embedded text layer (text characters ≥ 8). The page must contain at least 8 extractable characters in its text layer. This floor filters out pages that technically have a text layer but contain too little content to be meaningfully extracted natively (e.g. a page with only a page number or a single header).
- Unassigned words stay within a small tolerance. After native extraction, we assign each extracted word to the smallest layout-detected text region containing the center of its bounding box. A page qualifies only when no more than 50 words, and no more than 10% of all words, remain unassigned. This allows minor layout-detector misses without accepting a substantial mismatch between the text layer and the detected layout.

The page-level eligibility gate. A page falls through to the VLM at any failed check; only pages that pass all conditions are resolved natively.
Any page that fails a hard check, cannot be parsed, or exceeds the parsing timeout flows to the VLM unchanged. The fast path remains a conservative optimization layered on top of the VLM baseline.
Rejecting full-page images reduces the number of pages that take the fast path, but prevents low-quality hidden OCR layers from replacing a visual reading of the page.
Why page-level is the right granularity
Per-region routing would yield greater theoretical savings, but the detector’s bounding boxes are too noisy to feed a method that interprets its input literally. The page is the smallest unit at which we can both (a) make a reliable statement about content type and (b) assign words to regions using global page context rather than trusting individual bounding boxes. The tradeoff is that a mixed page (e.g. one with 80% plain text and one table) goes entirely to the VLM even though most of its content could be extracted natively. We accepted this to reduce the risk of corrupted output.
Results and impact
Across a representative corpus of 101,134 pages ingested by users in our system, the routing gate used in our original evaluation directed approximately 27% of pages (27,295) to the native fast path and the remaining 73% (73,839) to the VLM. This measurement predates the full-page-image guard, which reduces fast-path coverage.
| Min | p50 | Avg | Max | |
|---|---|---|---|---|
| VLM-only requests | 60.2 ms | 5,721 ms | 24,351 ms | 620,304 ms |
| Fast-only requests | <1 ms | 0.6 ms | 100 ms | 15,716 ms |
In this evaluation, mean latency was about 240× lower for fast-only requests than for VLM-only requests (100 ms versus 24,351 ms). This compares two request cohorts, not paired runs on the same pages; their p50 values are reported separately in the table. Fast-path requests require no GPU inference, leaving GPU capacity for pages that need visual processing.
Accuracy
Across that evaluation, all accuracy metrics remained within 2–3% of the all-OCR baseline. Pages are only routed natively after conservative safety checks, and every failed check falls back to the OCR baseline.
Where this helps and where it does not
This is a workload-dependent optimization, not a universal OCR shortcut. Its value is determined by the share of pages that are safe for native extraction under the eligibility gate.
It is especially effective for document collections with many born-digital, text-only pages: for example, reports, contracts, specifications, and exported business documents whose text is embedded in the PDF. It is much less useful for scanned pages, pages with full-page images, forms, pages with tables or formulas, and visually complex layouts. Those pages remain on the OCR path, so the fast-path rate can be close to zero for an extraction-quality benchmark or a highly structured customer corpus.
Before adding the full-page-image guard, our aggregate production routing rate was roughly 27% of pages. The stricter guard lowers this rate, with the impact depending on how many scanned or full-page-image documents a customer imports.
Model-agnostic routing
The routing approach is not specific to GLM-OCR. It combines native PDF extraction with a fallback OCR model, so the same principle applies when the fallback is replaced with another OCR or vision-language model. The speedup comes from avoiding model inference on pages whose PDF text layer is demonstrably safe to use; model quality still matters for every page that falls back.
Accuracy-first routing
Our implementation makes three deliberately conservative decisions:
- Page-level routing. We route at page level rather than region level because native extraction interprets detector boxes literally, while OCR models tolerate imperfect crops.
- Text-only eligibility. Retained tables, formulas, and any page that fails the conservative checks stay on the OCR path.
- Full-page-image rejection. A full-page image sends the page to GLM-OCR even when a hidden OCR text layer appears usable.
Together, these choices prioritize output quality and are consistent with only a 2–3% accuracy gap from the all-OCR baseline. However, they are not universal requirements. A team must decide what level of degradation is acceptable for its own workload.
For example, a less conservative page-level policy can allow pages containing tables or formulas to use the fast path instead of sending the entire page to OCR. Many PDFs are otherwise simple but contain a single table or formula, which is enough to route the whole page to OCR under our current policy. Allowing those pages onto the fast path could materially increase coverage, provided that imperfect Markdown table reconstruction or formula formatting is acceptable for the downstream use case.
Next steps
Mixed-page routing. Currently, a page with even one non-text region (e.g. a single table on an otherwise all-text page) is routed entirely to the VLM. As layout detectors improve and produce tighter bounding boxes, it may become feasible to selectively apply native extraction to the text regions of a mixed page while routing only the complex regions to the VLM.
Closing thoughts
We wrote this post because, when we set out to build this, we looked for prior work on hybrid extraction in production and found very little. The general recommendation exists: use a fast path for bulk extraction and fall back to a model for the rest. However, we could not find a detailed account of how to implement that routing correctly, what fails when you try the obvious approach, or what the operational surprises look like once it is running at scale. This is our attempt to fill that gap.
References
- GLM-OCR: vision-language model for document OCR.
- PP-DocLayoutV3 (PaddleOCR): document layout detection model.
- LiteParse: local document parser used for native PDF text extraction and word geometry.
DEVREV
See Computer work for you
Your AI teammate that finds answers, takes action, and gets work done across every tool.
Our customers
Resources
Initiatives




