# Benchmark OCR PP-OCRv5 CPU — 02/07/2026 > **Label**: baseline CPU, non verdict GPU > **Machine**: Ryzen 9 9950X 32 threads, 123GB RAM, RTX 5070 12GB VRAM, CUDA driver 580.159.03/13.0 > **Image**: `shot_0172_full.png` (2560×1600, 721K, RGB) — capture écran Windows Léa > **PaddleOCR**: 3.4.0, paddlepaddle 3.3.1 CPU-only (non compilé CUDA) --- ## 1. Résultats synthèse | Engine | Cold (s) | Warm (s) | Detections | Mem init (MB) | Mem peak (MB) | Statut | |--------|----------|----------|------------|---------------|---------------|--------| | **docTR CPU** | 0.776 | 0.717 | 139 | 263.2 | 263.2 | ✅ OK | | **EasyOCR CPU** | 4.878 | 4.856 | 54 | 0.6 | 156.9 | ✅ OK | | **PP-OCRv5 CPU** | — | — | — | — | — | ❌ BLOCKED | --- ## 2. PP-OCRv5 CPU — VERDICT: BLOCKED ### Crash récurrent Toute inference PaddleOCR sur paddlepaddle 3.3.1 CPU-only crash systématiquement : ``` (Unimplemented) ConvertPirAttribute2RuntimeAttribute not support [pir::ArrayAttribute] (at /paddle/paddle/fluid/framework/new_executor/instruction/onednn/onednn_instruction.cc:116) ``` ### Root cause Bug dans le **PIR new executor** de paddlepaddle 3.3.1 CPU-only : l'instruction OneDNN tente de convertir un `ArrayAttribute` en runtime attribute, opération non implémentée. Ce bug est : - **NON model-spécifique** : v3_mobile_det, v4_mobile_det, v5_mobile_det crashent tous - **NON version-spécifique** : PP-OCRv3, v4 (fr absent), v5 crashent tous - **NON API-spécifique** : `ocr()` (deprecated) et `predict()` crashent identiquement - **NON contournable** par flags : `FLAGS_use_mkldnn=0`, `FLAGS_use_pir_api=0` n'ont aucun effet ### 7 approches testées — TOUTES FAILED | # | Approche | Résultat | |---|----------|----------| | 1 | `FLAGS_use_mkldnn=0` via `os.environ` | Same crash | | 2 | `det='PP-OCRv5_mobile_det'` param | ValueError "Unknown argument: det" (PaddleOCR 3.4.0 rejette ce param) | | 3 | `FLAGS_use_mkldnn=0` shell-level avant Python | Same crash | | 4 | `text_detection_model_name='PP-OCRv5_mobile_det'` | mobile_det DL OK → inference crash (same OneDNN) | | 5 | `ocr_version='PP-OCRv4', lang='fr'` | ValueError "No models available for language 'fr' and PP-OCRv4" | | 6 | PP-OCRv3 + `ocr(img, cls=True)` legacy | DeprecationWarning → TypeError sur `cls` kwarg → predict() → same crash | | 7 | `FLAGS_use_pir_api=0` shell + os level | Same crash | ### PaddleOCR 3.4.0 __init__ params inspectés 28 paramètres au total. **Pas** de `enable_mkldnn`, `use_pir`, ou `det`. Param de détection remplacé par `text_detection_model_name`. API v3.4.0 : `use_angle_cls` deprecated → `use_textline_orientation=True`, `show_log` supprimé (ValueError si utilisé). ### Incompatibilité downgrade paddlepaddle 2.6.2 existe mais **incompatible** avec PaddleOCR 3.4.0 (requires ≥3.x). PaddleOCR 2.x serait compatible avec paddlepaddle 2.6.2 mais API/outils complètement différents — non évalué dans ce bench. ### Conclusion **PP-OCRv5 CPU = BLOCKED**. Bug upstream dans paddlepaddle CPU-only binary, aucune workaround applicative possible. Seules alternatives : 1. **paddlepaddle GPU binary** (RTX 5070 + CUDA 13.0 compatible) → bench GPU séparé 2. **Fix upstream** paddlepaddle (PR PIR executor OneDNN) 3. **Downgrade PaddleOCR 2.x + paddlepaddle 2.6.2** (API legacy, non testé) --- ## 3. docTR CPU — Résultats détaillés - **Cold latency**: 0.776s (incl. model loading) - **Warm latency**: 0.717s - **Detections**: 139 (mot-level, agressif — fragmente "Dites", "Sortie", "de", "veille") - **Mémoire**: 263.2MB stable (init = peak) - **Qualité**: haute sur mots courts, fragmente les phrases longues - **Confiance**: variable (0.26→0.99), nombreux tokens <0.7 ### Observations docTR - Word-level detection = 139 items → beaucoup de fragments 1-2 lettres - Bonne qualité sur labels UI ("Mode", "veille", "RPA", "VWB", "Python", "proxmox") - Fragmente les phrases ("Sortie de veille de l'accès vocal ou appuyez..." → 12 mots isolés) - IP correctement détecté : "192.168.1.40:3002" (conf 0.90) - Faux positifs : "0", "E03", "E", "€" isolés avec conf <0.4 --- ## 4. EasyOCR CPU — Résultats détaillés - **Cold latency**: 4.878s (heavy model loading) - **Warm latency**: 4.856s - **Detections**: 54 (line-level, plus conservatif) - **Mémoire**: 0.6MB init → 156.9MB peak - **Qualité**: bonne sur lignes complètes, plus robuste sur phrases ### Observations EasyOCR - Line-level detection = 54 items → phrases plus cohérentes - Cold start très lent (5x docTR) mais warm identique - Meilleur sur textes longs, moins de fragmentation - Peak mémoire plus élevé que docTR (156.9 vs 263.2 MB init docTR) --- ## 5. Comparaison avec baselines Mai 2026 > Bench Mai 2026 — image `landing_wide.png`, critère 11 items de référence | Engine | Score Mai (11 ref) | Score Juillet (detections) | Latency warm | Commentaire | |--------|-------------------|---------------------------|--------------|-------------| | Tesseract | **11/11** | — (non re-benché) | — | Référence May, non retesté | | EasyOCR brut | 8/11 | 54 det (shot_0172) | 4.856s | Fragmente moins, score < Tesseract | | EasyOCR preproc | 9/11 | — | — | +1 vs brut May | | docTR CPU | 10/11 | 139 det (shot_0172) | 0.717s | **Meilleur rapport qualité/latence** | | PP-OCRv5 CPU | non testé May | BLOCKED | — | Bug PIR/OneDNN, 0 inference possible | ### Hierarchie CPU confirmée ``` docTR CPU (0.7s, 10/11) > EasyOCR preproc (4.9s, 9/11) > EasyOCR brut (4.9s, 8/11) > PP-OCRv5 CPU (BLOCKED) ``` docTR reste le **meilleur moteur OCR CPU** pour Léa en termes de latence + qualité. Tesseract reste le plus précis (11/11) mais sans bounding boxes exploitables. --- ## 6. Recommandations 1. **docTR = moteur OCR CPU de production** — latence <1s, qualité 10/11, word-level bboxes 2. **PP-OCRv5 GPU bench = action séparée** — requiere paddlepaddle GPU binary sur RTX 5070 3. **PaddleOCR 3.4.0 = ORPHAN** — 0 imports dans le projet, pas dans requirements.txt, CPU-only install sans CUDA → retirer du venv si cleanup D2 (C-MORT) 4. **Ne pas dépendre de PaddleOCR** pour POC T1 — docTR suffisant 5. **Bug report upstream** — paddlepaddle PIR executor OneDNN, repro: any model + CPU binary --- ## 7. Annexes ### A. Script bench `scripts/bench_ppocrv5_cpu.py` — compare PP-OCRv5, docTR, EasyOCR sur shot_0172_full.png. PP-OCRv5 crash → résultats JSON avec error field. ### B. Résultats JSON `scripts/bench_ppocrv5_results.json` — 4522 lignes, contient tous texts + bboxes pour docTR (139 items) et EasyOCR (54 items). PP-OCRv5 = error only. ### C. Machine specs - CPU: Ryzen 9 9950X, 32 threads - RAM: 123 GB - GPU: RTX 5070 12GB VRAM (non utilisé — bench CPU) - CUDA driver: 580.159.03 / runtime 13.0 - OS: Linux (Ubuntu) - paddlepaddle: 3.3.1 CPU-only (pip install) - PaddleOCR: 3.4.0 - docTR: (version installée dans venv) - EasyOCR: (version installée dans venv)