docs(coordination): diagnostic perf MVP (D-19) — torch mono-thread + raster/OCR séquentiels

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-05 19:16:51 +02:00
parent 7f03acb8fb
commit 222b1d3970
2 changed files with 81 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
---
from: claude
to: dom
date: 2026-06-05T19:45:00+02:00
topic: diagnostic-perf-mvp
status: open
priority: blocker
references:
- decision: docs/coordination/decisions/2026-06-05_dom_d19-performance-mvp-p1.md
---
# Diagnostic performance MVP (D-19) — cause racine + hotfix proposés
Symptôme (test Windows Dom) : anonymisation très lente, **CPU ~12 %** (≈ 1 cœur sur 8),
RAM ~16 Go. Diagnostic par lecture du code (aucune modif appliquée — gel bêta respecté).
## Causes racines identifiées (3)
### C1 — torch bridé à 1 thread en EXE frozen (cause principale du CPU 12 %)
`torch.set_num_threads()` / `OMP_NUM_THREADS` ne sont **définis nulle part** en
production (vérifié : seulement dans un script batch et un archive legacy). En EXE
PyInstaller frozen, torch ne détecte pas correctement les cœurs et tombe souvent à
**1 thread**. Or torch porte **l'OCR docTR** (db_resnet50 + crnn) **et** une partie NER.
→ explique directement le CPU ~12 %.
### C2 — Rastérisation forcée séquentielle en frozen
`anonymizer_core_refactored_onnx.py:4316-4322` : en `sys.frozen`, la rastérisation
des pages passe en **séquentiel mono-cœur** (pour éviter que `ProcessPoolExecutor`
relance l'exe → fenêtres fantômes). Mono-cœur sur toutes les pages.
### C3 — OCR docTR séquentiel, page par page, à 300 dpi
`anonymizer_core_refactored_onnx.py:1259-1280` : sur les pages pauvres en texte
(< 150 chars, i.e. **scannées**), docTR tourne dans une **boucle `for` page par page**
à **300 dpi** (images ~26 Mo/page), un appel `model([img])` à la fois. Pour un doc
scanné, c'est le coût dominant. (Bonne nouvelle : les PDF natifs riches en texte
**sautent l'OCR** — donc le problème est surtout sur les scannés.)
## RAM ~16 Go — explication
Cumul : modèles docTR (det+reco) + torch + modèle ONNX CamemBERT + **gazetteer
paranames 1.4M noms en mémoire** + images 300 dpi. Élevé mais surtout dû aux modèles
chargés ; pas une fuite. Mitigation possible (libérer les images après OCR) mais
secondaire vs le CPU.
## Hotfix proposés (faible risque, classés impact/risque)
| # | Hotfix | Impact | Risque | Détection |
|---|---|---|---|---|
| **H1** | `torch.set_num_threads(os.cpu_count())` + `OMP_NUM_THREADS`/`MKL_NUM_THREADS` au démarrage | **Élevé** (OCR + NER multicœur) | **Quasi nul** | inchangée |
| **H2** | Rastérisation frozen → `ThreadPoolExecutor` (fitz/PIL/pyzbar libèrent le GIL → vrai multicœur, sans relance exe) | Élevé (docs natifs multi-pages) | Faible | inchangée |
| **H3** | OCR docTR en **batch** (`model([img1,img2,…])` au lieu d'1 page/appel) | Moyen-élevé (scannés) | Faible-moyen | inchangée (même modèle) |
| **H4** | **Timings par étape** (logging extract/OCR/NER/raster/save) | — (mesure) | Nul | inchangée |
**Non recommandé sans précaution** : baisser le DPI OCR (300→200). Gain réel mais
**risque sur le leak score 100/100** (texte manqué = fuite). À écarter du hotfix MVP.
## Pourquoi H1 et H2 sont sûrs vis-à-vis du leak
- Ils ne changent **ni la détection, ni les rectangles, ni le texte produit** — juste
le **nombre de cœurs** utilisés. La sortie est identique, seul le temps change.
- H2 : `_rasterize_page` ouvre déjà son propre `fitz.open()` par page (thread-safe
pour des Documents séparés). Aucun état partagé.
## Plan proposé (sans toucher la branche bêta tant que non validé)
1. **H4 d'abord** (timings) + **H1** → mesurer sur TON doc lent réel pour confirmer
quelle phase domine (raster vs OCR vs NER).
2. Selon la mesure : **H2** (si raster/natif) et/ou **H3** (si OCR/scanné).
3. Re-build EXE de test → tu mesures CPU/temps → si OK et **leak 100/100 + 98 tests
verts**, on intègre.
Je peux préparer ces patchs sur une **branche dédiée** (`fix/perf-mvp`, pas la branche
bêta) et te livrer un EXE de test. Dis-moi si tu veux que je code H1+H4 (les plus sûrs)
en premier pour une mesure réelle.
**Question** : ton doc de test lent était-il **scanné** (OCR) ou **natif** (texte) ?
Ça oriente direct H2 vs H3.
— Claude

View File

@@ -66,3 +66,8 @@ Format : `YYYY-MM-DD HH:MM | AUTEUR | ACTION | RÉSUMÉ`
2026-06-05 18:10 | claude | DEPOSE plan v11.5 | for-dom/2026-06-05_claude_plan-v11-5-parallele.md : 4 agents (A GUI v6 / B D-13 / C licence / D intégration), frontières fichiers, ordre merge, tests. ALERTE : WIP backup GUI v6 (b8c9c41) uniquement sur disque Windows → recommande push Gitea urgent. Gel bêta respecté (planif pure).
2026-06-05 18:14 | claude | INSTALLATEUR v11 OK | Inno Setup déjà présent (user). build_windows_installer_only.ps1 → release\Anonymisation-Setup.exe 695.8 Mo, EXIT_CODE=0, non signé. SHA256=12D9D6A8...663DC. Manifeste SHA256SUMS.txt MAJ (EXE+ZIP+Setup). Rapport → for-dom/2026-06-05_claude_package-beta-installateur-maj.md. OwnCloud toujours en attente du canal (D-16).
2026-06-05 18:18 | claude | 4 AGENTS v11.5 LIVRÉS | Sous-plans A(GUI v6)/B(D-13)/C(licence)/D(intégration) déposés for-dom. CORRECTION Agent A : le WIP backup b8c9c41 n'est PAS une GUI v6 mais l'ancêtre tkinter de v5.5 (v5.5 en avance de 24 lignes). Vraie base v6 = mockup HTML + logique v5.5. customtkinter à ajouter aux requirements. Qwen a livré en // T-P/T-Q/T-R (revue transverse, via Codex) — recoupe Agent D.
2026-06-05 19:20 | dom | DECISION D-18 | Lancement parallele `app.aivanov.fr` dans `/home/dom/ai/app_aivanov` : MVP portail licence/download remplace OwnCloud cible produit. Claude = dev plateforme, Qwen = tests/securite/contrat API, Codex = orchestration. Gel beta Windows maintenu.
2026-06-05 19:30 | dom | DECISION D-19 | Performance MVP devient P1 bloquant : test Windows trop lent, CPU ~12 %, RAM ~16 Go. Diagnostiquer mono-coeur PyInstaller/raster, OCR docTR 300 dpi, sortie raster systematique, timings par etape. Hotfix perf avant diffusion si necessaire.
2026-06-05 19:20 | dom | DECISION D-18 | Lancer plateforme app.aivanov.fr en parallèle (projet séparé /home/dom/ai/app_aivanov). Claude code la plateforme (FastAPI/PG/HTMX, RSA-PSS serveur, API activate/check/version/download), Qwen tests/sécu/RGPD. OwnCloud = HORS CIBLE produit (→ résout question canal OwnCloud).
2026-06-05 19:30 | dom | DECISION D-19 BLOQUANT | Perf MVP : test Windows Dom = trop lent, CPU 12% RAM 16Go. Diagnostiquer mono-cœur frozen, raster séquentiel, OCR docTR 300dpi, timings, hotfix faible risque.
2026-06-05 19:45 | claude | DEPOSE diagnostic perf | for-dom/2026-06-05_claude_diagnostic-perf-mvp.md. CAUSE RACINE : C1 torch jamais configuré (set_num_threads absent → 1 thread en frozen = CPU 12%), C2 raster séquentiel frozen (l.4316-4322), C3 OCR docTR séquentiel page/page 300dpi (l.1259-1280). Hotfix H1 (torch threads, quasi nul risque) + H2 (raster ThreadPoolExecutor) + H3 (OCR batch) + H4 (timings). DPI baissé = écarté (risque leak). Propose branche fix/perf-mvp. Question Dom : doc lent scanné ou natif ?