Overview of open-source PDF parsers
maindocling-parse and other low-level parsers like pypdf, PyMuPDF, or pdfminer.six based on their specific needs (e.g., rendering, text extraction, or table extraction).repository·main·Indexed 43 days ago
https://github.com/docling-project/docling-parseA high-performance package for extracting text (at character, word, and line levels), paths, and bitmap images with precise coordinates from programmatic PDFs. Version 7.20.0 serves as the core parsing engine for the Docling PDF conversion ecosystem and includes extensive CMap resource support for Adobe character collections including Traditional Chinese (Adobe-CNS1-7), Simplified Chinese (Adobe-GB1-5), and Japanese (Adobe-Japan1-7).
docling-parse and other low-level parsers like pypdf, PyMuPDF, or pdfminer.six based on their specific needs (e.g., rendering, text extraction, or table extraction).In addition to performance measurement and plotting, the repository provides specialized scripts for deep-dive analysis and quality assessment:
run_performance_analysis.py: Used to drill down into specific performance bottlenecks, such as identifying the slowest pages or inspecting C++ stage timings. It reads per-page CSVs and outputs detailed analysis tables.run_quality_benchmarking.py: Used to compare the quality of text and render agreement across different PDF engines. It reads PDFs (local or Hugging Face) and outputs quality CSVs, render visualizations, and histograms.Quality is measured by comparing docling-parse renders against pypdfium2 pixel by pixel. Both renders are composited onto opaque white before comparison.
delta: The primary headline metric on a 0.0 – 1.0 scale. It is calculated by taking the largest channel difference per pixel, dividing by 255, and averaging that over the page. 0.0 is pixel-identical; 1.0 is maximally inverted. It is designed to be comparable across pages of different sizes.mean_abs_error: The mean absolute per-channel deviation over RGBA, in 0–255 units. Alpha is constant, so this saturates at 191.25.changed_pixels_ratio: The fraction of pixels whose luma-weighted difference exceeds 12.max_abs_error: The largest single-channel deviation found anywhere on the page.changed_pixels: The absolute count of pixels meeting the changed_pixels_ratio threshold.canvas: The render size in pixels.While both map character codes unidirectionally, they serve different font types:
In some OpenType fonts based on these collections, CIDs may equal GIDs, but this is not guaranteed.
CMap (Character Map) resources are used to unidirectionally map character codes (like Unicode) to CIDs (Character IDs) of a CIDFont resource.
To ensure compatibility, a CMap resource and a CIDFont resource must have matching /Registry and /Ordering strings within their /CIDSystemInfo dictionaries.
A character collection is often referred to as an ROS, which is composed of three elements from the /CIDSystemInfo dictionary:
/Registry (string)/Ordering (string)/Supplement (integer)Example: Adobe-Japan1-7 corresponds to /Registry = Adobe, /Ordering = Japan1, and /Supplement = 7.
Each generated PNG contains three panels representing the same page:
pypdfium2 (the reference render).docling-parse (the Blend2D render).Note on the Difference Panel: The difference panel uses no brightness scaling. A grey level of 40 means the renders differ by 40 at that pixel; black means they are identical. This ensures that panels are directly comparable across different pages without artificial amplification.
The primary breaking change in v7 is the separation of DecodePageConfig into DecodeConfig and ContentConfig:
DecodeConfig: Used for compute-time tuning. This is fixed when the document or threaded batch is opened.ContentConfig: Used to decide what to skip, compute, or materialize per page. This can be overridden per page.Mapping Table:
| Old v6 Flag | New v7 Equivalent |
|---|---|
DecodePageConfig.keep_char_cells=True | ContentConfig(char_cells_content_level=ContentLevel.COMPUTE_AND_MATERIALIZE) |
DecodePageConfig.create_word_cells=True | ContentConfig(word_cells_content_level=ContentLevel.COMPUTE) |
materialize_bitmap_bytes=False | ContentConfig(include_bitmap_bytes=False) |
page_materialization_config | page_content_config (in threaded parser) |
Performance is evaluated based on two primary tasks:
parse: Extracts the text of every page along with its geometric location. This uses position-bearing APIs rather than plain-text dumps.parse+render: Performs the parse task and additionally rasterizes the page at a specified --scale (where scale=1.0 is 72 dpi) and materializes it as a PIL image.docling-parse decodes pages in parallel. Benchmarks report docling-parse results for various thread counts, while other packages are reported as single-threaded (threads = 1).Pages/sec and ms/page to provide a granular view of processing speed.CMap (Character Map) resources in this project follow specific technical conventions:
0x (e.g., 0x2121).-H) CMap resource is modified to support a newer Supplement, its corresponding vertical (-V) version is also updated to reflect the same Supplement.UCS-2 CMap files are considered obsolete and are no longer maintained. They have been replaced by a suite of UTF-8, UTF-16, and UTF-32 CMap resources that provide the same mappings.For detailed information on character sets and encodings, refer to CJKV Information Processing, Second Edition (O'Reilly Media, 2009).
cmap-tool.pl script provided by the Adobe Perl Scripts project.Install the package from PyPI to start extracting text, paths, and bitmap images from programmatic PDFs.
pip install docling-parseThe run_performance_eval.py script generates visualizations (histograms, scatters, hexbins) and per-document statistics from the per-page CSV files produced by the benchmarking script.
# Plot from a single CSV file
python scripts/benchmarking/run_performance_eval.py docs/performance_benchmarks/apple_m3_max_bo767_render.csv
# Scan an entire directory for CSVs
python scripts/benchmarking/run_performance_eval.py docs/performance_benchmarks
# Filter by task and threads
python scripts/benchmarking/run_performance_eval.py pages.csv --task parse --threads 1By default, plots are saved in a directory named after the input CSV (with the .csv extension removed). If --viz-dir is specified, they are saved there.
Generated Visualizations:
hist_stacked.png: Per-page time histograms.hist_pages_per_document.png: Corpus shape visualization.scaling_<task>.png: Log-scaled plot of seconds/page vs pages/second for docling-parse across thread counts.hex_loglog_<reference>_vs_<package>.png: Log-log per-page time comparison between docling-parse and other packages.per_document.csv: A table containing per-document statistics.python scripts/benchmarking/run_performance_eval.py docs/performance_benchmarks/apple_m3_max_bo767_render.csv