Ordered Regression of Lines
Project description
Orli
Orli (ordered regression of lines) is a layout-analysis model that detects text-line baselines and emits them directly in reading order. It is designed for historical-document OCR pipelines that need explicit line geometry without a separate reading-order heuristic.
The method is described in the article End-to-End Text Line Detection and Ordering.
Installation
pip install .
Orli integrates with kraken 7 through its model plugin system.
Model
The release base model is trained on 200000 pages spanning ten writing systems. It is published available through HTRMoPo with DOI 10.5281/zenodo.20558179.
Download it with kraken:
kraken get 10.5281/zenodo.20558179
The command prints the model directory and the downloaded model file, necessary for fine-tuning and programmatic inference.
Run baseline segmentation with kraken. This example writes PAGE XML:
kraken -i input.jpg output.xml -x segment -bl --model orli_base.safetensors
Programmatic inference uses the complete model path printed after download:
from PIL import Image
from orli.pred import segment
im = Image.open("input.jpg")
segmentation = segment(im, "/path/to/kraken/download/orli_base.safetensors")
Scores
Line metrics are computed using the cBAD evaluation score implemented in orli test. Footrule is normalized Spearman footrule, where lower is better.
Test Set
| Model | Precision | Recall | F1 | Cov. | Footrule | Kendall tau |
|---|---|---|---|---|---|---|
| base | 0.9554 | 0.9564 | 0.9559 | 0.9667 | 0.0304 | 0.9649 |
cBAD 2019
| Model | Precision | Recall | F1 | Cov. | Footrule | Kendall tau |
|---|---|---|---|---|---|---|
| base | 0.9378 | 0.9302 | 0.9340 | 0.9406 | 0.0768 | 0.9113 |
| fine-tuned | 0.9395 | 0.9306 | 0.9351 | 0.9421 | 0.0720 | 0.9165 |
Reading-Order Benchmarks
| Dataset | Model | Precision | Recall | F1 | Cov. | Footrule | Kendall tau |
|---|---|---|---|---|---|---|---|
| OHG | base | 0.9940 | 0.9937 | 0.9938 | 0.9993 | 0.0033 | 0.9967 |
| FCR | base | 0.9894 | 0.9874 | 0.9884 | 0.9905 | 0.0028 | 0.9971 |
| ABP | base | 0.8505 | 0.7919 | 0.8201 | 0.8071 | 0.5372 | 0.2878 |
| ABP | fine-tuned | 0.8498 | 0.7806 | 0.8137 | 0.7931 | 0.0898 | 0.8972 |
Dataset Preparation
Orli trains on Arrow datasets compiled from PageXML or ALTO files. The compiler stores each line as a normalized baseline polyline in source-file order. The arrow files are NOT compatible with kraken's compiled datasets.
orli compile -o dataset.arrow --allow-textless *.xml
For large images, pre-resizing during compilation reduces training I/O. The base model uses a high-resolution input size of 1920x1440:
orli compile -o dataset.arrow --allow-textless -r 1920 1440 *.xml
Compilation uses the implicit reading order, i.e. the sequence of line elements in the source file. Other reading-order annotations are ignored.
Training and Fine-Tuning
Training and fine-tuning are configured either through command-line options or a
YAML file. For fine-tuning the released base model, keep the high-resolution
input size and load the downloaded orli_base.safetensors file:
precision: bf16-mixed
device: auto
num_workers: 12
num_threads: 1
train:
training_data:
- train.arrow
evaluation_data:
- val.arrow
checkpoint_path: experiments/orli_finetuned
image_size: [1920, 1440]
optimizer: AdamW
epochs: 8
lrate: 5e-5
weight_decay: 1e-4
schedule: cosine
cos_t_max: 8
cos_min_lr: 1e-5
warmup: 1000
augment: true
batch_size: 8
val_batch_size: 8
accumulate_grad_batches: 8
baseline_num_points: 16
orli --config finetune.yaml train --load "$MODEL"
orli --config finetune.yaml train --resume /path/to/checkpoint.ckpt
The training command writes the best checkpoint and converts it to safetensors
automatically. The resulting best_*.safetensors file can be used with
kraken segment in the same way as the base model.
Evaluation
Evaluate a model on an Arrow dataset with baseline detection metrics and reading-order metrics:
orli test --load model.safetensors test.arrow
Citation
@misc{kiessling2026orli,
title = {End-to-End Text Line Detection and Ordering},
author = {Benjamin Kiessling},
year = {2026},
eprint = {2606.04166},
archivePrefix = {arXiv},
primaryClass = {cs.CV},
url = {https://arxiv.org/abs/2606.04166}
}
License
Orli is released under the Apache License 2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file orli-0.0.2.tar.gz.
File metadata
- Download URL: orli-0.0.2.tar.gz
- Upload date:
- Size: 65.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58b612a048110c3954ce740382ac1254256b423d3259c287200c309fec18269a
|
|
| MD5 |
b655f99ab95a4edd6e2252aeb0ad5cff
|
|
| BLAKE2b-256 |
ea983642533d89eb2f8834d669697ed885ffb9f310d0adcd4222cc5085421abd
|
Provenance
The following attestation bundles were made for orli-0.0.2.tar.gz:
Publisher:
test.yml on mittagessen/orli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orli-0.0.2.tar.gz -
Subject digest:
58b612a048110c3954ce740382ac1254256b423d3259c287200c309fec18269a - Sigstore transparency entry: 1733554908
- Sigstore integration time:
-
Permalink:
mittagessen/orli@f45c756cce1a6d059521909b4fe316a34ca21817 -
Branch / Tag:
refs/tags/0.0.2 - Owner: https://github.com/mittagessen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
test.yml@f45c756cce1a6d059521909b4fe316a34ca21817 -
Trigger Event:
push
-
Statement type:
File details
Details for the file orli-0.0.2-py3-none-any.whl.
File metadata
- Download URL: orli-0.0.2-py3-none-any.whl
- Upload date:
- Size: 84.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39ba08f802926133145ed1a822052771ad4c34f67381114827880556e7de86b0
|
|
| MD5 |
ff00a8bae6bd766f2cdb939beb24d74f
|
|
| BLAKE2b-256 |
a16c79f7d1c878b9a9776c30fa925b7f0be40b9d80232a97ecc6ff055cc26eec
|
Provenance
The following attestation bundles were made for orli-0.0.2-py3-none-any.whl:
Publisher:
test.yml on mittagessen/orli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orli-0.0.2-py3-none-any.whl -
Subject digest:
39ba08f802926133145ed1a822052771ad4c34f67381114827880556e7de86b0 - Sigstore transparency entry: 1733554957
- Sigstore integration time:
-
Permalink:
mittagessen/orli@f45c756cce1a6d059521909b4fe316a34ca21817 -
Branch / Tag:
refs/tags/0.0.2 - Owner: https://github.com/mittagessen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
test.yml@f45c756cce1a6d059521909b4fe316a34ca21817 -
Trigger Event:
push
-
Statement type: