Aller au contenu
English

Choisir un modèle qui fonctionne sur votre propre matériel

  • Étude de cas 2
  • 180 min
  • Facultative · 1 étude de cas requise pour le certificat

Ce que vous saurez faire

Choisissez un modèle de langage lorsque le texte ne doit jamais quitter vos ordinateurs. Vous comparez deux modèles à poids ouverts et deux tailles des mêmes poids sur un seul ordinateur. Vous mesurez les contraintes du matériel : mémoire, temps de chargement et vitesse. Vous notez ce que les utilisateurs perçoivent : la qualité des réponses. Puis vous recommandez une configuration, avec le matériel nécessaire, ses limites et une solution de rechange.

Étude de casPièce de portfolioDonnées synthétiques

Jeu de données
Notes de visites de soins à domicile, 18 notes avec un corrigé (créé pour cette étude de cas)
Durée
Environ 3 heures, dont environ 15 minutes d'exécutions
S’exécute dans
Votre ordinateur : Ollama et Python 3.12+
Compétences utilisées
  • Règle de confidentialité comme exigence obligatoire
  • Licences des modèles
  • Quantification
  • Mémoire, temps de chargement et vitesse
  • Notation avec une grille
  • Recommandation avec une solution de rechange

Décompressez le projet de départ, ouvrez le dossier dans VS Code et suivez les étapes ci-dessous. Elles commencent par un nouvel environnement virtuel.

Le projet de départ est un petit dossier : les notes, les instructions pour le modèle et quatre scripts. Vous exécutez les scripts; vous n’écrivez pas de code. Le projet terminé contient nos exécutions enregistrées, nos notes et notre recommandation, pour comparaison. Vous n’avez pas d’ordinateur adapté? Utilisez le projet terminé. Son dossier runs/ contient chaque réponse et chaque durée. Vous pouvez donc faire les parties 4 et 5 sans exécuter de modèle.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 180 minutes

Ce que vous devez savoir

Cette étude de cas utilise tout le cours. Voici les leçons sur lesquelles elle s’appuie le plus :

Ce qu’il vous faut sur votre ordinateur

  • Ollama, le programme gratuit qui exécute des modèles à poids ouverts sur votre ordinateur.
  • Python 3.12 ou une version plus récente. Les scripts utilisent uniquement la bibliothèque standard de Python, donc il n’y a rien à installer.
  • Un éditeur de texte comme VS Code, et un tableur pour remplir un fichier CSV.
  • Mémoire : 16 Go pour les trois configurations. Avec 8 Go, utilisez seulement gemma3:4b.
  • Environ 13 Go d’espace disque libre pour les trois fichiers de modèles, et une connexion Internet pour les télécharger une fois.

Exécutions enregistrées sur un Mac mini M4 avec 16 Go de mémoire. Logiciels : macOS, Ollama 0.40.1, Python 3.14.6. De nouvelles versions de modèles et de nouvelles quantifications paraissent souvent, donc vos chiffres seront différents. C’est la méthode qui reste valable. Les commandes Windows et Linux n’ont pas été testées.

Wren Home Care envoie du personnel de soins chez des clients âgés. Après chaque visite, la personne rédige une courte note sur une tablette. Elle décrit ce qui s’est passé : les médicaments, une chute éventuelle, la douleur. Une journée chargée compte 300 notes.

Ines Moreau coordonne les visites. Elle veut transformer chaque note en un petit formulaire de transmission, pour faire ressortir les cas urgents. Theo Lambert, responsable de l’informatique de l’agence, a essayé un modèle hébergé avec une note inventée. Le résultat était bon.

Puis Ruth Okoye, responsable de la confidentialité de l’agence, fixe une règle : les notes ne quittent jamais les ordinateurs de l’agence. Elles contiennent des renseignements de santé sur des personnes nommées. Les contrats de l’agence et la loi lui laissent peu de marge pour les envoyer à une autre entreprise. Il n’y aura donc pas d’API hébergée : seulement un modèle exécuté sur du matériel appartenant à l’agence.

L’agence dispose d’un ordinateur pour cette tâche : un Mac mini M4 avec 16 Go de mémoire, aussi utilisé pour du travail de bureau. Theo doit trouver quel modèle peut y faire le travail, et avec quelle qualité. Dans cette étude de cas, vous êtes Theo.

Un dossier de projet qui rassemble les preuves pour une décision : les notes de test, les réponses enregistrées, les mesures, les notes attribuées et une recommandation d’une page.

À l'intérieur d'une limite en pointillés portant l'étiquette « Cet ordinateur : les notes ne le quittent jamais » : les notes de visite vont à measure.py, qui les envoie uniquement à Ollama à l'adresse 127.0.0.1. Ollama charge un fichier de modèle depuis le disque (Q4 ou Q8). Ses réponses et ses durées vont dans runs/, puis à score.py et à une personne qui appliquent la grille. Elles vont ensuite à report.py pour produire un tableau et un choix. À l'extérieur de la limite, une API de modèle hébergé; la flèche depuis measure.py est barrée et porte l'étiquette « refusé ».
Tout se passe dans un seul ordinateur. Les scripts refusent toute adresse qui ne correspond pas à cet ordinateur.
Description textuelle du diagramme

Les notes et le corrigé sont les données d’entrée. measure.py envoie une note à la fois à Ollama à l’adresse 127.0.0.1, celle de l’ordinateur lui-même. Ollama charge un fichier de modèle du disque vers la mémoire. Les réponses et les durées vont dans le dossier runs. score.py vérifie ce qu’un programme peut vérifier, et une personne lit les résumés. Ensemble, ils attribuent les notes selon la grille. report.py rassemble tout dans un tableau, qui mène à un choix. Une API de modèle hébergé se trouve à l’extérieur de l’ordinateur; le chemin vers elle est refusé.

Vous comparez deux modèles et deux quantifications (vous apprenez ce mot dans la partie 2) :

Configuration Modèle Quantification Fichier sur disque Élément comparé
gemma3:4b Gemma 3 4B, de Google Q4_K_M 3,35 Go la référence de base
gemma3:4b-it-q8_0 le même modèle Q8_0 4,98 Go la quantification
mistral:7b Mistral 7B Instruct v0.3, de Mistral AI Q4_K_M 4,37 Go un autre modèle

Ce sont deux modèles à poids ouverts populaires que le cours a mesurés dans les modules précédents. L’un possède 4 milliards de poids, l’autre 7 milliards, et leurs licences diffèrent.

Nous avons aussi mesuré une quatrième configuration une fois : mistral:7b-instruct-v0.3-q8_0, 7,7 Go sur disque. Puis nous l’avons écartée. La partie 2 explique pourquoi.

On ne peut pas publier de vraies notes de visite. Les 18 notes de cette étude de cas sont donc synthétiques : rédigées pour elle, avec des clients et des événements inventés. Leur utilisation est libre (CC0). En voici une, avec son corrigé :

Note R02
C-2210, Mrs Okafor. Evening visit. Dosette box still had the lunchtime tablets in it.
She says she forgot, she was on the phone with her sister. Gave the evening tablets
and she took them. Pain 2/10 in her hip. No falls. Ate soup and toast.
Answer key for R02
{"fall": "no", "medication": "missed", "pain_score": 2, "urgency": "follow_up",
"must_mention": ["lunchtime tablets missed"]}

Le modèle reçoit les mêmes instructions pour chaque note (data/task_prompt.md). Il doit renvoyer uniquement un objet JSON avec cinq clés :

Clé Valeurs permises
fall yes (oui), no (non), not stated (non précisé)
medication taken (pris), missed (oublié), refused (refusé), not stated
pain_score un nombre de 0 à 10, ou null (valeur nulle) quand la note ne donne aucun nombre
urgency urgent (urgent : chute avec blessure, difficulté à respirer, confusion nouvelle), follow_up (suivi : dose oubliée, douleur de 6 ou plus, problème de sécurité, toute incertitude), routine (courant)
summary une phrase en anglais, au plus 30 mots, seulement des faits tirés de la note

Les 18 notes couvrent les cinq catégories d’un jeu de test représentatif :

Catégorie Notes Ce qu’elle teste
Courante R01–R08 Notes claires : 2 urgentes, 4 nécessitant un suivi, 2 courantes
Difficile D01–D04 Une ancienne chute, pas une nouvelle; une glissade évitée; la douleur en mots, sans chiffres; une confusion nouvelle facile à manquer
Information manquante M01–M03 La note ne le précise pas : la bonne réponse est donc not stated ou null, pas une supposition
Autre qu’une note de visite X01 Un message sur un échange de quarts de travail
Français F01–F02 Notes de membres du personnel bilingues

Dix-huit notes sont un début, pas une preuve : un écart d’une ou deux notes entre deux configurations relève du bruit.

  1. Téléchargez le projet de départ avec le bouton dans l’encadré en haut de cette page. Décompressez-le. Vous obtenez un dossier local-model-choice.

  2. Dans VS Code, ouvrez le dossier : File › Open Folder… (Fichier › Ouvrir un dossier…), puis choisissez local-model-choice. Ouvrez un terminal : Terminal › New Terminal (Terminal › Nouveau terminal).

  3. Installez Ollama depuis ollama.com/download et démarrez-le. Sur macOS et Windows, l’application démarre le serveur. Sur Linux, le programme d’installation le démarre comme service.

  4. Vérifiez qu’Ollama écoute uniquement sur cet ordinateur. C’est l’application concrète de la règle de confidentialité : un serveur qui écoute sur le réseau peut recevoir des requêtes d’autres machines.

    Fenêtre de terminal
    lsof -nP -iTCP:11434 -sTCP:LISTEN
    Output (macOS)
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    ollama 11142 you 3u IPv4 0x5cb6a0e092f429ed 0t0 TCP 127.0.0.1:11434 (LISTEN)

    L’adresse doit être 127.0.0.1:11434. Si vous voyez *:11434 ou 0.0.0.0:11434, le réglage OLLAMA_HOST fait écouter Ollama sur le réseau. Supprimez ce réglage et redémarrez Ollama avant de continuer.

  5. Exécutez le script de vérification. Sur Windows, tapez python au lieu de python3 dans chaque commande de cette page.

    Fenêtre de terminal
    python3 check_setup.py
Output (last lines, before the downloads)
missing gemma3:4b to get it: ollama pull gemma3:4b
missing gemma3:4b-it-q8_0 to get it: ollama pull gemma3:4b-it-q8_0
missing mistral:7b to get it: ollama pull mistral:7b
Pull the missing models, then run this script again.

Ce que cela nous indique. Python et Ollama fonctionnent, et aucun modèle n’est encore sur le disque. Le script n’a envoyé aucune note : il a seulement demandé à Ollama sa version et sa liste de modèles.

Téléchargez maintenant les trois fichiers de modèles. C’est le seul moment où le projet a besoin d’Internet, et seule la demande du fichier sort.

Fenêtre de terminal
ollama pull gemma3:4b
ollama pull gemma3:4b-it-q8_0
ollama pull mistral:7b

Avec 8 Go de mémoire, téléchargez seulement le premier. Puis exécutez de nouveau python3 check_setup.py :

Sortie
Python 3.14.6 on Darwin arm64
Memory: 16 GB
Ollama 0.40.1 answers at http://127.0.0.1:11434
ready gemma3:4b 3.3 GB on disk
ready gemma3:4b-it-q8_0 5.0 GB on disk
ready mistral:7b 4.4 GB on disk
Ready.

Ce que cela nous indique. Le fichier Q8 est une fois et demie plus gros que le fichier Q4 du même modèle. La partie 2 explique pourquoi.

Encore une vérification : la règle de confidentialité est aussi dans le code. Donnez à measure.py une adresse autre que celle de cet ordinateur, et il refuse d’envoyer quoi que ce soit :

Fenêtre de terminal
OLLAMA_URL=http://example.com:11434 python3 measure.py gemma3:4b --notes R01
Sortie
Refused: example.com is not this computer. The notes must not leave it.

Partie 1 : ce que la règle et les licences permettent

Section intitulée « Partie 1 : ce que la règle et les licences permettent »

Le problème : « ouvert » ne veut pas dire « toute utilisation »

Section intitulée « Le problème : « ouvert » ne veut pas dire « toute utilisation » »

La règle de Ruth élimine tous les modèles hébergés. Mais un modèle téléchargé possède une licence. Certaines licences limitent ce que vous pouvez en faire, même sur votre propre ordinateur.

La leçon Licences et conditions d’utilisation des données a examiné les deux licences pour Larkfield. Nous les avons relues sur les pages officielles. Lisez vous-même les pages actuelles : les licences changent. En bref :

  • Mistral 7B Instruct v0.3 utilise la Apache License 2.0, comme l’indique sa page de modèle : toute utilisation, y compris commerciale, sans liste d’utilisations interdites. La page du modèle avertit aussi : « Il ne possède aucun mécanisme de modération. »
  • Gemma 3 utilise les conditions d’utilisation de Gemma, modifiées pour la dernière fois le 1 avril 2026. L’utilisation commerciale est permise, et vous êtes « seul responsable des sorties » (section 3.3). Mais la section 3.2 interdit l’utilisation « pour les usages restreints énoncés dans la politique d’utilisation interdite de Gemma ».

Pour les réponses de soutien de Larkfield, cette politique n’avait pas d’effet. Pour les notes de santé, elle en a. La politique d’utilisation interdite de Gemma, modifiée pour la dernière fois le 21 février 2024, interdit notamment :

Prendre des décisions automatisées dans des domaines qui touchent les droits matériels ou individuels ou le bien-être (p. ex., finance, droit, emploi, santé, logement, assurance et aide sociale)

Générer, recueillir, traiter ou déduire des renseignements personnels sensibles ou privés sur des individus sans obtenir tous les droits, autorisations et consentements exigés par les lois applicables.

Les soins à domicile sont des soins de santé. Avec Gemma, l’agence doit donc s’assurer que le modèle ne décide pas. Dans cette conception, le formulaire aide seulement une personne : la coordonnatrice lit chaque note et chaque formulaire, puis décide quoi faire. L’agence doit aussi avoir une base juridique et les consentements nécessaires pour traiter les notes, quel que soit le modèle. Ces deux conditions figurent dans la recommandation.

La licence de Mistral n’ajoute aucune condition d’utilisation, ce qui donne plus de liberté à l’agence pour la suite. Aujourd’hui, les deux modèles sont admissibles. Ce n’est pas un avis juridique; une agence demande à son avocat de confirmer cette lecture.

Partie 2 : la quantification, ou ce que signifient Q4 et Q8

Section intitulée « Partie 2 : la quantification, ou ce que signifient Q4 et Q8 »

Un modèle est surtout constitué de ses poids : des milliards de nombres appris pendant l’entraînement. Mistral 7B en possède environ 7,2 milliards. À 16 bits (2 octets) chacun, le format habituel après l’entraînement, cela représente environ 14,4 Go. L’ordinateur de Wren possède 16 Go au total, et le système d’exploitation et les logiciels de bureau en utilisent une partie. Le modèle ne tiendrait pas en mémoire.

La quantification stocke chaque poids avec moins de bits, en l’arrondissant à un niveau sur une courte échelle (La quantification : une copie plus petite du même modèle). Q8_0 conserve 8 bits par poids, plus une petite échelle pour chaque bloc de 32 poids. Q4_K_M conserve environ 4 à 5 bits : la plupart des poids reçoivent 4 bits, et quelques parties sensibles en gardent davantage. Dans le module 3, Q8 a gardé en français les réponses françaises de Gemma. Aidera-t-il pour cette tâche? Seul un test sur la tâche peut le dire.

La taille des fichiers suit le calcul. Comme dans Le matériel : le modèle tiendra-t-il en mémoire?, Mistral 7B possède environ 7,2 milliards de poids. À environ 8,5 bits chacun (8 bits plus les échelles des blocs), cela donne 7,7 Go : le fichier Q8 écarté. À environ 4,9 bits (Q4_K_M), cela donne 4,4 Go : le fichier fait 4,37 Go. Et la mémoire suit le fichier :

Mémoire de chaque configuration après chargement, selon ollama ps, avec un contexte de 4 096 jetons. En orange : la configuration écartée.
Description textuelle du graphique

Un diagramme à colonnes de la mémoire utilisée par chaque configuration après chargement, en gigaoctets, de 0 à environ 9. Gemma Q4 : 2,89. Gemma Q8 : 4,53. Mistral Q4 : 4,94. Mistral Q8 : 8,21, la colonne la plus haute, dans une autre couleur.

Ce que cela nous indique. Les trois configurations conservées ont besoin de 3 à 5 Go. Mistral Q8 a besoin de 8,2 Go, la moitié de l’ordinateur. Avec l’une des trois configurations chargée, macOS avait encore de 40 % à 50 % de mémoire libre. Plus tôt ce jour-là, d’autres programmes avaient utilisé plusieurs modèles sur le même ordinateur. La mémoire libre était tombée à 9 %. L’ordinateur utilisait le disque comme mémoire (swapping, permutation), et tout était devenu lent. Sur un ordinateur de 16 Go aussi utilisé pour le bureau, un modèle de 8 Go ne laisse aucune marge de sécurité. Nous avons donc mesuré Mistral Q8 une fois, pour en garder une trace, puis nous l’avons écarté.

Q4_K_M est un choix par défaut courant, à environ un tiers de la taille en 16 bits. Sous 4 bits, la qualité baisse généralement vite. Le coût de la quantification est un risque, pas une perte fixe : mesurez-le sur votre propre tâche.

Le problème : « rapide » peut vouloir dire plusieurs choses

Section intitulée « Le problème : « rapide » peut vouloir dire plusieurs choses »

Ines veut savoir combien de temps un intervenant attend après avoir appuyé sur Send (envoyer). Elle veut aussi savoir combien de temps prennent les 300 notes d’une journée. Quatre mesures des Les compromis sur les ressources répondent à ces questions :

Mesure Ce qu’elle mesure Qui la ressent
Temps de chargement Lecture du fichier du modèle en mémoire, avant la première réponse La première personne après un redémarrage ou une période calme
Temps avant le premier jeton De l’envoi de la note au premier morceau de la réponse. Le modèle lit d’abord toute la requête. Toute personne qui regarde la réponse apparaître
Jetons par seconde Vitesse à laquelle le modèle écrit la réponse, une fois qu’il commence Une longue réponse
Temps total par note De l’envoi de la note à la fin de la réponse Le lot quotidien : 300 notes × ce temps

measure.py mesure tout cela. À chaque passage, pour chaque configuration, il décharge le modèle, puis le recharge, chronomètre le chargement et mesure la mémoire. Ensuite, il envoie les 18 notes une à une, à une température de 0, avec les mêmes paramètres pour chaque modèle. Trois passages alternent entre les configurations. Ainsi, une minute chargée ne touche pas une seule configuration. La médiane écarte un moment de lenteur.

Essayez une note avec une configuration avant l’exécution complète :

Fenêtre de terminal
python3 measure.py gemma3:4b --passes 1 --notes R01
Sortie
pass 1 gemma3:4b: loaded in 2.75 s
R01 3.19 s first token 1.25 s 37.0 tokens/s
Wrote runs/gemma3_4b.jsonl

Le fichier contient une ligne pour le modèle, une pour le chargement et une pour chaque note. Voici la ligne de R01, raccourcie :

runs/gemma3_4b.jsonl (shortened)
{"pass": 1, "type": "item", "id": "R01", "total_s": 3.195, "first_token_s": 1.248,
"input_tokens": 531, "output_tokens": 72, "tokens_per_s": 37.0,
"ollama_prompt_s": 1.236, "ollama_answer_s": 1.945, "other_models_loaded": [],
"free_memory_percent": 51, "text": "```json\n{\n \"fall\": \"no\",\n \"medication\": \"taken\", ..."}

Ce que cela nous apprend. Le chargement n’a pris que 2,75 secondes, car le fichier était déjà dans le cache de fichiers de l’ordinateur. Après un redémarrage, le premier chargement lit le disque et prend plus de temps. Regardez aussi le début du texte : ```json. Nous y revenons à la partie 4.

Fermez les autres programmes exigeants et vérifiez qu’aucun autre modèle n’est chargé :

Fenêtre de terminal
ollama ps

La liste doit être vide. Lancez ensuite les trois configurations :

Fenêtre de terminal
python3 measure.py gemma3:4b gemma3:4b-it-q8_0 mistral:7b --passes 3

L’exécution a envoyé 162 notes et a pris 11 minutes sur notre ordinateur. La sortie contient une ligne par note :

Output (the first notes of each set-up, pass 1)
pass 1 gemma3:4b: loaded in 1.24 s
R01 3.20 s first token 1.25 s 36.8 tokens/s
R02 3.25 s first token 1.15 s 34.7 tokens/s
...
pass 1 gemma3:4b-it-q8_0: loaded in 3.49 s
R01 4.61 s first token 1.24 s 22.3 tokens/s
R02 4.54 s first token 1.16 s 21.9 tokens/s
...
pass 1 mistral:7b: loaded in 2.53 s
R01 6.37 s first token 2.72 s 21.3 tokens/s
R02 4.59 s first token 0.47 s 20.9 tokens/s

Erreur courante

Le même modèle se charge cent fois plus lentement une heure plus tôt

Symptôme : le premier test de Theo avec gemma3:4b, à 14 h 13, a donné un chargement de 127,6 secondes. Le premier jeton arrivait après 6 à 13 secondes. À l’essai suivant, le chargement a pris 857 secondes. À 16 h 23, sur le même ordinateur, le même modèle s’est chargé en 1,2 seconde. Il a produit son premier jeton après 1,2 seconde.

Cause : d’autres programmes utilisaient Ollama en même temps. Sur notre ordinateur, d’autres auteurs de cours exécutaient leurs propres tests sur le même serveur Ollama. Ollama répond à une requête à la fois et garde seulement un ou quelques modèles en mémoire. Nos requêtes attendaient donc dans une file. D’autres programmes déchargeaient notre modèle pour charger le leur. Le chronomètre de measure.py compte aussi cette attente.

Solution : mesurez sur un ordinateur peu occupé et vérifiez ollama ps avant chaque exécution. measure.py --wait 10 attend jusqu’à 10 minutes avant chaque configuration, jusqu’à ce qu’aucun autre modèle ne soit chargé. Ollama indique aussi son propre temps de lecture de la requête et d’écriture de la réponse. report.py l’affiche sous « of which the model worked » (dont le temps de travail du modèle). Il exclut toute réponse qui a attendu dans la file ou qui a nécessité un nouveau chargement du modèle. Il indique combien de réponses ont été exclues. Répétez les passages et gardez les médianes.

Conséquence pour le travail en IA : un test de vitesse sur une machine partagée compare les autres utilisateurs, pas les modèles. Sur l’ordinateur de l’agence, la même file apparaît quand deux intervenants envoient des notes en même temps. Le deuxième attend le premier. Mesurez aussi cette attente avant de promettre un délai.

Exécutez le script de rapport. Il lit toutes les exécutions et écrit results.md :

Fenêtre de terminal
python3 report.py
Output (the speed rows)
| | gemma3:4b-it-q8_0 | gemma3:4b | mistral:7b |
|---|---|---|---|
| Size on disk (GB) | 4.98 | 3.35 | 4.37 |
| Memory while loaded (GB) | 4.53 | 2.89 | 4.94 |
| Load time (s) | 3.49 | 2.75 | 2.49 |
| Time to first token (s) | 1.1 | 1.16 | 0.32 |
| Tokens per second | 23.0 | 34.65 | 21.6 |
| Total time per note (s) | 4.32 | 3.29 | 4.1 |
| Of which the model worked (s) | 4.31 | 3.28 | 4.09 |
| Slowest note (s) | 4.73 | 3.546 | 6.374 |

La fin du fichier indique qu’aucune réponse n’a dû être exclue : l’ordinateur était peu occupé.

Vitesse d'écriture de chaque configuration : médiane sur 3 passages de 18 notes (Mistral Q8 : 1 passage). Bleu : Q4. Orange : Q8.
Description textuelle du graphique

Un graphique à colonnes de la médiane des jetons par seconde. Gemma Q4 : 34,65, la plus haute. Gemma Q8 : 23,0. Mistral Q4 : 21,6. Mistral Q8 : 12,2, la plus basse.

Ce que cela nous apprend.

  • Q8 est plus lent que Q4 : Gemma écrit 23 plutôt que 35 jetons par seconde, et Mistral, 12 plutôt que 22. Un fichier Q8 contient presque deux fois plus d’octets à lire pour chaque jeton (pourquoi).
  • Le plus gros modèle est aussi plus lent : Mistral Q4 a plus de poids que Gemma Q4. Il écrit environ 40 % moins de jetons par seconde.
  • Le temps avant le premier jeton montre autre chose : Mistral répond après 0,32 seconde, Gemma après 1,1 seconde. Selon Ollama, Mistral relisait les instructions communes seulement pour la première note après un chargement (2,7 secondes pour R01). Ensuite, il semble les réutiliser et lire seulement la nouvelle note. Gemma lisait toute la requête pour chaque note.
  • Pour le lot quotidien, les trois conviennent : 300 notes prennent de 16 à 22 minutes, une à la fois.

Le problème : une réponse rapide et fausse est pire que l’absence de réponse

Section intitulée « Le problème : une réponse rapide et fausse est pire que l’absence de réponse »

Un formulaire qui indique routine (courant) pour un client tombé qui n’a pas pu se relever est dangereux. Le cas urgent se cache parmi les cas courants. La vitesse ne vaut rien tant que les réponses ne sont pas correctes.

Voici la grille du module 4 : les mêmes quatre critères, notés 0, 1 ou 2 par note. Chaque score garde le même sens. La note remplace la politique. « S’abstenir » signifie écrire not stated (non indiqué) ou null (valeur nulle) au lieu de deviner.

Critère 2 1 0
Justesse Les quatre étiquettes et le résumé concordent avec la note Une petite erreur qui ne change pas les soins (une chute indiquée yes (oui) qui n’a pas eu lieu, follow_up (suivi) pour une note courante) Un fait faux ou inventé qui pourrait changer les soins : une note urgente sans l’étiquette urgent (urgent), une dose oubliée indiquée taken (prise) et routine
Exhaustivité Le résumé contient tous les faits de must_mention (faits à mentionner) Il manque un fait nécessaire Il manque le fait principal, ou il n’y a pas de résumé
Format Exactement un objet JSON avec les cinq clés, les valeurs permises et un résumé d’au plus 30 mots Utilisable après une petite correction : délimiteurs de bloc de code ou texte autour de l’objet, ou une valeur non permise Le programme ne peut pas l’utiliser : aucun objet JSON, ou une clé manquante
Abstention not stated ou null pour chaque champ absent de la note, et une valeur pour chaque champ qu’elle précise Trop prudent : not stated pour un fait indiqué dans la note Pas assez prudent : une valeur absente de la note, comme une « absence de chute » inventée

C’est une grille adaptée sur un point : elle n’a pas de règle « prêt ». Les notes urgentes manquées sont comptées séparément, comme une exigence essentielle. Comme au module 4, l’abstention compte pour chaque note. Un formulaire peut être trop prudent, ou pas assez. Un not stated pour un fait indiqué n’est pas faux. Il fait donc perdre des points d’abstention, pas de justesse. Nous comptons un autre nombre séparément, car c’est une exigence essentielle : les notes urgentes manquées, sur les 4 notes urgentes.

Fenêtre de terminal
python3 score.py
Sortie
gemma3:4b-it-q8_0: 18 answers in pass 1; answers that changed in later passes: 0
gemma3:4b: 18 answers in pass 1; answers that changed in later passes: 0
mistral:7b: 18 answers in pass 1; answers that changed in later passes: 0
Read the summaries: 54 rows of scores/reading.csv need completeness (0, 1 or 2) and false_fact (none, minor or serious). Then run this script again.

Ce que cela nous apprend. À une température de 0, chaque configuration a donné les mêmes réponses aux trois passages. Le script note donc le passage 1. (Lors d’une exécution précédente, gemma3:4b a changé un mot d’un résumé après son rechargement par Ollama. À une température de 0, « identique » est très probable, mais pas garanti.) Un programme ne peut pas déterminer si un résumé est fidèle à la note : cela demande une personne.

Ouvrez scores/reading.csv dans un tableur. Chaque ligne contient un résumé et les faits qu’il devrait mentionner. Remplissez deux colonnes :

  • completeness (exhaustivité) : 2 si le résumé contient tous les faits de must_mention, 1 s’il en contient certains, 0 sinon.
  • false_fact (fait faux) : none (aucun), minor (mineur : un détail faux qui ne change pas les soins), ou serious (grave : un fait faux qui pourrait changer les soins).

Ouvrez la note dans data/notes.jsonl si vous hésitez. Si possible, notez sans regarder le nom du modèle : triez les lignes par id (identifiant), pas par model (modèle). Voici quatre lignes réelles et les scores que nous leur avons donnés :

Note Résumé Exhaustivité Fait faux
D04 (nouvelle confusion) « Première visite depuis le retour de Mr Haddad de l’hôpital. Confusion inhabituelle, prise des médicaments avec aide, aucune chute, douleur de 2/10. » 2 none
D04 « Mr. Haddad a pris ses médicaments avec aide et a indiqué une douleur de 2/10. » 0 : aucun mot sur la confusion none
R06 (respiration) « Mrs Petrova a ressenti un nouvel essoufflement, nécessitant de s’asseoir plusieurs fois. Appel au coordonnateur pour une visite infirmière immédiate. » 2 minor : la note dit que l’infirmière vient cet après-midi
R02 (dose oubliée) « Mrs. Okafor a indiqué une douleur de 2 à la hanche et a pris ses médicaments du soir. » 0 : la dose oubliée du midi n’y est pas none

La première et la troisième ligne viennent de Mistral; la deuxième et la quatrième, de Gemma Q4. Enregistrez le fichier au format CSV et relancez le script :

Fenêtre de terminal
python3 score.py
Sortie (dernières lignes)
model correct complete format abstain urgent missed
gemma3:4b-it-q8_0 28/36 28/36 18/36 34/36 2 of 4
gemma3:4b 28/36 25/36 18/36 34/36 1 of 4
mistral:7b 30/36 35/36 36/36 33/36 1 of 4
Wrote scores/auto.csv, scores/reading.csv and scores/rubric.csv
Qualité selon la vitesse : plus haut signifie meilleur, plus à gauche signifie plus rapide. Les points additionnent les quatre critères, chacun sur 36 (18 notes × 2). L'axe vertical commence à 80.
Description textuelle du graphique

Un nuage de points de cinq configurations. L’axe horizontal montre la médiane des secondes par note, l’axe vertical les points de la grille. Gemma Q4 : 3,29 secondes, 105 points. Gemma Q8 : 4,32 secondes, 108 points. Mistral Q4 : 4,1 secondes, 134 points, le plus haut. Mistral Q8 : 6,9 secondes, 133 points. Gemma Q4 avec un schéma JSON : 3,11 secondes, 125 points.

Ce que cela nous apprend.

  • Mistral Q4 produit les meilleurs formulaires : des résumés complets (35 sur 36), un format parfait et aucune valeur inventée.
  • Q8 n’a pas aidé pour cette tâche. Gemma Q8 a obtenu 3 points de plus que Gemma Q4. Cet écart relève du bruit, et il a manqué une note urgente de plus. Mistral Q8 a obtenu 1 point de moins que Mistral Q4. Les deux fichiers Q8 demandent environ 1,6 fois plus de mémoire et 1,3 à 1,7 fois plus de temps par note.
  • Les deux modèles se trompent dans des directions opposées. Gemma devine : il a indiqué « aucune chute » pour M01, où la note ne dit rien sur une chute (abstention 0). Mistral est trop prudent : il a écrit not stated pour trois notes qui disent « Aucune chute » (abstention 1 chacune). La pire erreur de Mistral est R02 : il a indiqué taken et routine pour la dose oubliée du midi.
  • Toutes les configurations ont manqué D04 : une nouvelle confusion après un séjour à l’hôpital, que les règles classent urgent. Les trois ont écrit follow_up. Le résumé de Mistral dit « Confusion inhabituelle ». Une personne qui le lit voit donc le problème. L’étiquette seule le cache.

Erreur courante

Chaque réponse de Gemma fait échouer le programme qui lit le formulaire

Symptôme : le score de format des deux configurations Gemma est de 18 sur 36 : un point par note. Un programme qui lit les formulaires avec json.loads échoue sur les 18 réponses de Gemma.

Cause : Gemma place chaque réponse dans un bloc de code Markdown, ```json ... ```, malgré l’instruction « Return only a JSON object » (retournez seulement un objet JSON). Une personne ne le remarque pas; un programme, oui. score.py peut quand même trouver l’objet à l’intérieur. Le format obtient donc 1, pas 0.

Solution : demandez une sortie structurée à Ollama. Donnez-lui le schéma JSON du formulaire. Il permet alors au modèle seulement les jetons qui respectent le schéma. measure.py --structured le fait :

Fenêtre de terminal
python3 measure.py gemma3:4b mistral:7b --passes 3 --structured

Avec le schéma, le format de Gemma est passé de 18 à 36 sur 36, à la même vitesse (3,11 secondes par note). Ses résumés ont aussi changé et sont devenus plus complets (29 plutôt que 25). Mais il manquait toujours D04. Il inventait maintenant « aucune chute » dans X01, le message d’échange de quarts : abstention 32 sur 36. Les réponses de Mistral ont gardé les mêmes scores. Un schéma garantit la forme de la réponse, pas sa véracité.

Conséquence pour le travail en IA : un problème de format semble mineur dans une démonstration où une personne lit la réponse. Dans un pipeline, le programme qui lit le formulaire échoue sur chaque note. Ou une étape de nettoyage peu soigneuse cache d’autres erreurs. Notez le respect du format comme un critère distinct. Utilisez l’option stricte offerte par le logiciel qui sert le modèle.

Avant tout compromis, éliminez les configurations qui ne respectent pas une exigence essentielle. Wren en a quatre :

Exigence essentielle Gemma Q4 Gemma Q8 Mistral Q4 Mistral Q8
Fonctionne seulement sur l’ordinateur de l’agence oui oui oui oui
La licence permet l’utilisation, avec une personne qui décide oui oui oui oui
Tient dans 16 Go avec le travail de bureau oui (2,9 Go) oui (4,5 Go) oui (4,9 Go) non (8,2 Go)
Ne manque aucune note urgente dans les données de test non (1 sur 4) non (2 sur 4) non (1 sur 4) non (1 sur 4)

Aucune configuration ne respecte la dernière exigence essentielle. C’est un résultat, pas un échec de la méthode. Aucun modèle ne peut donc trier les notes seul : le formulaire ne doit jamais réduire la priorité d’une note. Le modèle peut quand même aider à la lecture, à côté de la note, pendant que le coordonnateur lit chaque note. Avec cette conception, la dernière ligne devient une limite connue. Le choix se fait entre les trois premières configurations.

Gemma Q4 Gemma Q8 Mistral Q4
Qualité (points de la grille sur 144) 105; 125 avec le schéma 108 134
Secondes par note 3,3 4,3 4,1
Mémoire 2,9 Go 4,5 Go 4,9 Go
Licence Gemma Terms (aucune décision automatisée en soins de santé) la même Apache 2.0

Mistral Q4 demande 0,8 seconde de plus par note que Gemma Q4 (4 minutes pour 300 notes) et 2 Go de mémoire de plus. En échange, le coordonnateur obtient les résumés les plus complets et des formulaires propres.

RECOMMENDATION.md, dans le projet terminé, est le document de décision d’une page. Voici l’essentiel :

Recommandation : mistral:7b (Mistral 7B Instruct v0.3, Q4_K_M) avec une sortie structurée, comme aide à la lecture à côté de chaque note, pas pour le triage.

Matériel : environ 5 Go de mémoire pour le modèle, donc un ordinateur de 16 Go; 4,4 Go sur disque. Une note à la fois, environ 4 secondes par note : 300 notes en environ 20 minutes.

Limites : aucune configuration n’a respecté l’exigence « ne manquer aucune note urgente » : toutes ont manqué la nouvelle confusion (D04). Mistral a indiqué qu’une dose oubliée avait été prise (R02). Il a écrit not stated pour « Aucune chute » trois fois. 18 notes inventées, non vérifiées par une deuxième personne. Le formulaire ne doit jamais réduire la priorité d’une note; le coordonnateur lit chaque note.

Solution de rechange : gemma3:4b avec une sortie structurée, sur un ordinateur de 8 Go ou si Mistral n’est pas disponible. Il demande 2,9 Go et 3,1 secondes par note, avec des résumés moins complets. Une personne doit décider, comme sa licence l’exige. Si l’ordinateur est en panne, le coordonnateur lit les notes sans formulaires, comme aujourd’hui. Aucune note n’est envoyée à un modèle hébergé.

Réexaminer quand : l’agence dispose d’un jeu de test de ses propres notes; la règle d’urgence pour la confusion change dans la requête; un nouveau modèle ou une nouvelle version d’Ollama arrive; plusieurs intervenants envoient des notes en même temps; un cas urgent est manqué en utilisation réelle.

Un modèle local règle un problème : les notes ne quittent plus l’agence. Cela ne suffit pas à rendre son utilisation sûre.

Le modèle aide; une personne décide. Dans notre jeu de test, chaque configuration a sous-estimé l’urgence d’au moins une note. Le formulaire ne doit jamais fermer un dossier, planifier une visite ou omettre un appel de lui-même. La personne responsable de la coordination lit la note, pas seulement le formulaire. La licence de Gemma l’exige en santé. C’est aussi une bonne pratique avec tout modèle.

L’ordinateur contient maintenant des données de santé. Les notes, le dossier runs/ et les journaux sur le Mac mini sont aussi sensibles que les dossiers des clients. L’ordinateur doit avoir un disque chiffré, des comptes utilisateurs, des mises à jour et des sauvegardes. C’est nécessaire pour tout système contenant des données de santé. Ollama doit continuer à écouter uniquement sur 127.0.0.1. Ne mettez jamais de vraies notes dans un dépôt public : ce projet utilise des notes synthétiques pour cette raison.

Testez avec vos propres notes, à l’interne. Ces 18 notes sont inventées et courtes. Avant toute utilisation réelle, l’agence crée un jeu de test à partir de ses propres notes, sur son propre ordinateur. Elle obtient l’approbation de la personne responsable de la protection des renseignements personnels et le note de la même façon. Les vraies notes sont plus longues, utilisent les abréviations de l’agence et mélangent les langues.

Les erreurs varient selon les personnes. Surveillez les notes en français et celles des membres du personnel qui écrivent moins en anglais. Pour nos deux notes en français, les trois configurations ont bien reconnu la chute urgente (F02). Gemma Q4 a classé F01 comme follow_up (suivi) plutôt que routine (habituel). Deux notes ne permettent pas de montrer une différence entre les langues. Un vrai jeu de test en exige beaucoup plus, provenant de chaque groupe du personnel.

Un modèle local change aussi. Une nouvelle version peut arriver sous le même nom. Notez le fichier exact du modèle (ollama show le fournit) et refaites la comparaison avant toute mise à jour.

Ce projet montre que vous pouvez choisir un modèle selon une contrainte réelle, avec des preuves. Il montre aussi une décision que quelqu’un d’autre peut vérifier. Publiez-le dans un dépôt à votre nom.

Quoi mettre dans le dépôt :

local-model-choice/
README.md the situation, the rule, how to run it, the result in one table
RECOMMENDATION.md the choice, the hardware, the limits, the fallback, when to look again
LICENSE MIT, for the code
data/ notes.jsonl, task_prompt.md, DATASET.md (synthetic, CC0)
check_setup.py, measure.py, score.py, report.py
runs/ every answer and every time, per set-up
scores/ auto.csv, reading.csv (your reading), rubric.csv
results.md, results.json
  1. Partez de votre propre dossier de projet, avec vos propres exécutions et votre propre lecture des résumés.
  2. Rédigez RECOMMENDATION.md à partir du modèle fourni dans le projet de départ. Réécrivez le premier paragraphe du README dans vos mots. Ajoutez les détails de votre ordinateur : modèle, mémoire, système d’exploitation, version d’Ollama.
  3. Créez le dépôt : git init, git add ., git commit -m "Local model choice for visit notes".
  4. Publiez-le sur GitHub comme dépôt public. Les notes sont synthétiques et sous licence CC0, vous pouvez donc les publier. Ne publiez jamais de vraies notes.

Comment le décrire en entrevue, en deux phrases : « Les notes de santé devaient rester sur notre matériel. J’ai donc comparé deux modèles à poids ouverts et deux quantifications avec Ollama, selon la mémoire, la vitesse et la qualité selon la grille. Aucune configuration n’a reconnu toutes les notes urgentes. J’ai donc recommandé Mistral 7B à 4 bits comme aide à la lecture, avec le matériel nécessaire, ses limites et une solution de rechange. »

Allez plus loin :

  1. Corrigez la règle sur la confusion. Modifiez la règle d’urgence dans data/task_prompt.md, par exemple avec « ne sait pas quel jour on est ni où on est ». Exécutez toutes les configurations de nouveau et vérifiez que les résultats des autres notes ne se dégradent pas.
  2. Un troisième modèle. Ajoutez Qwen3 4B (Apache 2.0). Il « réfléchit » avant de répondre : mesurez ce que cela coûte par note, comme dans Raisonnement et multimodalité.
  3. Deux requêtes à la fois. Envoyez deux notes en même temps et mesurez le temps par note. Cela représente la période chargée du matin, quand plusieurs membres du personnel terminent leurs visites ensemble.
  4. Un ordinateur plus petit. Exécutez gemma3:4b sur un portable avec 8 Go et ajoutez une colonne au tableau.

Vérifiez votre compréhension

Un collègue dit : « Q8 est plus précis que Q4, donc il est meilleur. Utilisez le plus gros fichier qui tient en mémoire. » Que répondez-vous?

Afficher la réponse

Q8 stocke chaque poids avec plus de précision, mais cela n’améliore pas les réponses pour toutes les tâches. Sur nos 18 notes, Gemma Q8 a obtenu 108 points contre 105 pour Q4 (du bruit). Il a aussi manqué une note urgente de plus; Mistral Q8 a obtenu 133 points contre 134. Les deux fichiers Q8 demandaient environ 1,6 fois plus de mémoire et étaient plus lents par note. « Le plus gros qui tient » ignore aussi les autres tâches de l’ordinateur : Mistral Q8 exige 8,2 Go sur une machine de 16 Go. Mesurez les deux sur votre propre jeu de test. Choisissez le fichier plus petit, sauf si le plus gros est clairement meilleur.

Vérifiez votre compréhension

Votre mesure indique que mistral:7b prend 12 secondes par note. Hier, il en prenait 4. Rien n'a changé dans le projet. Que vérifiez-vous, et comment?

Afficher la réponse

Vérifiez si l’ordinateur était occupé. Exécutez ollama ps : un autre modèle dans la liste signifie qu’un autre programme utilise Ollama. Comparez le temps total au temps de travail d’Ollama (« of which the model worked », soit « dont le temps de travail du modèle », dans results.md). Regardez combien de réponses report.py a exclues à cause d’une attente en file ou d’un rechargement du modèle. Ensuite, répétez les passages sur un ordinateur peu occupé et conservez les médianes. Une exécution lente ne caractérise pas le modèle.

Vérifiez votre compréhension

Les conditions de Gemma 3 interdisent de « prendre des décisions automatisées dans des domaines qui touchent [...] le bien-être (p. ex. [...] les soins de santé [...]) ». Wren peut-elle utiliser Gemma pour le formulaire de transfert?

Afficher la réponse

Oui, si le formulaire aide seulement une personne qui décide. Ici, la personne responsable de la coordination lit chaque note et formulaire, puis décide quoi faire. Le modèle ne décide rien seul. L’agence voudra peut-être plus tard que le formulaire déclenche des actions, comme omettre un appel pour une note « habituelle ». Cette utilisation exige un nouvel examen juridique. Sur notre jeu de test, aucun modèle n’est assez bon pour cela. Avec tout modèle, l’agence doit avoir le fondement juridique et les consentements nécessaires pour traiter les notes. C’est une interprétation des conditions, pas un avis juridique.

Récapitulatif

  • Une règle de confidentialité est une exigence obligatoire qui élimine tous les modèles hébergés. Vérifiez que le serveur local écoute uniquement sur 127.0.0.1.
  • Les poids ouverts sont accompagnés d’une licence : Apache 2.0 n’ajoute aucune règle d’utilisation. Les conditions de Gemma interdisent les décisions automatisées en santé.
  • La quantification stocke chaque poids avec moins de bits (Q8_0 environ 8,5 bits, Q4_K_M environ 4,9). La mémoire et le temps par jeton diminuent aussi; ici, Q8 n’a pas donné de meilleurs formulaires.
  • Mesurez le temps de chargement, le délai avant le premier jeton, les jetons par seconde, le temps par note et la mémoire. Répétez, conservez les médianes et vérifiez qu’aucun autre programme n’utilise le serveur.
  • Un programme vérifie les étiquettes, le format et l’abstention; une personne lit les résumés. Comptez séparément les notes urgentes manquées.
  • Mistral 7B à Q4 a donné les meilleurs formulaires en environ 4 secondes, avec 5 Go. Aucune configuration n’a reconnu toutes les notes urgentes. C’est donc une aide à la lecture, jamais au triage. Gemma Q4 avec un schéma est la solution de rechange.

Ensuite, le travail final du cours : choisissez un modèle pour votre propre tâche, avec la même méthode.

Leçon suivante : Travail final