Skip to content

Latest commit

 

History

History
210 lines (154 loc) · 7.42 KB

File metadata and controls

210 lines (154 loc) · 7.42 KB

HTR-Integration

Technische Spezifikation des Recognition-Stacks für Volltext aus Vision §5 („Lese-Hilfe für historische Texte" inkl. Lese-Lupe). Ergänzt architektur.md §13 und §14.

Kernprinzip: kein Eigenbau. „Lesen ist gelöst, keine Forschung" (architektur.md §1).


1. Default-Pfad: Transkribus Text Recognition API

API-Endpoints

  • POST /processes — Job anlegen (Modell-ID + Bild-URL/Base64 + Optionen).
  • GET /processes/{processId} — Status pollen (PENDING / RUNNING / FINISHED / FAILED).
  • GET /processes/{processId}/results — PAGE-XML, ALTO, TEI, Plaintext.
  • Auth: OpenID-Connect-Bearer-Token; pro App-Instanz eine Service-Account- Credential.

Modelle (Auswahl)

Stand: 2026-06 — Modellangebot und CER-Werte vor P1-Start neu verifizieren.

Modell Trainingsdaten CER (publiziert) Engine
German Kurrent 17th–20th c. ~3 Mio. Wörter, gemischt 5,4 % PyLaia
German_Kurrent_XIX_pylaia 19. Jh., Schwerpunkt 6,9 % PyLaia
German Kurrent 17th–18th älterer Schwerpunkt 5,5 % PyLaia
Swiss German Kurrent 18th Schweizer Kanzlei-Hände 5,9 % PyLaia
German Genius (Supermodel) mehrere Schulen kombiniert ≈ 5,5 % PyLaia

Modellwahl pro Source-Eigenschaft (Jahrhundert, Region) konfigurierbar. Default: German Kurrent 17th–20th c..

Kosten

Stand: 2026-06 — Vendor-Pricing ändert sich; vor P1-Start neu verifizieren.

  • Credit-Pack: 250 Credits = 59,50 € → 0,238 €/Credit.
  • UI: 1 Credit pro Seite Handschrift.
  • API: 50 % des UI-Preises = ≈ 0,12 €/Seite.
  • 1–4-seitiger Brief: 0,12 – 0,48 €.

Latenz

  • Queue-basiert, in der Praxis Sekunden bis wenige Minuten pro Seite.
  • Interaktiv genug für Vision §5 („Sofort-Nutzen" für Genealogie- Zielgruppe).

Output-Formate

  • PAGE-XML (Primärformat, interne Repräsentation). TextRegions → TextLines → Words mit Polygonen + Baseline + Recognition-Text.
  • ALTO 4.2 (Sekundär, für externe Konsumenten).
  • TEI (für DH-Konsumenten).
  • Plaintext (für simple Anzeige).

2. Free-Tier-Logik in unserer App

Quoten-Modell

  • Default-Quote: 5 Seiten pro Nutzer pro Monat (Gelegenheitsnutzer).
  • Power-User: Anlegen eigener Transkribus-Credentials in Account-Settings → unbegrenzt auf eigene Kosten.
  • Anonyme Nutzer: 1 Probe-Seite ohne Account (Demo).

Rate-Limiter

  • FastAPI-Middleware mit Postgres-backed counter pro Nutzer pro Monat.
  • Soft-Limit-Warnung bei 80 %, Hard-Stop bei 100 % mit Hinweis auf Credit-Kauf-Option.

Caching

  • PAGE-XML-Cache pro Bild-Hash (SHA-256 des Bytes).
  • Gleicher Brief, gleiche Modellwahl → Cache-Hit, kein Doppel-Bezug von Credits.
  • Cache liegt in Postgres als JSONB-Spalte auf transcriptions-Tabelle (kommt mit P1-Implementierung).

3. Optionaler Self-Hosted-Pfad (post-MVP)

TrOCR dh-unibe/trocr-kurrent

  • Universität Bern, HuggingFace.
  • CER: 2,65 % (publiziert) — deutlich besser als die öffentlichen Transkribus-Modelle.
  • Transformer-basiert (ViT + GPT2-style decoder).
  • Inferenz pro Zeile: ~600 ms auf V100 GPU; ~1–3 s auf modernem CPU.
  • Modell-Größe: ~558 MB (TrOCR-large) bzw. ~334 MB (TrOCR-base).

Architektur als Job-System

  • Synchron ist auf CPU nicht tragbar: 4-Seiten-Brief × 30 Zeilen/Seite × ~2 s/Zeile = 4 Minuten. Daher Job-basiert.
  • POST /htr/jobs → Job-ID; Frontend pollt Status oder erhält Notification.
  • Kein Background-Worker im MVP — kann später mit Celery/RQ/dramatiq ausgebaut werden.

Bild → Linien-Segmentierung davor

Bevor TrOCR auf die Zeilen losgelassen werden kann, muss das Bild in Zeilen zerlegt werden. Optionen (alle CPU-fähig):

  • Kraken (kraken.re) — etabliert, PAGE-XML out, gute Doku via UB Mannheim eScriptorium.
  • Loghi-Laypa (knaw-huc/loghi) — KNAW-HuC, Docker-Pipeline.
  • docTR (mindee/doctr) — Mindee, schlanker und neuer.

Default-Wahl: Kraken, weil PAGE-XML-Output direkt mit dem Transkribus- Pfad kompatibel ist (gleiche interne Repräsentation).


4. FastAPI-Adapter

Router /htr/

POST   /htr/transcribe        # Synchron-Versuch (Transkribus default)
POST   /htr/jobs              # Async-Job anlegen (TrOCR self-hosted)
GET    /htr/jobs/{job_id}     # Status pollen
GET    /htr/quota             # Free-Tier-Stand des aktuellen Nutzers

Backend-Abstraktion

# Pseudo-Code
class HtrBackend(ABC):
    async def transcribe(self, image: bytes, model_id: str) -> PageXml: ...

class TranskribusBackend(HtrBackend): ...  # default
class TrOcrBackend(HtrBackend): ...        # post-MVP, optional

Backend-Wahl pro Request über User-Setting oder Server-Default.

Interne Repräsentation: PAGE-XML

Wir halten einen Standard intern. Beide Backends müssen nach PAGE-XML mappen — bei Transkribus geht das nativ, bei TrOCR brauchen wir eine PAGE-XML-Konstruktion aus den Linien-Bounding-Boxes (Kraken liefert das) plus den TrOCR-Texten.

Frontend konsumiert nur PAGE-XML — über OpenSeadragon + Annotorious (der IiifViewer-Wrapper, siehe architektur.md §14 und frontend-stack.md §7). Andere Formate (ALTO, TEI, Plaintext) werden on-demand aus PAGE-XML abgeleitet.


5. Beziehung zur Lese-Lupe (§14)

Die Lese-Lupe konsumiert das gleiche PAGE-XML. Wort-Polygone werden als klickbare Annotorious-Annotations dargestellt. Bei Klick:

  1. Wort-Text aus PAGE-XML extrahieren.
  2. (Optional, post-MVP) Wort-Region als Crop an die eigene Glyph- Erkennung schicken (analysis-by-synthesis rückwärts — architektur.md §14).
  3. Regel-Lookup aus orthographie-regeln.md (Daten-konsumierende Schicht): „warum sieht das so aus, wie es aussieht".

6. Was wir nicht machen

  • Eigenes HTR-Modell trainieren. Trainingsdaten-Sammlung ist nicht im Vision-Scope; Vendor-Modelle decken die Reichweite.
  • OCR.space / Google Vision / Azure OCR / AWS Textract. Diese sind für Druckschrift, nicht historische Handschrift — CER wäre katastrophal.
  • Eigenen Layout-Analyzer. Kraken/docTR sind ausreichend; Layout ist kein Forschungs-Hebel für uns.

7. Quellen