Conservés comme trace de recherche — non documentés, non factorisés,
ne pas dépendre de ce dossier depuis le code de production.
- test_glm_ocr.py : benchmark GLM-OCR 0.9B (écarté pour
faiblesse sur dp_libelle, praticien et
colonne Recodage).
- test_got_ocr.py : tests GOT-OCR2.0 (échec sur tableaux
denses à en-têtes verticaux).
- test_paddle.py : tentative PaddleOCR (incompatible avec
paddlepaddle installé).
- test_surya.py : tentative Surya (incompatible
transformers 5.6).
- test_qwen_vl.py : Qwen2.5-VL-7B (excellent mais 220s/page,
écarté faute de VRAM et vitesse).
- test_qwen_vl_3b.py : Qwen2.5-VL-3B (retenu, 3s/page, qualité
> GLM-OCR sur les champs critiques).
- test_prompt_ab.py : A/B test prompts Accord/Désaccord.
- test_prompt_crop*.py : prompts + crop ciblé checkboxes (échec
→ module pipeline/checkboxes.py).
- test_prompt_recueil_*.py : prompts page recueil (consignes verbeuses
dégradent la sortie, cf. discussion).
- README.md : index du dossier.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
77 lines
3.0 KiB
Python
77 lines
3.0 KiB
Python
"""A/B test corrigé : GLM-OCR sait-il distinguer accord vs désaccord sur un crop ?"""
|
|
from pathlib import Path
|
|
from PIL import Image
|
|
from pipeline.ocr_glm import GLMOCR
|
|
from pipeline.ingest import pdf_to_images
|
|
|
|
ZONE = (0.55, 0.82, 0.92, 0.90)
|
|
|
|
# Ground truth vérifié visuellement + confirmé par legacy
|
|
CASES = [
|
|
("2018 CARC/OGC 7.pdf", 1, "accord"),
|
|
("2018 CARC/OGC 55.pdf", 1, "accord"),
|
|
("2018 CARC/OGC 27.pdf", 1, "accord"),
|
|
("2018 CARC/OGC 86.pdf", 1, "désaccord"),
|
|
("2018 CARC/OGC 9.pdf", 1, None), # ground truth à vérifier
|
|
("2018 CARC/OGC 43.pdf", 1, None),
|
|
("2018 CARC/OGC 68.pdf", 1, None),
|
|
]
|
|
|
|
PROMPTS = {
|
|
"P1_simple": """Quelle case est cochée (X) : "Accord" ou "Désaccord" ? Un seul mot.""",
|
|
"P2_json": """Renvoie UNIQUEMENT {"cochee":"accord"} ou {"cochee":"désaccord"} selon la case marquée d'une croix.""",
|
|
"P3_negatif": """Sur cette image, il y a DEUX cases. L'UNE est cochée par une croix noire, l'AUTRE est vide. Dis-moi laquelle est cochée. Réponds par un seul mot : accord ou désaccord.""",
|
|
"P4_explicite": """Regarde ATTENTIVEMENT les deux cases à cocher. Une case VIDE ressemble à [ ]. Une case COCHÉE ressemble à [X]. Quelle case est cochée ? Réponds UNIQUEMENT : accord ou désaccord.""",
|
|
}
|
|
|
|
|
|
def crop_rel(img, z):
|
|
w, h = img.size
|
|
return img.crop((int(z[0]*w), int(z[1]*h), int(z[2]*w), int(z[3]*h)))
|
|
|
|
|
|
def classify(txt):
|
|
low = txt.lower()
|
|
# Retirer les séquences "accord_desaccord" et "accord ou désaccord"
|
|
low = low.replace("accord_desaccord", "").replace("accord ou désaccord", "").replace("accord ou desaccord", "")
|
|
has_des = "désaccord" in low or "desaccord" in low
|
|
has_acc = "accord" in low
|
|
if has_des and not has_acc: return "désaccord"
|
|
if has_acc and not has_des: return "accord"
|
|
if has_acc and has_des: return "both"
|
|
return "?"
|
|
|
|
|
|
def main():
|
|
ocr = GLMOCR()
|
|
print(f"VRAM = {ocr.vram_gb:.2f} Go\n")
|
|
|
|
Path("/tmp/ogc_crops").mkdir(exist_ok=True)
|
|
scores = {name: [0, 0] for name in PROMPTS} # [hits, evaluated]
|
|
for pdf, page, expected in CASES:
|
|
images = pdf_to_images(pdf)
|
|
img = Image.open(images[page - 1])
|
|
crop = crop_rel(img, ZONE)
|
|
crop_path = f"/tmp/ogc_crops/{Path(pdf).stem.replace(' ', '_')}_cb.png"
|
|
crop.save(crop_path)
|
|
label = f"OGC {Path(pdf).stem.split()[-1]}"
|
|
print(f"=== {label} (attendu={expected}) ===")
|
|
for name, prompt in PROMPTS.items():
|
|
res = ocr.run(crop_path, prompt, max_new_tokens=48)
|
|
got = classify(res["text"])
|
|
verdict = ""
|
|
if expected:
|
|
if got == expected: scores[name][0] += 1; verdict = " ✓"
|
|
else: verdict = " ✗"
|
|
scores[name][1] += 1
|
|
print(f" [{name}] → {got:10s} (raw={res['text'].strip()[:80]!r}){verdict}")
|
|
print()
|
|
|
|
print("=== RÉCAPITULATIF (sur cas à ground truth vérifié) ===")
|
|
for name, (h, n) in scores.items():
|
|
print(f" {name:18s}: {h}/{n}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|