Train Tesseract on custom fonts
and data (tesstrain, v5).
A tested, decision-driven guide to fine-tuning and training Tesseract 5 models with tesstrain: building from source, preparing ground truth, running make training, tuning the important variables, measuring CER with lstmeval, and deploying your traineddata.
TL;DR — fine-tune an existing model
If your script is already supported, fine-tuning is the fastest path to a better model.
git clone https://github.com/tesseract-ocr/tesstrain.git
cd tesstrain && make tesseract-langdata
# put line images + .gt.txt in data/myfont-ground-truth/
make training MODEL_NAME=myfont START_MODEL=engTraining is not available through the binary installers. You need Linux or WSL2. See installation for building from source.
Decision tree: fine-tune vs cut top layer vs from scratch
Choosing the right approach saves days of wasted training.
| Approach | Use when | Data needed | Time |
|---|---|---|---|
Fine-tune (FINETUNE_TYPE=1) | Same script, new font or domain vocabulary | 1,000–5,000 lines | Hours |
Cut top layer (FINETUNE_TYPE=2) | Same script, meaningfully different glyph shapes | 5,000–20,000 lines | Hours–days |
| Train from scratch | New script or very different alphabet | 50,000+ lines | Days |
Start with the lightest option that could work, evaluate, and only escalate if CER is unacceptable. Most custom-font problems are solved by fine-tuning.
Prerequisites
Training requires the source build, not the packaged binary.
- A Linux environment — native or WSL2 on Windows. macOS is not supported for training.
git,make,pkg-config,automakeand a C++ toolchain.libtesseract-devandlibleptonica-dev(the training binaries link against these).- The
tesstrainrepository, pluslangdata_lstmand atessdata_beststarting model.
sudo apt update
sudo apt install -y git make automake pkg-config g++ \
libleptonica-dev libtesseract-dev tesseract-ocr
git clone https://github.com/tesseract-ocr/tesstrain.git
cd tesstrain
make tesseract-langdata # fetches langdata_lstm + tessdata_bestPrepare ground truth
Ground truth is line images paired with their exact text.
tesstrain expects one image per text line in data/<MODEL_NAME>-ground-truth/, each with a matching .gt.txt file containing the exact transcription. Generate images from a text file and a font with text2image, then split long text into lines with split_training_text.py from langdata_lstm.
# Generate line images from a text corpus + a font
text2image --text=corpus.txt \
--outputbase=data/myfont-ground-truth/myfont \
--font='My Custom Font' --fonts_dir=/usr/share/fonts \
--ptsize=14
# text2image also emits .box files; convert them to .gt.txt
# (tesstrain/training/ has helper scripts, or rename after verification)How much data: 100–500 lines to validate the pipeline, 1,000–5,000 for production. Accuracy comes from variety — different fonts, sizes, spacing and noise — more than raw volume.
Fonts and unicharset selection
The character set must cover everything the model will see.
- Install the training fonts in the environment; pass the exact family name to
--font. - When fine-tuning, keep the starting model's
unicharsetso the output layer matches. - For a new script, derive the unicharset from your ground truth so every glyph is represented.
- Include punctuation, digits and mixed case if the real documents contain them — otherwise the model will drop them.
Run training
One command drives the whole Makefile pipeline.
make training \
MODEL_NAME=myfont \
START_MODEL=eng \
TESSDATA_PREFIX=../tessdata_best \
MAX_ITERATIONS=10000| Variable | Meaning | Typical value |
|---|---|---|
START_MODEL | Model to continue from (fine-tuning) | eng, jpn… |
TESSDATA_PREFIX | Directory holding the starting model | ../tessdata_best |
MAX_ITERATIONS | Upper bound on training steps | 10000–100000 |
LEARNING_RATE | Step size; lower is safer for fine-tuning | 0.0001–0.001 |
FINETUNE_TYPE | 0 scratch, 1 fine-tune, 2 cut top layer | 1 |
NET_SPEC | Network architecture spec | leave default |
RATIO_TRAIN | Train/validation split | 0.9 |
TARGET_ERROR_RATE | Early-stop CER target | 0.01 |
Checkpoints, stop_training and best vs fast
- tesstrain writes periodic checkpoints (for example
myfont_checkpoint) you can evaluate or resume from. - Create a
stop_trainingfile in the output directory to end the run cleanly at the next iteration. - Convert a checkpoint to a usable model with
combine_tessdata -e/convert_to_intin the training tools. - best models are the most accurate; fast models are smaller and quicker. Fine-tune from
tessdata_bestwhen accuracy matters.
Evaluation: character error rate with lstmeval
Judge the model on data it never trained on.
lstmeval --model data/myfont_checkpoint \
--traineddata ../tessdata_best/eng.traineddata \
--eval_listfile data/myfont-ground-truth/eval_files.txtTrack CER on a held-out set. When it stops falling — or starts climbing while training loss still drops — you are overfitting; stop and use the earlier checkpoint.
Deploy the trained model
Copy the traineddata, point the engine at it, and test.
# Copy into a tessdata directory
cp data/myfont.traineddata /usr/share/tesseract-ocr/5/tessdata/
# or set a custom prefix
export TESSDATA_PREFIX=/path/to/tessdata
tesseract sample.png stdout -l myfontYou can combine your model with a base language, e.g. -l myfont+eng. In Python, pass the same value to pytesseract — see the Python guide.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Bad boxes / misaligned ground truth | Incorrect font metrics or oversized line images | Regenerate with the right --font and --ptsize; verify a few images by eye. |
| Missing characters in output | Character absent from the unicharset | Add the glyphs to your ground truth and rebuild the unicharset. |
| Loss diverges / NaN | Learning rate too high | Lower LEARNING_RATE and resume from an earlier checkpoint. |
| Out of memory | Batch too large for RAM/GPU | Reduce BATCH_SIZE/network size, or use a machine with more memory. |
| Validation CER rises while training loss falls | Overfitting | Stop earlier, add more varied ground truth, or use a lower learning rate. |
Training FAQ
Can I train Tesseract without building it from source?
No. The training tools are not in the binary installers; use Linux or WSL2 with libtesseract-dev and the tesstrain repository.
How many samples do I need?
About 100–500 lines to validate the pipeline, and 1,000–5,000 for production. Fine-tuning needs less than training from scratch.
Fine-tune or train from scratch?
Fine-tune for a new font or vocabulary in an existing script; train from scratch only for a genuinely new script.
When should I stop training?
When held-out CER stops improving — not when training loss flattens. That gap is overfitting.
Where does the model go?
Copy <MODEL_NAME>.traineddata into a tessdata directory (or set TESSDATA_PREFIX) and run tesseract image.png stdout -l myfont.