Modèles Multimodaux : Quand l'IA Voit, Entend et Parle
Pendant longtemps, les modèles d’IA étaient spécialisés : un modèle pour le texte (GPT-3), un autre pour les images (DALL-E), un troisième pour l’audio (Whisper). Chacun excellait dans son domaine, mais ils ne pouvaient pas communiquer entre eux de manière native.
Les modèles multimodaux changent radicalement la donne.
Un modèle multimodal peut traiter et générer plusieurs modalités (types de données) : texte, images, audio, vidéo. Plus important encore, il peut comprendre les relations entre ces modalités : analyser une image et la décrire en texte, écouter un audio et le transcrire, générer une image à partir d’une description, etc.

Pourquoi c’est révolutionnaire
Les humains sont naturellement multimodaux : nous voyons, entendons, lisons et parlons simultanément pour comprendre le monde. Les modèles multimodaux rapprochent l’IA de cette compréhension holistique.
Impact concret :
- Accessibilité : Décrire automatiquement des images pour les malvoyants
- Productivité : Analyser un document scanné avec diagrammes et tableaux
- Support client : Comprendre un screenshot d’erreur et proposer une solution
- Éducation : Tuteurs IA comprenant schémas, graphiques et formules mathématiques
- Santé : Analyser imagerie médicale avec contexte clinique
Évolution historique :
- 2017-2021 : Modèles unimodaux (GPT-3 texte uniquement, DALL-E images)
- 2022 : Premiers modèles multimodaux (Flamingo, CLIP)
- 2023 : GPT-4V (Vision) démocratise la vision pour LLMs
- 2024 : Gemini natif multimodal, Claude 3 avec vision, GPT-4o (omni)
- 2025 : Modèles any-to-any (n’importe quelle modalité vers n’importe quelle autre)
Comment fonctionnent les modèles multimodaux ?
Architecture unifiée
L’idée clé est de créer un espace latent unifié où différentes modalités peuvent être représentées de manière cohérente.
Principe général :
Encodeurs spécialisés : Chaque modalité a son encodeur
- Texte : Tokenizer + Transformer textuel
- Image : Vision Transformer (ViT) ou CNN
- Audio : Spectrogram + Transformer audio
Projection dans l’espace unifié : Les embeddings de chaque modalité sont projetés dans un espace commun
Fusion multimodale : Un Transformer central fusionne les informations
Décodeurs : Génèrent la sortie dans la modalité souhaitée
# Architecture simplifiée conceptuelle
class MultimodalModel:
def __init__(self):
# Encodeurs par modalité
self.text_encoder = TextTransformer()
self.image_encoder = VisionTransformer()
self.audio_encoder = AudioTransformer()
# Projections vers espace unifié
self.text_projection = nn.Linear(768, 1024)
self.image_projection = nn.Linear(768, 1024)
self.audio_projection = nn.Linear(768, 1024)
# Transformer central multimodal
self.fusion_transformer = MultimodalTransformer(
dim=1024,
depth=24,
heads=16
)
# Décodeurs
self.text_decoder = TextDecoder()
self.image_decoder = DiffusionDecoder()
def forward(self, text=None, image=None, audio=None):
embeddings = []
# Encoder chaque modalité présente
if text is not None:
text_emb = self.text_encoder(text)
text_emb = self.text_projection(text_emb)
embeddings.append(text_emb)
if image is not None:
image_emb = self.image_encoder(image)
image_emb = self.image_projection(image_emb)
embeddings.append(image_emb)
if audio is not None:
audio_emb = self.audio_encoder(audio)
audio_emb = self.audio_projection(audio_emb)
embeddings.append(audio_emb)
# Concaténer et fusionner
combined = torch.cat(embeddings, dim=1)
fused = self.fusion_transformer(combined)
return fused
Attention cross-modale
Le mécanisme d’attention permet au modèle de mettre en relation les différentes modalités.
Exemple : Pour la question “Quelle est la couleur du chat dans l’image ?”, le modèle :
- Encode le texte “Quelle est la couleur du chat”
- Encode l’image (pixels → embeddings)
- Applique l’attention cross-modale : les tokens “couleur” et “chat” vont attendre aux régions de l’image contenant le chat
- Fusionne les informations pour générer “Le chat est orange”
Analogie : Imaginez que vous regardez une photo de vacances tout en lisant la légende. Votre cerveau fait automatiquement des liens
Exemple : Comment GPT-4V “voit” une image
GPT-4 avec vision utilise une architecture hybride :
- Vision Transformer (ViT) : Découpe l’image en patches (ex: 16×16 pixels)
- Embeddings visuels : Chaque patch devient un vecteur
- Projection : Les embeddings visuels sont projetés dans l’espace du modèle textuel
- Fusion : Les tokens visuels sont concaténés avec les tokens textuels
- Traitement unifié : Le Transformer GPT-4 traite texte + vision ensemble
from openai import OpenAI
import base64
from pathlib import Path
client = OpenAI(api_key="your-api-key")
# Charger et encoder l'image
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
image_path = "vacation_photo.jpg"
base64_image = encode_image(image_path)
# Analyser l'image avec GPT-4V
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Décris cette image en détail. Identifie les objets, les couleurs, l'ambiance et le contexte."
},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
}
}
]
}
],
max_tokens=500
)
print(response.choices[0].message.content)
Résultat exemple :
L'image montre une plage au coucher du soleil. On y voit :
- Un ciel orange et rose avec des nuages dorés
- Une mer calme avec des vagues douces
- Deux personnes marchant pieds nus sur le sable
- Des palmiers sur la droite
- L'ambiance est paisible et romantique
- La photo semble prise en été, probablement en fin de journée vers 19h-20h
Les acteurs majeurs
GPT-4V et GPT-4o (OpenAI)
GPT-4V (V pour Vision) a été le premier modèle GPT-4 avec capacités visuelles. GPT-4o (o pour Omni) va plus loin avec audio natif.
Capacités :
- ✅ Texte + Image (input)
- ✅ Texte (output)
- ✅ Audio (input/output avec GPT-4o)
- ✅ Analyse de documents complexes (PDF, factures, diagrammes)
- ✅ OCR avancé et extraction structurée
- ✅ Compréhension de mèmes, graphiques, code manuscrit
Cas d’usage :
# Analyser une facture
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Extrait les informations clés de cette facture au format JSON : numéro, date, montant total, items."
},
{
"type": "image_url",
"image_url": {"url": "data:image/jpeg;base64,..."}
}
]
}
],
response_format={"type": "json_object"}
)
# Résultat structuré
{
"numero_facture": "FAC-2025-00142",
"date": "2025-11-27",
"montant_total": 1249.99,
"items": [
{"description": "Laptop Dell XPS 15", "quantite": 1, "prix": 1199.99},
{"description": "Souris sans fil", "quantite": 1, "prix": 50.00}
]
}
Limites :
- ❌ Pas de génération d’images (utiliser DALL-E séparément)
- ❌ Limite de résolution (images redimensionnées à ~2048px)
- ❌ Coût élevé : $10/million tokens visuels (vs $2.50 pour texte)
Gemini (Google)
Gemini est le premier modèle nativement multimodal de Google : entraîné dès le départ sur texte + image + audio + vidéo.
Versions :
- Gemini 1.5 Pro : 2 millions de tokens de contexte, multimodal complet
- Gemini 1.5 Flash : Plus rapide, moins cher, contexte réduit
- Gemini Nano : On-device pour smartphones
Capacités uniques :
- ✅ Contexte massif : Analyser 1h de vidéo ou 11h d’audio en une fois
- ✅ Vidéo native : Comprend la cohérence temporelle
- ✅ Multilingue avancé : 100+ langues
- ✅ Code dans images : Comprend screenshots de code
Exemple : Analyser une vidéo :
import google.generativeai as genai
from pathlib import Path
genai.configure(api_key="your-api-key")
# Upload une vidéo
video_file = genai.upload_file(path="presentation.mp4")
# Attendre le processing
import time
while video_file.state.name == "PROCESSING":
time.sleep(2)
video_file = genai.get_file(video_file.name)
# Analyser le contenu
model = genai.GenerativeModel("gemini-1.5-pro")
response = model.generate_content([
video_file,
"Résume cette présentation. Extrais les points clés de chaque section et identifie les moments importants avec timestamps."
])
print(response.text)
Résultat exemple :
Cette présentation de 15 minutes couvre les bases de l'IA multimodale :
00:00-02:30 - Introduction : Définition et historique
• Évolution des modèles unimodaux vers multimodaux
• Importance de la fusion des modalités
02:30-07:00 - Architecture technique
• Vision Transformers et encodeurs
• Attention cross-modale illustrée avec diagramme
• Slide 4 montre l'architecture complète (screenshot disponible)
07:00-12:00 - Applications pratiques
• Démo d'analyse de document médical
• Cas d'usage en e-commerce
• Graphique de performances (slide 8)
12:00-15:00 - Conclusion et perspectives
• Tendances 2025
• Appel à l'action : tester les modèles
Points clés à retenir : L'IA multimodale permet une compréhension holistique, avec des gains de 40% en précision sur tâches complexes.
Avantage majeur : Le contexte de 2M tokens permet d’analyser des contenus massifs (livres entiers, longs enregistrements, codebases complètes) en une seule requête.
Claude 3 (Anthropic)
Claude 3 (Opus, Sonnet, Haiku) a ajouté la vision tout en conservant les forces d’Anthropic : précision, sécurité et documents longs.
Capacités :
- ✅ Texte + Image (input)
- ✅ Texte (output)
- ✅ Excellent sur documents techniques : recherche scientifique, code, diagrammes
- ✅ Précision élevée : Moins d’hallucinations que concurrents
- ✅ Contexte 200K tokens
Points forts :
- Analyse de documents PDF complexes : Articles scientifiques avec formules mathématiques, tableaux, graphiques
- Diagrammes techniques : UML, architectures, flowcharts
- Sécurité : Constitutional AI appliqué aux images (refuse contenu inapproprié)
Exemple : Analyser un article scientifique :
import anthropic
import base64
client = anthropic.Anthropic(api_key="your-api-key")
# Charger PDF converti en images (une page = une image)
def encode_image(image_path):
with open(image_path, "rb") as f:
return base64.standard_b64encode(f.read()).decode("utf-8")
page1 = encode_image("research_paper_page1.png")
page2 = encode_image("research_paper_page2.png")
message = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2000,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": page1,
},
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": page2,
},
},
{
"type": "text",
"text": "Analyse cet article scientifique. Extrais : titre, auteurs, abstract, méthodologie, résultats clés et conclusion. Explique les équations mathématiques si présentes."
}
],
}
],
)
print(message.content[0].text)
Limite : Pas de génération d’images ni de vidéo (focus sur compréhension).
LLaVA (Large Language and Vision Assistant)
LLaVA est l’alternative open source aux modèles propriétaires.
Architecture :
- Vision encoder : CLIP (OpenAI)
- LLM : Vicuna (fine-tuné Llama) ou Mistral
- Training : Instruction tuning sur 150K image-texte paires
Avantages open source :
- ✅ Gratuit et self-hostable
- ✅ Personnalisable (fine-tuning sur vos données)
- ✅ Confidentialité (données restent locales)
- ✅ Performances comparables à GPT-4V sur certaines tâches
Installation et utilisation :
# Installation
pip install llava
# Télécharger le modèle
git lfs install
git clone https://huggingface.co/liuhaotian/llava-v1.6-vicuna-7b
from llava.model.builder import load_pretrained_model
from llava.mm_utils import get_model_name_from_path, process_images, tokenizer_image_token
from PIL import Image
import torch
# Charger le modèle
model_path = "liuhaotian/llava-v1.6-vicuna-7b"
tokenizer, model, image_processor, context_len = load_pretrained_model(
model_path=model_path,
model_base=None,
model_name=get_model_name_from_path(model_path),
device="cuda" if torch.cuda.is_available() else "cpu"
)
# Charger image
image = Image.open("example.jpg")
image_tensor = process_images([image], image_processor, model.config)
image_tensor = image_tensor.to(model.device, dtype=torch.float16)
# Prompt
prompt = "USER: <image>\nDécris cette image en détail.\nASSISTANT:"
# Inference
input_ids = tokenizer_image_token(prompt, tokenizer, return_tensors='pt')
input_ids = input_ids.to(model.device)
with torch.inference_mode():
output_ids = model.generate(
input_ids,
images=image_tensor,
max_new_tokens=512,
use_cache=True
)
output = tokenizer.decode(output_ids[0], skip_special_tokens=True)
print(output)
Cas d’usage : Parfait pour entreprises nécessitant confidentialité (santé, finance) ou voulant personnaliser le modèle.
Tableau comparatif des modèles
| Modèle | Modalités | Contexte | Prix (input) | Points forts | Open Source |
|---|---|---|---|---|---|
| GPT-4o | Texte, Image, Audio | 128K | $2.50/M text$10/M vision | Qualité, fonction calling | ❌ |
| Gemini 1.5 Pro | Texte, Image, Audio, Vidéo | 2M | $1.25/M text$2.50/M vision | Contexte massif, vidéo native | ❌ |
| Claude 3.5 Sonnet | Texte, Image | 200K | $3/M text$15/M vision | Précision, documents techniques | ❌ |
| Claude 3 Opus | Texte, Image | 200K | $15/M text$75/M vision | Qualité maximale, complexité | ❌ |
| LLaVA 1.6 | Texte, Image | 4K-8K | Gratuit | Open source, privacy, fine-tuning | ✅ |
| Qwen-VL | Texte, Image | 32K | Gratuit | Multilingue, chinois excellent | ✅ |
Modalités supportées
Texte ↔ Image
Compréhension d’images (Image → Texte) :
- Description détaillée
- OCR et extraction de texte
- Analyse de graphiques et tableaux
- Identification d’objets et scènes
- Réponse à des questions sur l’image
Génération d’images (Texte → Image) :
- DALL-E 3 : Génération créative haute qualité
- Stable Diffusion : Open source, personnalisable
- Midjourney : Artistique, esthétique poussée
- Imagen (Google) : Réalisme photographique
Séparation modèles : La plupart des LLMs multimodaux actuels (GPT-4V, Claude, Gemini) analysent les images mais ne les génèrent pas. La génération nécessite des modèles de diffusion séparés.
Texte ↔ Audio
Transcription (Audio → Texte) :
- Whisper (OpenAI) : State-of-the-art, 100+ langues
- Diarization : Identification des locuteurs
- Timestamps précis
- Ponctuation automatique
Synthèse vocale (Texte → Audio) :
- GPT-4o Audio : Voix naturelles avec émotions
- ElevenLabs : Clonage de voix réaliste
- Google TTS : 400+ voix, multilingue
Exemple Whisper :
from openai import OpenAI
client = OpenAI(api_key="your-api-key")
# Transcrire un audio
with open("meeting_recording.mp3", "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
response_format="verbose_json", # Inclut timestamps
timestamp_granularities=["segment"]
)
# Résultat avec timestamps
for segment in transcript.segments:
print(f"[{segment['start']:.2f}s - {segment['end']:.2f}s]: {segment['text']}")
Texte ↔ Vidéo
Analyse vidéo (Vidéo → Texte) :
- Gemini 1.5 : Compréhension temporelle native
- Description d’actions et événements
- Extraction de moments clés
- Génération de résumés avec timestamps
Génération vidéo (Texte → Vidéo) :
- Sora (OpenAI) : Génération réaliste jusqu’à 60s
- Runway Gen-2 : Édition et effets
- Pika : Accessible, communauté active
Exemple génération vidéo (Runway) :
import runwayml
client = runwayml.RunwayML(api_key="your-api-key")
# Générer une vidéo de 4s
task = client.ImageToVideo.create(
model="gen2",
prompts=[{
"text": "Un chat orange saute gracieusement sur un canapé, slow motion, cinematic lighting",
"image": "cat_start_frame.jpg",
"duration": 4
}]
)
# Attendre la génération
task.wait()
print(f"Vidéo disponible : {task.output.url}")
Combinaisons avancées
Image + Audio → Texte :
- Analyse de vidéos avec voix-off
- Compréhension de présentations
- Sous-titrage intelligent avec contexte visuel
Texte + Image → Image :
- ControlNet : Modifier images selon instructions
- Inpainting : Remplacer zones spécifiques
- Style transfer : “Transforme cette photo en style Van Gogh”
Applications pratiques
Accessibilité : Descriptions pour malvoyants
Les modèles multimodaux révolutionnent l’accessibilité web et mobile.
Cas d’usage : Extension navigateur décrivant automatiquement les images sans alt text.
from openai import OpenAI
import base64
client = OpenAI(api_key="your-api-key")
def describe_image_for_screen_reader(image_url):
"""Génère une description accessible pour lecteur d'écran"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Tu es un assistant d'accessibilité. Décris les images de manière:
- Concise (2-3 phrases max)
- Descriptive (objets, actions, contexte)
- Neutre et objective
- Utile pour quelqu'un ne voyant pas l'image"""
},
{
"role": "user",
"content": [
{"type": "text", "text": "Décris cette image pour un utilisateur de lecteur d'écran."},
{"type": "image_url", "image_url": {"url": image_url}}
]
}
],
max_tokens=150
)
return response.choices[0].message.content
# Exemple
description = describe_image_for_screen_reader("https://example.com/product.jpg")
print(f"alt=\"{description}\"")
# alt="Un laptop argenté ouvert sur un bureau en bois clair. L'écran affiche un éditeur de code. À côté, une tasse de café et une plante verte."
E-commerce : Recherche par image
Cas d’usage : “Trouve-moi des meubles similaires à cette photo”
# Architecture système de recherche visuelle
class VisualSearch:
def __init__(self):
self.openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.embedding_model = SentenceTransformer('clip-ViT-B-32')
self.vector_db = chromadb.Client()
self.collection = self.vector_db.get_or_create_collection("products")
def index_product(self, product_id, image_path, metadata):
"""Indexer un produit avec son image"""
# Générer embedding visuel
image = Image.open(image_path)
embedding = self.embedding_model.encode(image)
# Stocker dans base vectorielle
self.collection.add(
ids=[product_id],
embeddings=[embedding.tolist()],
metadatas=[metadata]
)
def search_by_image(self, query_image_path, n_results=5):
"""Rechercher produits similaires"""
# Embedding de l'image query
query_image = Image.open(query_image_path)
query_embedding = self.embedding_model.encode(query_image)
# Recherche vectorielle
results = self.collection.query(
query_embeddings=[query_embedding.tolist()],
n_results=n_results
)
# Enrichir avec description IA
for result in results['metadatas'][0]:
# GPT-4V analyse la similarité
explanation = self._explain_similarity(query_image_path, result['image_url'])
result['match_reason'] = explanation
return results
def _explain_similarity(self, image1_path, image2_url):
"""Expliquer pourquoi deux produits sont similaires"""
with open(image1_path, 'rb') as f:
image1_b64 = base64.b64encode(f.read()).decode()
response = self.openai_client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Compare ces deux produits. Quels sont les points communs (style, couleur, forme) ?"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image1_b64}"}},
{"type": "image_url", "image_url": {"url": image2_url}}
]
}],
max_tokens=100
)
return response.choices[0].message.content
# Utilisation
search = VisualSearch()
results = search.search_by_image("user_uploaded_sofa.jpg")
for product in results['metadatas'][0]:
print(f"Produit similaire : {product['name']}")
print(f"Raison : {product['match_reason']}")
print(f"Prix : {product['price']}€\n")
Éducation : Tuteur comprenant diagrammes
Cas d’usage : Élève prend photo de son exercice de math, IA explique étape par étape.
def math_tutor(problem_image_path):
"""Tuteur IA analysant problèmes mathématiques"""
client = OpenAI(api_key="your-api-key")
with open(problem_image_path, 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Tu es un tuteur patient et pédagogue. Quand tu analyses un problème :
1. Identifie le concept mathématique
2. Explique la démarche étape par étape
3. Donne des indices sans révéler la réponse directement
4. Encourage l'élève à réfléchir"""
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "J'ai du mal avec cet exercice. Peux-tu m'aider à comprendre comment le résoudre ?"
},
{
"type": "image_url",
"image_url": {"url": f"data:image/jpeg;base64,{image_b64}"}
}
]
}
],
max_tokens=600
)
return response.choices[0].message.content
# Exemple
explanation = math_tutor("math_problem.jpg")
print(explanation)
Résultat exemple :
Je vois un problème d'équation du second degré : x² - 5x + 6 = 0
Voici comment aborder ce problème :
Étape 1 : Identifier la forme
C'est une équation ax² + bx + c = 0 avec a=1, b=-5, c=6
Étape 2 : Choisir la méthode
Tu as deux options :
- Factorisation (chercher deux nombres qui multipliés donnent 6 et additionnés donnent -5)
- Formule discriminant Δ = b² - 4ac
Question pour réfléchir : Connais-tu deux nombres qui multipliés donnent 6 et additionnés donnent -5 ?
Indice : Pense aux facteurs de 6 → (1,6) ou (2,3)
Une fois que tu as trouvé, écris (x - ?)(x - ?) = 0 et résous !
Santé : Analyse d’imagerie médicale
Disclaimer médical : L’IA est un outil d’aide à la décision, pas un remplacement du diagnostic médical professionnel. Toute utilisation en santé doit être supervisée par des praticiens qualifiés.
Cas d’usage : Assistant pour radiologues analysant radios pulmonaires.
def medical_image_assistant(xray_path, patient_context):
"""Assistant d'analyse pour imagerie médicale (usage professionnel uniquement)"""
client = OpenAI(api_key="your-api-key")
with open(xray_path, 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Tu es un assistant d'aide au diagnostic pour radiologues qualifiés.
IMPORTANT :
- Fournis des observations structurées, pas de diagnostic définitif
- Signale les zones nécessitant attention particulière
- Suggère des examens complémentaires si pertinent
- Rappelle toujours que l'interprétation finale revient au médecin
Format de réponse :
1. Observations générales
2. Zones d'intérêt
3. Comparaison avec normes
4. Suggestions d'investigations"""
},
{
"role": "user",
"content": [
{
"type": "text",
"text": f"""Contexte patient : {patient_context}
Analyse cette radiographie thoracique et fournis des observations structurées."""
},
{
"type": "image_url",
"image_url": {"url": f"data:image/jpeg;base64,{image_b64}"}
}
]
}
],
max_tokens=800
)
return response.choices[0].message.content
# Exemple (usage hospitalier avec supervision)
context = "Patient 62 ans, fumeur, toux persistante 3 semaines"
analysis = medical_image_assistant("chest_xray.jpg", context)
print(analysis)
Avantages :
- Triage : Prioriser cas urgents
- Seconde opinion : Validation des observations
- Enseignement : Formation des étudiants en médecine
- Zones rurales : Support pour médecins isolés
Support client : Analyse de screenshots
Cas d’usage : Client envoie screenshot d’erreur, IA diagnostic et propose solution.
class TechnicalSupportBot:
def __init__(self):
self.client = OpenAI(api_key="your-api-key")
self.knowledge_base = self._load_knowledge_base()
def analyze_error_screenshot(self, screenshot_path, user_message):
"""Analyser screenshot d'erreur et proposer solution"""
with open(screenshot_path, 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
# Étape 1 : Extraire informations du screenshot
analysis = self.client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{
"type": "text",
"text": """Analyse ce screenshot d'erreur et extrait :
1. Type d'erreur (code, message)
2. Application concernée
3. Contexte visible (OS, version si visible)
4. Actions utilisateur apparentes
Format JSON."""
},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_b64}"}}
]
}],
response_format={"type": "json_object"}
)
error_info = json.loads(analysis.choices[0].message.content)
# Étape 2 : Chercher solution dans base de connaissance
solution = self._search_solution(error_info)
# Étape 3 : Générer réponse personnalisée
response = self.client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Tu es un agent de support technique empathique et efficace.
Structure ta réponse :
1. Comprendre le problème (reformuler)
2. Expliquer la cause probable
3. Donner solution étape par étape (simple et claire)
4. Proposer alternatives si première solution échoue
5. Offrir aide supplémentaire
Ton : Amical, patient, pas condescendant."""
},
{
"role": "user",
"content": f"""Message client : {user_message}
Analyse screenshot : {json.dumps(error_info, indent=2)}
Solutions connues : {solution}
Rédige une réponse de support complète."""
}
]
)
return response.choices[0].message.content
def _search_solution(self, error_info):
"""Rechercher solutions dans base de connaissance (simulé)"""
# En pratique : RAG sur documentation + tickets résolus
return {
"solution": "Réinstaller le pilote",
"steps": ["Désinstaller", "Redémarrer", "Réinstaller version latest"],
"success_rate": 0.89
}
def _load_knowledge_base(self):
# Charger base de connaissance vectorielle
pass
# Utilisation
bot = TechnicalSupportBot()
response = bot.analyze_error_screenshot(
screenshot_path="user_error.png",
user_message="Mon application crashe à chaque fois que j'ouvre un fichier 😕"
)
print(response)
Résultat exemple :
Bonjour ! Je comprends votre frustration, c'est effectivement problématique quand l'application crashe systématiquement.
D'après votre screenshot, je vois une erreur "Failed to load DLL: graphics_renderer.dll". Ce problème est généralement lié à un pilote graphique obsolète ou corrompu.
Voici la solution qui fonctionne dans 89% des cas :
**Étape 1 : Désinstaller le pilote actuel**
1. Clic droit sur le menu Démarrer → Gestionnaire de périphériques
2. Développer "Cartes graphiques"
3. Clic droit sur votre carte → Désinstaller
4. ☑️ Cocher "Supprimer le pilote"
**Étape 2 : Redémarrer**
Windows va installer un pilote basique temporaire.
**Étape 3 : Installer la dernière version**
1. Aller sur le site du fabricant (NVIDIA/AMD/Intel)
2. Télécharger le dernier pilote pour votre modèle
3. Installer et redémarrer à nouveau
⏱️ Temps total : 15-20 minutes
**Si le problème persiste** :
- Essayez de lancer l'application en mode compatibilité (Windows 8)
- Vérifiez les mises à jour Windows
- Je peux vous mettre en relation avec un technicien senior
Est-ce que vous souhaitez que je vous guide étape par étape, ou préférez-vous essayer seul(e) d'abord ?
Avantages :
- Résolution 24/7 : Pas d’attente
- Précision : IA voit exactement ce que voit l’utilisateur
- Scalabilité : Gérer des milliers de tickets simultanément
- Apprentissage : S’améliore avec chaque ticket résolu
Cas d’usage avancé : Système complet multimodal
Créons un assistant personnel multimodal combinant plusieurs modalités.
import os
from openai import OpenAI
import anthropic
import google.generativeai as genai
from pathlib import Path
import base64
import json
class MultimodalAssistant:
"""Assistant personnel multimodal intelligent"""
def __init__(self):
self.openai = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.anthropic = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
self.gemini = genai.GenerativeModel('gemini-1.5-pro')
self.conversation_history = []
def process_input(self, text=None, image=None, audio=None):
"""
Point d'entrée unifié : accepte texte, image et/ou audio
Choisit automatiquement le meilleur modèle selon le contexte
"""
input_modalities = []
if text: input_modalities.append("text")
if image: input_modalities.append("image")
if audio: input_modalities.append("audio")
# Sélection du modèle optimal
model = self._select_best_model(input_modalities, text)
# Préparation du contenu
content = self._prepare_content(text, image, audio)
# Traitement
response = self._query_model(model, content)
# Stocker dans historique
self._update_history(content, response)
return response
def _select_best_model(self, modalities, text):
"""Choisir le meilleur modèle selon le contexte"""
# Audio : GPT-4o pour transcription
if "audio" in modalities and not "image" in modalities:
return "gpt-4o-audio"
# Vidéo ou long contexte : Gemini
if text and len(text) > 50000:
return "gemini"
# Documents techniques/code : Claude
if text and any(keyword in text.lower() for keyword in ["code", "technique", "analyse", "pdf"]):
return "claude"
# Défaut : GPT-4o (polyvalent)
return "gpt-4o"
def _prepare_content(self, text, image, audio):
"""Préparer le contenu multimodal"""
content = []
if text:
content.append({"type": "text", "text": text})
if image:
if isinstance(image, str): # Path
with open(image, 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
content.append({
"type": "image_url",
"image_url": {"url": f"data:image/jpeg;base64,{image_b64}"}
})
else: # URL
content.append({"type": "image_url", "image_url": {"url": image}})
if audio:
# Transcription préalable
with open(audio, 'rb') as f:
transcript = self.openai.audio.transcriptions.create(
model="whisper-1",
file=f
)
content.append({
"type": "text",
"text": f"[Audio transcrit] : {transcript.text}"
})
return content
def _query_model(self, model, content):
"""Interroger le modèle sélectionné"""
if model == "gpt-4o" or model == "gpt-4o-audio":
response = self.openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Tu es un assistant personnel multimodal intelligent et serviable."},
{"role": "user", "content": content}
]
)
return response.choices[0].message.content
elif model == "claude":
# Claude nécessite format spécifique
formatted_content = []
for item in content:
if item["type"] == "text":
formatted_content.append(item)
elif item["type"] == "image_url":
# Extraire base64
image_data = item["image_url"]["url"].split(",")[1]
formatted_content.append({
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}
})
message = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2000,
messages=[{"role": "user", "content": formatted_content}]
)
return message.content[0].text
elif model == "gemini":
# Gemini accepte contenu multimodal directement
parts = []
for item in content:
if item["type"] == "text":
parts.append(item["text"])
# Gemini peut gérer images via URL ou upload
response = self.gemini.generate_content(parts)
return response.text
def _update_history(self, content, response):
"""Mettre à jour l'historique conversationnel"""
self.conversation_history.append({
"input": content,
"output": response,
"timestamp": datetime.now().isoformat()
})
def analyze_document(self, pdf_path):
"""Analyser un document PDF complet (multi-pages)"""
# Convertir PDF en images (une par page)
from pdf2image import convert_from_path
images = convert_from_path(pdf_path)
# Utiliser Claude pour documents techniques
pages_content = []
for i, image in enumerate(images):
# Sauver temporairement
temp_path = f"/tmp/page_{i}.jpg"
image.save(temp_path, "JPEG")
with open(temp_path, 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
pages_content.append({
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_b64
}
})
# Ajouter instruction
pages_content.insert(0, {
"type": "text",
"text": """Analyse ce document PDF. Pour chaque page, extrais :
- Titre et sections principales
- Points clés et informations importantes
- Tableaux, graphiques (décris-les)
- Formules mathématiques
Puis fournis un résumé global."""
})
# Envoyer à Claude
message = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4000,
messages=[{"role": "user", "content": pages_content}]
)
return message.content[0].text
def voice_conversation(self, audio_input_path):
"""
Conversation vocale complète :
Audio input → Transcription → Traitement → Synthèse vocale
"""
# Étape 1 : Transcrire
with open(audio_input_path, 'rb') as f:
transcript = self.openai.audio.transcriptions.create(
model="whisper-1",
file=f
)
user_text = transcript.text
print(f"Vous avez dit : {user_text}")
# Étape 2 : Générer réponse
response = self.process_input(text=user_text)
print(f"Assistant : {response}")
# Étape 3 : Synthèse vocale
speech = self.openai.audio.speech.create(
model="tts-1-hd",
voice="nova", # Voix féminine naturelle
input=response
)
# Sauvegarder audio
output_path = "response.mp3"
speech.stream_to_file(output_path)
return {
"transcription": user_text,
"response_text": response,
"audio_file": output_path
}
# =========================
# Exemples d'utilisation
# =========================
assistant = MultimodalAssistant()
# Cas 1 : Analyse d'image simple
response = assistant.process_input(
text="Qu'est-ce que tu vois dans cette image ?",
image="vacation_photo.jpg"
)
print(response)
# Cas 2 : Document technique
analysis = assistant.analyze_document("research_paper.pdf")
print("Résumé du document :", analysis)
# Cas 3 : Conversation vocale
result = assistant.voice_conversation("user_question.mp3")
# → Transcription, réponse textuelle ET audio generé
# Cas 4 : Multi-modal complexe
response = assistant.process_input(
text="J'ai enregistré ce message en réunion. Peux-tu analyser le slide présenté en même temps et me faire un résumé ?",
image="meeting_slide.jpg",
audio="meeting_recording.mp3"
)
print(response)
Ce système montre :
- ✅ Routing intelligent vers le meilleur modèle
- ✅ Fusion de multiples modalités
- ✅ Historique conversationnel
- ✅ Cas d’usage variés (analyse doc, conversation vocale, etc.)
- ✅ Architecture extensible (facile d’ajouter de nouveaux modèles)
Limites et défis
Hallucinations visuelles
Les modèles peuvent “voir” des choses qui n’existent pas dans l’image.
Exemple :
- Image : Photo d’un chien brun
- Modèle : “Je vois un chien brun avec un collier rouge”
- Réalité : Pas de collier visible
Causes :
- Entraînement sur corrélations statistiques (chien → collier fréquent)
- Résolution insuffisante (détails flous)
- Biais du dataset d’entraînement
Mitigation :
# Technique : Demander explicitement de vérifier
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{
"type": "text",
"text": """Décris cette image. IMPORTANT :
- Si tu n'es PAS SÛR d'un détail, indique "possiblement" ou "semble être"
- Ne mentionne QUE ce qui est clairement visible
- Si une partie est floue, mentionne-le"""
},
{"type": "image_url", "image_url": {"url": image_url}}
]
}]
)
Coûts élevés
Les tokens visuels coûtent 4-5x plus cher que les tokens textuels.
Comparaison des coûts :
| Action | Tokens équivalents | Coût GPT-4o |
|---|---|---|
| Texte : 1000 mots | ~1,300 tokens | $0.003 |
| Image : 1024×1024 | ~765 tokens | $0.008 |
| Image : 2048×2048 | ~1,105 tokens | $0.011 |
Optimisation :
- Réduire résolution si détails fins non nécessaires
- Cacher embeddings visuels pour requêtes répétées
- Utiliser modèles moins chers pour tâches simples (GPT-4o-mini)
# Exemple : Réduire résolution avant envoi
from PIL import Image
def optimize_image(image_path, max_size=1024):
"""Réduire taille pour économiser tokens"""
img = Image.open(image_path)
# Redimensionner si trop grand
if max(img.size) > max_size:
ratio = max_size / max(img.size)
new_size = (int(img.size[0] * ratio), int(img.size[1] * ratio))
img = img.resize(new_size, Image.Resampling.LANCZOS)
# Sauvegarder temporairement
temp_path = "/tmp/optimized.jpg"
img.save(temp_path, "JPEG", quality=85)
return temp_path
# Utilisation
optimized = optimize_image("high_res_photo.jpg", max_size=1024)
# → Économie de 30-50% sur les tokens
Latence accrue
Le traitement multimodal est plus lent que texte seul.
Temps de réponse typiques :
- Texte seul : 1-3 secondes
- Texte + Image : 3-8 secondes
- Texte + Audio : 5-10 secondes
- Vidéo : 30-60 secondes
Optimisation :
- Streaming de la réponse pour perception de rapidité
- Processing asynchrone pour tâches non-urgentes
- Caching agressif
# Streaming pour réduire latence perçue
response = client.chat.completions.create(
model="gpt-4o",
messages=[...],
stream=True # ← Réponse progressive
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
Confidentialité des images
Envoyer images à APIs externes = risque de confidentialité.
Solutions :
- Modèles locaux : LLaVA, Qwen-VL
- Anonymisation : Flouter visages, infos sensibles avant envoi
- APIs sur site : Azure OpenAI, Google Vertex AI avec VPC
# Exemple : Flouter visages avant envoi
import cv2
def anonymize_faces(image_path):
"""Flouter les visages détectés"""
img = cv2.imread(image_path)
# Détection de visages
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
faces = face_cascade.detectMultiScale(img, 1.1, 4)
# Flouter chaque visage
for (x, y, w, h) in faces:
face_region = img[y:y+h, x:x+w]
blurred = cv2.GaussianBlur(face_region, (99, 99), 30)
img[y:y+h, x:x+w] = blurred
# Sauvegarder
anonymized_path = "anonymized_" + image_path
cv2.imwrite(anonymized_path, img)
return anonymized_path
# Utilisation
safe_image = anonymize_faces("team_photo.jpg")
# Envoyer safe_image au lieu de l'original
Limites de résolution
Les modèles redimensionnent les images à des résolutions maximales :
- GPT-4o : ~2048px max
- Claude 3 : ~1568px max
- Gemini : ~3072px max
Impact : Perte de détails fins (texte petit, diagrammes complexes).
Solution :
# Découper image en tiles pour analyser haute résolution
def analyze_high_res_image(image_path):
"""Analyser image haute résolution par sections"""
img = Image.open(image_path)
# Découper en 4 quadrants
width, height = img.size
tiles = [
img.crop((0, 0, width//2, height//2)), # Haut gauche
img.crop((width//2, 0, width, height//2)), # Haut droit
img.crop((0, height//2, width//2, height)), # Bas gauche
img.crop((width//2, height//2, width, height)) # Bas droit
]
# Analyser chaque tile
analyses = []
for i, tile in enumerate(tiles):
tile_path = f"/tmp/tile_{i}.jpg"
tile.save(tile_path)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": f"Décris en détail cette section (quadrant {i+1}/4) de l'image."},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{encode_image(tile_path)}"}}
]
}]
)
analyses.append(response.choices[0].message.content)
# Synthèse globale
synthesis = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": f"""Voici les analyses de 4 sections d'une même image :
Quadrant 1 (haut gauche) : {analyses[0]}
Quadrant 2 (haut droit) : {analyses[1]}
Quadrant 3 (bas gauche) : {analyses[2]}
Quadrant 4 (bas droit) : {analyses[3]}
Fournis une description cohérente et complète de l'image entière."""
}]
)
return synthesis.choices[0].message.content
L’avenir du multimodal
Modèles “Any-to-Any”
La prochaine génération permettra n’importe quelle modalité vers n’importe quelle autre de manière native.
Exemples :
- Image → Audio : “Transforme cette partition en musique”
- Audio → Vidéo : “Crée une animation correspondant à cette musique”
- Texte → 3D : “Génère un modèle 3D de cette description”
Recherches en cours :
- ImageBind (Meta) : Espace d’embeddings unifié pour 6 modalités
- CoDi (Microsoft) : Any-to-any diffusion
- GPT-4o evolution : Omni multimodal complet
Temps réel
Vision : Conversations vidéo naturelles avec IA (comme Zoom).
Challenges techniques :
- Latence < 200ms (seuil de naturalité)
- Processing 30 FPS vidéo en temps réel
- Compréhension émotions et expressions faciales
Avancées récentes :
- GPT-4o : 232ms latence audio (proche humain : ~200ms)
- Gemini Flash : Streaming vidéo en temps quasi-réel
3D et réalité augmentée
Applications futures :
- Shopping AR : “Montre-moi ce canapé dans mon salon” (photo + 3D)
- Chirurgie assistée : Overlay AR avec informations patient
- Éducation immersive : Tuteurs holographiques
Technologies émergentes :
- NeRF (Neural Radiance Fields) : Reconstruction 3D depuis photos
- Gaussian Splatting : Rendu 3D photoréaliste temps réel
- Vision Pro + IA : Assistants contextuels AR
Intégration sensorielle avancée
Au-delà de la vision et l’audio :
Toucher :
- Génération de patterns haptiques depuis descriptions
- “Simule la texture de la soie” → feedback tactile
Olfactif :
- IA génération de parfums depuis descriptions
- “Crée un parfum évoquant une forêt après la pluie”
Gustatif :
- Recommandations recettes basées sur préférences gustatives
- Analyse photos de plats → prédiction saveurs
Exercices pratiques
Analyseur de CV multimodal
Objectif : Créer un système analysant CVs (PDF avec photo) et générant feedback.
Fonctionnalités :
- Extraire texte et analyser structure
- Analyser photo professionnelle (qualité, appropriée ?)
- Évaluer compétences techniques mentionnées
- Générer recommandations d’amélioration
Squelette de code :
def analyze_resume(pdf_path):
# 1. Convertir PDF en images
# 2. Envoyer à GPT-4o ou Claude
# 3. Extraire données structurées (JSON)
# 4. Générer feedback
pass
# Attendu : Score /100 + recommandations
Chatbot support technique avec vision
Objectif : Bot pouvant analyser screenshots d’erreurs et proposer solutions.
Features :
- Upload screenshot + description textuelle
- Détection automatique type d’erreur
- Recherche dans base de connaissance (RAG)
- Génération solution étape par étape
- Follow-up questions si besoin
Générateur de descriptions produits e-commerce
Objectif : Depuis photo produit, générer titre SEO, description, tags et catégorie.
Pipeline :
- Analyser image produit (GPT-4V)
- Extraire : catégorie, couleur, style, matériaux
- Générer titre optimisé SEO (50 caractères)
- Rédiger description marketing (200 mots)
- Proposer 10 tags pertinents
- Détecter produits similaires (CLIP embeddings)
Exemple résultat :
{
"titre": "Chaise de Bureau Ergonomique en Cuir Noir - Réglable",
"categorie": "Mobilier > Bureau > Chaises",
"description": "Découvrez le confort ultime avec cette chaise...",
"tags": ["ergonomique", "cuir", "noir", "réglable", "bureau"],
"couleur_dominante": "#1a1a1a",
"prix_suggere": 299.99,
"produits_similaires": ["prod_123", "prod_456"]
}
Conclusion
Les modèles multimodaux représentent un saut qualitatif majeur dans l’IA. En combinant vision, audio, texte et bientôt bien plus, ils se rapprochent de la compréhension holistique humaine.
Points clés à retenir :
- Architecture unifiée : Encodeurs spécialisés + fusion dans espace latent commun
- Acteurs majeurs : GPT-4o (polyvalent), Gemini (contexte massif), Claude (précision), LLaVA (open source)
- Applications concrètes : Accessibilité, e-commerce, éducation, santé, support client
- Défis : Hallucinations, coûts, latence, confidentialité
- Futur : Any-to-any, temps réel, AR/VR, intégration sensorielle
Recommandations :
- Débutants : Commencer avec GPT-4o (API simple, bien documentée)
- Entreprises : Claude 3 pour documents techniques, Gemini pour vidéos longues
- Confidentialité : LLaVA ou modèles on-premise
- Prototypage : Playgrounds web (OpenAI, Anthropic, Google)
Les modèles multimodaux ne sont plus une technologie futuriste : ils sont disponibles aujourd’hui et transforment déjà de nombreuses industries. Le moment est idéal pour expérimenter et innover !
Liens et ressources
Articles liés :
Documentation officielle :
Papers de recherche :
- CLIP (Learning Transferable Visual Models) - OpenAI 2021
- Flamingo (Multimodal Few-Shot Learning) - DeepMind 2022
- GPT-4V Technical Report - OpenAI 2023
- Gemini Technical Report - Google 2024
Tutoriels pratiques :