Modèles Multimodaux : Quand l'IA Voit, Entend et Parle

tl;dr: Les modèles multimodaux comme GPT-4V, Gemini et Claude 3 peuvent analyser et générer plusieurs types de contenu : texte, images, audio et vidéo. Cette capacité révolutionne l'IA en permettant une compréhension plus naturelle et complète du monde.

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.

💡 Définition : Un modèle multimodal est un modèle d’IA capable de traiter et de générer plusieurs types de données (modalités) de manière unifiée, en comprenant les relations entre elles.

Illustration détaillée de les modèles multimodaux combinant texte, image et audio

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 :

  1. Encodeurs spécialisés : Chaque modalité a son encodeur

    • Texte : Tokenizer + Transformer textuel
    • Image : Vision Transformer (ViT) ou CNN
    • Audio : Spectrogram + Transformer audio
  2. Projection dans l’espace unifié : Les embeddings de chaque modalité sont projetés dans un espace commun

  3. Fusion multimodale : Un Transformer central fusionne les informations

  4. 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 :

  1. Encode le texte “Quelle est la couleur du chat”
  2. Encode l’image (pixels → embeddings)
  3. Applique l’attention cross-modale : les tokens “couleur” et “chat” vont attendre aux régions de l’image contenant le chat
  4. Fusionne les informations pour générer “Le chat est orange”
🔎 Tip
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 :

  1. Vision Transformer (ViT) : Découpe l’image en patches (ex: 16×16 pixels)
  2. Embeddings visuels : Chaque patch devient un vecteur
  3. Projection : Les embeddings visuels sont projetés dans l’espace du modèle textuel
  4. Fusion : Les tokens visuels sont concaténés avec les tokens textuels
  5. 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 :

  1. Analyse de documents PDF complexes : Articles scientifiques avec formules mathématiques, tableaux, graphiques
  2. Diagrammes techniques : UML, architectures, flowcharts
  3. 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èleModalitésContextePrix (input)Points fortsOpen Source
GPT-4oTexte, Image, Audio128K$2.50/M text$10/M visionQualité, fonction calling
Gemini 1.5 ProTexte, Image, Audio, Vidéo2M$1.25/M text$2.50/M visionContexte massif, vidéo native
Claude 3.5 SonnetTexte, Image200K$3/M text$15/M visionPrécision, documents techniques
Claude 3 OpusTexte, Image200K$15/M text$75/M visionQualité maximale, complexité
LLaVA 1.6Texte, Image4K-8KGratuitOpen source, privacy, fine-tuning
Qwen-VLTexte, Image32KGratuitMultilingue, chinois excellent
💡 Note sur les prix : Les prix sont indicatifs (décembre 2024) et varient selon le fournisseur. Les modèles open source nécessitent infrastructure (GPU) donc coûts de compute.

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
⚠️ Warning
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

⚠️ Warning
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 :

ActionTokens équivalentsCoû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
💡 Vision long terme : IA intégrant l’ensemble des sens humains pour une compréhension véritablement holistique du monde. Nous n’en sommes qu’au début !

Exercices pratiques

Analyseur de CV multimodal

Objectif : Créer un système analysant CVs (PDF avec photo) et générant feedback.

Fonctionnalités :

  1. Extraire texte et analyser structure
  2. Analyser photo professionnelle (qualité, appropriée ?)
  3. Évaluer compétences techniques mentionnées
  4. 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 :

  1. Analyser image produit (GPT-4V)
  2. Extraire : catégorie, couleur, style, matériaux
  3. Générer titre optimisé SEO (50 caractères)
  4. Rédiger description marketing (200 mots)
  5. Proposer 10 tags pertinents
  6. 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 :

  1. Architecture unifiée : Encodeurs spécialisés + fusion dans espace latent commun
  2. Acteurs majeurs : GPT-4o (polyvalent), Gemini (contexte massif), Claude (précision), LLaVA (open source)
  3. Applications concrètes : Accessibilité, e-commerce, éducation, santé, support client
  4. Défis : Hallucinations, coûts, latence, confidentialité
  5. 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 :