Repository Public
1# Models served by htr.spboucher.ai23Each sub-directory is one reconstruction model: `models/<id>/` holds the weights (never committed) and a tracked4`model_card.json` (plus `README.md` / `LICENSE-MODEL.txt` for the HTR releases). `server.py` discovers the5directories at start-up through `htr.inference.backbones.ModelRegistry`: the model flagged `"default": true` is6loaded immediately, the others on their first request (at most 2 non-pinned models resident, LRU eviction;7`htr-tiny-0.3.0` is pinned).89| id | Name | Family | Parameters | Base model | Default |10|---|---|---|---|---|---|11| `htr-tiny-0.3.0` | HTR-Tiny 0.3.0 | `htr` | 33.5 M | — (paper's confirmatory model M*) | |12| `htr-base-0.1.0` | HTR-Base 0.1.0 | `htr` | 334.8 M | — | |13| `flan-t5-large-htr` | Flan-T5-Large-HTR | `hf-seq2seq` | 783 M | google/flan-t5-large | |14| `qwen2.5-1.5b-htr` | Qwen2.5-1.5B-HTR | `hf-causal` | 1.54 B | Qwen/Qwen2.5-1.5B | yes |1516Families: `htr` = HTR Transformer trained from scratch (loaded by `HTRReconstructor`, greedy or beam 3);17`hf-seq2seq` = Hugging Face encoder–decoder (`HFSeq2SeqReconstructor`, greedy); `hf-causal` = Hugging Face18decoder-only LLM (`HFCausalReconstructor`, greedy). All metrics in the cards are chrF++ differences versus the19identity baseline on the Medium Haiku pairs (exploratory except the confirmatory test number of HTR-Tiny).2021## `model_card.json`2223```jsonc24{25 "id": "qwen2.5-1.5b-htr", // = directory name26 "name": "Qwen2.5-1.5B-HTR", // display name27 "family": "hf-causal", // htr | hf-seq2seq | hf-causal28 "n_params": 1543714304,29 "base_model": "Qwen/Qwen2.5-1.5B", // null for htr models30 "licence": "…",31 "default": true, // exactly one model32 "speed_hint": "≈5–15 s per paragraph (greedy, Apple GPU)",33 "max_len": 512, // hf-seq2seq: encoder window (tokens)34 "max_new_tokens": 768, // hf-causal: generation budget (tokens)35 "metrics": {36 "reference": "…",37 "val_chrf_delta": 2.19, "val_chrf_pm": 0.12,38 "test_chrf_delta": 1.97, "test_chrf_pm": 0.06, "test_chrf_ci": null, "test_confirmatory": false,39 "heldout_domain_chrf_delta": 1.78, "heldout_domain_pm": 0.13,40 "heldout_period_chrf_delta": 1.30, "heldout_period_pm": 0.14,41 "number_recall": 0.997, "placeholders_exact": 0.998,42 "pangram_human": 48, "pangram_n": 54, "pangram_mixed": 643 },44 "notes": ["…"], // backbones: keep the pretraining-corpus caveat45 "trained_on": "…",46 "exported_at": "2026-11-10"47}48```4950## Adding a model (no code change)5152From the laptop, with the export directory containing the weights and a `model_card.json`:5354```bash55scripts/add_model.sh <laptop-model-dir> <id> # e.g. scripts/add_model.sh artifacts/runs/medium_b2_flan_t5_xl/best flan-t5-xl-htr56```5758The script checks the card, rsyncs the directory to `m4mm:~/apps/htr/models/<id>/`, restarts PM2 `htr-web`, waits59for `/api/models` to list the id, and commits the tracked card files on the node. Candidates: `flan-t5-xl-htr`,60`qwen2.5-3b-htr`, `htr-large`. To change the default, set `"default": true` in exactly one card and restart.61Weights required per family: `htr` → `model.safetensors`, `config.json`, `tokenizer.model`, `release_meta.json`;62`hf-*` → the Hugging Face `save_pretrained` directory (`config.json`, `model.safetensors`, tokenizer files).63