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>
4.6 KiB
4.6 KiB
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:4bretourne 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:8bignoreformat=jsonOllama : 0 réponse parsable. À écarter pour cette tâche tant que le tooling Ollama / le modèle ne convergent pas.qwen2.5vl:7bdé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:3brapide 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:latestgagne : 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=24hrecommandé 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
- 46% de détection est faible : à présenter comme aide au médecin, pas comme certification. Le médecin reste le décideur.
- 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.
- 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.
- Pas de test sur des dossiers SANS anomalie (faux positifs) : à ajouter.
- 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)