Tout le carnet
Architecture IA15 min

Le vrai coût d'un LLM se décide avant l'entraînement

Un développeur backend reçoit pour mission d'intégrer un agent conversationnel capable de manipuler l'inventaire d'une base de données et de rédiger des rapports d'anomalies selon la charte graphique de...

La panne coûteuse : entraîner pour résoudre un problème d’orchestration

Un développeur backend reçoit pour mission d’intégrer un agent conversationnel capable de manipuler l’inventaire d’une base de données relationnelle complexe et de rédiger des rapports d’anomalies conformes à la charte graphique de l’entreprise. Le premier réflexe, souvent dicté par l’excitation technique autour de l’IA autonome, consiste à télécharger un modèle open source de 8 milliards de paramètres, louer une instance GPU Nvidia H100 ou A100 chez un fournisseur cloud, puis lancer un fine-tuning sur des exports SQL et des documents internes.

Scène du mode de panne : Le vrai coût d'un LLM se décide avant l'entraînement
Scène du mode de panne : Le vrai coût d'un LLM se décide avant l'entraînement
Vue éditoriale du système : Le vrai coût d'un LLM se décide avant l'entraînement
Vue éditoriale du système : Le vrai coût d'un LLM se décide avant l'entraînement

Deux semaines et 3 000 dollars de calcul plus tard, le modèle produit des hallucinations polies. Il ignore le schéma réel de la base, invente des clés étrangères, mélange des tables obsolètes et adopte un ton inadapté à un contexte métier. Le projet est gelé, le budget est consommé, et la confiance de la direction métier est entamée.

Le lecteur repart avec une grille de décision simple : savoir quand rester au niveau de l’orchestration applicative, quand passer au fine-tuning d’un modèle existant, et quand l’entraînement complet à partir de zéro devient réellement justifiable.

La panne n’est pas d’abord logicielle. Elle est architecturale. L’équipe a tenté de résoudre par modification des poids du modèle ce qui relevait d’un problème d’exécution de flux, de validation de schémas, de droits d’accès, de fraîcheur des données et de gestion du contexte.

Le fine-tuning n’est pas une base de données. Il ne remplace ni un connecteur SQL, ni un validateur JSON, ni un moteur de règles, ni un contrôleur d’autorisation. Il modifie la manière dont un modèle répond. Il ne garantit pas que l’état métier interrogé existe, soit à jour, soit autorisé, soit cohérent avec la base de production.

Prenons le contre-exemple typique du fine-tuning « fourre-tout ». L’équipe extrait 50 000 lignes de transactions historiques, quelques schémas de tables et des rapports internes. Elle transforme le tout en paires question-réponse. Pendant l’entraînement, la loss diminue. Le tableau de bord donne l’impression d’un apprentissage réel. Mais en conditions réelles, le système échoue sur une demande simple :

ÉlémentValeur
Requête utilisateur« Donne-moi l’état du stock pour le commutateur réseau modèle X-200. »
Comportement attenduGénérer ou déclencher une requête contrôlée sur la table de production.
Sortie correcteSELECT stock_qty FROM inventory WHERE model = 'X-200';
Sortie du modèle fine-tunéSELECT stock_quantity FROM stocks_v2 WHERE model_name LIKE '%X-200%';
Problèmestocks_v2 n’existe pas en production. Elle vient d’un vieil export utilisé pendant l’entraînement.

Le modèle n’a pas compris l’inventaire comme un système vivant. Il a absorbé des traces historiques. Il a figé dans ses poids des structures périmées. Plus grave : il répond avec assurance, car rien dans son fonctionnement ne l’oblige à vérifier l’existence d’une table, l’actualité d’un stock ou le droit de lire une donnée.

La bonne question n’est donc pas : « Quel modèle devons-nous entraîner ? » La bonne question est : « Quelle partie du besoin doit être déterministe, vérifiable et maintenable hors du modèle ? »

Pourquoi les poids ne doivent pas porter l’état métier

L’erreur centrale consiste à confondre trois types de mémoire : la connaissance générale du modèle, l’état métier de l’entreprise et la mémoire de session. Ces trois couches n’ont ni le même rythme de changement, ni le même niveau de risque, ni le même mécanisme de correction.

La connaissance générale du modèle est lente à produire et coûteuse à modifier. Elle concerne la langue, les raisonnements usuels, les formats courants, les concepts techniques généraux. L’état métier est beaucoup plus volatile : stocks, prix, statuts de commande, règles de remise, droits utilisateurs, versions de schéma, politiques internes. La mémoire de session est encore plus locale : ce que l’utilisateur vient de demander, les objets déjà sélectionnés, le contexte immédiat de conversation.

Vouloir stocker l’état métier dans les poids d’un modèle crée trois pannes récurrentes.

PanneCauseSymptôme en productionCorrection saine
Dérive d’alignementLe fine-tuning optimise trop fortement le modèle sur un corpus interneRéponses moins robustes, ton étrange, perte de capacités généralesRéduire le fine-tuning, isoler le style, tester sur tâches générales
Mémoire figéeDes faits volatils sont appris comme s’ils étaient structurelsPrix, stocks ou schémas obsolètes répétés avec confianceDéplacer les faits vers des outils, bases ou caches contrôlés
Coût fixe inutileUn modèle personnalisé impose une infrastructure dédiéeGPU provisionné même lorsque l’usage est faibleRevenir à une API managée ou à une orchestration légère

La dérive d’alignement apparaît lorsque l’on injecte trop de données internes pour « apprendre l’entreprise » au modèle. Le modèle perd une partie de sa robustesse généraliste. Il peut devenir excellent sur un style documentaire étroit, mais moins fiable sur les demandes ordinaires. Il peut appliquer un jargon interne à des utilisateurs qui ne le comprennent pas. Il peut aussi produire des réponses très formatées, mais fragiles dès que la requête sort du cadre du corpus.

L’illusion de la mémoire par les poids est plus dangereuse. Une base de données change. Un modèle fine-tuné ne change pas à chaque ligne mise à jour. Si un tarif, un stock ou une relation de table évolue après l’entraînement, le modèle porte déjà une version morte de la réalité. L’hallucination devient alors difficile à détecter : elle ressemble à une réponse experte, mais elle provient d’une mémoire périmée.

Le troisième coût est opérationnel. Héberger un modèle personnalisé, même avec un adaptateur QLoRA, implique de gérer l’inférence, la disponibilité, la latence, la VRAM, les déploiements, les versions, les tests de non-régression et le repli en cas d’incident. Pour un outil interne utilisé par intermittence, cette infrastructure permanente peut coûter plus cher que des appels API correctement orchestrés.

La règle saine est simple : les poids apprennent des comportements stables ; les outils lisent l’état vivant ; l’orchestrateur décide du flux.

Le modèle COH : arbitrer entre orchestration, fine-tuning et entraînement

Pour éviter de descendre trop tôt dans la pile d’entraînement, on peut formaliser la décision avec le Harnais d’Orchestration Contextuelle, ou COH (Contextual Orchestration Harness). Le COH repose sur une contrainte forte : on ne modifie pas les poids tant qu’un système d’orchestration peut résoudre le problème de manière vérifiable.

Ce modèle distingue trois niveaux.

+-----------------------------------------------------------------------+
| TIER 3 : Orchestration contextuelle                                   |
| Résout : flux métier, appels d’outils, RAG, validation, permissions   |
| Coût : faible à variable | Délai : heures à jours                     |
+-----------------------------------------------------------------------+
                                  |
                    Si le format, la latence ou le coût échouent
                                  v
+-----------------------------------------------------------------------+
| TIER 2 : Adaptation spécialisée                                       |
| Résout : format strict, style stable, classification, grammaire        |
| Coût : moyen | Délai : jours à semaines                               |
+-----------------------------------------------------------------------+
                                  |
                    Si les capacités de base sont absentes
                                  v
+-----------------------------------------------------------------------+
| TIER 1 : Entraînement initial                                         |
| Résout : nouveau langage, domaine fondamental, capacité inexistante    |
| Coût : très élevé | Délai : mois                                      |
+-----------------------------------------------------------------------+

Le Tier 3 considère le modèle comme un moteur de raisonnement et de langage déjà compétent. On ne lui demande pas de porter l’état du système. On lui fournit des outils, des schémas, un contexte limité, une mémoire de session et des règles de validation. La logique critique reste dans le logiciel.

Le Tier 2 devient utile lorsque le modèle comprend déjà la tâche, mais échoue régulièrement sur la forme. Par exemple : produire un JSON très strict, respecter une grammaire de sortie, classer rapidement des tickets selon une taxonomie stable, réduire un prompt trop long ou stabiliser un style rédactionnel. Le fine-tuning sert alors à apprendre une procédure ou une forme, pas à mémoriser des faits métier.

Le Tier 1 n’est justifié que si les modèles disponibles ne possèdent pas la capacité fondamentale recherchée. Cela peut concerner une langue très peu représentée, un langage propriétaire, un domaine scientifique très spécialisé ou un contexte où l’organisation possède un volume massif de données propres et une équipe capable d’entraîner, évaluer et maintenir un modèle de base. Ce niveau n’est pas une optimisation de confort. C’est un programme de recherche et d’infrastructure.

Critère d’évaluationTier 3 : orchestrationTier 2 : fine-tuningTier 1 : from scratch
Nature de la donnéeDynamique, sensible, dépendante du contexteStable, répétitive, stylistique ou structurelleFondamentale, massive, rare ou inexistante sur le marché
Volume utileQuelques exemples, schémas, règles, jeux de test1 000 à 100 000 exemples propresTrès grands corpus spécialisés
Coût d’entréeFaible, souvent à l’usageMoyen, avec coûts d’entraînement et d’hébergementTrès élevé, avec calcul, recherche et MLOps
Compétence dominanteIngénierie logicielleData engineering et évaluation MLRecherche deep learning et infrastructure GPU
Risque principalMauvaise orchestration ou mauvais outillageSurapprentissage, dérive, dette d’évaluationCoût, délai, gouvernance, incertitude scientifique
Bon usageAgents métier, recherche documentaire, workflowsFormat strict, style, classification rapideCapacité absente des modèles existants

La thèse est donc précise : le vrai coût d’un LLM se décide au moment où l’on place la frontière entre modèle, données, outils et logiciel. Si cette frontière est mal dessinée, le projet paie en GPU ce qu’il aurait dû résoudre en architecture.

Décomposer la décision avant de toucher au modèle

Avant toute ligne de fine-tuning, il faut décomposer le besoin en séquence. Cette étape évite les décisions spectaculaires mais fragiles. Elle force l’équipe à séparer ce qui doit être généré, récupéré, validé, exécuté ou refusé.

Vue de la décision d'architecture : Le vrai coût d'un LLM se décide avant l'entraînement
Vue de la décision d'architecture : Le vrai coût d'un LLM se décide avant l'entraînement

La décomposition minimale tient en sept questions.

  1. Quelle est l’intention utilisateur ?

Le système doit-il répondre, rechercher, classer, rédiger, exécuter une action, ou demander une précision ?

  1. Quelle donnée est nécessaire ?

Est-elle statique, dynamique, confidentielle, réglementée, calculée, ou dépendante d’une permission ?

  1. Où vit la donnée fiable ?

Dans une base SQL, un CRM, un ERP, un moteur documentaire, un cache, une API interne ou un fichier validé ?

  1. Quelle partie doit être déterministe ?

Les calculs, les permissions, les requêtes SQL, les changements d’état et les validations doivent généralement rester hors du modèle.

  1. Quelle partie peut être probabiliste ?

Reformulation, synthèse, priorisation, explication et aide à la décision peuvent être confiées au modèle si elles sont encadrées.

  1. Quel échec est acceptable ?

Un refus poli peut être acceptable. Une action erronée en base de données ne l’est pas.

  1. Comment mesure-t-on la réussite ?

Le projet doit avoir des critères observables : exactitude des appels d’outils, validité JSON, latence, coût par requête, taux de refus correct, absence de fuite de données.

Cette décomposition révèle souvent que le besoin initial n’est pas « entraîner un LLM », mais « construire un contrôleur fiable autour d’un LLM ». Dans le cas de l’inventaire, la séquence correcte ressemble à ceci :

ÉtapeResponsableSortie attendueÉchec à intercepter
Comprendre la demandeLLMIntention structuréeIntention ambiguë ou action non autorisée
Identifier l’outilOrchestrateur + LLMNom d’outil validéOutil inexistant ou mauvais domaine
Extraire les paramètresLLM sous schémaJSON conformeParamètre manquant, type invalide
Vérifier les droitsApplicationAutorisation expliciteUtilisateur non habilité
Exécuter la lectureService métierRésultat réelErreur SQL, donnée absente, timeout
Rédiger la réponseLLMRéponse claire et sourcée par le résultat outilInvention hors résultat
JournaliserApplicationTrace exploitableLogs incomplets ou données sensibles exposées

Cette séquence change le centre de gravité du projet. Le modèle ne décide pas seul. Il propose une intention et des arguments. Le logiciel valide, exécute et refuse si nécessaire. Le système devient testable avec des outils ordinaires : tests unitaires, tests d’intégration, fixtures, jeux d’évaluation, logs structurés.

L’artefact opérationnel : contrat d’outil, parseur et garde-fous

Le COH devient concret lorsqu’il produit un artefact exploitable par l’équipe : un contrat d’orchestration. Ce contrat décrit les outils disponibles, leurs paramètres, leurs contraintes, les règles de refus et la manière dont la réponse finale peut être formulée.

Voici un exemple de payload envoyé au contrôleur d’orchestration. L’objectif n’est pas d’injecter toute la base dans le prompt. L’objectif est de forcer le modèle à utiliser un outil documenté, limité et vérifiable.

{
  "session_id": "usr_99281a0e",
  "system_prompt": "Tu es un agent d’inventaire technique. Tu ne devines jamais les stocks. Tu utilises exclusivement l’outil get_inventory_status pour toute question de disponibilité. Si l’outil retourne une erreur ou une absence de donnée, tu le dis clairement sans inventer de quantité.",
  "user_message": "Est-ce qu’on a encore des disques SSD 2 To en rayon ?",
  "available_tools": [
    {
      "name": "get_inventory_status",
      "description": "Retourne le stock réel d’un composant à partir d’une description structurée.",
      "parameters": {
        "type": "object",
        "properties": {
          "item_type": {
            "type": "string",
            "enum": ["SSD", "HDD", "RAM"]
          },
          "capacity_gb": {
            "type": "integer"
          }
        },
        "required": ["item_type", "capacity_gb"],
        "additionalProperties": false
      }
    }
  ],
  "context_memory": [
    {
      "role": "assistant",
      "content": "Session démarrée. Prêt à interroger les stocks."
    }
  ]
}

Le parseur de sortie joue le rôle de garde-fou. Il ne se contente pas de lire la réponse. Il vérifie que le modèle respecte le contrat. Si l’utilisateur demande un stock, le modèle doit appeler l’outil. S’il répond directement, la transaction est rejetée.

class ContractViolation(Exception):
    pass

def validate_llm_output(response_payload, user_message):
    tool_calls = response_payload.get("tool_calls", [])
    content = response_payload.get("content", "")

    asks_inventory = any(
        marker in user_message.lower()
        for marker in ["stock", "disponible", "en rayon", "reste"]
    )

    if asks_inventory and not tool_calls:
        raise ContractViolation(
            "Question d’inventaire sans appel à l’outil get_inventory_status."
        )

    for call in tool_calls:
        if call.get("name") != "get_inventory_status":
            raise ContractViolation("Outil non autorisé pour cette intention.")

        args = call.get("arguments", {})
        if args.get("item_type") not in ["SSD", "HDD", "RAM"]:
            raise ContractViolation("Type de composant non reconnu.")

        if not isinstance(args.get("capacity_gb"), int):
            raise ContractViolation("Capacité invalide ou absente.")

    if asks_inventory and "probablement" in content.lower():
        raise ContractViolation("Réponse spéculative sur une donnée métier.")

    return response_payload

Ce code est volontairement simple. Sa valeur ne vient pas de sa sophistication, mais de sa position dans l’architecture. Il transforme une sortie probabiliste en décision contrôlée. Il interdit au modèle de franchir seul la frontière entre langage et action métier.

Pour rendre cet artefact exploitable en équipe, le contrat doit être versionné comme du code. Chaque outil a un propriétaire, une version, une documentation courte, des exemples valides, des exemples invalides et des tests de non-régression. Une modification de schéma doit déclencher les mêmes réflexes qu’une modification d’API publique.

Élément du contratRôleExemple de règle
Nom d’outilRéduit l’ambiguïtéget_inventory_status ne modifie jamais la base
DescriptionOriente le choix du modèleMentionner le domaine exact, éviter les synonymes trop larges
Schéma JSONContraint les paramètresadditionalProperties: false
Règles métierProtègent l’exécutionInterdire les lectures hors périmètre utilisateur
Refus attendusStabilisent les cas limitesDemander une précision si la capacité manque
TestsMesurent la robustesseVérifier 50 à 200 scénarios représentatifs

Ce que cette frontière change dans le coût réel

La séparation entre modèle, outils et données transforme l’économie du projet. Le coût n’est plus seulement le prix d’un appel API ou d’une heure GPU. Il devient le coût total de changement, de test, d’incident et de maintenance.

Avec une architecture centrée sur le fine-tuning, une règle métier change difficilement. Si le schéma de l’inventaire évolue, il faut reconstituer un dataset, relancer un entraînement, mesurer les régressions et redéployer un artefact ML. Même si l’entraînement coûte peu en calcul brut, le coût humain devient élevé. Chaque changement crée de l’incertitude.

Avec le COH, une règle métier change dans l’outil, le schéma ou le contrôleur. Le modèle frontal reste interchangeable. L’équipe peut tester la logique avec son pipeline habituel. Elle peut simuler des erreurs, vérifier les refus, mesurer les appels d’outils, comparer plusieurs modèles et remplacer un fournisseur sans réécrire toute l’application.

Le levier d’équipe change également. Le projet n’exige pas immédiatement une équipe de recherche en deep learning. Il exige d’abord de bons ingénieurs backend, une discipline de contrats, des tests, une observabilité correcte et une compréhension claire des données. Les compétences ML deviennent utiles plus tard, lorsque les limites de l’orchestration sont démontrées par des mesures, pas supposées par intuition.

DécisionCoût apparentCoût réel cachéAlternative COH
Fine-tuner pour apprendre les stocksQuelques dizaines à milliers de dollarsDonnées périmées, réentraînements, hallucinationsAppel d’outil vers la base de stock
Fine-tuner pour apprendre le tonCoût modéréSurapplication du style, perte de robustessePrompt système, exemples, éventuellement Tier 2 ciblé
Héberger un modèle dédiéMaîtrise apparenteGPU idle, maintenance, supervisionAPI managée ou modèle interchangeable
Injecter le schéma SQL completSimple à prototyperPrompt long, fuite de structure, erreurs de générationOutils limités par intention
Laisser le modèle écrire du SQL libreFlexibleRisque de requêtes invalides ou dangereusesRequêtes paramétrées derrière services métier

Cela ne signifie pas que le fine-tuning est inutile. Il devient au contraire plus propre lorsqu’il intervient après l’orchestration. Les échecs du Tier 3 fournissent alors un dataset de qualité : prompts réels, sorties attendues, cas limites, erreurs de format, confusions d’outils. Le Tier 2 n’est plus un pari. Il devient une optimisation mesurée.

Le bon signal pour envisager le Tier 2 n’est pas « nous avons beaucoup de documents internes ». Le bon signal est : « malgré un contrat clair, un modèle adapté, des outils bien décrits et un jeu d’évaluation solide, nous échouons encore sur un comportement stable et mesurable ».

Critères de rejet et passage en production

Une architecture LLM doit avoir des critères de rejet explicites. Sans eux, l’équipe accepte progressivement des comportements flous, puis découvre trop tard qu’elle ne sait ni expliquer ni corriger les erreurs.

Rejetez immédiatement une architecture qui tente d’intégrer des données nominatives, des variables d’affaires volatiles ou des secrets dans les poids d’un modèle. Les données personnelles doivent être protégées par des contrôles applicatifs. Les prix, stocks, statuts et permissions doivent être lus depuis des systèmes de référence. Les secrets doivent rester dans un gestionnaire dédié, jamais dans un prompt.

Rejetez aussi les architectures qui laissent le modèle exécuter librement du SQL, choisir des endpoints non déclarés ou modifier un état métier sans validation applicative. Un LLM peut proposer une action. Il ne doit pas posséder seul le droit de l’exécuter.

Les critères de production doivent être concrets :

CritèreSeuil de départ raisonnableAction si échec
Appel correct du bon outil95 % ou plus sur le jeu d’évaluationClarifier les descriptions d’outils ou changer de modèle
JSON valide99 % ou plusAjouter validation stricte, retries contrôlés ou fine-tuning ciblé
Réponse sans invention après outil98 % ou plusInterdire les formulations spéculatives dans le parseur
Latence utilisateurSelon le produit, souvent sous 2 secondesRéduire contexte, choisir modèle plus rapide, mettre en cache
Coût par requêteDéfini par le cas d’usageRéduire tokens, router vers modèles moins chers
Taux de refus correctMesuré sur cas ambigus et non autorisésAméliorer règles de refus et tests adversariaux
Traçabilité100 % des décisions critiques journaliséesBloquer la mise en production

La mise en production doit ensuite suivre une boucle courte.

  1. Construire un jeu de 50 à 200 scénarios représentatifs : demandes simples, demandes ambiguës, erreurs d’entrée, utilisateurs non autorisés, données absentes, cas limites.
  2. Journaliser le triplet intention détectée, outil sélectionné, arguments transmis, sans exposer de secret ni donnée inutile.
  3. Mesurer les erreurs par catégorie : mauvais outil, mauvais paramètre, absence de refus, hallucination après outil, latence excessive.
  4. Corriger d’abord le contrat, les descriptions d’outils, les schémas et les validations.
  5. Comparer plusieurs modèles frontaux avant de conclure que le fine-tuning est nécessaire.
  6. Ne passer au Tier 2 que si l’échec est stable, mesuré et lié à la forme ou au comportement du modèle, pas à l’absence d’un bon outil.
  7. Garder un chemin de repli : refus contrôlé, modèle alternatif, désactivation d’un outil risqué, alerte humaine.

La propriété de la boucle doit être claire. L’équipe d’ingénierie logicielle possède l’orchestration, les contrats, les outils, les tests et les journaux. Le modèle de langage reste un composant interchangeable. Si l’application est tellement couplée à un fournisseur ou à un modèle qu’il faut plusieurs jours pour le remplacer, l’abstraction est trop faible.

Le coût d’un LLM ne se décide donc pas au moment de louer un GPU. Il se décide plus tôt, lorsque l’équipe choisit ce qu’elle met dans les poids, ce qu’elle garde dans les systèmes de référence et ce qu’elle rend vérifiable par le logiciel. La décision senior consiste à résister au réflexe d’entraînement tant que la panne relève encore d’un contrat, d’un outil, d’un schéma ou d’un garde-fou.