Konfiguration
Konfigurieren Sie TurboOCR über Umgebungsvariablen, die Sie an docker run -e KEY=VALUE übergeben. Jede Einstellung wird einmalig beim Start gelesen — starten Sie den Container neu, um eine Änderung zu übernehmen. Das Verhalten pro Anfrage (Layout, PDF-Modus, Render-DPI) steuern Sie über Query-Parameter; siehe die API-Referenz.
Schnellübersicht
Abschnitt betitelt „Schnellübersicht“| Variable | Standard | Beschreibung | Wann ändern |
|---|---|---|---|
OCR_MODEL | tiny | Der Erkenner-Selektor. PP-OCRv6-Stufen tiny / small / medium (Latein + Chinesisch + Japanisch) oder ein PP-OCRv5-Schriftmodell arabic / eslav / korean / thai / greek. Ein unbekannter Wert ist fatal und gibt die gültige Liste aus. | Höhere Genauigkeit (small/medium) oder eine nicht-lateinische/chinesische/japanische Schrift. |
TABLE_BACKEND | nicht gesetzt | slanext lädt SLANet-Plus (Tabelle → HTML); der Encoder wird automatisch aus dem eingebackenen Bundle aufgelöst. (vlm routet zu einem VL-Endpoint.) Beim Start erforderlich, damit ?tables=1 funktioniert. | Sie parsen Tabellen. |
FORMULA_BACKEND | nicht gesetzt | ppformulanet_s (Englisch/Latein, Standard-Engine) ppformulanet_plus_m (chinesisch-fähig, nur GPU) oder auto (nur GPU: -S überall, CJK-Crops laufen erneut auf plus-M — englische Ausgabe bleibt byte-identisch zu -S) lädt Formel → LaTeX. (vlm routet zu einem VL-Endpoint.) Beim Start erforderlich, damit ?formulas=1 funktioniert. | Sie parsen Formeln. |
PIPELINE_POOL_SIZE | auto | Anzahl paralleler GPU-Pipelines. Beim Start aus dem Gesamt-VRAM bestimmt. | Begrenzen Sie den Pool, wenn Sie die GPU mit anderen Workloads teilen, oder fixieren Sie ihn für Kapazitätsplanung. |
TURBO_OCR_CUDA_GRAPHS | 1 | Backt beim Warmup CUDA-Graphen für die Recognition-Batch-Shapes (seit v3.1.0 standardmäßig an): +10–16 % Durchsatz und niedrigere p50-Latenz bei identischer Genauigkeit, ~0,5 GiB zusätzlicher VRAM pro Pipeline. | Auf VRAM-knappen Karten 0 setzen. |
DISABLE_LAYOUT | 0 | 1 überspringt das Laden von PP-DocLayoutV3 vollständig. Anfragen mit ?layout=1 schlagen dann fehl. | Sie werden Layout-Erkennung nie nutzen. |
LAYOUT_MERGE_MODE | all | Wie verschachtelte Layout-Boxen abgeglichen werden: all (alles behalten) / outer (Container behalten) / inner (innerste behalten). | Formulare kollabieren unter outer — auf all belassen. |
LAYOUT_KEEP_NESTED_CHILDREN | 0 | 1 behält die in einer Elternregion verschachtelten Kindboxen. | Sie wollen jede verschachtelte Region sichtbar machen. |
ENABLE_PDF_MODE | ocr | Standardmodus für /ocr/pdf, wenn keine ?mode= mitgesendet wird: ocr / geometric / auto / auto_verified. | Sie verarbeiten vertrauenswürdige PDFs und wollen einen schnelleren Standardpfad. |
DISABLE_ANGLE_CLS | 0 | 1 überspringt den Winkel-Klassifikator (~0,4 ms gespart pro Bild). | Sie verarbeiten ausschließlich aufrechten Text. |
DET_LIMIT_TYPE | min | Detektions-Resize-Strategie: min vergrößert die kürzere Seite auf DET_LIMIT_SIDE_LEN; max verkleinert die längere Seite. | Auf max umstellen, um große Scans für mehr Durchsatz herunterzuskalieren. |
DET_LIMIT_SIDE_LEN | 64 (min) | Ziel-Seitenlänge für die Resize-Strategie. Unter max ist der Default stattdessen DET_MAX_SIDE_LIMIT (seit v3.1.0 — ein bloßes max behält die native Auflösung statt auf 64 px zu verkleinern). | Detektions-Eingangsauflösung anpassen. |
DET_MAX_SIDE_LIMIT | 1280 | Begrenzt die längere resizte Seite. (PaddleOCRs 4000 sprengt den vorab allokierten Pool.) | Sehr kleiner Text auf hochauflösenden Scans. |
REQUEST_TIMEOUT_MS | 60000 | Inferenz-Deadline pro Anfrage (ms). Überschreitung → 504 INFERENCE_TIMEOUT und der Slot wird freigegeben. 0 = unbegrenzt (Verhalten vor v3). | Strengere SLAs (senken) oder lange Einzeljobs (erhöhen). |
PIPELINE_HARD_KILL_MS | 600000 | Hard-Kill-Marge des Watchdogs (ms). Bleibt ein Worker so lange mitten in CUDA hängen, nachdem eine Deadline ausgelöst hat, beendet sich der Prozess, damit ein Orchestrator ihn neu startet. | Selten — nur inert, wenn REQUEST_TIMEOUT_MS=0. |
PORT | 8080 | HTTP-Port, auf dem das Drogon-Binary lauscht. nginx steht im Container davor auf 8000 und proxyt per Reverse-Proxy auf diesen Port. | Port-Kollision innerhalb des Containers. |
GRPC_PORT | 50051 | gRPC-Port. | Port-Kollision in Ihrer Umgebung. |
PDF_DAEMONS | 16 | Anzahl warmgehaltener PDFium-Daemon-Prozesse für das PDF-Rendering. | Hohe PDF-Last — erhöhen, um mehr Renderer bereit zu halten; senken, um RAM zu sparen. |
PDF_WORKERS | 4 | Render-Worker-Parallelität innerhalb eines einzelnen PDF-Requests. | Überwiegend mehrseitige große PDFs — erhöhen, um Seiten parallel zu rendern. |
HTTP_THREADS | max(pool * 32, 128) | Drogon-Work-Pool-Threads für blockierendes Inferenz-Dispatching. | Sie sehen Thread-Hunger unter hoher Last. Selten nötig. |
MAX_PDF_PAGES | 2000 | Lehnt PDFs mit mehr Seiten vor dem Rendern ab. | Strikteres Limit für gehostete oder Multi-Tenant-Deployments. |
MAX_BATCH_IMAGES | 1024 | Max. Bilder pro /ocr/batch und gRPC RecognizeBatch; darüber → 400 BATCH_TOO_LARGE. | Größere clientseitige Batches. |
MAX_BODY_MB | 100 | Maximale Request-Body-Größe in Megabyte (beim Start gegen 1..102400 validiert — Werte außerhalb stürzen den Server mit klarer Meldung ab). Greift sowohl im Drogon-HTTP-Server als auch im vorgelagerten nginx. | Größere Uploads (erhöhen) oder strengere Hosting-Limits (senken). |
LOG_LEVEL | info | debug, info, warn oder error. | Leiser in Produktion, lauter beim Debuggen. |
LOG_FORMAT | json | json (eine strukturierte Zeile pro Eintrag) oder text (menschenlesbar). | Lokale Entwicklung — text lässt sich leichter im Terminal verfolgen. |
Modellauswahl
OCR_MODEL ist der einzige Erkenner-Selektor. Alle Modelle sind beim Image-Build eingebacken (SHA256-verifiziert aus gepinnten PaddleOCR-Releases) — keine Laufzeit-Downloads, keine Netzwerkabhängigkeit beim Containerstart. Ein Wechsel ist ein Neustart mit anderem Wert.
Die drei PP-OCRv6-Stufen decken Latein + Chinesisch + Japanisch ab und tauschen Genauigkeit gegen Geschwindigkeit, nicht Sprachabdeckung:
tiny(Standard) — maximaler Durchsatz; die schnelle Stufe.small— ein Mittelweg.medium— höchste Genauigkeit; die Stufe, die die FUNSD-92-%- / CORD-93-%-Wort-F1-Werte trägt.
Andere Schriften nutzen die beibehaltenen PP-OCRv5-Erkenner, gewählt über dieselbe Variable:
arabic,eslav(Ostslawisch — Russisch, Ukrainisch, …),korean,thai,greek.
Tabellen & Formeln
Beide Stufen sind strikt opt-in und laufen lokal in C++ — kein Python, kein Sidecar. Eine Stufe lädt nur, wenn ihre Backend-Umgebungsvariable beim Start gesetzt ist, und läuft nur, wenn eine Anfrage ?tables=1 / ?formulas=1 übergibt (was auch automatisch ?layout=1 aktiviert).
TABLE_BACKEND=slanext— SLANet-Plus (TRT-FP16-CNN-Encoder + handgeschriebener C++-GRU-Decoder), Tabellen → HTML mit Zell-Quads. Der Encoder wird automatisch aus dem eingebackenen Bundle aufgelöst.FORMULA_BACKEND=ppformulanet_s— PP-FormulaNet-S, Formeln → LaTeX. Englisch/Latein, die Standard-Engine; reines C++ in-process (ORT-CUDA-13 im GPU-Build, ORT-CPU im CPU-Build).FORMULA_BACKEND=ppformulanet_plus_m— die chinesisch-fähige Formel-Engine (nur GPU).- Jedes Backend kann auf
vlmgesetzt werden, um diese Stufe statt an das lokale Modell an einen VL-Endpoint zu routen.
Eine Stufe anzufordern, mit der der Server nicht gestartet wurde, ist ein harter 400 TABLE_BACKEND_DISABLED / 400 FORMULA_BACKEND_DISABLED — nie ein stilles leeres Ergebnis. Eine konfigurierte, aber fehlgeschlagene Stufe scheitert beim Start, statt leere Ergebnisse zu liefern.
Pipeline-Pool
Jede Pipeline besitzt einen eigenen CUDA-Stream und bedient eine Anfrage zur Zeit. PIPELINE_POOL_SIZE wird beim Start aus dem Gesamt-VRAM bestimmt. Setzen Sie den Wert explizit, um:
- den Pool zu begrenzen, wenn Sie die GPU mit einem anderen Prozess teilen;
- bei zu konservativer Auto-Erkennung einen höheren Wert zu erzwingen;
- über Deployments hinweg einen festen Wert für die Kapazitätsplanung zu pinnen.
HTTP_THREADS ist standardmäßig max(pool * 32, 128). Der Multiplikator deckt PDF-Anfragen ab, die mehrere Pipeline-Slots gleichzeitig halten — eine Override ist selten nötig.
Layout-Erkennung
Die Layout-Erkennung (PP-DocLayoutV3, RT-DETR-L, 25 Bereichsklassen) wird beim Start geladen, läuft aber nur, wenn eine Anfrage ?layout=1 enthält (oder implizit über ?tables=1 / ?formulas=1). Anfragen ohne sie haben null Layout-Overhead.
DISABLE_LAYOUT=1 überspringt das Laden des Modells komplett. Tun Sie das nur, wenn Sie sicher sind, dass das Deployment Layout-Erkennung nie braucht — danach liefern Anfragen mit ?layout=1 einen Fehler.
Abgleich verschachtelter Boxen
Abschnitt betitelt „Abgleich verschachtelter Boxen“LAYOUT_MERGE_MODE (Standard all) steuert, wie die verschachtelten Boxen des Detektors abgeglichen werden:
all(Standard) — behält jede Box, sodass Formeln/Tabellen/Titel, die das Modell in eine größere Region verschachtelt, nie verloren gehen.outer— behält die äußeren Container-Regionen und verwirft darin verschachtelte Boxen. Kollabiert Formulare, bei denen jedes Feld in einem äußeren Rahmen sitzt — dortalloderinnerverwenden.inner— behält die innersten Boxen und verwirft die reinen Container.
Die alten Namen large / small / union werden als veraltete Aliasse von outer / inner / all akzeptiert. Setzen Sie LAYOUT_KEEP_NESTED_CHILDREN=1, um zusätzlich die in einer Elternregion verschachtelten Kindboxen sichtbar zu machen.
PDF-Standardmodus
ENABLE_PDF_MODE legt fest, welcher Modus auf /ocr/pdf greift, wenn die Anfrage keine ?mode= mitsendet. Die vier Modi:
ocr— jede Seite rendern und durch die volle OCR-Pipeline schicken. Basisgeschwindigkeit; gegen Manipulation am Textlayer immun. Der sichere Standard.geometric— nur den Textlayer von PDFium auslesen, kein Rastern. ~10× schneller alsocr, vertraut aber dem PDF-Autor.auto— pro Seite: Textlayer wenn vorhanden, sonst OCR. Schnellste Variante für gemischte PDFs aus vertrauenswürdiger Quelle.auto_verified— volle OCR plus Abgleich mit dem Textlayer; nativer Text wird nur akzeptiert, wenn er eine Heuristik besteht (Zeichenzahl, Anteil Replacement-Char, keine Rotation). Etwas langsamer alsocr.
Winkel-Klassifikator
Der Winkel-Klassifikator behandelt um 90°, 180° oder 270° gedrehten Text vor der Erkennung. Er kostet ~0,4 ms pro Bild. Setzen Sie DISABLE_ANGLE_CLS=1, wenn Sie ausschließlich aufrechte Scans verarbeiten (etwa Dokumentenscanner mit automatischer Ausrichtung) und diese Zeit sparen wollen. Gedrehter Text wird dann falsch gelesen.
Detektions-Eingangsgröße
Drei Stellschrauben formen, was das Detektionsmodell sieht:
DET_LIMIT_TYPE(Standardmin) — Resize-Strategie.minvergrößert die kürzere Seite bisDET_LIMIT_SIDE_LEN;maxverkleinert die längere Seite darauf.DET_LIMIT_SIDE_LEN(Standard64) — die Ziel-Seitenlänge für diese Strategie.DET_MAX_SIDE_LIMIT(Standard1280) — begrenzt die längere resizte Seite. Offizielles PaddleOCR nutzt4000, das sprengt aber den vorab allokierten Pool;1280verarbeitet die große Mehrheit der Dokumente in nativer Auflösung. Erhöhen Sie ihn für sehr kleinen Text auf hochauflösenden Scans.
DET_MAX_SIDE wird weiterhin als Einzel-Stellschraube respektiert, die die MAX-Seite des TensorRT-Engine-Optimierungsprofils überschreibt; ein Ändern invalidiert die gecachte Engine und erzwingt einen einmaligen Neubau.
Request-Lebenszyklus
REQUEST_TIMEOUT_MS (Standard 60000) ist die Inferenz-Deadline pro Anfrage. Bei Überschreitung liefert eine Einzelbild- / Batch- / gRPC-Anfrage 504 INFERENCE_TIMEOUT und gibt ihren GPU-Slot frei; PDF-Jobs begrenzen ihren Join pro Seite mit demselben Wert, skaliert mit der Seitenzahl. Setzen Sie 0, um es zu deaktivieren (unbegrenztes Warten — das Verhalten vor v3).
PIPELINE_HARD_KILL_MS (Standard 600000) ist die Hard-Kill-Marge des Dispatcher-Watchdogs. Bleibt ein Worker so lange mitten in CUDA hängen, nachdem eine Deadline ausgelöst hat und ein Recycle angefordert wird, beendet sich der Prozess, damit ein Orchestrator ihn neu starten kann. Es ist inert, wenn REQUEST_TIMEOUT_MS=0 (der Watchdog scannt nur, sobald eine Deadline gesetzt ist).
Eingangsgrößen-Limits
Der Server lehnt überdimensionierte Eingaben vor jeder echten Arbeit mit einem 400 ab:
MAX_BATCH_IMAGES(Standard1024) — max. Bilder pro/ocr/batchund gRPCRecognizeBatch→400 BATCH_TOO_LARGE.MAX_PDF_PAGE_PIXELS_MP(Standard40) — max. gerenderte Megapixel pro PDF-Seite (Schutz vor Dekompressionsbomben) →400 PIXELS_TOO_LARGE.MAX_IMAGE_PIXELS_MP(Standard128) — Obergrenze der Gesamtbildfläche auf Bild-Routen →400 DIMENSIONS_TOO_LARGE.MAX_IMAGE_DIM(Standard16384) — Pixel-Obergrenze pro Seite auf Decode-Routen.
Ports und Split-Modus
PORT (Standard 8080) ist der Port, auf dem das Drogon-Binary lauscht. nginx steht im Container davor auf 8000 und proxyt per Keep-alive — das absorbiert Verbindungs-Stürme. GRPC_PORT (Standard 50051) bedient das Binary direkt und muss sich von PORT unterscheiden (sonst fatal).
PORT / GRPC_PORT ändern Sie nur bei einer Port-Kollision in Ihrer Umgebung.
PDF-Pipeline-Tuning
PDF-Anfragen werden über zwei Pools verteilt, bevor sie die GPU erreichen:
PDF_DAEMONS(Standard16) — langlebige PDFium-Daemons, jeder einsträngig und für genau ein PDF zur Zeit. Erhöhen bei hoher PDF-Parallellast; senken, um RAM zu sparen.PDF_WORKERS(Standard4) — Render-Parallelität innerhalb einer einzelnen PDF-Anfrage. Erhöhen bei überwiegend mehrseitigen großen PDFs (Seiten werden parallel gerendert); für viele kleine PDFs Standardwert lassen.MAX_PDF_PAGES(Standard2000) — harte Obergrenze für Seiten pro Anfrage. PDFs mit mehr Seiten werden vor jedem Rendern abgelehnt.HTTP_THREADS(Standardmax(pool * 32, 128)) — Drogons Pool für blockierende Arbeit. PDFs halten einen Slot über den gesamten Render+OCR-Zyklus, daher der bewusste Multiplikator. Override nur, wenn Sie unter Last Thread-Hunger sehen.
Request-Body-Limit
MAX_BODY_MB (Standard 100, Bereich 1..102400) begrenzt den Request-Body, den der Server akzeptiert. Sowohl der Drogon-HTTP-Server als auch der vorgelagerte docker-nginx-Reverse-Proxy lesen denselben Wert beim Start, sodass das Limit konsistent durchgesetzt wird und ein überdimensionierter Upload am Rand mit einem 413 abgewiesen wird, statt in den Speicher gelesen zu werden.
Der Wert wird beim Start validiert — alles außerhalb von [1, 102400] (oder nicht-numerisch, führende Null usw.) stürzt den Server mit einer klaren Fehlermeldung ab, statt 90 s später mit einem verwirrenden nginx-Parsing-Fehler zu scheitern.
Logging
LOG_FORMAT=json gibt eine strukturierte Zeile pro Eintrag aus — direkt für jede Log-Pipeline geeignet (Loki, Elasticsearch, CloudWatch). LOG_FORMAT=text ist beim lokalen tail im Terminal angenehmer.
LOG_LEVEL=debug liefert per-Request-Timing-Aufschlüsselungen; info ist der richtige Standard für Produktion. warn und error sind noch leiser — passend für hochvolumige gehostete Deployments, wo jede Logzeile Geld kostet.
Beispiel: Produktiv-Deployment der vollen Pipeline
Abschnitt betitelt „Beispiel: Produktiv-Deployment der vollen Pipeline“Ein typisches Setup für strukturiertes Parsing — der genaue medium-Erkenner, die Tabellen- und chinesisch-fähigen Formel-Backends, ein gepinnter Pool und JSON-Logs:
docker run --gpus all -p 8000:8000 -p 50051:50051 \ -v trt-cache:/home/ocr/.cache/turbo-ocr \ -e OCR_MODEL=medium \ -e TABLE_BACKEND=slanext \ -e FORMULA_BACKEND=ppformulanet_plus_m \ -e PIPELINE_POOL_SIZE=3 \ -e LOG_LEVEL=info \ -e LOG_FORMAT=json \ ghcr.io/aiptimizer/turboocr:v3.1.0Deployment-Topologie, GPU- und Treiberanforderungen sowie Docker-Tag-Auswahl finden Sie im Deployment-Leitfaden.