Downloads · 30 days
7
13% of all-time downloads
BarzinV/maltese-ocr-trocr
maltese-ocr-trocr is a image-to-text model from BarzinV. Use it when you need a caption or text from an image. It is set up for transformers. The card lists the license as mit.
A printed-text OCR model for Maltese, built for the DocEng 2026 "OCRs for Corpus Extraction for the Maltese Language" competition. It is a TrOCR vision-encoder-decoder whose decoder has been re-vocabularised to a char…
Downloads · 30 days
7
13% of all-time downloads
All-time downloads
53
Public
Parameters
283M
1.1 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors1.1 GB · 100%
From the Hugging Face model README
A printed-text OCR model for Maltese, built for the DocEng 2026 "OCRs for Corpus Extraction for the Maltese Language" competition. It is a TrOCR vision-encoder-decoder whose decoder has been re-vocabularised to a character-level Maltese vocabulary and fine-tuned only on synthetic data (per the competition's synthetic-data-only rule).
VisionEncoderDecoderModel.<pad>/<bos>/<eos> + 117
characters), covering the Maltese alphabet (Ċ ċ Ġ ġ Ħ ħ Ż ż), Latin letters,
digits, punctuation and the accented/typographic characters seen in the corpus.
This replaces TrOCR's default subword (RoBERTa) vocabulary.evaluate.load('cer'). (The
training-time per-step eval reported 0.3945 at step 36 000; see best.json.)Scope. This is a synthetic-data-only research model. The competition's Tesseract + NOMOCRAT baseline scores a lower CER but is excluded here by the synthetic-data-only rule and by NOMOCRAT licensing/provenance, so it is reported only as a baseline — not submitted.
The competition interface is a no-argument constructor plus a single
transcribe(PIL.Image) -> str method:
from PIL import Image
from competition_transcriber import CompetitionTranscriber # ships with the submission
transcriber = CompetitionTranscriber() # downloads this repo on first use, then caches
text = transcriber.transcribe(Image.open("line.png"))
print(text)
CompetitionTranscriber downloads this repo via from_pretrained(...) (model +
processor) plus one hf_hub_download(...) for the character tokenizer, then runs
beam search (num_beams=2, no_repeat_ngram_size=3, repetition_penalty=1.2,
length_penalty=1.0, max_new_tokens=511) at batch size 1.
To load the pieces directly:
import json, torch
from huggingface_hub import hf_hub_download
from transformers import TrOCRProcessor, VisionEncoderDecoderModel
REPO = "BarzinV/maltese-ocr-trocr"
dtype = torch.float16 if torch.cuda.is_available() else torch.float32
model = VisionEncoderDecoderModel.from_pretrained(REPO, torch_dtype=dtype).eval()
processor = TrOCRProcessor.from_pretrained(REPO) # image preprocessing
chars = json.load(open(hf_hub_download(REPO, "char_tokenizer.json")))["chars"]
id_to_token = ["<pad>", "<bos>", "<eos>", *dict.fromkeys(chars)] # ids 0/1/2 are special
px = processor.image_processor(images=img.convert("RGB"), return_tensors="pt").pixel_values.to(dtype)
ids = model.generate(pixel_values=px, num_beams=2, no_repeat_ngram_size=3,
repetition_penalty=1.2, length_penalty=1.0, max_new_tokens=511)[0].tolist()
text = "".join(id_to_token[i] for i in ids if i > 2) # skip pad/bos/eos
Note: decoding uses the character tokenizer in char_tokenizer.json, not
the processor's bundled RoBERTa tokenizer (which is vestigial — only the image
processor is used). The decoder's positional table is 512, so cap generation at
511 new tokens.
MLRS/korpus_malti
corpus were rendered to images by a custom renderer (multiple serif/sans fonts,
regular/bold/italic, varied sizes, widths, justification and backgrounds), then
fed as image→text pairs. No real/scanned competition images were used for
training.v2 → v3 → v4.length_penalty=1.0 optimal (a <1 penalty only over-truncates
legitimate longer text); this is what the submission uses.| File | Purpose |
|---|---|
model.safetensors | model weights |
config.json | VisionEncoderDecoderModel config (ViT encoder + char decoder, vocab_size=120) |
generation_config.json | generation defaults (bos/eos/pad ids) |
char_tokenizer.json | custom character tokenizer (the decode vocabulary) |
processor_config.json | TrOCRProcessor / ViTImageProcessor config (384×384, normalize) |
tokenizer_config.json, tokenizer.json | processor's bundled RoBERTa tokenizer (loaded by TrOCRProcessor; not used for decoding) |
Released under the MIT license, matching the base model
microsoft/trocr-base-handwritten.