Scanned and image documents · C++ · ONNX Runtime
PDFs and images, read a page at a time.
gRParse turns PDF pages and scanned images into structured protobuf. It runs OCR, finds the layout, reads tables, and works out reading order, then streams each page as it finishes. The models run on the GPU, and if a model is missing or the GPU will not start, the server stops instead of quietly falling back to something slower and worse.
A page becomes text, boxes, and structure.
Each page runs through OCR and a set of layout models, and the result comes back as typed items rather than a wall of text.
OCR comes from RapidOCR, and the layout, table, and figure work comes from a set of models run through ONNX Runtime. A page turns into text items with their bounding boxes, layout regions, tables with cells whose geometry is worked out from the grid, and picture items. Every piece of text carries a stable offset and a confidence, and it says whether it came from OCR or from a digital PDF's own text layer, so a caller can tell a scanned word from a born-digital one.
Reading order is not left to chance. For multi-column pages the service runs a recursive cut over the layout regions to put the text back in the order a person would read it, rather than the order the boxes happened to be found.
Pages stream as they finish.
A long document does not wait for its last page. Each page goes out the moment it is done, in page order, and then a final event closes the stream.
The document shape is the same one the rest of the suite uses. The stream is just a way to deliver it incrementally, one page of text, tables, and pictures at a time. Each outgoing page is built in a short lived memory arena that is released as soon as it has been written, so a thousand-page scan does not pile up in memory.
The work is kept bounded end to end. There are limits on how many documents are in flight, how many pages a single document can run ahead, and how deep each internal queue can get. A client that stops reading stops getting page credits, so its document pauses while everyone else's keeps moving.
Turn on only the work you need.
Layout, tables, figure classification, and barcodes are each switchable, so a job that only needs text does not pay for the rest.
Layout detection, table structure, figure classification, and barcode reading are separate stages that can each be on, off, or automatic. Layout finds the regions of a page. Table structure turns a detected table into a real cell grid. Figure classification sorts pictures into kinds. Barcode reading needs no model at all. Reading of embedded picture bytes is off by default, since most callers want the text and the geometry rather than the pixels.
It runs on the GPU, and says so.
The execution provider is a deliberate choice, not a silent fallback.
gRParse runs its models on an NVIDIA GPU through CUDA by default, and there is a separate build that targets Intel GPUs through OpenVINO. If a caller asks for a provider that is not available, or a required model is missing, the server fails at startup and tells you what it actually has, rather than starting up and running slow CPU OCR that looks fine until the bill or the latency arrives. That single decision is the difference between a service you can trust in a pipeline and one that degrades in ways you only notice later.
It also runs the suite.
gRParse is the coordinator. Hand it a mixed document and it sends each part to the right service and merges the results.
Beyond its own computer-vision path, gRParse can fan a document out to collectors and stitch their output back together. It does the OCR and layout work itself, sends office documents to grpc-libreoffice for rendering, and holds reserved slots in its contract for the Apache POI and spreadsheet collectors. It never turns an office file into a PDF just to read it. Native formats go to the service that understands them, and only real images take the OCR path. If one collector fails, the others still return, and the failure is reported rather than swallowed.
Read the code and run it.
The protobuf contract, the C++ server, and the CUDA and OpenVINO container builds are all in the repository. Uploaded documents are capped and refused past the limit, and nothing is written to disk on the parsing path.