File size: 2,804 Bytes
dabedb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
---
license: apache-2.0
library_name: pytorch
pipeline_tag: image-to-text
tags:
  - ocr
  - htr
  - handwritten-text-recognition
  - historical-documents
---

# DeepOCR v3

A line-level text recognition model for historical print and handwriting: Fraktur, Antiqua, Kurrent, and medieval and modern Latin script, in one checkpoint. Code, training and architecture: [DeepOCR](https://github.com/m2key1/DeepOCR).

## Files

| File | What it is |
|---|---|
| `deepocr-v3.pt` | The model weights (EMA), with every architecture setting stored inside |
| `union_bytes_v3.bin` | Byte-level 6-gram KenLM, fused into the beam search |
| `union_bytes_v3.dict` | The LM's token list, index-parallel to the model's 261-token byte vocabulary |

The LM belongs to this checkpoint. Do not pair it with another one.

## Use

```python
from pathlib import Path

import torch
from PIL import Image
import infer
from infer import load_model, transcribe_beam

infer.KENLM_PATH = Path('union_bytes_v3.bin')
infer.LM_DICT_PATH = Path('union_bytes_v3.dict')
infer.LM_WEIGHT = 1.0
infer.BEAM_WIDTH = 10

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model, tokenizer = load_model('deepocr-v3.pt', device)
print(transcribe_beam(model, tokenizer, [Image.open('line.png')], device)[0])
```

Input is one text line as an RGB image; it is scaled to 256 px high and read up to 6144 px wide. Three flags choose the transcription convention: `long_s` (ſ), `oblique_hyphen` (⸗) and `typographic_punctuation`. Set them in `infer.CONVENTION`; all off by default.

The model is also the OCR builtin of [DeepLabel](https://github.com/m2key1/DeepLabel).

## Model

170.5M parameters. A grouped CNN backbone feeds four mixture-of-experts transformer layers (64 experts, 8 active per column, plus one shared expert) and a CTC head over bytes, so it can emit any Unicode character. Trained from scratch.

## Evaluation

CER on the held-out validation split, 25,000 lines:

| Decoding | CER |
|---|---|
| Greedy | 3.68% |
| Beam 10 | 3.57% |
| Beam 10 + KenLM, weight 1.0 | 3.03% |

## Training data

Public datasets of historical print and handwriting. The language model was built from the same training split.

## Limitations

- Reads single lines only; it needs a line detector or segmentation in front of it.
- Reads best on material like its training data: European print and handwriting from the medieval to the modern period. Accuracy drops on other scripts and unusual hands.
- The language model favours the training text; for mostly numeric or tabular text, lower `LM_WEIGHT` or decode without it.

## License

Apache-2.0.

## Citation

```bibtex
@software{fleischhacker_deepocr,
  author = {Fleischhacker, David},
  title  = {DeepOCR},
  year   = {2026},
  url    = {https://github.com/m2key1/DeepOCR}
}
```