Aller au contenu principal

Déployer un modèle fine-tuné

Du développement à la production

Votre modèle fine-tuné est évalué et approuvé. Il est temps de le déployer en production. Cette leçon couvre les bonnes pratiques pour un déploiement fiable, sécurisé et maintenable.

Utiliser votre modèle fine-tuné

Le modèle fine-tuné s’utilise exactement comme n’importe quel modèle OpenAI. La seule différence est le nom du modèle :

from openai import OpenAI

client = OpenAI()

# Le modèle fine-tuné a un identifiant unique
MODELE_PRODUCTION = "ft:gpt-5.3-mini:votre-org::mon-assistant-v3:abc12345"

response = client.responses.create(
    model=MODELE_PRODUCTION,
    input="Bonjour, j'ai un problème avec ma commande #12345."
)

print(response.output_text)

Architecture de déploiement

Configuration centralisée

Ne codez jamais le nom du modèle en dur dans votre application. Utilisez une configuration centralisée :

import os

class Config:
    """Configuration centralisée des modèles."""

    # Variable d'environnement pour le modèle en production
    MODEL_ID = os.environ.get(
        "OPENAI_FT_MODEL",
        "gpt-5.3-mini"  # fallback sur le modèle de base
    )

    # Prompt système (peut être vide si intégré dans le fine-tuning)
    SYSTEM_PROMPT = os.environ.get("SYSTEM_PROMPT", "")

    # Paramètres de génération
    MAX_TOKENS = int(os.environ.get("MAX_TOKENS", "1024"))
    TEMPERATURE = float(os.environ.get("TEMPERATURE", "0.7"))

Service wrapper

from openai import OpenAI

class AssistantService:
    """Service encapsulant les appels au modèle fine-tuné."""

    def __init__(self):
        self.client = OpenAI()
        self.model = Config.MODEL_ID

    def repondre(self, question: str, contexte: str = "") -> str:
        """Génère une réponse."""
        input_msg = question
        if contexte:
            input_msg = f"Contexte : {contexte}\n\nQuestion : {question}"

        try:
            response = self.client.responses.create(
                model=self.model,
                input=input_msg,
                max_output_tokens=Config.MAX_TOKENS,
                temperature=Config.TEMPERATURE
            )
            return response.output_text

        except Exception as e:
            # Fallback sur le modèle de base en cas d'erreur
            return self._fallback(input_msg, str(e))

    def _fallback(self, input_msg: str, erreur: str) -> str:
        """Fallback sur le modèle de base."""
        print(f"Fallback activé : {erreur}")
        response = self.client.responses.create(
            model="gpt-5.3-mini",
            instructions=Config.SYSTEM_PROMPT,
            input=input_msg
        )
        return response.output_text

Gestion des erreurs en production

Fallback automatique

Si votre modèle fine-tuné est temporairement indisponible, basculez automatiquement sur le modèle de base :

import time

def appel_resilient(
    client: OpenAI,
    modele_principal: str,
    modele_fallback: str,
    input_msg: str,
    max_retries: int = 3
) -> dict:
    """Appel résilient avec retry et fallback."""

    for tentative in range(max_retries):
        try:
            response = client.responses.create(
                model=modele_principal,
                input=input_msg,
                timeout=30
            )
            return {
                "reponse": response.output_text,
                "modele_utilise": modele_principal,
                "fallback": False
            }
        except Exception as e:
            print(f"Tentative {tentative + 1} échouée : {e}")
            if tentative < max_retries - 1:
                time.sleep(2 ** tentative)  # backoff exponentiel

    # Fallback
    try:
        response = client.responses.create(
            model=modele_fallback,
            input=input_msg
        )
        return {
            "reponse": response.output_text,
            "modele_utilise": modele_fallback,
            "fallback": True
        }
    except Exception as e:
        return {"erreur": str(e), "fallback": True}

Logging et monitoring

import logging
import datetime

logger = logging.getLogger("fine_tuning_prod")

def log_appel(
    modele: str,
    input_msg: str,
    output: str,
    latence_ms: float,
    fallback: bool
):
    """Log structuré pour chaque appel en production."""
    logger.info(
        "appel_modele",
        extra={
            "modele": modele,
            "input_tokens": len(input_msg.split()),
            "output_tokens": len(output.split()),
            "latence_ms": latence_ms,
            "fallback": fallback,
            "timestamp": datetime.datetime.now().isoformat()
        }
    )

Rate limiting et quotas

Les modèles fine-tunés partagent les mêmes limites de taux que les modèles de base. Gérez vos quotas :

from openai import RateLimitError
import time

def appel_avec_rate_limit(client, modele, input_msg, max_wait=60):
    """Gère le rate limiting avec attente progressive."""
    wait = 1
    while wait <= max_wait:
        try:
            return client.responses.create(
                model=modele,
                input=input_msg
            )
        except RateLimitError:
            print(f"Rate limit atteint, attente {wait}s...")
            time.sleep(wait)
            wait *= 2

    raise Exception("Rate limit persistant — vérifiez vos quotas")

Variables d’environnement

# .env (ne pas committer)
OPENAI_API_KEY=sk-...
OPENAI_FT_MODEL=ft:gpt-5.3-mini:org::suffix:abc12345
OPENAI_FT_MODEL_FALLBACK=gpt-5.3-mini
SYSTEM_PROMPT="Vous êtes un assistant support client professionnel."
MAX_TOKENS=1024
TEMPERATURE=0.7

Checklist de déploiement

  • Le modèle est évalué et approuvé (score > seuil défini)
  • Le nom du modèle est dans une variable d’environnement, pas en dur
  • Un mécanisme de fallback est en place
  • Le logging est activé (modèle utilisé, latence, tokens)
  • Le rate limiting est géré
  • Les alertes sont configurées (taux d’erreur, latence P95)
  • Le rollback est documenté et testable

Points clés à retenir

  • Utilisez des variables d’environnement pour le nom du modèle
  • Implémentez toujours un fallback sur le modèle de base
  • Loggez chaque appel avec le modèle utilisé et la latence
  • Gérez le rate limiting avec un backoff exponentiel
  • Testez votre mécanisme de fallback avant de déployer