lukak85/rare

Automatic Slovene magazine parsing, encompasing the practical part of master thesis at UL FRI.

Python

0

210 commits

updated Oct 16, 2026

See the code

README

Razčlenjevalnik Revij (RaRe)

RaRe is a parsing toolkit for Slovene magazines (primarily Glasbena Mladina), built on top of a fork of layoutparser. It exposes two tracks for parsing PDFs and comparing models on annotated data:

  • Pipeline track — DLA model → reading-order (additional OCR → figure linking →) assembled GlasanaDocument → HTML / Markdown / JSON.
  • VLM track — vision-language model (cloud or locally-served) producing HTML / Markdown / JSON directly.

These are furthermore enriched with named entities, and classification.

Pipelines track assumes presence of previously OCR-ed PDFs. If empty, the text layer can be re-read using --ocr flag.

Installation

Before running either of these, check Additional model-specific setup below for additional per-model requirements. Then run (if the code below doesn't include the desired model, no additional dependencies are needed):

pip install -e .                   # core package + 'rare' command

# Model specific dependencies
pip install -e ".[detr]" # + DETR dependencies
pip install -e ".[dit]" # + DiT dependencies
pip install -e ".[doclayout-yolo]" # + DocLayout-YOLO dependencies
pip install -e ".[faster-rcnn]" # + Faster R-CNN dependencies
pip install -e ".[layoutlmv3]" # + LayoutLMv3 dependencies 
pip install -e ".[mask-rcnn]" # + Mask R-CNN dependencies
pip install -e ".[pp-doclayoutv3]" --extra-index-url https://download.pytorch.org/whl/cpu # + PP-DocLayoutV3 dependencies
pip install -e ".[rf-detr]" # + RF-DETR dependencies
pip install -e ".[vgt]" # + VGT dependencies

pip install -e ".[marker]" # + Marker dependencies

Furthermore, install LayoutParser fork:

pip install -e layout-parser

It is recommended to create a separate Conda environment for each of the intended models in order to avoid library and version clashes between different model's dependencies.

Usage

The single rare command exposes three subcommands.

rare parse — parse a PDF

# Pipeline track
rare parse <pdf> --layout doclayout-yolo --order top-bottom

# VLM track (mutually exclusive with --layout)
rare parse <pdf> --vlm claude

# Pipeline track, with per-page Markdown for OmniDocBench's end2end evaluator
rare parse <pdf> --layout doclayout-yolo --emit-omnidocbench

# Choose the NER backend used by the linking stage
rare parse <pdf> --layout doclayout-yolo --ner rudar-slv

# Re-read regions the PDF's text layer left empty (running headers, by default)
rare parse <pdf> --layout doclayout-yolo --ocr tesseract

# Discover backends
rare parse --list-models
Additional info

Linking

After a document is assembled, a whole-document pass fills in additional information, one of which is linking, which uses named entities on every text region, captions bound to their figure, merging continuing paragraph produced by for example a page break, into one paragraph and in the end connecting them into an article.

Since linking also uses NER, we can provide it using --ner rudar-slv. NER is also used for enriching resulting JSON with additional metadata.

OCR fallback for failed regions (--ocr)

The corpus PDFs are scans: one full-page image per page with an invisible OCR text layer over it. Some regions contain incorrect OCR, which we correct using the following flags:

  • --ocr tesseract re-reads those regions from the pixels using the given model,
  • --ocr-dpi,
  • --ocr-labels (default: Header) and
  • --ocr-min-confidence, score below which region's OCR is discarder.

Classification

Final articles are classified by passing in --classification <classifier> (default: gams). --classification heuristic takes the genre from the article's running header, else its title, and uses a map to determine its class.

rare evaluate — score one model against a dataset

# Pipeline track
rare evaluate --track pipeline --dataset glasbena_mladina \
    --layout doclayout-yolo --order top-bottom \
    [--run-id myrun-2026-05] [--limit 5]

# VLM track 
rare evaluate --track vlm --dataset glasbena_mladina \
    --vlm claude \
    [--pdfs-dir dataset/pdfs] [--run-id myrun-2026-05]

Each invocation runs one model. Re-invoke with the same --run-id to accumulate models; report.md produces the manual evaluation report.

Outputs are stored in outputs/evaluations/<run_id>/{report.md, scores.csv, per_model/}.

Additional info

Figure/caption → article attachment (--track figure-link)

There's two concerns with images in reading order:

  1. The models tested other than LayotutReader perform worse than heuristic on our dataset, and LayoutReader works with text lines, so providing it with figures would break the result.
  2. Figures can mostly be viewed in any order (at the start). Only their affiliation to the article is important.

Linking is done using 3 heuristics:

  1. Figure + caption's proximity to the article.
  2. NER similarity between caption and article.
  3. Position of the figure relative to the article and its header (their preferred position is to the upper-left direction).

Evaluation of the resulting links:

rare evaluate --track figure-link --dataset glasbena_mladina \
    --pdfs-dir datasets/glasbena_mladina/pdfs/eval

Article genre (--track article-genre)

Compares the genre the classifier gives each article with a ground-truth genre, over ground-truth articles.

Ground-truth genres are derived from the annotated page_type of the pages an article touches. An article gets a genre when all of its pages that name one agree; otherwise genre is left null for manual labelling.

Page typeGenre
ArticlePagečlanek
NewsPagenovice
InterviewPageintervju
RecordsPagerecenzija
LettersPagepisma
QuizPagekviz
EventsPagedogodki
ImagesPageslike
TOCPagekazalo
AdvertPagereklama
CoverPagenaslovnica
rare evaluate --track article-genre --classification gams \
    --dataset glasbena_mladina

Reported are macro_f1 and micro_f1.

OmniDocBench evaluation (--run-omnidocbench)

Both tracks can run OmniDocBench's end-to-end evaluator, which emits text_block and reading_order NED.

On the pipeline track, mode can be selected with --omnidocbench-eval:

PassMetrics
detectionmAP over the predicted boxes
end2endtext_block / reading_order NED over per-page Markdown
both (default)both of the above

The two passes ship in different images, so they are configured separately:

  • --omnidocbench-image for end-to-end,
  • --omnidocbench-layout-image for detection.
OmniDocBench end2end evaluation

Before running, pull the following image:

docker pull ghcr.io/zeng-weijun/omnidocbench-eval:repro-ubuntu2204

Then run:

rare evaluate --track pipeline --dataset glasbena_mladina \
    --layout doclayout-yolo --order top-bottom \
    --run-omnidocbench --pdfs-dir datasets/glasbena_mladina/pdfs

rare evaluate --track vlm --dataset glasbena_mladina \
    --vlm dots-ocr \
    --run-omnidocbench --pdfs-dir datasets/glasbena_mladina/pdfs
OmniDocBench Layout detection evaluation

The pipeline track can also run OmniDocBench's layout evaluator, including mAP. Pass --run-omnidocbench. Use --omnidocbench-image to override the image.

Inside OmnoDocBench-Dockerfile, build the Docker image:

docker build -t omnidocbench-v15 .

Then run:

rare evaluate --track pipeline --dataset glasbena_mladina \
    --layout doclayout-yolo --order top-bottom \
    --run-omnidocbench --pdfs-dir datasets/glasbena_mladina/pdfs

rare tools — annotation utilities

rare tools -m count-annotations -a dataset/annotations.json
rare tools -m join-annotations -p results/<doc_hash>/ -o merged.json
rare tools -m prepare-annotations -a merged.json -o cleaned.json
rare tools -m review-annotations -a cleaned.json -s reviewed/

rare tools -h prints the full flag list (same as the old helper.py).

Supported Models

The supported models (and therefore given Python version recommendations) were tested using:

  • Ubuntu 24.04
  • CUDA 12.8

Pipeline track — layout backends

ModelCLI nameTypeRecommended Python version
DETRdetrVision transformers3.14.3
DiTditVision transformers3.8
DocLayout-YOLOdoclayout-yoloObject detection3.10
Faster R-CNN*faster-rcnnCNN-based3.12
LayoutLMv3layoutlmv3Multimodal3.7
Mask R-CNN*mask-rcnnCNN-based3.12
Nemotron-Page-Elements-v3nemotronObject detection3.14
PP-DocLayoutV3pp-doclayoutv3Vision transformers3.12
RF-DETRrf-detrVision transformers3.14
SwinDocSegmenterswindocsegVision transformers3.8
VGTvgtMultimodal3.8

* Included in LayoutParser with detectron2

Pipeline track — reading-order backends

ModelCLI nameTypeRecommended Python version
Top-bottomDefaultRule basedAny
Left-rightleft-rightRule basedAny
PaddleX's Improved XY-Cutpaddlex-xy-cutRule basedAny
LayoutReaderlayoutreaderVision transformersAny

VLM track

ModelCLI nameTypeRecommended Python version
DeepSeek-OCR-2deepseekocrSpecialized VLMs3.12.9
DoclingdoclingSpecialized VLMs3.14
DolphindolphinSpecialized VLMs3.13
dots.ocrdots-ocrSpecialized VLMs3.12
GLM-OCRglm-ocrSpecialized VLMs3.13
MarkermarkerSpecialized VLMs3.10
MinerUmineruSpecialized VLMs3.13
Nemotron-Parse-v1.2nemotronSpecialized VLMs3.13
PaddleOCRpaddleocrSpecialized VLMs3.12
Qwen3-VLqwenLocal general VLMs3.12
Youtu-ParsingyoutuSpecialized VLMs3.10

Outputs

Main result of the parser is <stem>_articles.json, which contains one entry per article with its items in reading order. It can be used to render articles into formats such as Markdown and HTML.

Project Structure

rare/                         # installable package — entry point: rare = "rare.cli:main"
├── cli.py                    # rare parse | evaluate | tools
├── doc/{schema,renderers}.py # GlasanaDocument + 43 region classes + HTML/MD renderers
├── models/
│   ├── base.py               # LayoutBackend / ReadingOrderBackend / VLMBackend protocols
│   ├── registry.py           # lazy registry; sets LAYOUTPARSER_BACKEND env var
│   ├── layout/               # layout detection model/method classes
│   ├── order/                # order detection model/method classes
│   └── vlm/                  # visual language model document parsing classes
├── parse/                    # PDF → pages → layout → order → text → GlasanaDocument
├── evaluate/                 # dataset loaders + pipeline/VLM/figure-link metrics + runner + report
├── tools/_helper.py          # annotation utilities
└── utils/                    # eval / display / file / conversion / character helpers
configs/                      # JSON configs per model
data/                         # default path for model weights and model files
datasets/                     # default path for datasets
layout-parser/                # git submodule (layoutparser fork)
outputs/                      # outputs/parsed/* + outputs/evaluations/*

Additional model-specific setup

Additional model-specific setup

DiT

The installation roughly follows that of DiT install notes. Install Pytorch via:

pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html

Due to Detectron2 backbone, install it via:

python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.9/index.html

LayoutLMv3

The installation rougly follows that of LayoutLMv3 install notes. Install Pytorch via:

pip install torch==1.10.0+cu111 torchvision==0.11.1+cu111 -f https://download.pytorch.org/whl/torch_stable.html

Due to Detectron2 backbone, install it via:

python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.10/index.html

Check Pytorch version. If not 1.10.0+cu111, run the Pytorch installation command again.

Then clone the unilm repository:

git clone https://github.com/microsoft/unilm.git

And inside /unilm/layoutlmv3 run:

pip install -e .

Inside configs/layoutlmv3/yaml place cascade_layoutlmv3.yaml, and change WEIGHTS path to the path with weights on your system.

PP-DocLayoutV3

Based on your CUDA version, use the fitting command from PaddlePaddle install page to install paddlepaddle. For example, given CUDA version 12.8:

python -m pip install paddlepaddle-gpu==3.3.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/

If NVCC is not is not available, it must be installed. For example, given CUDA version 12.8:

conda install nvidia::cuda-nvcc==12.8.93

RF-DETR

Given CUDA version 12.8, install torch via:

pip install torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0 --index-url https://download.pytorch.org/whl/cu128

VGT

The installation instructions largely follow VGT install notes.

After installing RaRe and VGT dependencies, install Pytorch:

pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html

Also install detectron2:

python -m pip install detectron2==0.6 -f  https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.9/index.html

This method requires .pkl grid file for each input image. Therefore before running, generate pkl grid information by running create_grid_input.py from VGT's Generating grid information section. First, an installation of transformers is needed:

pip install transformers

And then run (for each PDF):

python create_grid_input.py \
--pdf 'path-to-pdf-file' \
--output 'path-to-output-folder' \
--tokenizer 'google-bert/bert-base-uncased' \
--model 'doclaynet'

Then point rare parse or rare evaluate at it via --config {"grid_root": "<path>"}.


DeepSeek-OCR-2

Follow the installation instructions on DeepSeek-OCR-2 GitHub repository.

Docling

Follow the installation instructions. If you have a NVIDIA GPU with CUDA version 12.8, run:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128

dots.ocr

Install the appropriate Pytorch version according to your CUDA version. E.g., for CUDA 12.8:

pip install torch==2.10.0 torchvision==0.25.0 torchaudio==2.10.0 --index-url https://download.pytorch.org/whl/cu128

For faster inference, also install flash-attn and its required packages:

pip install psutil
pip install flash-attn --no-build-isolation

Then clone the dots.ocr repository and insall:

pip install -e .

Then install vLLM using uv:

pip install uv # If uv is not previously installed
uv pip install vllm --torch-backend=cu128

If using GPU, vLLM also requires nvcc. If not available, install via:

conda install nvidia::cuda-nvcc==12.8.93

And run the vLLM server:

CUDA_VISIBLE_DEVICES=0 vllm serve rednote-hilab/dots.mocr --tensor-parallel-size 1 --gpu-memory-utilization 0.9 --chat-template-content-format string --served-model-name model --trust-remote-code
Additional troubleshooting If your Pytorch and driver CUDA version are mismatched, try installing Pytorch using the commands above again.

If needed, use a vLLM version below 0.20:

pip install "vllm<0.20"

GLM-OCR

Follow the GLM-OCR installation instructions.

Additionally, install zai-sdk for evaluation using OmniDocBench:

pip install zai-sdk

If using GPU, vLLM also requires nvcc. If not available, install via:

conda install nvidia::cuda-nvcc==12.8.93

Then run a vLLM server:

vllm serve zai-org/GLM-OCR --allowed-local-media-path / --port 8080
Additional troubleshooting Install an appropriate Pytorch version, if there is a mismatch, e.g. for CUDA 12.8:
pip install torch==2.10.0 torchvision==0.25.0 torchaudio==2.10.0 --index-url https://download.pytorch.org/whl/cu128

And reinstall vllm:

pip uninstall vllm
pip install "vllm<0.20"

Marker

To enable GPU inference, use torch built with CUDA. Given GPU with CUDA 12.8:

pip install torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0 --index-url https://download.pytorch.org/whl/cu128

MinerU

As per MinerU installation instructions, run the following commands:

pip install --upgrade pip
pip install uv
uv pip install -U "mineru[all]"

Install CUDA driver compatible Pytorch version. If you have a NVIDIA GPU with CUDA version 12.8, run:

pip install torch==2.9.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128

Install vllm module for inference acceleration:

uv pip install "mineru[core,vllm]"
Additional troubleshooting In our tests, we encountered the following errors, and fixed them the following ways:
  • RuntimeError: flashinfer-cubin version (0.6.8.post1) does not match flashinfer version (0.5.3). Please install the same version of both packages. Set FLASHINFER_DISABLE_VERSION_CHECK=1 to bypass this check.

    pip install -U "flashinfer-python==0.6.8" "flashinfer-cubin==0.6.8"
    
  • Permission denied: 'nvcc'

    conda install nvidia::cuda-nvcc==12.8.93
    

Nemotron-Parse

Following the NVIDIA-Nemotron-Parse-v1.2 quick start, in addition to transformers, install:

pip install albumentations timm open_clip_torch

After running the following download script:

hf download nvidia/NVIDIA-Nemotron-Parse-v1.2 chat_template.jinja --local-dir . 

Run via vLLM:

vllm serve nvidia/NVIDIA-Nemotron-Parse-v1.2 \
    --dtype bfloat16 \
    --max-num-seqs 8 \
    --limit-mm-per-prompt '{"image": 1}' \
    --trust-remote-code \
    --port 8000 \
    --chat-template chat_template.jinja

PaddleOCR

As per instructions, given CUDA 12.8, install:

 python -m pip install paddlepaddle-gpu==3.3.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/

And then:

python -m pip install "paddleocr[all]"

Youtu

Follow the instructions on Youtu's GitHub repository.


Qwen3-VL

Follow the instructions of model of choice on Qwen3-VL's Hugging Face repository.

Our tests were done with the following model and command:

vllm serve Qwen/Qwen3-VL-8B-Instruct \
  --gpu-memory-utilization 0.95 \
  --max-model-len 12288 \ 
  --max-num-seqs 2 \
  --limit-mm-per-prompt '{"image": 1}' \
  --mm-processor-kwargs '{"max_pixels": 1003520}'

Note: for Claude, ChatGPT and Gemini, the user must have an account and API key, which is pasted into the config file, which must then be passed as a parameter. The examples for each of them are present in ther respective configs directories.

Evaluation results

The following results were obtained by evaluating detections made by the following models on ground truths of manually annotated Glasbena Mladina magazines.

Note: NED - Normalized edit distance.

Layout Analysis

Two approaches to evaluation are can be computed:

  • manual (hand written functions for computation of mAP), however we don't report the results here and
  • using OmniDocBench — run as part of rare evaluate via --run-omnidocbench (see the usage section).

The results in the following table were obtained using OmniDocBench's evaluation.

Model (detection backbone)Pretrained (or model size) / fine-tuned onScore thresholdmAP / mAP50 / mAP75 / mAP-s / mAP-m / mAP-l (%)Title / text / figure / figure caption AP (%)
DETRDocLayNet0.441.58 / 60.31 / 43.46 / 4.94 / 24.10 / 51.1028.59 / 54.56 / 68.43 / 14.73
DiT (Cascade R-CNN)Large / PubLayNet0.533.05 / 42.76 / 35.55 / 3.46 / 22.47 / 38.3316.34 / 59.34 / 23.46 / -
DocLayout-YOLO (YOLOv10)DocSynth300k / D4LA053.44 / 67.81 / 56.52 / 11.64 / 33.86 / 67.4936.40 / 68.21 / 77.13 / 32.02
DocLayout-YOLO (YOLOv10)DocSynth300k / DocLayNet048.22 / 65.59 / 50.06 / 8.28 / 31.92 / 61.8235.99 / 65.42 / 69.82 / 21.64
DocLayout-YOLO (YOLOv10)DocSynth300k / DocStructBench055.06 / 65.98 / 58.61 / 18.02 / 38.38 / 64.1148.43 / 71.72 / 69.91 / 30.17
LayoutLMv3 (Cascade R-CNN)Base / PubLayNet0.140.88 / 54.08 / 44.12 / 8.35 / 27.80 / 45.1326.12 / 64.03 / 32.50 / -
RF-DETR (RF-DETR)DocLayNet031.37 / 44.34 / 31.96 / 4.98 / 15.59 / 45.6024.73 / 38.10 / 52.38 / 10.26
PP-DocLayoutV3In-house064.24 / 73.04 / 67.75 / 16.24 / 33.98 / 76.9842.46 / 71.09 / 79.15 / -
SwinDocSegmenterDocLayNet0.221.42 / 27.72 / 22.69 / 6.23 / 14.43 / 26.2721.90 / 34.30 / 23.52 / 5.98
VGT (Cascade R-CNN)DocLayNet0.150.56 / 70.60 / 50.48 / 9.28 / 34.10 / 64.1136.11 / 65.96 / 78.62 / 21.54
VGT (Cascade R-CNN)D4LA0.150.15 / 69.24 / 52.66 / 10.70 / 32.37 / 65.4232.81 / 66.53 / 70.37 / 30.88
Manual evaluation

Results were obtained using this repo's own implementations for evaluations (used mainly for more controlled, manual control and checking of calculations):

ModelBackboneDatasetmAP / mAP50 / mAP70Class agnostic mAP / mAP50 / mAP70
RF-DETR-DocLayNet0.3422 / 0.4064 / 0.36780.4910 / 0.6244 / 0.53606

Reading Order

ModelNEDBLEU
Top to bottom0.65560.1007
Left to right0.22220.6322
PaddleX's Improved XY-Cut0.24110.6349
LayoutReader0.16960.7143

VLM

Specialized VLMs:

ModelTypeText block NEDReading order NED
DeepSeekOCR-2-0.1880.115
DoclingDefault0.06640.164
dots.ocrdots.mocr0.3480.0722
DolphinDolphinv20.05420.0896
GLM-OCRGLM-4V0.1379*0.1941*
MarkerDefault0.04160.1033
MinerUMinerU2.5-Pro-2604-1.2B0.1810.137
Nemotron-Parse-v1.2-0.06860.0914
PaddleOCRPaddleOCR-VL-1.60.1150.170
Youtu-ParsingYoutu-LLM-2B-Base0.03060.0835

* Only results successfully parsed were scored against ground truth.

General VLMs

ModelTypeText block NED*Reading order NED*Mean cost per page** and token usage
ChatGPTGPT 5.50.056880.0706$0.1444 / 0,13€
-$0.0203 for 4050 tokens at $5/MTok IN
-$0.1247 for 4157 at $30.00/MTok OUT
ClaudeOpus 4.80.05040.0800$0.0935 / 0,082€
-$0.0279 for 5584 tokens at $5/MTok IN
-$0.0656 for 2624 tokens at $25/MTok OUT
GeminiGemini 3.1 Pro0.07180.0664$0.0988 / 0,086€
-$0.0025 for 1277 tokens at ~$2/MTok IN
-$0.0961 for 8007 tokens at ~$12/MTok OUT

* As of 15.7.2026, unoptimized (no use of cache), using similar resolution as seen on OmniDocBench dataset images.

Retried OCR results

Text block NED scores for our pipeline implementation with and without OCR retrying, using our trained DocLayout-YOLO model and LayoutReader for reading order.

ModelText block NED
No re-OCR-ing0.061
Re-OCR-ing0.059

Page wise breakdown of NED scores for best VLMs

Comparison of the best performing VLMs compared to our implementation, given with normalized edit distance by page type.

Text = text blocks, Order = reading order.

Page typeYP: TextYP: OrderMarker: TextMarker: Orderdots.ocr: Textdots.ocr: OrderDLY+LR: TextDLY+LR: Order
Advert0.0480.1040.1130.1740.0380.0590.2150.231
Article0.0240.0680.0240.0890.0250.0600.0320.162
Cover0.0100.1940.0350.1940.0200.1110.0110.194
Events0.0500.2250.1230.2420.0350.2080.4000.412
Images0.1720.0920.4010.1920.1850.0830.4170.314
Interview0.0220.0750.0330.0970.0230.0710.0280.159
Letters0.0200.0500.0150.0750.0340.0650.0160.183
News0.0200.0920.0210.1020.0230.0660.0430.223
Quiz0.0540.0680.0750.1020.1090.0970.1040.254
Records0.0170.1100.0150.0840.0320.0710.0470.221
Special0.1670.2180.2810.3510.1390.2310.4040.427
TOC0.0560.1440.0580.1490.0470.1440.0840.297
All (page avg)0.0310.0840.0420.1030.0350.0720.0610.197
All (whole)0.0250.0810.0280.0990.0290.0680.0410.212
All (sample avg)0.0390.0840.0550.1030.0430.0720.0550.197

YP = Youtu-Parsing, DLY+LR = DocLayout-YOLO + LayoutReader.

* Due to ground truth being obtained using bounding boxes but same OCR-ed letters (barring retrying of failed extractions), the text block NED is not directly comparable to the other VLMs, but is included for reference.

Figure linking results

Ablation study, scores figures, captions and figure bylines correctly linked to their respective articles using proximity, NER and additional heuristics.

VariantDescriptionAccuracy (%)
fullProximity (nearest element, above/left preferred) + NER82.63
no-nerProximity only82.78
no-geometryNER only16.01
no-ner-no-directionProximity only, without the above/left preference83.65
mean-distancefull, with mean instead of nearest distance to an article52.79

Classification results

Number of correctly classified articles.

ModelTypeMacro F1Micro F1Weighted F1Accuracy
HeuristicsHeader name0.30830.19200.26580.19
GAMS12B-Instruct0.28520.51610.48130.52
ChatGPTGPT 5.50.37910.53750.53430.54

Demo

To be added.

TODO

Top priority:

  • Add mappings from other datasets (PubLayNet, DocBank, DocLayNet) to OmniDocBench schema for evaluation
  • Add OmniDocBench evaluation support for pipeline track
    • Fix classes and other issues in OmniDocBench layout evaluation
  • Add specialized VLM support:
    • Marker
  • Add general VLM support, among others:
    • Qwen3-VL
    • GPT 5.5
    • Gemini Pro 3.1
    • Anthropic Claude Opus 4.8
  • Evaluate all models:
    • Pipeline
    • Specialized VLM
    • General VLM

Limitations and Further Work

Pipeline based track:

  • Built layout detection and reading order detection tasks are evaluated separately (reading order is evaluated using ground bounding boxes).
  • Currently, RaRe only supports inference; possible extension includes training of the available models.
  • VLM track currently only supports Youtu-parse. Further improvement could see integration of a larger number of models into rare, so they can be output in an arbitrary format (such as JSON, HTML etc.)

Acknowledgements

Thanks for the work of the authors of these projects:

  • PaddleX — the improved XY-Cut reading-order backend is vendored from PaddleX (Apache-2.0); see NOTICE and licenses/LICENSE-PADDLEX.
  • OmniDocBench — the end-to-end Edit-distance evaluator (run via --run-omnidocbench) and the specialized VLM img2md parsing backends are adapted from OmniDocBench (Apache-2.0); see NOTICE and licenses/LICENSE-OMNIDOCBENCH.
  • layoutreader — the layoutreader reading-order backend uses the LayoutLMv3 inference helpers and the hantian/layoutreader checkpoint from Hantian Pang's faster LayoutReader (CC BY-NC-SA 4.0); neither is redistributed by RaRe, see NOTICE and the licensing note below.
  • DocLayout-YOLO
LayoutReader specifics

RaRe is licensed GPL-3.0-or-later (see LICENSE). The LayoutLMv3 inference helpers from FreeOCR-AI/layoutreader are CC BY-NC-SA 4.0, whose NonCommercial term is an additional restriction that GPLv3 §7 forbids — so RaRe does not ship them. The first time you run --order layoutreader, the single upstream v3/helpers.py is downloaded and cached under ~/.cache/rare/ (override with RARE_CACHE_DIR); the hantian/layoutreader checkpoint the backend loads is likewise CC BY-NC-SA 4.0 and fetched at runtime.

Citation

@phdthesis{
    Kuzman_2026,
    title={Samodejno razčlenjevanje kompleksnih postavitev dokumentov},
    url={https://hdl.handle.net/20.500.12556/RUL-189793},
    abstractNote={Razčlenjevanje kompleksnih vrst dokumentov, kot so revije, je zahtevnejše od razčlenjevanja preprostejših dokumentov, na primer znanstvenih člankov. Primerne zbirke za razčlenjevanje slovenskih dokumentov doslej še ni bilo. V sklopu magistrskega dela smo z ročnim anotiranjem 35 dokumentov, ki vsebujejo 881 slik, ustvarili prvo takšno zbirko v slovenščini. Na njej smo ovrednotili celovite modele za razčlenjevanje in posamezne dele cevovodnega pristopa; najbolje se je izkazal Youtu-Parsing z oceno razdalje urejanja 0,031. Na zbirki smo naučili model DocLayout-YOLO, ki dosega mAP 64,3 %. Razvili smo tudi cevovod, ki s temi modeli iz dokumentov izlušči članke ter jih obogati z metapodatki.},
    author={Kuzman, Luka},
    year={2026}
}
LayoutReader specifics

If you use the layoutreader reading-order backend, please cite the upstream implementation and the original LayoutReader paper:

@software{Pang_Faster_LayoutReader_based_2024,
  author  = {Pang, Hantian},
  month   = feb,
  title   = {{Faster LayoutReader based on LayoutLMv3}},
  url     = {https://github.com/ppaanngggg/layoutreader},
  version = {1.0.0},
  year    = {2024}
}

@inproceedings{wang-etal-2021-layoutreader,
  title     = {{L}ayout{R}eader: Pre-training of Text and Layout for Reading Order Detection},
  author    = {Wang, Zilong and Xu, Yiheng and Cui, Lei and Shang, Jingbo and Wei, Furu},
  booktitle = {Proceedings of the 2021 Conference on Empirical Methods in Natural Language Processing},
  month     = nov,
  year      = {2021},
  address   = {Online and Punta Cana, Dominican Republic},
  publisher = {Association for Computational Linguistics},
  url       = {https://aclanthology.org/2021.emnlp-main.389/},
  doi       = {10.18653/v1/2021.emnlp-main.389},
  pages     = {4735--4744}
}

lukak85/rare

Automatic Slovene magazine parsing, encompasing the practical part of master thesis at UL FRI.

Python

0

210 commits

updated Oct 16, 2026

See the code

README

Razčlenjevalnik Revij (RaRe)

RaRe is a parsing toolkit for Slovene magazines (primarily Glasbena Mladina), built on top of a fork of layoutparser. It exposes two tracks for parsing PDFs and comparing models on annotated data:

  • Pipeline track — DLA model → reading-order (additional OCR → figure linking →) assembled GlasanaDocument → HTML / Markdown / JSON.
  • VLM track — vision-language model (cloud or locally-served) producing HTML / Markdown / JSON directly.

These are furthermore enriched with named entities, and classification.

Pipelines track assumes presence of previously OCR-ed PDFs. If empty, the text layer can be re-read using --ocr flag.

Installation

Before running either of these, check Additional model-specific setup below for additional per-model requirements. Then run (if the code below doesn't include the desired model, no additional dependencies are needed):

pip install -e .                   # core package + 'rare' command

# Model specific dependencies
pip install -e ".[detr]" # + DETR dependencies
pip install -e ".[dit]" # + DiT dependencies
pip install -e ".[doclayout-yolo]" # + DocLayout-YOLO dependencies
pip install -e ".[faster-rcnn]" # + Faster R-CNN dependencies
pip install -e ".[layoutlmv3]" # + LayoutLMv3 dependencies 
pip install -e ".[mask-rcnn]" # + Mask R-CNN dependencies
pip install -e ".[pp-doclayoutv3]" --extra-index-url https://download.pytorch.org/whl/cpu # + PP-DocLayoutV3 dependencies
pip install -e ".[rf-detr]" # + RF-DETR dependencies
pip install -e ".[vgt]" # + VGT dependencies

pip install -e ".[marker]" # + Marker dependencies

Furthermore, install LayoutParser fork:

pip install -e layout-parser

It is recommended to create a separate Conda environment for each of the intended models in order to avoid library and version clashes between different model's dependencies.

Usage

The single rare command exposes three subcommands.

rare parse — parse a PDF

# Pipeline track
rare parse <pdf> --layout doclayout-yolo --order top-bottom

# VLM track (mutually exclusive with --layout)
rare parse <pdf> --vlm claude

# Pipeline track, with per-page Markdown for OmniDocBench's end2end evaluator
rare parse <pdf> --layout doclayout-yolo --emit-omnidocbench

# Choose the NER backend used by the linking stage
rare parse <pdf> --layout doclayout-yolo --ner rudar-slv

# Re-read regions the PDF's text layer left empty (running headers, by default)
rare parse <pdf> --layout doclayout-yolo --ocr tesseract

# Discover backends
rare parse --list-models
Additional info

Linking

After a document is assembled, a whole-document pass fills in additional information, one of which is linking, which uses named entities on every text region, captions bound to their figure, merging continuing paragraph produced by for example a page break, into one paragraph and in the end connecting them into an article.

Since linking also uses NER, we can provide it using --ner rudar-slv. NER is also used for enriching resulting JSON with additional metadata.

OCR fallback for failed regions (--ocr)

The corpus PDFs are scans: one full-page image per page with an invisible OCR text layer over it. Some regions contain incorrect OCR, which we correct using the following flags:

  • --ocr tesseract re-reads those regions from the pixels using the given model,
  • --ocr-dpi,
  • --ocr-labels (default: Header) and
  • --ocr-min-confidence, score below which region's OCR is discarder.

Classification

Final articles are classified by passing in --classification <classifier> (default: gams). --classification heuristic takes the genre from the article's running header, else its title, and uses a map to determine its class.

rare evaluate — score one model against a dataset

# Pipeline track
rare evaluate --track pipeline --dataset glasbena_mladina \
    --layout doclayout-yolo --order top-bottom \
    [--run-id myrun-2026-05] [--limit 5]

# VLM track 
rare evaluate --track vlm --dataset glasbena_mladina \
    --vlm claude \
    [--pdfs-dir dataset/pdfs] [--run-id myrun-2026-05]

Each invocation runs one model. Re-invoke with the same --run-id to accumulate models; report.md produces the manual evaluation report.

Outputs are stored in outputs/evaluations/<run_id>/{report.md, scores.csv, per_model/}.

Additional info

Figure/caption → article attachment (--track figure-link)

There's two concerns with images in reading order:

  1. The models tested other than LayotutReader perform worse than heuristic on our dataset, and LayoutReader works with text lines, so providing it with figures would break the result.
  2. Figures can mostly be viewed in any order (at the start). Only their affiliation to the article is important.

Linking is done using 3 heuristics:

  1. Figure + caption's proximity to the article.
  2. NER similarity between caption and article.
  3. Position of the figure relative to the article and its header (their preferred position is to the upper-left direction).

Evaluation of the resulting links:

rare evaluate --track figure-link --dataset glasbena_mladina \
    --pdfs-dir datasets/glasbena_mladina/pdfs/eval

Article genre (--track article-genre)

Compares the genre the classifier gives each article with a ground-truth genre, over ground-truth articles.

Ground-truth genres are derived from the annotated page_type of the pages an article touches. An article gets a genre when all of its pages that name one agree; otherwise genre is left null for manual labelling.

Page typeGenre
ArticlePagečlanek
NewsPagenovice
InterviewPageintervju
RecordsPagerecenzija
LettersPagepisma
QuizPagekviz
EventsPagedogodki
ImagesPageslike
TOCPagekazalo
AdvertPagereklama
CoverPagenaslovnica
rare evaluate --track article-genre --classification gams \
    --dataset glasbena_mladina

Reported are macro_f1 and micro_f1.

OmniDocBench evaluation (--run-omnidocbench)

Both tracks can run OmniDocBench's end-to-end evaluator, which emits text_block and reading_order NED.

On the pipeline track, mode can be selected with --omnidocbench-eval:

PassMetrics
detectionmAP over the predicted boxes
end2endtext_block / reading_order NED over per-page Markdown
both (default)both of the above

The two passes ship in different images, so they are configured separately:

  • --omnidocbench-image for end-to-end,
  • --omnidocbench-layout-image for detection.
OmniDocBench end2end evaluation

Before running, pull the following image:

docker pull ghcr.io/zeng-weijun/omnidocbench-eval:repro-ubuntu2204

Then run:

rare evaluate --track pipeline --dataset glasbena_mladina \
    --layout doclayout-yolo --order top-bottom \
    --run-omnidocbench --pdfs-dir datasets/glasbena_mladina/pdfs

rare evaluate --track vlm --dataset glasbena_mladina \
    --vlm dots-ocr \
    --run-omnidocbench --pdfs-dir datasets/glasbena_mladina/pdfs
OmniDocBench Layout detection evaluation

The pipeline track can also run OmniDocBench's layout evaluator, including mAP. Pass --run-omnidocbench. Use --omnidocbench-image to override the image.

Inside OmnoDocBench-Dockerfile, build the Docker image:

docker build -t omnidocbench-v15 .

Then run:

rare evaluate --track pipeline --dataset glasbena_mladina \
    --layout doclayout-yolo --order top-bottom \
    --run-omnidocbench --pdfs-dir datasets/glasbena_mladina/pdfs

rare tools — annotation utilities

rare tools -m count-annotations -a dataset/annotations.json
rare tools -m join-annotations -p results/<doc_hash>/ -o merged.json
rare tools -m prepare-annotations -a merged.json -o cleaned.json
rare tools -m review-annotations -a cleaned.json -s reviewed/

rare tools -h prints the full flag list (same as the old helper.py).

Supported Models

The supported models (and therefore given Python version recommendations) were tested using:

  • Ubuntu 24.04
  • CUDA 12.8

Pipeline track — layout backends

ModelCLI nameTypeRecommended Python version
DETRdetrVision transformers3.14.3
DiTditVision transformers3.8
DocLayout-YOLOdoclayout-yoloObject detection3.10
Faster R-CNN*faster-rcnnCNN-based3.12
LayoutLMv3layoutlmv3Multimodal3.7
Mask R-CNN*mask-rcnnCNN-based3.12
Nemotron-Page-Elements-v3nemotronObject detection3.14
PP-DocLayoutV3pp-doclayoutv3Vision transformers3.12
RF-DETRrf-detrVision transformers3.14
SwinDocSegmenterswindocsegVision transformers3.8
VGTvgtMultimodal3.8

* Included in LayoutParser with detectron2

Pipeline track — reading-order backends

ModelCLI nameTypeRecommended Python version
Top-bottomDefaultRule basedAny
Left-rightleft-rightRule basedAny
PaddleX's Improved XY-Cutpaddlex-xy-cutRule basedAny
LayoutReaderlayoutreaderVision transformersAny

VLM track

ModelCLI nameTypeRecommended Python version
DeepSeek-OCR-2deepseekocrSpecialized VLMs3.12.9
DoclingdoclingSpecialized VLMs3.14
DolphindolphinSpecialized VLMs3.13
dots.ocrdots-ocrSpecialized VLMs3.12
GLM-OCRglm-ocrSpecialized VLMs3.13
MarkermarkerSpecialized VLMs3.10
MinerUmineruSpecialized VLMs3.13
Nemotron-Parse-v1.2nemotronSpecialized VLMs3.13
PaddleOCRpaddleocrSpecialized VLMs3.12
Qwen3-VLqwenLocal general VLMs3.12
Youtu-ParsingyoutuSpecialized VLMs3.10

Outputs

Main result of the parser is <stem>_articles.json, which contains one entry per article with its items in reading order. It can be used to render articles into formats such as Markdown and HTML.

Project Structure

rare/                         # installable package — entry point: rare = "rare.cli:main"
├── cli.py                    # rare parse | evaluate | tools
├── doc/{schema,renderers}.py # GlasanaDocument + 43 region classes + HTML/MD renderers
├── models/
│   ├── base.py               # LayoutBackend / ReadingOrderBackend / VLMBackend protocols
│   ├── registry.py           # lazy registry; sets LAYOUTPARSER_BACKEND env var
│   ├── layout/               # layout detection model/method classes
│   ├── order/                # order detection model/method classes
│   └── vlm/                  # visual language model document parsing classes
├── parse/                    # PDF → pages → layout → order → text → GlasanaDocument
├── evaluate/                 # dataset loaders + pipeline/VLM/figure-link metrics + runner + report
├── tools/_helper.py          # annotation utilities
└── utils/                    # eval / display / file / conversion / character helpers
configs/                      # JSON configs per model
data/                         # default path for model weights and model files
datasets/                     # default path for datasets
layout-parser/                # git submodule (layoutparser fork)
outputs/                      # outputs/parsed/* + outputs/evaluations/*

Additional model-specific setup

Additional model-specific setup

DiT

The installation roughly follows that of DiT install notes. Install Pytorch via:

pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html

Due to Detectron2 backbone, install it via:

python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.9/index.html

LayoutLMv3

The installation rougly follows that of LayoutLMv3 install notes. Install Pytorch via:

pip install torch==1.10.0+cu111 torchvision==0.11.1+cu111 -f https://download.pytorch.org/whl/torch_stable.html

Due to Detectron2 backbone, install it via:

python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.10/index.html

Check Pytorch version. If not 1.10.0+cu111, run the Pytorch installation command again.

Then clone the unilm repository:

git clone https://github.com/microsoft/unilm.git

And inside /unilm/layoutlmv3 run:

pip install -e .

Inside configs/layoutlmv3/yaml place cascade_layoutlmv3.yaml, and change WEIGHTS path to the path with weights on your system.

PP-DocLayoutV3

Based on your CUDA version, use the fitting command from PaddlePaddle install page to install paddlepaddle. For example, given CUDA version 12.8:

python -m pip install paddlepaddle-gpu==3.3.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/

If NVCC is not is not available, it must be installed. For example, given CUDA version 12.8:

conda install nvidia::cuda-nvcc==12.8.93

RF-DETR

Given CUDA version 12.8, install torch via:

pip install torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0 --index-url https://download.pytorch.org/whl/cu128

VGT

The installation instructions largely follow VGT install notes.

After installing RaRe and VGT dependencies, install Pytorch:

pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html

Also install detectron2:

python -m pip install detectron2==0.6 -f  https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.9/index.html

This method requires .pkl grid file for each input image. Therefore before running, generate pkl grid information by running create_grid_input.py from VGT's Generating grid information section. First, an installation of transformers is needed:

pip install transformers

And then run (for each PDF):

python create_grid_input.py \
--pdf 'path-to-pdf-file' \
--output 'path-to-output-folder' \
--tokenizer 'google-bert/bert-base-uncased' \
--model 'doclaynet'

Then point rare parse or rare evaluate at it via --config {"grid_root": "<path>"}.


DeepSeek-OCR-2

Follow the installation instructions on DeepSeek-OCR-2 GitHub repository.

Docling

Follow the installation instructions. If you have a NVIDIA GPU with CUDA version 12.8, run:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128

dots.ocr

Install the appropriate Pytorch version according to your CUDA version. E.g., for CUDA 12.8:

pip install torch==2.10.0 torchvision==0.25.0 torchaudio==2.10.0 --index-url https://download.pytorch.org/whl/cu128

For faster inference, also install flash-attn and its required packages:

pip install psutil
pip install flash-attn --no-build-isolation

Then clone the dots.ocr repository and insall:

pip install -e .

Then install vLLM using uv:

pip install uv # If uv is not previously installed
uv pip install vllm --torch-backend=cu128

If using GPU, vLLM also requires nvcc. If not available, install via:

conda install nvidia::cuda-nvcc==12.8.93

And run the vLLM server:

CUDA_VISIBLE_DEVICES=0 vllm serve rednote-hilab/dots.mocr --tensor-parallel-size 1 --gpu-memory-utilization 0.9 --chat-template-content-format string --served-model-name model --trust-remote-code
Additional troubleshooting If your Pytorch and driver CUDA version are mismatched, try installing Pytorch using the commands above again.

If needed, use a vLLM version below 0.20:

pip install "vllm<0.20"

GLM-OCR

Follow the GLM-OCR installation instructions.

Additionally, install zai-sdk for evaluation using OmniDocBench:

pip install zai-sdk

If using GPU, vLLM also requires nvcc. If not available, install via:

conda install nvidia::cuda-nvcc==12.8.93

Then run a vLLM server:

vllm serve zai-org/GLM-OCR --allowed-local-media-path / --port 8080
Additional troubleshooting Install an appropriate Pytorch version, if there is a mismatch, e.g. for CUDA 12.8:
pip install torch==2.10.0 torchvision==0.25.0 torchaudio==2.10.0 --index-url https://download.pytorch.org/whl/cu128

And reinstall vllm:

pip uninstall vllm
pip install "vllm<0.20"

Marker

To enable GPU inference, use torch built with CUDA. Given GPU with CUDA 12.8:

pip install torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0 --index-url https://download.pytorch.org/whl/cu128

MinerU

As per MinerU installation instructions, run the following commands:

pip install --upgrade pip
pip install uv
uv pip install -U "mineru[all]"

Install CUDA driver compatible Pytorch version. If you have a NVIDIA GPU with CUDA version 12.8, run:

pip install torch==2.9.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128

Install vllm module for inference acceleration:

uv pip install "mineru[core,vllm]"
Additional troubleshooting In our tests, we encountered the following errors, and fixed them the following ways:
  • RuntimeError: flashinfer-cubin version (0.6.8.post1) does not match flashinfer version (0.5.3). Please install the same version of both packages. Set FLASHINFER_DISABLE_VERSION_CHECK=1 to bypass this check.

    pip install -U "flashinfer-python==0.6.8" "flashinfer-cubin==0.6.8"
    
  • Permission denied: 'nvcc'

    conda install nvidia::cuda-nvcc==12.8.93
    

Nemotron-Parse

Following the NVIDIA-Nemotron-Parse-v1.2 quick start, in addition to transformers, install:

pip install albumentations timm open_clip_torch

After running the following download script:

hf download nvidia/NVIDIA-Nemotron-Parse-v1.2 chat_template.jinja --local-dir . 

Run via vLLM:

vllm serve nvidia/NVIDIA-Nemotron-Parse-v1.2 \
    --dtype bfloat16 \
    --max-num-seqs 8 \
    --limit-mm-per-prompt '{"image": 1}' \
    --trust-remote-code \
    --port 8000 \
    --chat-template chat_template.jinja

PaddleOCR

As per instructions, given CUDA 12.8, install:

 python -m pip install paddlepaddle-gpu==3.3.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/

And then:

python -m pip install "paddleocr[all]"

Youtu

Follow the instructions on Youtu's GitHub repository.


Qwen3-VL

Follow the instructions of model of choice on Qwen3-VL's Hugging Face repository.

Our tests were done with the following model and command:

vllm serve Qwen/Qwen3-VL-8B-Instruct \
  --gpu-memory-utilization 0.95 \
  --max-model-len 12288 \ 
  --max-num-seqs 2 \
  --limit-mm-per-prompt '{"image": 1}' \
  --mm-processor-kwargs '{"max_pixels": 1003520}'

Note: for Claude, ChatGPT and Gemini, the user must have an account and API key, which is pasted into the config file, which must then be passed as a parameter. The examples for each of them are present in ther respective configs directories.

Evaluation results

The following results were obtained by evaluating detections made by the following models on ground truths of manually annotated Glasbena Mladina magazines.

Note: NED - Normalized edit distance.

Layout Analysis

Two approaches to evaluation are can be computed:

  • manual (hand written functions for computation of mAP), however we don't report the results here and
  • using OmniDocBench — run as part of rare evaluate via --run-omnidocbench (see the usage section).

The results in the following table were obtained using OmniDocBench's evaluation.

Model (detection backbone)Pretrained (or model size) / fine-tuned onScore thresholdmAP / mAP50 / mAP75 / mAP-s / mAP-m / mAP-l (%)Title / text / figure / figure caption AP (%)
DETRDocLayNet0.441.58 / 60.31 / 43.46 / 4.94 / 24.10 / 51.1028.59 / 54.56 / 68.43 / 14.73
DiT (Cascade R-CNN)Large / PubLayNet0.533.05 / 42.76 / 35.55 / 3.46 / 22.47 / 38.3316.34 / 59.34 / 23.46 / -
DocLayout-YOLO (YOLOv10)DocSynth300k / D4LA053.44 / 67.81 / 56.52 / 11.64 / 33.86 / 67.4936.40 / 68.21 / 77.13 / 32.02
DocLayout-YOLO (YOLOv10)DocSynth300k / DocLayNet048.22 / 65.59 / 50.06 / 8.28 / 31.92 / 61.8235.99 / 65.42 / 69.82 / 21.64
DocLayout-YOLO (YOLOv10)DocSynth300k / DocStructBench055.06 / 65.98 / 58.61 / 18.02 / 38.38 / 64.1148.43 / 71.72 / 69.91 / 30.17
LayoutLMv3 (Cascade R-CNN)Base / PubLayNet0.140.88 / 54.08 / 44.12 / 8.35 / 27.80 / 45.1326.12 / 64.03 / 32.50 / -
RF-DETR (RF-DETR)DocLayNet031.37 / 44.34 / 31.96 / 4.98 / 15.59 / 45.6024.73 / 38.10 / 52.38 / 10.26
PP-DocLayoutV3In-house064.24 / 73.04 / 67.75 / 16.24 / 33.98 / 76.9842.46 / 71.09 / 79.15 / -
SwinDocSegmenterDocLayNet0.221.42 / 27.72 / 22.69 / 6.23 / 14.43 / 26.2721.90 / 34.30 / 23.52 / 5.98
VGT (Cascade R-CNN)DocLayNet0.150.56 / 70.60 / 50.48 / 9.28 / 34.10 / 64.1136.11 / 65.96 / 78.62 / 21.54
VGT (Cascade R-CNN)D4LA0.150.15 / 69.24 / 52.66 / 10.70 / 32.37 / 65.4232.81 / 66.53 / 70.37 / 30.88
Manual evaluation

Results were obtained using this repo's own implementations for evaluations (used mainly for more controlled, manual control and checking of calculations):

ModelBackboneDatasetmAP / mAP50 / mAP70Class agnostic mAP / mAP50 / mAP70
RF-DETR-DocLayNet0.3422 / 0.4064 / 0.36780.4910 / 0.6244 / 0.53606

Reading Order

ModelNEDBLEU
Top to bottom0.65560.1007
Left to right0.22220.6322
PaddleX's Improved XY-Cut0.24110.6349
LayoutReader0.16960.7143

VLM

Specialized VLMs:

ModelTypeText block NEDReading order NED
DeepSeekOCR-2-0.1880.115
DoclingDefault0.06640.164
dots.ocrdots.mocr0.3480.0722
DolphinDolphinv20.05420.0896
GLM-OCRGLM-4V0.1379*0.1941*
MarkerDefault0.04160.1033
MinerUMinerU2.5-Pro-2604-1.2B0.1810.137
Nemotron-Parse-v1.2-0.06860.0914
PaddleOCRPaddleOCR-VL-1.60.1150.170
Youtu-ParsingYoutu-LLM-2B-Base0.03060.0835

* Only results successfully parsed were scored against ground truth.

General VLMs

ModelTypeText block NED*Reading order NED*Mean cost per page** and token usage
ChatGPTGPT 5.50.056880.0706$0.1444 / 0,13€
-$0.0203 for 4050 tokens at $5/MTok IN
-$0.1247 for 4157 at $30.00/MTok OUT
ClaudeOpus 4.80.05040.0800$0.0935 / 0,082€
-$0.0279 for 5584 tokens at $5/MTok IN
-$0.0656 for 2624 tokens at $25/MTok OUT
GeminiGemini 3.1 Pro0.07180.0664$0.0988 / 0,086€
-$0.0025 for 1277 tokens at ~$2/MTok IN
-$0.0961 for 8007 tokens at ~$12/MTok OUT

* As of 15.7.2026, unoptimized (no use of cache), using similar resolution as seen on OmniDocBench dataset images.

Retried OCR results

Text block NED scores for our pipeline implementation with and without OCR retrying, using our trained DocLayout-YOLO model and LayoutReader for reading order.

ModelText block NED
No re-OCR-ing0.061
Re-OCR-ing0.059

Page wise breakdown of NED scores for best VLMs

Comparison of the best performing VLMs compared to our implementation, given with normalized edit distance by page type.

Text = text blocks, Order = reading order.

Page typeYP: TextYP: OrderMarker: TextMarker: Orderdots.ocr: Textdots.ocr: OrderDLY+LR: TextDLY+LR: Order
Advert0.0480.1040.1130.1740.0380.0590.2150.231
Article0.0240.0680.0240.0890.0250.0600.0320.162
Cover0.0100.1940.0350.1940.0200.1110.0110.194
Events0.0500.2250.1230.2420.0350.2080.4000.412
Images0.1720.0920.4010.1920.1850.0830.4170.314
Interview0.0220.0750.0330.0970.0230.0710.0280.159
Letters0.0200.0500.0150.0750.0340.0650.0160.183
News0.0200.0920.0210.1020.0230.0660.0430.223
Quiz0.0540.0680.0750.1020.1090.0970.1040.254
Records0.0170.1100.0150.0840.0320.0710.0470.221
Special0.1670.2180.2810.3510.1390.2310.4040.427
TOC0.0560.1440.0580.1490.0470.1440.0840.297
All (page avg)0.0310.0840.0420.1030.0350.0720.0610.197
All (whole)0.0250.0810.0280.0990.0290.0680.0410.212
All (sample avg)0.0390.0840.0550.1030.0430.0720.0550.197

YP = Youtu-Parsing, DLY+LR = DocLayout-YOLO + LayoutReader.

* Due to ground truth being obtained using bounding boxes but same OCR-ed letters (barring retrying of failed extractions), the text block NED is not directly comparable to the other VLMs, but is included for reference.

Figure linking results

Ablation study, scores figures, captions and figure bylines correctly linked to their respective articles using proximity, NER and additional heuristics.

VariantDescriptionAccuracy (%)
fullProximity (nearest element, above/left preferred) + NER82.63
no-nerProximity only82.78
no-geometryNER only16.01
no-ner-no-directionProximity only, without the above/left preference83.65
mean-distancefull, with mean instead of nearest distance to an article52.79

Classification results

Number of correctly classified articles.

ModelTypeMacro F1Micro F1Weighted F1Accuracy
HeuristicsHeader name0.30830.19200.26580.19
GAMS12B-Instruct0.28520.51610.48130.52
ChatGPTGPT 5.50.37910.53750.53430.54

Demo

To be added.

TODO

Top priority:

  • Add mappings from other datasets (PubLayNet, DocBank, DocLayNet) to OmniDocBench schema for evaluation
  • Add OmniDocBench evaluation support for pipeline track
    • Fix classes and other issues in OmniDocBench layout evaluation
  • Add specialized VLM support:
    • Marker
  • Add general VLM support, among others:
    • Qwen3-VL
    • GPT 5.5
    • Gemini Pro 3.1
    • Anthropic Claude Opus 4.8
  • Evaluate all models:
    • Pipeline
    • Specialized VLM
    • General VLM

Limitations and Further Work

Pipeline based track:

  • Built layout detection and reading order detection tasks are evaluated separately (reading order is evaluated using ground bounding boxes).
  • Currently, RaRe only supports inference; possible extension includes training of the available models.
  • VLM track currently only supports Youtu-parse. Further improvement could see integration of a larger number of models into rare, so they can be output in an arbitrary format (such as JSON, HTML etc.)

Acknowledgements

Thanks for the work of the authors of these projects:

  • PaddleX — the improved XY-Cut reading-order backend is vendored from PaddleX (Apache-2.0); see NOTICE and licenses/LICENSE-PADDLEX.
  • OmniDocBench — the end-to-end Edit-distance evaluator (run via --run-omnidocbench) and the specialized VLM img2md parsing backends are adapted from OmniDocBench (Apache-2.0); see NOTICE and licenses/LICENSE-OMNIDOCBENCH.
  • layoutreader — the layoutreader reading-order backend uses the LayoutLMv3 inference helpers and the hantian/layoutreader checkpoint from Hantian Pang's faster LayoutReader (CC BY-NC-SA 4.0); neither is redistributed by RaRe, see NOTICE and the licensing note below.
  • DocLayout-YOLO
LayoutReader specifics

RaRe is licensed GPL-3.0-or-later (see LICENSE). The LayoutLMv3 inference helpers from FreeOCR-AI/layoutreader are CC BY-NC-SA 4.0, whose NonCommercial term is an additional restriction that GPLv3 §7 forbids — so RaRe does not ship them. The first time you run --order layoutreader, the single upstream v3/helpers.py is downloaded and cached under ~/.cache/rare/ (override with RARE_CACHE_DIR); the hantian/layoutreader checkpoint the backend loads is likewise CC BY-NC-SA 4.0 and fetched at runtime.

Citation

@phdthesis{
    Kuzman_2026,
    title={Samodejno razčlenjevanje kompleksnih postavitev dokumentov},
    url={https://hdl.handle.net/20.500.12556/RUL-189793},
    abstractNote={Razčlenjevanje kompleksnih vrst dokumentov, kot so revije, je zahtevnejše od razčlenjevanja preprostejših dokumentov, na primer znanstvenih člankov. Primerne zbirke za razčlenjevanje slovenskih dokumentov doslej še ni bilo. V sklopu magistrskega dela smo z ročnim anotiranjem 35 dokumentov, ki vsebujejo 881 slik, ustvarili prvo takšno zbirko v slovenščini. Na njej smo ovrednotili celovite modele za razčlenjevanje in posamezne dele cevovodnega pristopa; najbolje se je izkazal Youtu-Parsing z oceno razdalje urejanja 0,031. Na zbirki smo naučili model DocLayout-YOLO, ki dosega mAP 64,3 %. Razvili smo tudi cevovod, ki s temi modeli iz dokumentov izlušči članke ter jih obogati z metapodatki.},
    author={Kuzman, Luka},
    year={2026}
}
LayoutReader specifics

If you use the layoutreader reading-order backend, please cite the upstream implementation and the original LayoutReader paper:

@software{Pang_Faster_LayoutReader_based_2024,
  author  = {Pang, Hantian},
  month   = feb,
  title   = {{Faster LayoutReader based on LayoutLMv3}},
  url     = {https://github.com/ppaanngggg/layoutreader},
  version = {1.0.0},
  year    = {2024}
}

@inproceedings{wang-etal-2021-layoutreader,
  title     = {{L}ayout{R}eader: Pre-training of Text and Layout for Reading Order Detection},
  author    = {Wang, Zilong and Xu, Yiheng and Cui, Lei and Shang, Jingbo and Wei, Furu},
  booktitle = {Proceedings of the 2021 Conference on Empirical Methods in Natural Language Processing},
  month     = nov,
  year      = {2021},
  address   = {Online and Punta Cana, Dominican Republic},
  publisher = {Association for Computational Linguistics},
  url       = {https://aclanthology.org/2021.emnlp-main.389/},
  doi       = {10.18653/v1/2021.emnlp-main.389},
  pages     = {4735--4744}
}