Skip to main content

Recrystal

A layout parser for research papers: PDF in, ordered typed blocks out.

PDF ──▶ [detector: fine-tuned YOLO11, 12 classes] ──▶ regions
    ──▶ [assembler: textreflow] ──▶ typed blocks ──▶ [grain_growth] ──▶ chunks

A YOLO11 layout model fine-tuned on research papers (DocLayNet's 11 classes plus Authors) finds the regions on each page, run through onnxruntime with no ultralytics at runtime. PyMuPDF supplies the words, each assigned to the smallest region containing it; regions the model merged across a column gutter are split back apart. textreflow then rebuilds reading order and paragraphs.

Install

pip install recrystal            # CPU
pip install recrystal[gpu]       # CUDA 12 / cuDNN 9, via onnxruntime-gpu

onnxruntime and onnxruntime-gpu share one package directory, so whichever is installed last wins. If another package pulls in the CPU build after the GPU one (chromadb does), reinstall onnxruntime-gpu. A GPU session that silently falls back to CPU is logged as a warning.

Use

from recrystal import parse_pdf

blocks, dropped = parse_pdf("paper.pdf")
# blocks:  [{"type": "title", "page": 0, "text": "..."},
#           {"type": "authors", ...}, {"type": "paragraph", ...}, ...]
# dropped: page headers, footers and text inside figures, kept out of the flow

The blocks are the input of grain-growth-chunking. For the intermediate layout — regions with boxes, labels and lines, in the textreflow input contract — use layout_pdf:

from recrystal import LayoutDetector, layout_pdf

detector = LayoutDetector()                       # load once, reuse across PDFs
layout = layout_pdf("paper.pdf", detector=detector, max_pages=5)

LayoutDetector(model_path=..., providers=["CPUExecutionProvider"]) takes a local .onnx and an explicit provider list. On a GPU that runs out of memory, inference drops to CPU instead of failing.

Weights

The weights (38 MB, .onnx) are downloaded on first use from darkdwine/yolo11-doc-layout-research-papers into $RECRYSTAL_HOME, default ~/.cache/recrystal. Put the file there yourself for offline use.

Evaluation

From a pre-registered evaluation over 514 papers and 400 questions, round 2 of Anneal's report:

  • Fewest answers lost in parsing: 24 of 400 answer spans missing from the output (near match), against Docling's 48 and PyMuPDF4LLM's 61. A span the parser never emits cannot be retrieved by any chunker.
  • Retrieves better under every chunker tested: pooled +0.064 on span_hit_near@4000ch against Docling and +0.122 against PyMuPDF4LLM, significant on 3 of 3 chunkers for each.
  • 2.88× faster than Docling per page, 0.1375 s against 0.3958, over 6,076 pages on a 4 GB consumer GPU.

Licence

AGPL-3.0-or-later, for two independent reasons: it links PyMuPDF (AGPL-3.0), and the weights are fine-tuned from Ultralytics YOLO11 (AGPL-3.0). The assembler, textreflow, and the chunker, grain-growth-chunking, link neither and are Apache-2.0.

Citation

See CITATION.cff.

Metadata

Release files for recrystal 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for recrystal 1.0.0
File Size Uploaded
recrystal-1.0.0.tar.gz 35.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for recrystal 1.0.0
File Interpreter ABI Platform
recrystal-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 63.4 kB

Release files / recrystal-1.0.0.tar.gz

Download URL recrystal-1.0.0.tar.gz
Size 35.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e129c8a9b01c203ffe6699395238a5c487c8c3d65adea850c257ce31bd4cae51
BLAKE2b-256 checksum
How to use checksums
3a97087fd9004467d0be3546a5e7dc2eca304de75ad99b97541884bc9dd81778
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / recrystal-1.0.0-py3-none-any.whl

Download URL recrystal-1.0.0-py3-none-any.whl
Size 28.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
286c016fec407a2ccbe6411740dfa441647e6ad0e3e4eda78fc2d1ec0f811bb5
BLAKE2b-256 checksum
How to use checksums
e4af581af6c1f6d0c1ef225034df66bf0409ccac17f4be3932e2ae173a055993
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page