Aller au contenu principal

Module 8 — Exécution locale et hors ligne

Le modèle est choisi, quantifié, affiné, converti en GGUF. Le déployer sur le poste d'un agent de support est la partie triviale du projet — à condition d'avoir tranché quelques questions d'exploitation avant. Ce module décrit les deux voies pratiques, Ollama et llama.cpp, et les points d'organisation que trop d'équipes découvrent en production.

Ollama : la voie simple

Ollama est un service local qui télécharge, gère et sert des modèles GGUF via une API compatible avec celle d'OpenAI. Le cours 29 lui est entièrement consacré ; nous retenons ici l'essentiel.

L'installation tient en une ligne (curl -fsSL https://ollama.com/install.sh | sh sous Linux ou macOS, un installateur .exe sous Windows). Le service démarre automatiquement, expose localhost:11434, et une commande ollama pull ministral:3b-instruct-q4_K_M télécharge le modèle en cinq à dix minutes selon la connexion.

Un fichier Modelfile permet d'importer notre propre modèle affiné :

FROM ./ministral-tickets.Q4_K_M.gguf
TEMPLATE """..."""
SYSTEM """Vous êtes un assistant de classification de tickets d'assistance..."""
PARAMETER temperature 0.1
PARAMETER num_ctx 4096

La commande ollama create tickets-assist -f Modelfile enregistre le modèle sous un nom court, prêt à l'usage. L'intégration côté application est ensuite une requête HTTP standard.

Le point fort d'Ollama est l'absence de configuration. Le point faible : le mode « boîte noire » ; certains paramètres avancés (nombre de fils, taille de bloc, gestion fine du cache KV) ne sont pas exposés simplement. Pour un déploiement standard, c'est un avantage. Pour un cas exigeant, on retombe sur llama.cpp direct.

llama.cpp : le contrôle complet

llama.cpp est le moteur qui tourne sous Ollama, mais qu'on peut aussi utiliser directement. Il fournit un binaire llama-server qui expose lui aussi une API compatible OpenAI, avec toutes les options en ligne de commande :

llama-server \
--model ministral-tickets.Q4_K_M.gguf \
--ctx-size 4096 \
--threads 6 \
--n-gpu-layers 32 \
--host 127.0.0.1 --port 8080

Les paramètres qui comptent en pratique sont trois. --threads fixe le nombre de fils CPU : la valeur optimale est souvent le nombre de cœurs physiques, jamais tous les fils logiques. --n-gpu-layers décide combien de couches sont poussées sur GPU ; à -1, toutes ; à 32, les 32 premières, ce qui permet d'exploiter un GPU trop petit pour tout le modèle en partageant avec la RAM. --ctx-size fixe la fenêtre de contexte allouée ; réduire de 32 000 à 4 000 libère 500 Mo à 1 Go de RAM et gagne 20 % de latence si la tâche n'a pas besoin de la fenêtre complète.

Le budget mémoire à connaître

L'ordre de grandeur, sur un modèle 3B en 4 bits, avec un contexte de 4 000 jetons :

ComposantTaille
Poids quantifiés en mémoire~2,1 Go
Cache KV pour 4 000 jetons~380 Mo
Marge d'activations pendant l'inférence~250 Mo
Système d'exploitation et le reste2 à 3 Go
Total minimal recommandé6 Go de RAM libres, 8 Go de RAM installée

Si le poste dispose d'un GPU 6 Go, tout tient dessus et la latence est optimale. Sur GPU 4 Go, on passe une partie des couches en RAM et la latence remonte de 30 à 50 %. Sur CPU seul avec 8 Go de RAM, le modèle tient mais la marge est étroite ; passer à 16 Go de RAM est un investissement à 40 euros qui règle définitivement le problème.

La mise à jour du modèle

Le modèle affiné doit pouvoir être mis à jour après un mois de production, quand les catégories métier évoluent ou qu'un nouveau produit apparaît. Trois pratiques rendent cette mise à jour indolore.

Un nom versionné. tickets-assist:v3-2026-09 plutôt que tickets-assist. Les postes acceptent temporairement les deux versions, et le retour arrière est immédiat en cas de régression.

Un canari. La nouvelle version est déployée d'abord sur cinq postes volontaires pendant une semaine. Les métriques d'exactitude perçue et de plaintes sont comparées à la version courante. Sans dégradation, la bascule générale se déclenche.

Une distribution centrale. Un serveur interne héberge les GGUF signés ; les postes tirent via ollama pull ou curl avec vérification de somme de contrôle. Ne jamais laisser chaque poste télécharger depuis une source publique — bande passante, cohérence de version et sécurité.

L'intégration dans l'outil de tickets

Sur notre fil rouge, l'assistant s'ajoute à l'outil de ticket existant via une extension navigateur ou un plugin desktop qui appelle localhost:11434. Trois règles techniques.

Toujours passer par localhost. Jamais par 0.0.0.0 ou par une IP externe. Le modèle ne doit pas être joignable depuis le réseau ; c'est autant un choix de sécurité qu'une décision d'architecture.

Un délai maximal côté client. Si le modèle ne répond pas en 5 s, l'agent doit voir l'ancien flux revenir immédiatement. Un assistant qui bloque l'outil est pire qu'un assistant absent.

Un journal minimal. Numéro de ticket, catégorie proposée, catégorie corrigée par l'agent, latence observée. Rien de plus. Ces données servent à mesurer la qualité perçue et à préparer le prochain affinage — pas à surveiller les agents.

Le passage à l'échelle multi-postes est un vrai chantier

Déployer sur un poste est facile ; déployer sur 200 postes hétérogènes — Windows 10, 11, macOS Sonoma, Ubuntu 22.04, avec ou sans GPU, avec des versions de pilotes différentes — est un vrai projet d'exploitation. Prévoir un pilote de trois mois avec un support informatique dédié, et n'industrialiser qu'après.

En résumé

  • Ollama offre un déploiement en trois commandes ; llama.cpp offre le contrôle complet des paramètres via llama-server.
  • Trois paramètres décident du confort d'inférence : fils CPU, couches sur GPU, taille de contexte ajustée à la tâche réelle.
  • 6 Go de RAM libres suffisent pour un modèle 3B en 4 bits avec un contexte de 4 000 ; passer à 16 Go de RAM installée règle toutes les tensions.
  • Le déploiement industriel exige versionnage, canari et distribution centrale signée ; un pilote de trois mois avant l'industrialisation.

Module suivant : l'argument de confidentialité, ce qu'il justifie vraiment et ce qu'il ne protège pas malgré une exécution locale.