Local scores
Metric (competition metric): score = 1 − WER_w/24 − CER_w/110, where word and character edit distances are weighted per line by
√(reference length). WER/CER columns are plain micro-averaged percentages. Greedy decoding at image scale 1.5 unless noted.
Table with columns: split, lines, score, WER %, CER %, exact lines, role| split | lines | score | WER % | CER % | exact lines | role |
|---|
| dev minus original100 ("dev150") | 150 | 0.9013 | 14.93 | 4.56 | 29 | selection set: checkpoint and image scale chosen here |
| dev250 (dev150 + original100) | 250 | 0.8987 | 15.38 | 4.58 | 46 | |
| original100 | 100 | 0.8949 | 16.04 | 4.61 | 17 | reported once, never used for any choice |
| audit350 | 350 | 0.9004 | 14.87 | 4.78 | 93 | holdout, never used for any choice |
| dev150, zero-shot base model | 150 | 0.7713 | 32.70 | 12.45 | 3 | scale 1.5, same usage |
Decoding comparison (same checkpoint; beam = 5 beams; "+ char LM" = beam candidates re-ranked with a character 6-gram trained on the training transcriptions, weights λ=0.05, μ=-0.25 chosen on dev150 — the LM is not included in this repo):
Table with columns: split, greedy, beam-5 top-1, beam-5 re-ranked by model log-prob, beam-5 + char LM, best candidate in the 5-best (oracle)| split | greedy | beam-5 top-1 | beam-5 re-ranked by model log-prob | beam-5 + char LM | best candidate in the 5-best (oracle) |
|---|
| dev-minus-o100 (tuning set) | 0.9013 | 0.9046 | 0.9019 | 0.9042 | 0.9260 |
| audit350 (holdout) | 0.9004 | 0.9033 | 0.9026 | 0.9028 | 0.9291 |
| original100 (once) |
Paired bootstrap on audit350: beam-5 vs greedy +0.0022 (95% CI -0.0012 to +0.0067); beam-5 + char LM vs greedy +0.0024 (95% CI -0.0015 to +0.0069).
Data splits (frozen, SHA-256 verified images)
Table with columns: split, lines, use| split | lines | use |
|---|
| train3497 | 3,497 | training only |
| dev150 = dev250 minus original100 | 150 | every choice: checkpoint, image scale, decoding settings |
| original100 | 100 | reported once at the end; never used for any choice |
| audit350 | 350 | holdout for comparisons; never tuned on |
| test | 1,374 | competition test lines (no labels) |
The splits are disjoint by line ID and by exact image hash.
Requirements
transformers==4.57.6 (the base repo's pin; the model uses remote code: trust_remote_code=True)
torch>=2.4 with torchvision, Pillow, huggingface_hub, accelerate
- a CUDA GPU with bf16 (≈ 14 GB for inference: the weights are FP32, ~12 GB).
flash-attn is optional: without it
barbados_inference.py registers a stub and uses PyTorch SDPA attention (same results).
pip install "transformers==4.57.6" torch torchvision pillow huggingface_hub acceleratehuggingface-cli login # after your access request is approved
How to use
from huggingface_hub import snapshot_downloadimport syspath = snapshot_download("Abdoul27/dots-mocr-barbados")sys.path.insert(0, path)from barbados_inference import load, transcribemodel, processor = load(path)print(transcribe(model, processor, ["line_001.jpg", "line_002.jpg"])) # greedy (scores above)print(transcribe(model, processor, ["line_001.jpg"], num_beams=5)) # beam-5 (see decoding comparison)
What barbados_inference.py does (reproduce this exactly to get the scores above):
- Input: one image per handwritten line (not a full page), converted to RGB and resized by 1.5× (bicubic),
capped at 1,605,632 pixels.
- Prompt: the official dots.mocr OCR prompt
"Extract the text content from this image.", image first, no system prompt, through the model's own chat template.
- Decoding: greedy (or beam search), at most 51 new tokens, stop at
<|endofassistant|> (also <|endoftext|>,
<|assistant|>); FP32 weights with BF16 autocast; one image per call. Vision attention runs per image with PyTorch SDPA, and beam
search copies the image correctly for every beam (the default expansion would scramble dots.mocr's flat patch matrix).
- Output: multi-line outputs are joined with single spaces; repetition loops are trimmed only when the length cap is hit.
Transcription conventions learned from the training labels: original spelling and abbreviations are kept (pnts, Xpian, w^th);
^ marks raised (superscript) letters, e.g. w^th, Exec:^rs; & is kept.
Training
- Full fine-tune of all weights of
dots-studio/dots.mocr: FP32 weights with BF16 autocast, AdamW (β = (0.9, 0.95), weight decay 0.1
except norms/biases/embeddings; 8-bit AdamW on GPUs under 70 GB), lr 1e-05 (vision encoder 2e-06), warm-up then cosine
to 10 %, effective batch 16, up to 5 epochs with evaluation twice per epoch;
best checkpoint epoch_05_half, selected on dev150.
- Answer-only loss including the end token
<|endofassistant|>; mild augmentation (±10 % scale, ±1.5° rotation, brightness/contrast,
light blur); gradient checkpointing. barbados_training_worker.py is the complete training/evaluation code.
Limitations
- Line-level model: it expects one cropped text line per image; full pages need line segmentation first.
- Trained on 3497 lines from one archive and period; other hands, languages or scripts may degrade.
Licence
Same licence as the base model dots-studio/dots.mocr (mit; see LICENSE when present).