Files
rpa_vision_v3/docs/BENCH_SAFETY_CHECKS_2026-05-06.md
Dom 0a02a6ec9c
Some checks failed
tests / Lint (ruff + black) (push) Successful in 15s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped
feat(qw4): bench rigoureux LLM safety_checks → gemma4:latest par défaut
Bench 5 modèles × 5 scénarios × cold+warm sur RTX 5070 :
- gemma4:latest : warm 2.9s, JSON 92%, détection 46% → gagnant
- qwen2.5vl:7b : warm 6.6s, détection 23% (trop lent)
- qwen2.5vl:3b : warm 2.0s, détection 8% (vérifie pour vérifier)
- medgemma:4b : warm 0.5s, détection 0% (refuse de signaler) → mauvais
  défaut initial, corrigé
- qwen3-vl:8b : 0% JSON valide (ignore format=json Ollama) → écarté

Modifications safety_checks_provider.py :
- RPA_SAFETY_CHECKS_LLM_MODEL défaut: medgemma:4b → gemma4:latest
- RPA_SAFETY_CHECKS_LLM_TIMEOUT_S défaut: 5 → 7 (warm 2.9s + marge)

Doc complète : docs/BENCH_SAFETY_CHECKS_2026-05-06.md
Script : tools/bench_safety_checks_models.py (reproductible, ~10-15 min)

Limite assumée : 46% de détection. À présenter en démo comme aide médecin,
pas certification. Amélioration V2 = prompt plus dirigé sur champs à vérifier.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:23:09 +02:00

4.6 KiB
Raw Permalink Blame History

Bench QW4 safety_checks — sélection du LLM contextuel

Date : 2026-05-06 Contexte : QW4 du sprint mai. La fonction _call_llm_for_contextual_checks appelle Ollama avec un screenshot + prompt court pour générer 0-3 checks de vérification supplémentaires que l'humain doit acquitter avant la reprise d'un replay en pause supervisée (safety_level=medical_critical).

Méthodologie

  • 5 scénarios : screenshots synthétiques de dossiers patient avec UNE anomalie volontaire chacun (date de naissance aberrante, IPP incohérent, diagnostic vide, code CIM inadapté à l'âge, forfait incohérent avec durée).
  • 5 candidats : gemma4:latest, qwen3-vl:8b, qwen2.5vl:7b, qwen2.5vl:3b, medgemma:4b.
  • Protocole par modèle : déchargement VRAM (keep_alive=0 sur tous les modèles loaded) → 1er appel = cold start chronométré → 4 autres screenshots × 3 runs = 12 mesures warm.
  • Métriques : cold start, warm avg, warm p95, % JSON valide, % détection (anomalie cible présente dans label/evidence d'au moins un check renvoyé).
  • Script : tools/bench_safety_checks_models.py.

Résultats

Modèle Cold (s) Warm avg (s) Warm p95 (s) JSON Détection
gemma4:latest 10.6 2.9 3.4 92% (12/13) 46% (6/13)
qwen3-vl:8b 5.6 0% (0/12) 0% (0/12)
qwen2.5vl:7b 9.4 6.6 8.1 100% (13/13) 23% (3/13)
qwen2.5vl:3b 6.0 2.0 2.5 100% (13/13) 8% (1/13)
medgemma:4b 2.0 0.5 0.7 100% (13/13) 0% (0/13)

Lecture

  • medgemma:4b retourne systématiquement [] sur les 13 mesures. Trop obéissant à "Si rien d'inhabituel à signaler, retourne []", refuse de pointer ne serait-ce qu'une date 1900-01-01. Mauvais choix par défaut malgré sa rapidité et sa spécialisation médicale revendiquée.
  • qwen3-vl:8b ignore format=json Ollama : 0 réponse parsable. À écarter pour cette tâche tant que le tooling Ollama / le modèle ne convergent pas.
  • qwen2.5vl:7b détecte mais 2× plus lent (warm 6.6s) que gemma4 et tend à inventer des anomalies de format de date qui ne sont pas la vraie cible.
  • qwen2.5vl:3b rapide mais détection 8% — il "vérifie pour vérifier" (renvoie souvent "vérification de la date de naissance" même quand la date est correcte).
  • gemma4:latest gagne : meilleur taux de détection (46%) ET deuxième meilleur warm (2.9s). Tend à raisonner cohérence motif/diagnostic plutôt que valeurs aberrantes brutes.

Détail détection par scénario

Scénario gemma4 qwen2.5vl:7b qwen2.5vl:3b medgemma:4b
Date naissance aberrante (1900)
IPP incohérent (ABC@@##XYZ)
Diagnostic principal vide
Code CIM inadapté à l'âge
Forfait UHCD vs durée 1h

Aucun modèle ne détecte les 5 scénarios. L'IPP corrompu et le forfait incohérent ne sont détectés par personne — ces anomalies demanderaient soit un prompt plus dirigé (liste explicite des champs à vérifier), soit un modèle plus large.

Décision

  • Défaut serveur : RPA_SAFETY_CHECKS_LLM_MODEL=gemma4:latest
  • Timeout : RPA_SAFETY_CHECKS_LLM_TIMEOUT_S=7 (warm 2.9s + marge)
  • Persistance VRAM : OLLAMA_KEEP_ALIVE=24h recommandé pour éviter le cold start de 10s en démo

Modifications appliquées dans agent_v0/server_v1/safety_checks_provider.py.

Limites & travail futur

  1. 46% de détection est faible : à présenter comme aide au médecin, pas comme certification. Le médecin reste le décideur.
  2. Prompt actuel trop générique : un prompt qui liste explicitement les champs à vérifier (DDN, IPP, diagnostic, forfait, cohérence âge/diagnostic) donnerait probablement de meilleurs résultats. À mesurer en V2.
  3. Bench sur 5 anomalies seulement : à étendre dès qu'on a un corpus de vrais dossiers Easily Assure avec anomalies confirmées par Pauline / Amina.
  4. Pas de test sur des dossiers SANS anomalie (faux positifs) : à ajouter.
  5. Pas de bench des modèles cloud (gemma3:27b-cloud, deepseek, gpt-oss) par contrainte 100% local — mais à explorer si on lève cette contrainte pour les checks contextuels (qui ne contiennent pas de PII si on anonymise les screenshots).

Reproductibilité

cd /home/dom/ai/rpa_vision_v3
.venv/bin/python tools/bench_safety_checks_models.py
# (BENCH_TIMEOUT=60 par défaut, ~10-15 min sur RTX 5070)