Configuration
Configurez TurboOCR via des variables d’environnement passées à docker run -e KEY=VALUE. Chaque réglage est lu une fois au démarrage — redémarrez le conteneur pour appliquer un changement. Le comportement par requête (mise en page, mode PDF, DPI de rendu) se contrôle via les paramètres de query ; voir la Référence API.
Référence rapide
Section intitulée « Référence rapide »| Variable | Défaut | Description | Quand modifier |
|---|---|---|---|
OCR_MODEL | tiny | Le sélecteur de reconnaisseur. Paliers PP-OCRv6 tiny / small / medium (latin + chinois + japonais), ou un modèle par écriture PP-OCRv5 arabic / eslav / korean / thai / greek. Une valeur inconnue est fatale et affiche la liste valide. | Plus de précision (small/medium) ou une écriture non latine/chinoise/japonaise. |
TABLE_BACKEND | non défini | slanext charge SLANet-Plus (tableau → HTML) ; l’encodeur se résout automatiquement depuis le pack intégré. (vlm route vers un endpoint VL.) Requis au démarrage pour que ?tables=1 fonctionne. | Vous parsez des tableaux. |
FORMULA_BACKEND | non défini | ppformulanet_s (anglais/latin, moteur par défaut) ppformulanet_plus_m (compatible chinois, GPU uniquement) ou auto (GPU uniquement : -S partout, les crops CJK repassent sur plus-M — la sortie anglaise reste identique octet pour octet à -S) charge formule → LaTeX. (vlm route vers un endpoint VL.) Requis au démarrage pour que ?formulas=1 fonctionne. | Vous parsez des formules. |
PIPELINE_POOL_SIZE | auto | Pipelines GPU concurrents. Auto-dimensionné depuis la VRAM totale au démarrage. | Plafonner pour partager le GPU avec d’autres charges, ou figer pour la planification de capacité. |
TURBO_OCR_CUDA_GRAPHS | 1 | Compile des graphes CUDA pour les shapes de batch de reconnaissance au warmup (par défaut activé depuis v3.1.0) : +10–16 % de débit et p50 plus bas à précision identique, ~0,5 GiB de VRAM en plus par pipeline. | Mettre 0 sur les cartes limitées en VRAM. |
DISABLE_LAYOUT | 0 | Mettez 1 pour ne pas charger PP-DocLayoutV3 du tout. Les requêtes avec ?layout=1 échouent alors. | Vous n’utiliserez jamais la détection de mise en page. |
LAYOUT_MERGE_MODE | all | Comment réconcilier les boîtes de layout imbriquées : all (tout garder) / outer (garder les conteneurs) / inner (garder les plus internes). | Les formulaires s’effondrent sous outer — laissez sur all. |
LAYOUT_KEEP_NESTED_CHILDREN | 0 | Mettez 1 pour conserver les boîtes enfants imbriquées dans une région parente. | Vous voulez faire ressortir chaque région imbriquée. |
ENABLE_PDF_MODE | ocr | Mode par défaut de /ocr/pdf quand aucun ?mode= n’est fourni : ocr / geometric / auto / auto_verified. | Vous traitez des PDF de confiance et voulez un défaut plus rapide. |
DISABLE_ANGLE_CLS | 0 | Mettez 1 pour ignorer le classifieur d’angle (~0,4 ms économisée par image). | Vous n’OCRisez que du texte droit. |
DET_LIMIT_TYPE | min | Politique de redimensionnement de détection : min agrandit le côté court jusqu’à DET_LIMIT_SIDE_LEN ; max réduit le côté long. | Passez à max pour réduire les grands scans et gagner du débit. |
DET_LIMIT_SIDE_LEN | 64 (min) | Longueur de côté cible pour la politique de redimensionnement. Sous max, la valeur par défaut devient DET_MAX_SIDE_LIMIT (depuis v3.1.0 — un max seul garde la résolution native au lieu de réduire à 64 px). | Ajuster la résolution d’entrée de la détection. |
DET_MAX_SIDE_LIMIT | 1280 | Plafonne le côté long redimensionné. (Le 4000 de PaddleOCR fait déborder le pool pré-alloué.) | Texte très petit sur des scans haute résolution. |
REQUEST_TIMEOUT_MS | 60000 | Délai d’inférence par requête (ms). Dépassement → 504 INFERENCE_TIMEOUT et le slot est libéré. 0 = illimité (comportement pré-v3). | SLA plus stricts (baisser) ou longs jobs uniques (augmenter). |
PIPELINE_HARD_KILL_MS | 600000 | Marge de hard-kill du watchdog (ms). Si un worker reste bloqué en plein CUDA aussi longtemps après le déclenchement d’un délai, le processus se termine pour qu’un orchestrateur le redémarre. | Rarement — seulement inerte quand REQUEST_TIMEOUT_MS=0. |
PORT | 8080 | Port HTTP sur lequel le binaire Drogon écoute. nginx, dans le conteneur, se place devant sur 8000 et fait du reverse-proxy vers ce port. | Collision de port à l’intérieur du conteneur. |
GRPC_PORT | 50051 | Port gRPC. | Collision de port dans votre environnement. |
PDF_DAEMONS | 16 | Nombre de processus daemons PDFium maintenus chauds pour le rendu PDF. | Trafic PDF intense — augmentez pour garder plus de renderers prêts, ou baissez pour économiser de la RAM. |
PDF_WORKERS | 4 | Concurrence de rendu au sein d’une requête PDF. | Surtout des PDF multi-pages volumineux — augmentez pour rendre les pages en parallèle. |
HTTP_THREADS | max(pool * 32, 128) | Threads du work-pool Drogon qui dispatchent l’inférence bloquante. | Vous observez de la famine de threads sous forte concurrence. Rarement nécessaire. |
MAX_PDF_PAGES | 2000 | Refuse les PDF dépassant ce nombre de pages avant tout rendu. | Plafond plus strict pour les déploiements hébergés ou multi-tenant. |
MAX_BATCH_IMAGES | 1024 | Nombre max d’images par /ocr/batch et gRPC RecognizeBatch ; au-delà → 400 BATCH_TOO_LARGE. | Batches client plus grands. |
MAX_BODY_MB | 100 | Plafond du corps de requête en mégaoctets (validé à 1..102400 au démarrage — toute valeur hors plage fait planter le serveur avec un message clair). Appliqué à la fois par le serveur HTTP Drogon et par le nginx en frontal. | Uploads plus volumineux (augmenter) ou limites hébergées plus strictes (diminuer). |
LOG_LEVEL | info | Au choix : debug, info, warn, error. | Plus discret en prod, plus bavard en debug. |
LOG_FORMAT | json | json (un objet structuré par ligne) ou text (lisible par l’humain). | Dev local — text est plus facile à suivre dans un terminal. |
Sélection de modèle
OCR_MODEL est l’unique sélecteur de reconnaisseur. Tous les modèles sont intégrés à l’image au moment du build (vérifiés par SHA256 depuis des releases PaddleOCR épinglées) — aucun téléchargement à l’exécution, aucune dépendance réseau au démarrage du conteneur. Changer, c’est redémarrer avec une autre valeur.
Les trois paliers PP-OCRv6 couvrent latin + chinois + japonais et échangent précision contre vitesse, pas couverture linguistique :
tiny(défaut) — débit maximal ; le palier rapide.small— un entre-deux.medium— précision maximale ; le palier qui porte les chiffres FUNSD 92 % / CORD 93 % de F1 par mot.
Les autres écritures utilisent les reconnaisseurs PP-OCRv5 conservés, sélectionnés avec la même variable :
arabic,eslav(slave oriental — russe, ukrainien, …),korean,thai,greek.
Tableaux et formules
Les deux étapes sont strictement opt-in et tournent en local en C++ — aucun Python, aucun sidecar. Une étape ne se charge que si sa variable d’env de backend est définie au démarrage, et ne s’exécute que si une requête passe ?tables=1 / ?formulas=1 (qui activent aussi automatiquement ?layout=1).
TABLE_BACKEND=slanext— SLANet-Plus (encodeur CNN TRT FP16 + décodeur GRU écrit à la main en C++), tableaux → HTML avec quads de cellules. L’encodeur se résout automatiquement depuis le pack intégré.FORMULA_BACKEND=ppformulanet_s— PP-FormulaNet-S, formules → LaTeX. Anglais/latin, le moteur par défaut ; pur C++ in-process (ORT-CUDA-13 sur le build GPU, ORT-CPU sur le build CPU).FORMULA_BACKEND=ppformulanet_plus_m— le moteur de formules compatible chinois (GPU uniquement).- L’un ou l’autre backend peut être mis à
vlmpour router cette étape vers un endpoint VL au lieu du modèle local.
Demander une étape avec laquelle le serveur n’a pas été démarré est une erreur dure 400 TABLE_BACKEND_DISABLED / 400 FORMULA_BACKEND_DISABLED — jamais un résultat vide silencieux. Une étape configurée mais en échec échoue au démarrage plutôt que de servir du vide.
Pool de pipelines
Chaque pipeline possède son propre CUDA stream et sert une requête à la fois. PIPELINE_POOL_SIZE est auto-dimensionné depuis la VRAM totale au démarrage. Définissez-le explicitement pour :
- plafonner le pool quand vous partagez le GPU avec un autre processus ;
- forcer une valeur plus haute quand l’auto-détection est trop conservatrice ;
- figer une valeur connue entre déploiements pour la planification de capacité.
HTTP_THREADS vaut par défaut max(pool * 32, 128). Le multiplicateur couvre les requêtes PDF qui occupent plusieurs slots de pipeline simultanément ; il y a rarement une raison de l’écraser.
Détection de mise en page
La détection de mise en page (PP-DocLayoutV3, RT-DETR-L, 25 classes de régions) est chargée au démarrage mais ne s’exécute que si la requête contient ?layout=1 (ou implicitement via ?tables=1 / ?formulas=1). Les requêtes sans elle ont zéro surcoût de mise en page.
Mettez DISABLE_LAYOUT=1 pour ne pas charger le modèle du tout. Ne le faites que si vous êtes certain que ce déploiement n’aura jamais besoin de mise en page — une fois désactivée, les requêtes avec ?layout=1 renvoient une erreur.
Réconciliation des boîtes imbriquées
Section intitulée « Réconciliation des boîtes imbriquées »LAYOUT_MERGE_MODE (défaut all) contrôle comment les boîtes imbriquées du détecteur sont réconciliées :
all(défaut) — garde chaque boîte, de sorte que les formules/tableaux/titres que le modèle imbrique dans une région plus grande ne sont jamais perdus.outer— garde les régions conteneurs externes et abandonne les boîtes imbriquées dedans. Effondre les formulaires, où chaque champ se trouve dans un cadre externe — utilisezallouinnerlà.inner— garde les boîtes les plus internes et abandonne les purs conteneurs.
Les anciens noms large / small / union sont acceptés comme alias dépréciés de outer / inner / all. Mettez LAYOUT_KEEP_NESTED_CHILDREN=1 pour faire ressortir en plus les boîtes enfants imbriquées dans une région parente.
Mode PDF par défaut
ENABLE_PDF_MODE fixe le mode appliqué sur /ocr/pdf quand la requête omet ?mode=. Les quatre modes :
ocr— rendre chaque page et passer par tout le pipeline OCR. Vitesse de référence ; immunisé aux manipulations du calque texte. Le défaut sûr.geometric— lit uniquement le calque texte de PDFium, sans rastérisation. ~10× plus rapide queocr, mais fait confiance à l’auteur du PDF.auto— par page : calque texte si disponible, OCR sinon. Le plus rapide pour des PDF mixtes d’origine fiable.auto_verified— OCR complet plus contrôle croisé avec le calque texte ; le texte natif n’est accepté que s’il passe une heuristique (nombre de caractères, ratio de caractères de remplacement, pas de rotation). Légèrement plus lent queocr.
Classifieur d’angle
Le classifieur d’angle gère le texte tourné de 90°, 180° ou 270° avant la reconnaissance. Il coûte ~0,4 ms par image. Mettez DISABLE_ANGLE_CLS=1 si vous n’OCRisez que des scans droits (par exemple des scanners à orientation automatique) et voulez ce gain. Le texte tourné sera alors mal lu.
Résolution d’entrée de la détection
Trois molettes façonnent ce que voit le modèle de détection :
DET_LIMIT_TYPE(défautmin) — politique de redimensionnement.minagrandit le côté court jusqu’àDET_LIMIT_SIDE_LEN;maxréduit le côté long jusqu’à lui.DET_LIMIT_SIDE_LEN(défaut64) — la longueur de côté cible pour cette politique.DET_MAX_SIDE_LIMIT(défaut1280) — plafonne le côté long redimensionné. PaddleOCR officiel utilise4000, mais cela fait déborder le pool pré-alloué ;1280traite la grande majorité des documents à résolution native. Montez-le pour du texte très petit sur des scans haute résolution.
DET_MAX_SIDE reste honoré comme molette unique écrasant le côté MAX du profil d’optimisation du moteur TensorRT ; le changer invalide le moteur en cache et force une reconstruction unique.
Cycle de vie de la requête
REQUEST_TIMEOUT_MS (défaut 60000) est le délai d’inférence par requête. En cas de dépassement, une requête image / batch / gRPC renvoie 504 INFERENCE_TIMEOUT et libère son slot GPU ; les jobs PDF bornent leur join par page par la même valeur, mise à l’échelle par le nombre de pages. Mettez 0 pour le désactiver (attente illimitée — le comportement pré-v3).
PIPELINE_HARD_KILL_MS (défaut 600000) est la marge de hard-kill du watchdog du dispatcher. Si un worker reste bloqué en plein CUDA aussi longtemps après le déclenchement d’un délai et qu’un recyclage est demandé, le processus se termine pour qu’un orchestrateur le redémarre. Il est inerte quand REQUEST_TIMEOUT_MS=0 (le watchdog ne scanne qu’une fois un délai défini).
Limites de taille d’entrée
Le serveur refuse les entrées surdimensionnées avant tout travail réel, avec un 400 :
MAX_BATCH_IMAGES(défaut1024) — images max par/ocr/batchet gRPCRecognizeBatch→400 BATCH_TOO_LARGE.MAX_PDF_PAGE_PIXELS_MP(défaut40) — mégapixels rendus max par page de PDF (garde anti-bombe de décompression) →400 PIXELS_TOO_LARGE.MAX_IMAGE_PIXELS_MP(défaut128) — plafond d’aire totale d’image sur les routes image →400 DIMENSIONS_TOO_LARGE.MAX_IMAGE_DIM(défaut16384) — plafond pixel par côté sur les routes de décodage.
Ports et mode split
PORT (défaut 8080) est le port sur lequel le binaire Drogon écoute. Dans le conteneur, nginx se place devant sur 8000 et reverse-proxy en keep-alive — cela absorbe les tempêtes de connexions. GRPC_PORT (défaut 50051) est servi directement par le binaire et doit différer de PORT (fatal sinon).
Ne changez PORT / GRPC_PORT qu’en cas de collision de port dans votre environnement.
Réglage du pipeline PDF
Les requêtes PDF traversent deux pools avant d’atteindre le GPU :
PDF_DAEMONS(défaut16) — daemons PDFium long-vie, mono-thread, traitant un PDF à la fois. Augmentez en cas de fort trafic PDF concurrent ; baissez pour économiser de la RAM.PDF_WORKERS(défaut4) — concurrence de rendu au sein d’une seule requête PDF. Augmentez pour des PDF multi-pages majoritairement volumineux (rend les pages en parallèle) ; laissez par défaut pour beaucoup de petits PDF.MAX_PDF_PAGES(défaut2000) — plafond strict de pages par requête. Les PDF qui dépassent sont refusés avant tout rendu.HTTP_THREADS(défautmax(pool * 32, 128)) — pool de travail bloquant de Drogon. Les PDF tiennent un slot durant tout le cycle rendu+OCR, d’où ce multiplicateur volontaire. À écraser uniquement si vous voyez de la famine de threads sous charge.
Plafond du corps de requête
MAX_BODY_MB (défaut 100, plage 1..102400) plafonne le corps de requête que le serveur accepte. Le serveur HTTP Drogon et le reverse-proxy nginx docker en frontal lisent la même valeur au démarrage, donc le plafond est appliqué de manière cohérente et un upload surdimensionné est rejeté en périphérie par un 413 au lieu d’être lu en mémoire.
La valeur est validée au démarrage — tout ce qui sort de [1, 102400] (ou non numérique, zéro en tête, etc.) fait planter le serveur avec un message d’erreur clair plutôt que d’échouer 90 s plus tard sur une erreur de parsing nginx déroutante.
Journalisation
LOG_FORMAT=json émet un objet structuré par ligne — directement consommable par toute pipeline de logs (Loki, Elasticsearch, CloudWatch). LOG_FORMAT=text est plus agréable pour suivre la sortie dans un terminal en dev local.
LOG_LEVEL=debug inclut le détail des temps par requête ; info est le bon défaut en prod. warn et error sont encore plus discrets — adaptés aux déploiements hébergés à fort volume où chaque ligne de log a un coût.
Exemple : déploiement pipeline complet en production
Section intitulée « Exemple : déploiement pipeline complet en production »Un setup de parsing structuré typique — le reconnaisseur précis medium, les backends tableaux et formules (compatible chinois), un pool figé et des logs JSON :
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.0Pour la topologie de déploiement, les exigences GPU et pilote, et le choix des tags Docker, voir le guide Déploiement.