Réduisez les coûts des LLM : stratégies d'optimisation des tokens

Réduisez les coûts LLM de 80 % grâce à une optimisation intelligente des tokens

Sommaire

L’optimisation des tokens est la compétence critique qui distingue les applications LLM rentables des expériences coûteuses.

Avec les coûts API qui augmentent linéairement en fonction de l’utilisation des tokens, comprendre et mettre en œuvre des stratégies d’optimisation peut réduire les dépenses de 60 à 80 % tout en maintenant la qualité.

architecture intelligente

Compréhension de l’économie des tokens

Avant d’optimiser, vous devez comprendre comment les tokens et le tarifage fonctionnent chez différents fournisseurs LLM.

Bases des tokens

Les tokens sont les unités fondamentales que les LLM traitent – approximativement équivalents à 4 caractères ou 0,75 mots en anglais. La chaîne « Hello, world ! » contient environ 4 tokens. Différents modèles utilisent des tokenizers différents (GPT utilise tiktoken, Claude utilise le leur), donc les comptages de tokens varient légèrement entre les fournisseurs.

Comparaison des modèles de tarification

Tarification OpenAI (au 2025) :

  • GPT-4 Turbo : 0,01 $ d’entrée / 0,03 $ de sortie par 1 000 tokens
  • GPT-3.5 Turbo : 0,0005 $ d’entrée / 0,0015 $ de sortie par 1 000 tokens
  • GPT-4o : 0,005 $ d’entrée / 0,015 $ de sortie par 1 000 tokens

Tarification Anthropic :

  • Claude 3 Opus : 0,015 $ d’entrée / 0,075 $ de sortie par 1 000 tokens
  • Claude 3 Sonnet : 0,003 $ d’entrée / 0,015 $ de sortie par 1 000 tokens
  • Claude 3 Haiku : 0,00025 $ d’entrée / 0,00125 $ de sortie par 1 000 tokens

Pour une comparaison complète des fournisseurs LLM en nuage incluant des tarifs détaillés, des fonctionnalités et des cas d’utilisation, consultez notre guide dédié.

Insight clé : Les tokens de sortie coûtent 2 à 5 fois plus que les tokens d’entrée. Limiter la longueur de sortie a un impact disproportionné sur les coûts.

Ingénierie de prompts pour l’efficacité

Une ingénierie de prompts efficace réduit considérablement la consommation de tokens sans sacrifier la qualité.

1. Éliminer la redondance

Exemple mauvais (127 tokens) :

Vous êtes un assistant utile. Veuillez m'aider avec la tâche suivante.
Je voudrais que vous analysiez le texte suivant et me fournissiez
un résumé. Voici le texte que je voudrais que vous résumiez :
[text]
Veuillez fournir un résumé concis des points principaux.

Optimisé (38 tokens) :

Résumez les points clés :
[text]

Économies : Réduction de 70 % des tokens, qualité de sortie identique.

2. Utiliser des formats structurés

Les formats JSON et les sorties structurées réduisent le gaspillage de tokens causé par le langage naturel verbeux.

Au lieu de :

Veuillez extraire le nom, l'âge et l'occupation de cette personne
et formater votre réponse clairement.

Utilisez :

Extraire en JSON : {nom, âge, occupation}
Texte : [entrée]

3. Optimisation de l’apprentissage par exemple

Les exemples par exemple sont puissants mais coûteux. Optimisez en :

  • Utiliser le minimum d’exemples nécessaires (1 à 3 généralement suffisants)
  • Garder les exemples concis – supprimer les mots inutiles
  • Partager les préfixes communs – réduire les instructions répétées
# Prompt optimisé avec quelques exemples
prompt = """Classifiez le sentiment (positif/négatif) :
Texte : "Produit excellent ! " -> positif
Texte : "Déçu" -> négatif
Texte : "{input_utilisateur}" ->"""

Pour plus de modèles d’optimisation Python et de raccourcis de syntaxe, consultez notre feuille de triche Python.

Stratégies de mise en cache du contexte

Le mise en cache du contexte est la stratégie d’optimisation la plus efficace pour les applications avec du contenu statique répétitif.

Fonctionnement du mise en cache du contexte

Les fournisseurs comme OpenAI et Anthropic mettent en cache les préfixes de prompt qui apparaissent dans plusieurs demandes. Les parties mises en cache coûtent 50 à 90 % moins que les tokens normaux.

Exigences :

  • Contenu minimum mis en cache : 1024 tokens (OpenAI) ou 2048 tokens (Anthropic)
  • Durée de vie du cache (TTL) : 5 à 60 minutes selon le fournisseur
  • Le contenu doit être identique et apparaître au début du prompt

Exemple d’implémentation

from openai import OpenAI

client = OpenAI()

# Message système mis en cache entre les demandes
SYSTEM_PROMPT = """Vous êtes un assistant client pour TechCorp.
Politiques de l'entreprise :
[Document de politique important - 2000 tokens]
"""

# Cela est mis en cache automatiquement
response = client.chat.completions.create(
    model="gpt-4-turbo",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": "Comment puis-je retourner un article ?"}
    ]
)

# Les appels ultérieurs dans la durée de vie du cache utilisent le prompt système mis en cache
# Payant uniquement pour le message utilisateur + sortie

Impact réel : Les applications avec des bases de connaissances ou des instructions longues voient une réduction de coûts de 60 à 80 %.

Stratégie de sélection de modèles

Utiliser le bon modèle pour chaque tâche est crucial pour l’optimisation des coûts.

L’escalier des modèles

  1. GPT-4 / Claude Opus - Raisonnement complexe, tâches créatives, précision critique
  2. GPT-4o / Claude Sonnet - Performance/cout équilibré, usage général
  3. GPT-3.5 / Claude Haiku - Tâches simples, classification, extraction
  4. Modèles plus petits affinés - Tâches répétitives spécialisées

Modèle de routage

def route_request(task_complexity, user_query):
    """Route vers le modèle approprié en fonction de la complexité"""
    
    # Tâche simple - utiliser Haiku
    if task_complexity == "simple":
        return call_llm("claude-3-haiku", user_query)
    
    # Modérée - utiliser Sonnet
    elif task_complexity == "modérée":
        return call_llm("claude-3-sonnet", user_query)
    
    # Raisonnement complexe - utiliser Opus
    else:
        return call_llm("claude-3-opus", user_query)

Étude de cas : Un chatbot de service client qui routait 80 % des requêtes vers GPT-3.5 et 20 % vers GPT-4 a réduit les coûts de 75 % par rapport à l’utilisation de GPT-4 pour tout.

Traitement par lots

Pour les charges de travail non urgentes, le traitement par lots offre une réduction de 50 % chez la plupart des fournisseurs.

API de traitement par lots d’OpenAI

from openai import OpenAI
client = OpenAI()

# Créer un fichier de lot
batch_requests = [
    {"custom_id": f"request-{i}", 
     "method": "POST",
     "url": "/v1/chat/completions",
     "body": {
         "model": "gpt-3.5-turbo",
         "messages": [{"role": "user", "content": query}]
     }}
    for i, query in enumerate(queries)
]

# Soumettre le lot (réduction de 50 %, traitement en 24 heures)
batch = client.batches.create(
    input_file_id=upload_batch_file(batch_requests),
    endpoint="/v1/chat/completions",
    completion_window="24h"
)

Cas d’utilisation :

  • Étiquetage et annotation de données
  • Génération de contenu pour blogs/SEO
  • Génération de rapports
  • Traductions en lots
  • Génération synthétique de jeux de données

Techniques de contrôle de sortie

Puisque les tokens de sortie coûtent 2 à 5 fois plus, le contrôle de la longueur de sortie est critique.

1. Définir un nombre maximum de tokens

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    max_tokens=150  # Limite dure pour éviter les coûts excessifs
)

2. Utiliser des séquences d’arrêt

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    stop=["FIN", "\n\n\n"]  # Arrêter aux marqueurs
)

3. Demander des formats concis

Ajoutez des instructions comme :

  • “Répondez en moins de 50 mots”
  • “Fournissez uniquement des points en liste”
  • “Retournez uniquement du JSON, aucune explication”

Streaming pour une meilleure UX

Bien que le streaming ne réduise pas les coûts, il améliore la performance perçue et permet une terminaison précoce.

stream = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        token = chunk.choices[0].delta.content
        print(token, end="")
        
        # Terminaison précoce si la réponse s'éloigne
        if undesired_pattern(token):
            break

Optimisation RAG

La génération augmentée par récupération (RAG) ajoute du contexte, mais un RAG non optimisé gaspille des tokens.

Modèle RAG efficace

def optimized_rag(query, vector_db):
    # 1. Récupérer les morceaux pertinents
    chunks = vector_db.search(query, top_k=3)  # Pas trop nombreux
    
    # 2. Comprimer les morceaux - supprimer la redondance
    compressed = compress_chunks(chunks)  # Compression personnalisée
    
    # 3. Tronquer à la limite de tokens
    context = truncate_to_tokens(compressed, max_tokens=2000)
    
    # 4. Prompt structuré
    prompt = f"Contexte : \n{context}\n\nQ : {query}\nA :"
    
    return call_llm(prompt)

Techniques d’optimisation :

  • Utiliser le regroupement sémantique (pas de taille fixe)
  • Supprimer le formatage Markdown des morceaux récupérés
  • Implémenter un classement secondaire pour obtenir le contenu le plus pertinent
  • Considérer la synthèse de morceaux pour les documents volumineux

Mise en cache des réponses

Mettez en cache les requêtes identiques ou similaires pour éviter les appels API.

Implémentation avec Redis

import redis
import hashlib
import json

redis_client = redis.Redis()

def cached_llm_call(prompt, model="gpt-4", ttl=3600):
    # Créer une clé de cache à partir du prompt + modèle
    cache_key = hashlib.md5(
        f"{model}:{prompt}".encode()
    ).hexdigest()
    
    # Vérifier le cache
    cached = redis_client.get(cache_key)
    if cached:
        return json.loads(cached)
    
    # Appeler LLM
    response = call_llm(model, prompt)
    
    # Mettre en cache le résultat
    redis_client.setex(
        cache_key, 
        ttl, 
        json.dumps(response)
    )
    
    return response

Mise en cache sémantique : Pour les requêtes similaires (pas identiques), utilisez des embeddings vectoriels pour trouver les réponses mises en cache.

Suivi et analyse

Suivez l’utilisation des tokens pour identifier les opportunités d’optimisation.

Métriques essentielles

class SuiviTokens:
    def __init__(self):
        self.métriques = {
            'tokens_totaux': 0,
            'tokens_entrée': 0,
            'tokens_sortie': 0,
            'coût': 0.0,
            'requêtes': 0
        }
    
    def suivre_demande(self, réponse, modèle):
        usage = réponse.usage
        self.métriques['tokens_entrée'] += usage.prompt_tokens
        self.métriques['tokens_sortie'] += usage.completion_tokens
        self.métriques['tokens_totaux'] += usage.total_tokens
        self.métriques['coût'] += calculer_coût(usage, modèle)
        self.métriques['requêtes'] += 1
    
    def rapport(self):
        return {
            'moyenne_tokens_par_demande': 
                self.métriques['tokens_totaux'] / self.métriques['requêtes'],
            'coût_total': self.métriques['coût'],
            'ratio_entrée_sortie': 
                self.métriques['tokens_entrée'] / self.métriques['tokens_sortie']
        }

Alertes de coût

Configurez des alertes lorsque l’utilisation dépasse les seuils :

def vérifier_seuil_coût(coût_jour, seuil=100):
    if coût_jour > seuil:
        envoyer_alerte(f"Coût quotidien ${coût_jour} dépassé ${seuil}")

Techniques avancées

1. Modèles de compression de prompts

Utilisez des modèles dédiés pour compresser les prompts :

  • LongLLMLingua
  • AutoCompressors
  • Tokens de compression appris

Ces modèles peuvent atteindre des rapports de compression de 10 fois tout en maintenant 90 % + de performance de tâche.

2. Décodage spéculatif

Exécutez un petit modèle en parallèle d’un grand modèle pour prédire les tokens, réduisant ainsi les appels de grands modèles. Généralement 2 à 3 fois plus rapide et moins coûteux pour une qualité similaire.

3. Quantification

Pour les modèles auto-hébergés, la quantification (4 bits, 8 bits) réduit la mémoire et le calcul :

  • 4 bits : ~75 % de réduction de mémoire, perte de qualité minimale
  • 8 bits : ~50 % de réduction de mémoire, perte de qualité négligeable

Si vous exécutez des LLM localement, Ollama fournit une plateforme excellente pour déployer des modèles quantifiés avec un minimum de configuration. Pour la sélection du matériel et les benchmarks de performance, notre comparaison NVIDIA DGX Spark vs Mac Studio vs RTX-4080 montre la performance réelle sur différentes configurations matérielles exécutant de grands modèles quantifiés.

Checklist d’optimisation des coûts

  • Profil de l’utilisation actuelle des tokens et des coûts par point de terminaison
  • Audit des prompts pour la redondance – supprimer les mots inutiles
  • Implémenter le mise en cache du contexte pour le contenu statique > 1K tokens
  • Configurer le routage des modèles (petit pour simple, grand pour complexe)
  • Ajouter des limites max_tokens à toutes les demandes
  • Implémenter le mise en cache des réponses pour les requêtes identiques
  • Utiliser l’API de traitement par lots pour les charges de travail non urgents
  • Activer le streaming pour une meilleure UX
  • Optimiser RAG : moins de morceaux, meilleur classement
  • Suivre avec le suivi des tokens et les alertes de coût
  • Considérer l’affinage pour les tâches répétitives
  • Évaluer les modèles plus petits (Haiku, GPT-3.5) pour la classification

Étude de cas réelle

Scénario : Chatbot de service client, 100 000 demandes/mois

Avant optimisation :

  • Modèle : GPT-4 pour toutes les demandes
  • Tokens d’entrée moyens : 800
  • Tokens de sortie moyens : 300
  • Coût : 100 000 × (800 × 0,00003 + 300 × 0,00006) = 4 200 $/mois

Après optimisation :

  • Routage des modèles : 80 % GPT-3.5, 20 % GPT-4
  • Mise en cache du contexte : 70 % des prompts mis en cache
  • Compression des prompts : réduction de 40 %
  • Mise en cache des réponses : taux de cache de 15 %

Résultats :

  • 85 % des demandes évitent GPT-4
  • 70 % bénéficient de la réduction du cache
  • 40 % moins de tokens d’entrée
  • Coût effectif : 780 $/mois
  • Économies : 81 % (3 420 $/mois)

Liens utiles

Conclusion

L’optimisation des tokens transforme l’économie des LLM de prohibitivement coûteuse à scalable de manière durable. En mettant en œuvre la compression des prompts, le mise en cache du contexte, la sélection intelligente des modèles et le mise en cache des réponses, la plupart des applications obtiennent une réduction de coûts de 60 à 80 % sans compromis sur la qualité.

Commencez par les gains rapides : auditez vos prompts, activez le mise en cache du contexte et routez les tâches simples vers des modèles plus petits. Suivez religieusement votre utilisation de tokens – ce qui est mesuré est optimisé. La différence entre une application LLM rentable et une coûteuse n’est pas la technologie – c’est la stratégie d’optimisation.

Articles liés