---
title: "Automatic reading of archive registers"
url: "https://edoardo.anteprime.edoardogabrielli.com/en/projects/archive-registers"
lang: "en"
updated: "2026-11-01"
---

# Automatic reading of archive registers

> A tool to index tens of thousands of handwritten and typed files, with a reading model trained on single rows and review by the archivist.

A tool to index tens of thousands of handwritten and typed files, leaving the last word to the archivist.

### What it is for / What it can do

Designed for public archives and technical offices with scanned registers to index. ETT, a digitisation company, offers it through its Scripta line in its collection digitisation projects. It saves retyping thousands of rows by hand; the check stays with the archivist.

- Reads tabular registers, typed and handwritten, and proposes each row already split into the required fields.
- Highlights uncertain values, to be checked next to the page image.
- Keeps a history of corrections and lets you step back.
- Exports the result to a spreadsheet.
- Runs on an internal server: scans never leave the institution.

[See the solution on ETT's site](https://ettsolutions.com/scripta/)

### Context

A public archive keeps registers of building permit files from the 1960s onwards: tables filled in by hand or by typewriter, each with one row per file and about twenty columns. To make them searchable, every row has to be transcribed into a database. Done by hand, it takes years.

I developed this project at the software company where I work as a developer. Everything runs on an internal server, so the scans never leave the institution.

### How it works

The application reads each scanned page and proposes the rows already split into the required fields. The archivist sees the page next to the form, checks the values (uncertain ones are highlighted) and confirms or corrects them. At the end they export a spreadsheet.

![Row-by-row review of the extracted fields next to the scanned page, example data](https://edoardo.anteprime.edoardogabrielli.com/media/originals/2026/11/7828f5e0519e4995830a50cbf947fae1/registri-revisione.webp)

Row-by-row review: the uncertain field is yellow, the matching row is highlighted on the page. Data and page are examples.

### The model I trained

At first the reading was done by a large general-purpose vision model (Qwen, 35 billion parameters), which received the whole page. On handwritten registers it often got things wrong.

So I trained a much smaller model, of about one billion parameters, that reads one row at a time. The difficulty was finding training data: the archivists had already confirmed thousands of values, but nobody knew where on the page each one was. The solution was to flip the question: instead of asking the large model *what is written*, I asked it *where a value we already knew is located*. From there the piece of the page is cropped, read again, and kept only if the reading matches the confirmed value.

The small model is trained on the validated rows with LoRA, a method that updates only a small part of the parameters. Every night an automatic cycle updates it with the pages confirmed during the day, evaluates it on pages it has never seen, and puts it into production only if no register gets worse.

### Results

On a test of 115 pages from 23 registers (9,169 fields, never used for training) the small model reads 84.7% of the fields correctly; the large model, on the same pages, 39%. Short, regular fields such as the file number are almost always right. Addresses and notes remain hard.

A manual check showed that some of the "errors" were differences of form or wrong reference values: the real figure is somewhat higher. In any case the model does not replace the archivist; it saves them time.

## More screenshots (example data)

![List of registers with validation progress, example data](https://edoardo.anteprime.edoardogabrielli.com/media/originals/2026/11/61f0c4b71cdf42a9a51a1c85e35c82d5/registri-elenco.webp)

![Work progress statistics and finish forecast, example data](https://edoardo.anteprime.edoardogabrielli.com/media/originals/2026/11/5d0be0c5065747db9bc4e3503de20dc8/registri-avanzamento.webp)

### A second project: summarising case files

As a prototype I adapted the same work to another problem: finding out what a file of mixed scans (reports, drawings, photos) contains without reading it all. For each page the vision model writes a note (document type, dates, people, places, transcription); then a text model writes a summary in which every statement links back to the source page, so the reader can check it. Dates and cross-references between sheets are derived by code, not invented by the model. It was delivered on a test file of 9 documents and 63 sheets and remains a prototype.

### What I did

The web application (backend, review interface, guided tutorial), the reading pipeline, the training and evaluation of the model, and putting it into production on the GPU server. For the case-file prototype I did the adaptation.

### Limits

The project is not public and there is no demo, because of the client. The model does not cope with a hand or a form it has never seen, and each register has its own conventions (the "ditto" marks are the hardest part).

### Stack

Python · FastAPI · PostgreSQL · Redis · React/Next.js · OpenCV · vLLM · LoRA (PEFT) · llama.cpp · Docker · NVIDIA DGX Spark

[← All projects](https://edoardo.anteprime.edoardogabrielli.com/en/projects)