Accéder au contenu principal

DeepSeek V3.2 : Un guide avec un projet de démonstration

Découvrez DeepSeek-V3.2-Exp, son nouveau mécanisme d'attention clairsemée, comment il réduit les coûts API et améliore la gestion des contextes longs, et comment l'utiliser dans vos propres projets.
· 12 min lire

Explorez l'IA

DeepSeek vient de publier la version 3.2-Exp, un modÚle expérimental qui réduit de plus de moitié les coûts liés à l'API. Si vous avez déjà travaillé avec des modÚles linguistiques de grande envergure, vous savez que le traitement de contextes longs peut rapidement devenir coûteux. Cette nouvelle version résout ce problÚme grùce à une technique appelée «DeepSeek Sparse Attention » ( ).

Dans ce tutoriel, je vais vous expliquer en quoi la version 3.2 diffÚre des versions précédentes de DeepSeek, comment fonctionne l'attention clairsemée en arriÚre-plan et comment utiliser le modÚle dans vos projets. Nous aborderons les principes fondamentaux des appels API et créerons un projet de démonstration illustrant les domaines dans lesquels ce modÚle est le plus efficace.

À la fin, vous aurez dĂ©veloppĂ© une application Streamlit qui compare les coĂ»ts de diffĂ©rents LLM, y compris DeepSeek v3.2 :

Interface Multi-Document Research Assistant affichant la barre latérale avec les documents chargés (57 204 tokens), quatre cases à cocher pour la sélection des modÚles GPT-5, Claude Sonnet 4.5, DeepSeek v3.2-Exp et DeepSeek v3.1-Terminus, ainsi qu'une zone de saisie des questions.

Qu'est-ce que DeepSeek V3.2 ?

Commençons par présenter DeepSeek et les modifications apportées dans cette version.

La famille de modĂšles DeepSeek

DeepSeek est une entreprise d'intelligence artificielle open source basée en Chine qui développe de grands modÚles linguistiques sous licence MIT. Leurs modÚles rivalisent avec GPT-5 et Claude en matiÚre de raisonnement, de codage et de tùches générales. La société a publié plusieurs versions au cours de l'année écoulée, notamment DeepSeek-V3 et DeepSeek-R1, qui ont attiré l'attention en raison de leurs performances élevées à des coûts inférieurs à ceux des alternatives à code source fermé.

Avant la version 3.2, la version la plus récente était v3.1-Terminus, un modÚle comportant 685 milliards de paramÚtres. Bien qu'il ait affiché des performances solides, le traitement de contextes longs restait coûteux. C'est là qu'intervient la nouvelle version expérimentale.

V3.2-Exp : La version expérimentale

DeepSeek a publié la version la version 3.2-Exp le 29 septembre 2025 (2025-09-29). Le préfixe « Exp » signifie « expérimental », ce qui indique que le modÚle est encore en cours de test et de perfectionnement. Ne vous attendez pas encore à une stabilité de niveau production, mais vous pouvez l'utiliser pour vos recherches et vos projets lorsque vous souhaitez tester les derniÚres fonctionnalités.

Le modĂšle est basĂ© sur la version 3.1-Terminus et conserve la mĂȘme architecture de paramĂštres 685B. Ce qui le distingue, c'est la maniĂšre dont il traite les informations en interne. Il utilise un format API compatible avec OpenAI. Par consĂ©quent, si vous avez dĂ©jĂ  utilisĂ© le SDK OpenAI, vous savez dĂ©jĂ  comment utiliser DeepSeek (je vous expliquerai Ă©galement dans cet article comment effectuer votre premier appel API).

La principale innovation : Coût et efficacité

Voici le changement majeur : DeepSeek a rĂ©duit les tarifs de son API de plus de 50 % par rapport Ă l' ion v3.1. Et les performances sont restĂ©es identiques. Vous bĂ©nĂ©ficiez de la mĂȘme qualitĂ© de rĂ©ponses Ă  un coĂ»t rĂ©duit de moitiĂ©.

Cette baisse de prix rĂ©sulte d'une amĂ©lioration technique appelĂ©e DeepSeek Sparse Attention (DSA). Au lieu de demander au modĂšle de prĂȘter attention Ă  chaque jeton de votre entrĂ©e (ce qui est coĂ»teux en termes de calcul), DSA se concentre de maniĂšre sĂ©lective sur ce qui est important. Nous examinerons comment cela fonctionne dans la section suivante.

Si vous souhaitez obtenir tous les détails techniques, DeepSeek a publié un rapport technique sur GitHub qui explique les modifications apportées à l'architecture et les résultats des tests de performance.

Qu'est-ce que DeepSeek Sparse Attention (DSA) ?

Avant d'aborder le code, examinons ce qui rend la version 3.2 d' e plus économique et plus rapide. La réponse réside dans la maniÚre dont le modÚle traite vos données.

Mécanismes d'attention dans les transformateurs : introduction rapide

Lorsque vous envoyez du texte à un modÚle linguistique, celui-ci divise votre saisie en tokens (grosso modo des mots ou des parties de mots). Le modÚle doit ensuite déterminer quels jetons sont liés les uns aux autres. Ce processus est appelé attention.

Dans les transformateurs traditionnels, transformateurs, chaque jeton examine tous les autres jetons. Si vous disposez de 1 000 jetons, chacun d'entre eux vérifie les 999 autres. Cela représente un million de comparaisons. Avec 10 000 jetons, vous disposez de 100 millions de comparaisons. Le calcul est quadratique: doublez la longueur de votre entrée et vous quadruplez le coût de calcul.

C'est pourquoi le traitement dans un contexte étendu peut s'avérer coûteux. Votre facture API augmente rapidement à mesure que vos documents s'allongent.

Ce que signifie « peu d'attention »

Tous les jetons n'ont pas besoin de prendre en compte tous les autres jetons. Lorsque vous lisez cette phrase en ce moment, vous ne relisez pas constamment chaque mot qui précÚde. Vous vous concentrez sur ce qui est pertinent.

Une attention limitĂ©e produit le mĂȘme effet. Au lieu de comparer chaque jeton Ă  tous les autres jetons, le modĂšle sĂ©lectionne de maniĂšre sĂ©lective les comparaisons pertinentes. Certaines approches plus anciennes incluent :

  • s d'attention Ă  blocs clairsemĂ©s: Divisez les jetons en blocs et ne permettez qu'aux blocs de s'occuper des blocs voisins.
  • s relatives Ă  l'attention locale aux fenĂȘtres: Chaque jeton ne considĂšre que les jetons situĂ©s Ă  une distance fixe.

Ces méthodes permettent d'économiser des ressources informatiques, mais elles sont rigides. Ils déterminent à l'avance quels jetons peuvent interagir, indépendamment du contenu réel de votre texte. Il est parfois nécessaire d'utiliser un mot au début d'un document pour faire le lien avec un élément à la fin. Les modÚles fixes peuvent passer à cÎté de cela.

Attention clairsemée DeepSeek (DSA) : Une approche détaillée

DSA adopte une approche diffĂ©rente. Au lieu d'utiliser des modĂšles fixes, il identifie quels tokens doivent rĂ©ellement ĂȘtre pris en compte les uns par rapport aux autres en fonction du contenu lui-mĂȘme. Le modĂšle sĂ©lectionne les connexions pertinentes en temps rĂ©el.

Voici comment cela fonctionne Ă  un niveau Ă©levĂ©. Au cours de la formation, DeepSeek a intĂ©grĂ© un mĂ©canisme de sĂ©lection Ă  chaque couche d'attention. Ce mĂ©canisme examine vos jetons et dĂ©termine quelles connexions d'attention mĂ©ritent d'ĂȘtre calculĂ©es. Il conserve les Ă©lĂ©ments importants et ignore le reste.

La sélection n'est pas aléatoire. Le modÚle a appris pendant la formation quels types de connexions sont importants pour différentes tùches. Lorsque vous envoyez une invite concernant du code, celle-ci se concentre sur des modÚles différents de ceux utilisés lorsque vous envoyez un document juridique.

Le rĂ©sultat : Le DSA rĂ©duit le nombre d'opĂ©rations d'attention sans compromettre la qualitĂ© du rĂ©sultat. Dans le rapport technique, DeepSeek dĂ©montre quela version 3.2 d' s affiche des performances quasi identiques Ă  celles de la version 3.1-Terminus lors des tests de performance, tout en nĂ©cessitant moins de calculs par jeton. Vous bĂ©nĂ©ficiez de la mĂȘme qualitĂ© de modĂšle pour environ la moitiĂ© du coĂ»t de l'API.

Pourquoi cela est-il important pour les développeurs ?

Voici ce que signifie concrĂštement le DSA :

  • RĂ©duction des coĂ»ts API: Vous payez moins pour des rĂ©ponses de mĂȘme qualitĂ©.
  • AmĂ©lioration de la gestion des contextes longs: Le modĂšle prend en charge une fenĂȘtre contextuelle de 128K jetons et traite ces entrĂ©es plus longues de maniĂšre plus Ă©conomique que les modĂšles sans attention clairsemĂ©e.
  • Inference plus rapide: Moins d'opĂ©rations signifie des temps de rĂ©ponse plus rapides

Les avantages sont particuliÚrement évidents dans les cas d'utilisation suivants :

  • Analyse simultanĂ©e de plusieurs documents
  • PrĂ©server le contexte dans les conversations prolongĂ©es
  • Traitement de bases de code volumineuses ou de documents techniques
  • RĂ©sumer des articles de recherche ou des contrats juridiques

Si votre application traite des entrĂ©es volumineuses, DSA fait une rĂ©elle diffĂ©rence. Vous ne faites pas que rĂ©aliser des Ă©conomies. Vous obtenez de meilleurs rĂ©sultats dans les tĂąches oĂč l'attention traditionnelle est difficile.

Effectuer votre premier appel DeepSeek V3.2

Maintenant que vous comprenez le fonctionnement de DSA, nous allons utiliser le modĂšle via son API.

Conditions préalables

Il est nécessaire que Python 3.8 ou une version plus récente soit installé sur votre ordinateur. Si vous débutez dans l'utilisation des LLM via des API, nous vous recommandons de consulter le guide DataCamp sur l'apprentissage de l'IA afin de vous familiariser avec les concepts fondamentaux. Nous proposons également un tutoriel sur l'API DeepSeek qui couvre les versions antérieures si vous souhaitez approfondir vos connaissances.

La bonne nouvelle : si vous avez déjà utilisé l'API d'OpenAI, vous savez déjà comment utiliser DeepSeek. Le format de l'API est identique.

Configuration de l'environnement

Tout d'abord, veuillez obtenir votre clé API à partir de platform.deepseek.com. Il vous sera nécessaire de créer un compte si vous n'en possédez pas déjà un.

Veuillez installer les paquets requis :

uv add openai python-dotenv

Veuillez créer un fichier .env dans le répertoire de votre projet et y ajouter votre clé API :

DEEPSEEK_API_KEY=your_api_key_here

Votre premier appel API

Voici un exemple simple utilisant le SDK OpenAI. La seule différence par rapport à l'utilisation de l'API d'OpenAI réside dans le paramÚtre base_url et votre clé API :

from openai import OpenAI
from dotenv import load_dotenv
import os

# Load environment variables from .env file
load_dotenv()

# Initialize OpenAI-compatible client with DeepSeek endpoint
client = OpenAI(
   api_key=os.getenv("DEEPSEEK_API_KEY"),
   base_url="https://api.deepseek.com"
)

# Send a chat completion request to DeepSeek v3.2
response = client.chat.completions.create(
   model="deepseek-chat",
   messages=[
       {"role": "user", "content": "Explain sparse attention in one sentence."}
   ]
)

# Print the model's response
print(response.choices[0].message.content)

Lorsque vous exécutez cette commande, vous obtiendrez une réponse similaire à celle-ci :

Sparse attention reduces computational cost by having each token attend to only a subset of relevant tokens rather than all tokens in a sequence.

Le modÚle de l'« deepseek-chat » (l'esprit qui ne pense pas) est le mode de fonctionnement de l'v3.2-Exp. Il traite votre demande et renvoie une réponse sans exposer les étapes de son raisonnement.

Utilisation du modĂšle de raisonnement

Si vous souhaitez consulter le processus de raisonnement du modÚle, veuillez utiliser deepseek-reasoner. Ce modÚle présente son raisonnement avant de vous fournir la réponse finale :

# Use deepseek-reasoner to see the model's reasoning process
response = client.chat.completions.create(
   model="deepseek-reasoner",
   messages=[
       {"role": "user", "content": "Which is larger: 9.11 or 9.8?"}
   ]
)

# Print both reasoning and final answer
print("Reasoning:", response.choices[0].message.reasoning_content)
print("Answer:", response.choices[0].message.content)

Cela produira un résultat similaire à celui-ci :

Reasoning: To compare 9.11 and 9.8, I need to look at the digits after the decimal point. 9.11 has digits 1 and 1 after the decimal, making it 9 + 0.11. Meanwhile, 9.8 is 9 + 0.8. Since 0.8 is greater than 0.11, 9.8 is the larger number.

Answer: 9.8 is larger than 9.11.

Le modÚle de raisonnement peut générer jusqu'à 64 000 jetons de contenu de raisonnement (valeur par défaut : 32 000) avant de produire la réponse finale. Veuillez noter que certains paramÚtres tels que temperature ou top_p ne sont pas pris en charge. L'API officielle de DeepSeek ne prend pas encore en charge le paramÚtre reasoning_effort permettant de contrÎler la profondeur du raisonnement (bien que certains fournisseurs tiers, tels que LangChain, l'aient ajouté à leurs intégrations).

L'objet de réponse respecte la structure d'OpenAI. Vous pouvez accéder au contenu via response.choices[0].message.content, vérifier l'utilisation des jetons avec response.usage et consulter le modÚle utilisé avec response.model.

Autres moyens d'accéder à DeepSeek v3.2

L'API n'est pas votre seule option. DeepSeek publie ses modĂšles en open source, vous pouvez donc les exĂ©cuter vous-mĂȘme.

Hugging Face: Le modĂšle est disponible Ă  l'adresse suivante : huggingface.co/deepseek-ai/DeepSeek-V3.2-Exp. Vous pouvez utiliser les fournisseurs d'infĂ©rence de Hugging Face pour exĂ©cuter le modĂšle sans avoir Ă  gĂ©rer vous-mĂȘme l'infrastructure, ou tĂ©lĂ©charger les poids pour une infĂ©rence locale. La solution locale est efficace si vous disposez du matĂ©riel nĂ©cessaire (pensez aux budgets des centres de donnĂ©es ou Ă  une petite ferme de GPU dans votre placard pour un modĂšle Ă  685 milliards de paramĂštres).

s sur le vLLM: Pour les déploiements auto-hébergés à grande échelle, vLLM offre une inférence optimisée avec la prise en charge de la version 3.2. Il est plus rapide que l'exécution du modÚle via des transformateurs standard et gÚre efficacement le traitement par lots. Veuillez utiliser cette option si vous déployez le modÚle en production et disposez d'une infrastructure solide pour le soutenir.

Quand utiliser chaque méthode:

  • Veuillez utiliser l'API si vous souhaitez une configuration rapide, si vous prĂ©fĂ©rez ne pas gĂ©rer l'infrastructure ou si vous avez des charges de travail variables.
  • Veuillez utiliser les fournisseurs d'infĂ©rence Hugging Face si vous souhaitez bĂ©nĂ©ficier des avantages de l'infĂ©rence hĂ©bergĂ©e avec davantage d'options de fournisseurs.
  • HĂ©bergez vous-mĂȘme via Hugging Face si vous avez besoin d'un contrĂŽle total, si vous avez des exigences en matiĂšre de confidentialitĂ© ou si vous souhaitez expĂ©rimenter l'architecture du modĂšle.
  • Veuillez utiliser vLLM si vous exĂ©cutez des charges de travail de production Ă  haut volume et disposez du budget matĂ©riel nĂ©cessaire.

Pour la plupart des développeurs débutants, l'API constitue le choix approprié. Vous ne payez que ce que vous utilisez, et DeepSeek se charge de la mise à l'échelle et de la maintenance.

Assistant de recherche multi-documents : Comparaison des performances dans un contexte étendu

Vous avez observé le fonctionnement de l'API DeepSeek v3.2 et effectué vos premiers appels. Maintenant, examinons cela à l'aide d'une comparaison concrÚte.

L'attention limitée de DeepSeek permet-elle réellement de réduire les coûts lors du traitement de contextes longs ? Et comment se positionne-t-il par rapport à GPT-5 et Claude Sonnet 4.5 ?

Pour rĂ©pondre Ă  cette question, nous allons crĂ©er un outil de comparaison qui charge plusieurs articles de recherche dans un seul contexte et envoie la mĂȘme requĂȘte aux quatre modĂšles. Vous pourrez voir prĂ©cisĂ©ment le coĂ»t de chaque modĂšle, sa rapiditĂ© de rĂ©ponse et le type de rĂ©ponses qu'il fournit.

La plupart des systÚmes d'analyse de documents utilisent RAG: ils divisent vos documents en petits morceaux, les intÚgrent, puis ne récupÚrent que les morceaux pertinents lorsque vous posez une question. Cette méthode est efficace pour les recherches simples, mais elle peut entraßner la perte de connexions entre différentes parties de vos documents. Que faire si la réponse nécessite de comprendre les relations entre plusieurs articles ?

Les modÚles à contexte long résolvent ce problÚme en lisant tout en une seule fois. Pas de fragmentation, pas de récupération, pas de contexte manquant. Vous chargez tous vos documents dans une seule invite et permettez au modÚle d'avoir une vue d'ensemble. Le problÚme réside dans le coût. Avec une approche traditionnelle, le traitement de plus de 50 000 jetons devient rapidement coûteux.

C'est ici que nous Ă©valuons l'attention clairsemĂ©e de DeepSeek. Nous allons dĂ©velopper une application qui charge trois articles de recherche (environ 57 000 tokens au total) dans un seul contexte et compare la maniĂšre dont quatre modĂšles traitent la mĂȘme requĂȘte : GPT-5, Claude Sonnet 4.5, DeepSeek v3.2-Exp (avec attention clairsemĂ©e) et DeepSeek v3.1-Terminus (la version prĂ©cĂ©dente sans attention clairsemĂ©e). Vous pourrez comparer les diffĂ©rences de coĂ»ts, les dĂ©lais de rĂ©ponse et la qualitĂ© des rĂ©sultats.

Voici à quoi ressemble l'application terminée :

Interface Multi-Document Research Assistant affichant la barre latérale avec les documents chargés (57 204 tokens), quatre cases à cocher pour la sélection des modÚles GPT-5, Claude Sonnet 4.5, DeepSeek v3.2-Exp et DeepSeek v3.1-Terminus, ainsi qu'une zone de saisie des questions.

Section des résultats présentant quatre panneaux de réponse et un tableau comparatif des métriques avec l'utilisation des jetons, les coûts et les temps de réponse pour GPT-5, Claude Sonnet 4.5, DeepSeek v3.2-Exp et DeepSeek v3.1-Terminus.

Tableaux comparatifs visuels présentant le coût, le temps de réponse, l'utilisation des jetons et le rapport coût/temps pour les quatre modÚles, avec des conclusions clés soulignant que DeepSeek v3.2-Exp est le plus rentable à 0,0162 $ et Claude Sonnet 4.5 le plus rapide à 16,13 s.

Remarque : Le reste de cette section présente une description détaillée de la maniÚre de créer cette application à partir de zéro. Il n'est pas nécessaire de le créer pour comprendre les résultats de la comparaison, mais parcourir le code vous fournit des modÚles pratiques pour créer vos propres applications à contexte long avec DeepSeek.

Développement de l'application

Nous allons dĂ©velopper cette application sous forme d'application Streamlit avec trois modules de support : un pour le chargement des documents, un pour la configuration du modĂšle et un pour le traitement des requĂȘtes. Le processus d'utilisation est simple : chargez les fichiers PDF, sĂ©lectionnez les modĂšles, posez une question et comparez les rĂ©sultats.

Commencez par créer un répertoire de projet et installer les dépendances :

mkdir multi-document-qa
cd multi-document-qa
uv add streamlit langchain langchain-openai langchain-anthropic langchain-community pypdf tiktoken python-dotenv matplotlib pandas

Veuillez créer un fichier .env contenant vos clés API :

OPENAI_API_KEY=your_openai_key
ANTHROPIC_API_KEY=your_anthropic_key
DEEPSEEK_API_KEY=your_deepseek_key

Veuillez télécharger trois articles de recherche sur les mécanismes de l'attention :

mkdir documents
cd documents
curl -L -o selective-attention.pdf "https://arxiv.org/pdf/2410.02703"
curl -L -o differential-transformer.pdf "https://arxiv.org/pdf/2410.05258"
curl -L -o sparse-attention-long-range.pdf "https://arxiv.org/pdf/2406.16747"
cd ..

Ces trois documents totalisent 57 204 tokens lorsqu'ils sont chargés.

Chargement et comptage des jetons

Créer un document_loader.py:

from langchain_community.document_loaders import PyPDFLoader
import tiktoken
from pathlib import Path


def load_documents(documents_dir="documents"):
   docs_path = Path(documents_dir)
   pdf_files = list(docs_path.glob("*.pdf"))
  
   all_text = ""
   document_names = []
  
   # Load each PDF and concatenate with separators
   for pdf_file in sorted(pdf_files):
       loader = PyPDFLoader(str(pdf_file))
       pages = loader.load()
       doc_text = "\n\n".join([page.page_content for page in pages])
       all_text += f"\n\n=== Document: {pdf_file.name} ===\n\n{doc_text}"
       document_names.append(pdf_file.name)

Cette fonction charge tous les fichiers PDF d'un répertoire, extrait le texte de chaque page et concatÚne le tout à l'aide de séparateurs de documents.

# Count tokens using GPT-4 encoding (accurate across providers)
   encoding = tiktoken.encoding_for_model("gpt-4")
   token_count = len(encoding.encode(all_text))
  
   return all_text, token_count, document_names

Le comptage des jetons utilise tiktoken avec le codage GPT-4, qui fournit des estimations précises pour tous les fournisseurs, car ils utilisent une tokenisation similaire. Veuillez consulter le document_loader.py complet sur GitHub.

Configuration des modĂšles et tarification

Créer un model_config.py:

from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
import os


# Pricing per million tokens (as of October 2025)
MODEL_PRICING = {
   "gpt-5": {"input": 2.50, "output": 10.00, "name": "GPT-5"},
   "claude-sonnet-4-5-20250929": {"input": 3.00, "output": 15.00, "name": "Claude Sonnet 4.5"},
   "deepseek-chat": {"input": 0.28, "output": 0.42, "name": "DeepSeek v3.2-Exp"},
   "deepseek-chat-v3.1": {"input": 0.55, "output": 2.19, "name": "DeepSeek v3.1-Terminus"},
}

Le dictionnaire des prix contient les coûts par million de jetons (à compter d'octobre 2025). DeepSeek v3.2 avec attention clairsemée est environ 10 fois moins coûteux que GPT-5 et Claude, tandis que la version v3.1 se situe entre les deux, avec un coût deux fois supérieur à celui de la version v3.2.

def get_model(model_name):
   """Initialize a chat model by name using LangChain's unified interface."""
   if model_name == "gpt-5":
       return ChatOpenAI(model="gpt-5", temperature=0, api_key=os.getenv("OPENAI_API_KEY"))
   elif model_name == "claude-sonnet-4-5-20250929":
       return ChatAnthropic(model="claude-sonnet-4-5-20250929", temperature=0,
                          api_key=os.getenv("ANTHROPIC_API_KEY"))
   elif model_name == "deepseek-chat":
       return ChatOpenAI(model="deepseek-chat", temperature=0,
                        api_key=os.getenv("DEEPSEEK_API_KEY"),
                        base_url="https://api.deepseek.com")
   elif model_name == "deepseek-chat-v3.1":
       # Note: v3.1-Terminus endpoint expires on October 15, 2025
       return ChatOpenAI(model="deepseek-chat", temperature=0,
                        api_key=os.getenv("DEEPSEEK_API_KEY"),
                        base_url="https://api.deepseek.com/v3.1_terminus_expires_on_20251015")


def calculate_cost(model_name, input_tokens, output_tokens):
   """Calculate total cost based on input and output token usage."""
   pricing = MODEL_PRICING[model_name]
   input_cost = (input_tokens / 1_000_000) * pricing["input"]
   output_cost = (output_tokens / 1_000_000) * pricing["output"]
   return input_cost + output_cost

La fonction « get_model() » initialise chaque modÚle à l'aide de l'interface unifiée de LangChain. Les modÚles DeepSeek utilisent des points de terminaison compatibles avec OpenAI avec des URL de base personnalisées. Remarque : Le point de terminaison v3.1-Terminus expirera le 15 octobre 2025. Le fichier complet script model_config.py est disponible sur GitHub.

Interrogation de modÚles avec suivi des métriques

Créer un query_handler.py:

import time
from langchain_core.messages import SystemMessage, HumanMessage
from model_config import get_model, calculate_cost, MODEL_PRICING


def query_model(model_name, context, question):
   """Query a model with document context and track performance metrics."""
   model = get_model(model_name)
  
   # Embed full document context in system prompt
   system_prompt = f"""Use the given context to answer the question.
If you don't know the answer, say you don't know. Keep the answer concise.

Context:
{context}"""
  
   messages = [
       SystemMessage(content=system_prompt),
       HumanMessage(content=question)
   ]
  
   # Track response time
   start_time = time.time()

Le systÚme intÚgre l'ensemble des 57 000 jetons des documents. Les processus d'attention traditionnels traitent chaque élément par rapport à tous les autres éléments. DeepSeek v3.2 ignore les connexions non pertinentes, ce qui réduit les coûts.

try:
       response = model.invoke(messages)
       elapsed_time = time.time() - start_time
      
       # Extract token usage (different providers use different formats)
       if hasattr(response, 'response_metadata') and 'token_usage' in response.response_metadata:
           token_usage = response.response_metadata['token_usage']
           input_tokens = token_usage.get('prompt_tokens', 0)
           output_tokens = token_usage.get('completion_tokens', 0)
       elif hasattr(response, 'usage_metadata'):
           input_tokens = response.usage_metadata.get('input_tokens', 0)
           output_tokens = response.usage_metadata.get('output_tokens', 0)
      
       # Calculate total cost
       cost = calculate_cost(model_name, input_tokens, output_tokens)
      
       return {
           "model": MODEL_PRICING[model_name]["name"],
           "response": response.content,
           "input_tokens": input_tokens,
           "output_tokens": output_tokens,
           "total_tokens": input_tokens + output_tokens,
           "cost": cost,
           "time": elapsed_time,
           "error": None
       }

Différentes intégrations LangChain renvoient l'utilisation des jetons dans différents formats (OpenAI utilise response_metadata, Anthropic utilise usage_metadata), nous vérifions donc les deux. Cette fonction permet de suivre le temps, d'extraire le nombre de jetons, de calculer les coûts et de renvoyer un dictionnaire contenant toutes les métriques. Veuillez consulter le fichier complet query_handler.py sur GitHub.

Développement de l'interface Streamlit

Créer un app.py:

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
from document_loader import load_documents
from query_handler import query_model
from dotenv import load_dotenv

# Load API keys from .env file
load_dotenv()

# Configure Streamlit page with wide layout
st.set_page_config(
   page_title="Multi-Document Research Assistant",
   page_icon="📚",
   layout="wide"
)

st.title("📚 Multi-Document Research Assistant")
st.markdown("Compare long-context performance across GPT-5, Claude Sonnet 4.5, DeepSeek v3.2, and DeepSeek v3.1")

Configuration Streamlit standard avec une mise en page large pour les comparaisons cĂŽte Ă  cĂŽte.

# Sidebar for document loading
with st.sidebar:
   st.header("📄 Documents Loaded")
  
   if st.button("Load Documents"):
       with st.spinner("Loading documents..."):
           # Load all PDFs and count tokens
           context, token_count, doc_names = load_documents("documents")
           st.session_state.context = context
           st.session_state.token_count = token_count
           st.session_state.doc_names = doc_names
  
   # Display loaded documents info
   if "token_count" in st.session_state:
       st.success(f"✅ Loaded {len(st.session_state.doc_names)} documents")
       st.metric("Total Tokens", f"{st.session_state.token_count:,}")
       st.write("**Documents:**")
       for name in st.session_state.doc_names:
           st.write(f"‱ {name}")

La barre latérale charge les documents et affiche le nombre de jetons. L'état de session de Streamlit conserve les documents chargés entre les interactions.

# Main content area
if "context" not in st.session_state:
   st.info("👈 Click 'Load Documents' in the sidebar to begin")
else:
   st.subheader("Select Models to Compare")
   col1, col2, col3, col4 = st.columns(4)
  
   # Model selection checkboxes
   with col1:
       use_gpt5 = st.checkbox("GPT-5", value=True)
   with col2:
       use_claude = st.checkbox("Claude Sonnet 4.5", value=True)
   with col3:
       use_deepseek_v32 = st.checkbox("DeepSeek v3.2-Exp", value=True)
   with col4:
       use_deepseek_v31 = st.checkbox("DeepSeek v3.1-Terminus", value=True)
  
   # Sample questions for quick testing
   sample_questions = [
       "Compare the main approaches to attention mechanisms described in these documents",
       "What are the key differences between sparse and dense attention?",
       "Summarize the common themes across all documents"
   ]

Quatre cases à cocher pour la sélection du modÚle et des exemples de questions prédéfinies.

# Question input with samples
   question_choice = st.selectbox(
       "Select a sample question or write your own:",
       ["Custom"] + sample_questions
   )
  
   if question_choice == "Custom":
       question = st.text_area("Enter your question:", height=100)
   else:
       question = st.text_area("Enter your question:", value=question_choice, height=100)
  
   # Query button and model execution
   if st.button("🚀 Query Models", type="primary"):
       if not question:
           st.error("Please enter a question")
       else:
           # Build list of selected models
           selected_models = []
           if use_gpt5:
               selected_models.append("gpt-5")
           if use_claude:
               selected_models.append("claude-sonnet-4-5-20250929")
           if use_deepseek_v32:
               selected_models.append("deepseek-chat")
           if use_deepseek_v31:
               selected_models.append("deepseek-chat-v3.1")

Les utilisateurs sĂ©lectionnent une question ou rĂ©digent la leur, puis cliquent sur « Query Models » (ModĂšles de requĂȘte) pour lancer la comparaison sur les modĂšles sĂ©lectionnĂ©s.

results = []
          
           # Query each model sequentially with progress indicator
           for model_name in selected_models:
               with st.spinner(f"Querying {model_name}..."):
                   result = query_model(
                       model_name,
                       st.session_state.context,
                       question
                   )
                   results.append(result)
          
           # Store results in session state for persistence
           st.session_state.results = results

Chaque modÚle est interrogé de maniÚre séquentielle à l'aide d'un indicateur de progression.

# Display results if available
if "results" in st.session_state:
   st.divider()
   st.subheader("📊 Results")
  
   results = st.session_state.results
  
   # Show model responses in expandable panels
   st.markdown("### Responses")
   for result in results:
       with st.expander(f"**{result['model']}** - ${result['cost']:.4f} | {result['time']:.2f}s"):
           if result['error']:
               st.error(f"Error: {result['error']}")
           else:
               st.write(result['response'])
  
   # Create metrics comparison table
   metrics_df = pd.DataFrame([
       {
           "Model": r['model'],
           "Input Tokens": r['input_tokens'],
           "Output Tokens": r['output_tokens'],
           "Total Tokens": r['total_tokens'],
           "Cost ($)": f"${r['cost']:.4f}",
           "Time (s)": f"{r['time']:.2f}"
       }
       for r in results
   ])
  
   st.dataframe(metrics_df, use_container_width=True)

Les rĂ©sultats affichent la rĂ©ponse de chaque modĂšle dans des panneaux extensibles avec le coĂ»t et le temps dans l'en-tĂȘte, suivis d'un tableau de mesures triables.

# Create visualization charts
   fig, axes = plt.subplots(2, 2, figsize=(12, 10))
  
   # Chart 1: Cost comparison bar chart
   axes[0, 0].bar([r['model'] for r in results], [r['cost'] for r in results],
                  color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'][:len(results)])
   axes[0, 0].set_title('Cost Comparison')
   axes[0, 0].set_ylabel('Cost ($)')
   axes[0, 0].tick_params(axis='x', rotation=45)
  
   # Chart 2: Response time bar chart
   axes[0, 1].bar([r['model'] for r in results], [r['time'] for r in results],
                  color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'][:len(results)])
   axes[0, 1].set_title('Response Time Comparison')
   axes[0, 1].set_ylabel('Time (seconds)')
  
   # Chart 3: Token usage grouped bar chart
   models = [r['model'] for r in results]
   input_tokens = [r['input_tokens'] for r in results]
   output_tokens = [r['output_tokens'] for r in results]
   x = range(len(models))
   width = 0.35
   axes[1, 0].bar([i - width/2 for i in x], input_tokens, width, label='Input', color='#1f77b4')
   axes[1, 0].bar([i + width/2 for i in x], output_tokens, width, label='Output', color='#ff7f0e')
   axes[1, 0].set_title('Token Usage Comparison')
   axes[1, 0].legend()

Quatre graphiques matplotlib dans une grille 2x2 : barres de coût, barres de temps, barres d'utilisation groupée des jetons et nuage de points coût-temps.

# Chart 4: Cost vs time tradeoff scatter plot
   axes[1, 1].scatter([r['cost'] for r in results], [r['time'] for r in results],
                      s=100, alpha=0.6, color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'][:len(results)])
   for i, r in enumerate(results):
       axes[1, 1].annotate(r['model'], (r['cost'], r['time']), fontsize=8, ha='right')
   axes[1, 1].set_title('Cost vs Time Trade-off')
   axes[1, 1].set_xlabel('Cost ($)')
   axes[1, 1].set_ylabel('Time (seconds)')
   axes[1, 1].grid(True, alpha=0.3)
  
   plt.tight_layout()
   st.pyplot(fig)
  
   # Display key findings
   if len(results) > 1:
       cheapest = min(results, key=lambda x: x['cost'])
       fastest = min(results, key=lambda x: x['time'])
      
       col1, col2 = st.columns(2)
       with col1:
           st.metric("Most Cost-Effective", cheapest['model'], f"${cheapest['cost']:.4f}")
       with col2:
           st.metric("Fastest Response", fastest['model'], f"{fastest['time']:.2f}s")

Les principales conclusions mettent automatiquement en évidence les modÚles les plus économiques et les plus rapides. Veuillez consulter le fichier complet app.py sur GitHub.

Effectuer la comparaison

Veuillez démarrer l'application :

streamlit run app.py

Veuillez cliquer sur « Charger les documents » pour télécharger les trois fichiers PDF (57 204 jetons au total). Veuillez sélectionner les modÚles à comparer (les quatre par défaut), choisir ou rédiger une question, puis cliquer sur « Query Models » (Interroger les modÚles).

Temps de réponse attendus pour un contexte de 57 000 jetons :

  • Claude Sonnet 4.5 : 15 Ă  20 secondes
  • DeepSeek v3.2 : 30 Ă  35 secondes
  • DeepSeek v3.1 : 35 Ă  40 secondes
  • GPT-5 : 40 Ă  45 secondes

Résultats : Analyse des coûts et des performances

Section des résultats présentant quatre panneaux de réponse et un tableau comparatif des indicateurs avec l'utilisation des jetons, les coûts et les temps de réponse pour les quatre modÚles.

GPT-5 a traitĂ© 56 937 jetons d'entrĂ©e et gĂ©nĂ©rĂ© 1 996 jetons de sortie pour un coĂ»t de 0,1623 $ en 42,28 secondes. Claude Sonnet 4.5 a traitĂ© 65 855 jetons d'entrĂ©e et gĂ©nĂ©rĂ© 485 jetons de sortie pour un coĂ»t de 0,2048 $ en 16,13 secondes — le plus rapide, mais Ă©galement le plus onĂ©reux. DeepSeek v3.2-Exp a traitĂ© 56 842 jetons d'entrĂ©e et gĂ©nĂ©rĂ© 698 jetons de sortie pour seulement 0,0162 $ en 32,16 secondes. DeepSeek v3.1-Terminus a traitĂ© 56 842 jetons d'entrĂ©e et gĂ©nĂ©rĂ© 700 jetons de sortie pour un coĂ»t de 0,0328 $ en 35,85 secondes.

La comparaison entre les versions 3.1 et 3.2 démontre l'impact de l'attention clairsemée. Les deux versions ont traité des entrées identiques et produit des résultats presque identiques (698 contre 700 jetons), mais la version 3.2 a coûté deux fois moins cher (0,0162 $ contre 0,0328 $) et a fonctionné légÚrement plus rapidement (32,16 s contre 35,85 s). Cela représente une réduction des coûts de 50 % par rapport à l'attention clairsemée seule.

Par rapport Ă  GPT-5 et Claude, la version 3.2 est 10 fois moins chĂšre que GPT-5 (0,0162 $ contre 0,1623 $) et 13 fois moins chĂšre que Claude (0,0162 $ contre 0,2048 $). Pour plus de 100 requĂȘtes de cette longueur, vous dĂ©penseriez 16,20 $ avec DeepSeek v3.2, contre 162,30 $ avec GPT-5 ou 204,80 $ avec Claude.

Tableaux comparatifs visuels présentant le coût, le temps de réponse, l'utilisation des jetons et le compromis coût-temps pour les quatre modÚles.

Les graphiques confirment la position de DeepSeek v3.2 dans le quadrant inférieur gauche du compromis coût-temps : le moins cher globalement à 0,0162 $ tout en conservant une vitesse raisonnable de 32 secondes. Claude privilégie la rapidité au détriment du coût (il est onéreux mais le plus rapide), GPT-5 se classe en derniÚre position sur ces deux critÚres (il est onéreux et le plus lent), et la version 3.1 se situe entre les deux. Le graphique d'utilisation des tokens montre que tous les modÚles traitent des tailles d'entrée similaires, mais que la longueur des sorties varie : GPT-5 a généré la réponse la plus longue avec 1 996 tokens, Claude est resté concis avec 485 tokens, et les deux versions de DeepSeek ont produit des sorties similaires d'environ 700 tokens.

Quand cette approche est pertinente

Le chargement de documents complets dans le contexte est particuliÚrement efficace lorsque vous avez besoin d'une compréhension globale des documents. Si votre question nécessite de relier des idées issues de trois articles différents, le découpage et la récupération pourraient omettre ces liens. Le modÚle doit pouvoir visualiser l'ensemble des éléments simultanément.

Ce modĂšle convient Ă  plusieurs cas d'utilisation :

  • Recherche et analyse: Comparer plusieurs documents, rapports ou articles oĂč les relations sont plus importantes que la recherche de faits spĂ©cifiques.
  • RĂ©vision de documents juridiques: Comparaison de contrats, analyse de politiques ou examen rĂ©glementaire oĂč le contexte et les diffĂ©rences subtiles sont importants.
  • Documentation technique: Comprendre comment les diffĂ©rentes documentations API ou spĂ©cifications techniques sont liĂ©es les unes aux autres.
  • s sur la crĂ©ation de contenu long format: RĂ©daction qui synthĂ©tise les informations provenant de plusieurs sources tout en conservant une conscience de ce que chacune d'elles exprime.

Cette approche n'est pas efficace lorsque :

  • Les documents sont trop volumineux: La plupart des modĂšles sont limitĂ©s Ă  128 000-200 000 jetons. Si vos documents dĂ©passent cette limite, il est nĂ©cessaire de procĂ©der au regrouper.
  • Vous recherchez des informations sur: Le RAG avec rĂ©cupĂ©ration fonctionne mieux pour les requĂȘtes de type « trouver la rĂ©ponse Ă  X » lorsque vous savez que l'information se trouve dans une section spĂ©cifique.
  • Vous disposez de nombreux documents: Le chargement de 20 documents dans leur intĂ©gralitĂ© pourrait dĂ©passer les limites du contexte. Envisagez des approches hybrides qui filtrent les documents avant leur chargement.
  • Le budget est illimitĂ©.: Si le coĂ»t n'est pas un facteur dĂ©terminant, GPT-5 ou Claude pourraient vous fournir des rĂ©ponses lĂ©gĂšrement plus pertinentes pour les requĂȘtes complexes.

L'attention limitĂ©e de DeepSeek modifie l'Ă©conomie du traitement de contextes longs. Ce qui coĂ»tait auparavant entre 0,15 et 0,20 dollar par requĂȘte coĂ»te dĂ©sormais entre 0,01 et 0,02 dollar. Cela rend les approches contextuelles complĂštes pratiques pour les applications qui exĂ©cutent des centaines ou des milliers de requĂȘtes par jour.

Conclusion

La fonctionnalitĂ© « sparse attention » de DeepSeek v3.2 offre la mĂȘme qualitĂ© de modĂšle que la version v3.1, mais Ă  un coĂ»t deux fois moins Ă©levĂ©. La comparaison de plusieurs documents que nous avons rĂ©alisĂ©e a dĂ©montrĂ© cela dans la pratique. Le traitement de 57 000 jetons coĂ»te 0,0162 $ avec la version 3.2 contre 0,0328 $ avec la version 3.1, et les deux versions produisent des rĂ©sultats pratiquement identiques. Par rapport Ă  GPT-5 et Claude, la version 3.2 est 10 Ă  13 fois plus Ă©conomique tout en conservant des temps de rĂ©ponse raisonnables. Pour les applications qui traitent rĂ©guliĂšrement des contextes longs, ces Ă©conomies s'accumulent rapidement.

Si vous travaillez sur l'analyse de documents, des outils de recherche ou toute autre application traitant de contextes longs, la version 3.2 mĂ©rite d'ĂȘtre testĂ©e. Veuillez noter qu'il s'agit encore d'une fonctionnalitĂ© expĂ©rimentale, il est donc recommandĂ© de la tester avant de l'utiliser en production.

Pour en savoir plus sur les derniÚres avancées en matiÚre d'IA, veuillez consulter ces blogs :

Sujets

Contenus associés

blog

Comprendre les TPU et les GPU dans l'IA : Un guide complet