Préparation aux entretiens de ML Multimodal

Questions d'entretien pour Ingénieur en Apprentissage Automatique Multimodal

15 questions d'entretien sélectionnées en apprentissage automatique multimodal, regroupées par niveau de séniorité. Utilisez-les pour réviser les fondamentaux, les compromis pratiques et le raisonnement de production de niveau senior.

Commencer un entretien d'IA en ML MultimodalAucune carte bancaire requise. 1 session gratuite disponible.
Préparation aux entretiens techniques en anglaisUn mode où les non-natifs peuvent s'entraîner à passer des entretiens techniques.

Questions Junior

1Expliquez l'idée fondamentale de l'apprentissage contrastif pour aligner les représentations d'images et de texte, et pourquoi un espace d'intégration partagé est utile.

L'idée fondamentale de l'apprentissage contrastif pour les représentations image-texte est de projeter les entrées d'image et de texte dans un espace vectoriel latent partagé de telle sorte que les paires sémantiquement correspondantes (positives) soient rapprochées, tandis que les paires non correspondantes (négatives) soient éloignées. En entraînant des encodeurs visuels et textuels séparés à l'aide d'objectifs de similarité (comme la similarité cosinus), le modèle aligne la sémantique des pixels visuels continus avec les tokens textuels discrets. Un espace d'intégration partagé est utile car il permet de résoudre les tâches multimodales directement via une recherche de similarité vectorielle. Dans cet espace unifié, la récupération intermodale (trouver des images à partir de requêtes textuelles, ou vice-versa) et la classification zéro-shot (évaluer un embedding d'image par rapport à des embeddings de prompt tels que 'une photo d'un chien') deviennent de simples recherches par plus proche voisin ou produit scalaire très efficaces, sans nécessiter de têtes de classificateur spécifiques à la tâche.

import torch
import torch.nn.functional as F

# image_features: [B, D], text_features: [B, D]
image_norm = F.normalize(image_features, dim=-1)
text_norm = F.normalize(text_features, dim=-1)

# Pairwise cosine similarity matrix: [B, B]
sim_matrix = image_norm @ text_norm.T
# Positive pairs lie on the diagonal; off-diagonals are negatives
Essayer de répondre à cette question avec un coach IA

2Expliquez l'architecture à double encodeur de type CLIP et les hypothèses qu'elle fait concernant l'interaction image-texte.

L'architecture à double encodeur de type CLIP se compose de deux réseaux neuronaux distincts et découplés : un encodeur visuel (par exemple, Vision Transformer ou ResNet) qui traite les images en vecteurs de caractéristiques visuelles, et un encodeur de texte (par exemple, Transformer) qui traite le texte en vecteurs de caractéristiques textuelles. Les deux représentations sont projetées dans une dimension d'intégration commune, où l'alignement est mesuré à l'aide d'une métrique de similarité simple (telle que la similarité cosinus normalisée ou le produit scalaire). L'hypothèse architecturale fondamentale est la fusion tardive (ou interaction cross-modale factorisée) : les modalités d'image et de texte n'interagissent pas au niveau des couches intermédiaires via l'attention croisée ou les interactions au niveau des jetons. Au lieu de cela, la sémantique complète de chaque modalité est supposée être compressible en un unique résumé vectoriel dense, et l'interaction cross-modale est supposée être entièrement décomposable en un produit interne. Ce compromis privilégie une efficacité de récupération extrême (permettant un pré-calcul hors ligne des intégrations d'images pour la recherche vectorielle à l'échelle de milliards) plutôt qu'un raisonnement cross-modal à grain fin (tel que l'ancrage jeton-région ou les relations spatiales compositionnelles complexes).

import torch
import torch.nn as nn
import torch.nn.functional as F

class CLIPDualEncoder(nn.Module):
    def __init__(self, visual_encoder, text_encoder, img_dim, txt_dim, embed_dim):
        super().__init__()
        self.visual_encoder = visual_encoder
        self.text_encoder = text_encoder
        self.img_proj = nn.Linear(img_dim, embed_dim, bias=False)
        self.txt_proj = nn.Linear(txt_dim, embed_dim, bias=False)
        self.logit_scale = nn.Parameter(torch.ones([]) * 2.659)

    def forward(self, images, text_tokens):
        # Independent uncoupled encoding
        v_feat = self.img_proj(self.visual_encoder(images))
        t_feat = self.txt_proj(self.text_encoder(text_tokens))
        # L2 normalize
        v_norm = F.normalize(v_feat, p=2, dim=-1)
        t_norm = F.normalize(t_feat, p=2, dim=-1)
        # Late interaction via dot product
        return torch.matmul(v_norm, t_norm.T) * self.logit_scale.exp()
Essayer de répondre à cette question avec un coach IA

3Décrivez l'intuition derrière la projection des caractéristiques d'image et de texte dans un espace normalisé commun et l'optimisation de la similarité cosinus.

La projection des caractéristiques d'image et de texte dans un espace normalisé commun (généralement sur une hypersphère unitaire via la normalisation L2) et l'optimisation de la similarité cosinus découplent la direction sémantique d'un embedding de la magnitude de son vecteur. Sans normalisation, un produit scalaire non contraint permet au modèle de minimiser la perte d'entraînement (training loss) en gonflant trivialement les normes des caractéristiques pour des échantillons faciles ou fréquents, plutôt que d'aligner leurs directions sémantiques.<br><br>La normalisation des vecteurs sur l'hypersphère unitaire borne les valeurs de similarité strictement dans [-1, 1], garantissant que la distance correspond purement à la séparation angulaire. Cela stabilise les gradients d'optimisation, empêche l'explosion ou l'effondrement de la représentation, et garantit que chaque échantillon d'un lot contribue équitablement à la perte, quelles que soient les différences d'échelle spécifiques à la modalité. Lorsqu'elle est associée à un paramètre de température apprenable, cela contrôle la netteté de la distribution de probabilité sur l'hypersphère pour équilibrer l'alignement des vraies paires avec la dispersion uniforme des paires négatives.

import torch
import torch.nn.functional as F

# Unnormalized embeddings with extreme norm differences
v = torch.tensor([[10.0, 0.0], [0.1, 0.0]])
t = torch.tensor([[5.0, 0.0], [0.1, 0.0]])

# Raw dot products: heavily distorted by magnitude (50.0 vs 0.01)
raw_dot = v @ t.T

# L2 Normalized:
v_norm = F.normalize(v, p=2, dim=-1)
t_norm = F.normalize(t, p=2, dim=-1)
cosine_sim = v_norm @ t_norm.T
print('Cosine similarity matrix:\n', cosine_sim)
Essayer de répondre à cette question avec un coach IA

4Expliquez l'ancrage visuel (visual grounding) et la compréhension d'expression référentielle (referring expression comprehension) en tant que localisation conditionnée par le langage, et comment ils diffèrent de la similarité au niveau de l'image.

L'ancrage visuel (visual grounding), souvent mis en œuvre sous forme de compréhension d'expression référentielle (Referring Expression Comprehension, ou REC), est la tâche de localiser une région visuelle spécifique, une boîte englobante ou un masque de segmentation dans une image basée sur une expression référentielle en langage naturel (par exemple, 'l'homme portant une veste bleue à côté de la lampe'). Il traite la localisation comme étant conditionnée par le langage, exigeant que le modèle résolve les relations spatiales linguistiques, les attributs et les identités d'objets jusqu'aux coordonnées de pixels ou spatiales. Cela diffère fondamentalement de la similarité au niveau de l'image, qui calcule un score d'affinité sémantique holistique unique entre une image entière et une chaîne de texte (par exemple, déterminer si une image correspond à la légende 'un homme dans un parc'). La similarité au niveau de l'image ne produit pas de coordonnées spatiales, peut faire correspondre des images où l'objet référencé n'est pas localisé de manière unique, et échoue souvent à résoudre une désambiguïsation référentielle fine entre plusieurs objets similaires dans la même scène.

# Image-level similarity:
# Input: Image I, Text T ("black dog sitting on the left")
# Output: scalar score s in [0, 1] or dot product
similarity_score = image_text_model(image, text)

# Referring Expression Comprehension (Visual Grounding):
# Input: Image I, Text T ("black dog sitting on the left")
# Output: Bounding box coordinates [x_min, y_min, x_max, y_max]
bbox = grounding_model.predict_box(image, text)
Essayer de répondre à cette question avec un coach IA

5Expliquez l'attention croisée (cross-attention) comme mécanisme de fusion entre les jetons visuels et les jetons textuels dans les transformeurs multimodaux.

Dans les transformeurs multimodaux, l'attention croisée agit comme un mécanisme de fusion asymétrique où une modalité dirige des requêtes (Q) pour s'attacher aux clés (K) et valeurs (V) extraites d'une autre modalité. Par exemple, lorsque les jetons visuels agissent comme des requêtes et les jetons textuels comme des clés et des valeurs, chaque jeton visuel calcule une somme pondérée par l'attention sur les représentations textuelles, conditionnant dynamiquement les caractéristiques visuelles sur le contexte textuel (et vice-versa lorsque le texte interroge les jetons visuels). Mathématiquement, étant donné une séquence visuelle X_v et une séquence textuelle X_t, l'attention croisée calcule : ``` CrossAttention(Q_v, K_t, V_t) = softmax((Q_v * K_t^T) / sqrt(d)) * V_t ``` Où Q_v = X_v * W_Q, K_t = X_t * W_K, et V_t = X_t * W_V. Ce mécanisme permet au modèle d'effectuer un alignement sémantique fin jeton-à-jeton entre les modalités, quelles que soient les différences de longueurs de séquence ou d'espaces de caractéristiques initiaux. Une fusion bidirectionnelle peut être réalisée en utilisant deux couches d'attention croisée symétriques (par exemple, vision-vers-langage et langage-vers-vision) ou en alternant les blocs d'attention croisée.

import torch
import torch.nn as nn

class MultimodalCrossAttention(nn.Module):
    def __init__(self, d_model, n_heads):
        super().__init__()
        self.mha = nn.MultiheadAttention(embed_dim=d_model, num_heads=n_heads, batch_first=True)
        self.norm = nn.LayerNorm(d_model)

    def forward(self, visual_query_tokens, text_kv_tokens):
        # visual_query_tokens: [B, N_v, D], text_kv_tokens: [B, N_t, D]
        attn_out, _ = self.mha(
            query=visual_query_tokens, 
            key=text_kv_tokens, 
            value=text_kv_tokens
        )
        # Residual connection and normalization
        output = self.norm(visual_query_tokens + attn_out)
        return output
Essayer de répondre à cette question avec un coach IA

6Expliquez comment les augmentations d'images telles que le recadrage, le jitter de couleur et la compression peuvent aider ou nuire à l'alignement contrastif image-texte.

Dans l'apprentissage contrastif multimodal (comme CLIP), les augmentations d'images servent un objectif différent que dans l'apprentissage auto-supervisé unimodal (comme SimCLR). Parce que les images sont mises en contraste avec des légendes textuelles appariées plutôt qu'avec une autre vue augmentée de la même image, les augmentations peuvent à la fois bénéficier et corrompre l'apprentissage des représentations. **Comment les augmentations aident :** 1. **Prévenir l'apprentissage par raccourci :** Les augmentations légères (telles que le recadrage aléatoire, les retournements horizontaux légers et le jitter de couleur modéré) empêchent l'encodeur visuel de s'appuyer sur des artefacts visuels de bas niveau triviaux (par exemple, les distributions de couleurs d'arrière-plan, les filigranes de coin ou les biais de position spatiale). 2. **Invariance au point de vue et à l'échelle :** La mise à l'échelle et le recadrage modérés encouragent le modèle à identifier des objets sémantiques à travers différentes distances focales et perspectives, assurant une généralisation robuste sans exemples. **Comment les augmentations peuvent nuire (désalignement sémantique) :** 1. **Recadrage aléatoire agressif :** Si une légende décrit un objet spécifique (« un oiseau perché sur une branche ») et qu'un recadrage agressif coupe entièrement l'oiseau, le recadrage restant (juste des feuilles/ciel) est toujours forcé de s'aligner avec la légende de l'oiseau. Cela introduit un faux bruit de supervision et dégrade la précision de la récupération. 2. **Fort jitter de couleur / Inversion de teinte :** De nombreuses légendes décrivent explicitement les attributs de couleur (« un taxi jaune », « une pomme rouge »). De forts changements de couleur transforment le taxi en bleu ou la pomme en vert, ce qui provoque une contradiction sémantique directe entre l'entrée visuelle et la légende textuelle. 3. **Flou et compression intenses :** Le sous-échantillonnage spatial agressif, la compression JPEG ou le flou gaussien détruisent les indices textuels à grain fin (texte OCR (Reconnaissance Optique de Caractères) sur les panneaux, logos, textures fines) qui sont explicitement décrits dans les légendes appariées. **Règle pratique :** L'entraînement contrastif multimodal nécessite des augmentations significativement plus conservatrices (par exemple, un recadrage redimensionné aléatoire avec une plage d'échelle [0.5, 1.0] et un retournement léger) que l'apprentissage auto-supervisé unimodal.

from torchvision import transforms

# Multimodal contrastive transform: conservative to preserve caption semantics
clip_transforms = transforms.Compose([
    transforms.RandomResizedCrop(224, scale=(0.5, 1.0)),  # Conservative crop avoids dropping described entities
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.481, 0.457, 0.408], std=[0.268, 0.261, 0.275])
])

# Unimodal self-supervised transform: aggressive, risks breaking image-text alignment
simclr_heavy_transforms = transforms.Compose([
    transforms.RandomResizedCrop(224, scale=(0.08, 1.0)), # Extreme crop can remove captioned subjects
    transforms.RandomApply([transforms.ColorJitter(0.8, 0.8, 0.8, 0.2)], p=0.8), # Alters color adjectives
    transforms.RandomGrayscale(p=0.2),
    transforms.GaussianBlur(kernel_size=23, sigma=(0.1, 2.0)), # Destroys fine OCR/textures
    transforms.ToTensor()
])
Essayer de répondre à cette question avec un coach IA

7Expliquez la récupération image-texte en tant que tâche et la différence entre l'appariement en ensemble fermé (closed-set matching) et la récupération en monde ouvert (open-world retrieval) sur de vastes corpus.

La récupération image-texte est la tâche consistant à trouver des données correspondantes à travers différentes modalités à partir d'une requête dans une modalité (texte vers image ou image vers texte), généralement accomplie en mappant les images et les textes dans un espace de représentation partagé où la similarité est corrélée à la pertinence. L'appariement en ensemble fermé suppose un pool de candidats fixe et prédéfini avec des paires de vérité terrain connues (comme les benchmarks standards Flickr30k ou MS-COCO), permettant un calcul exhaustif de similarité par paires ou une attention croisée de tous à tous. La récupération en monde ouvert opère sur des corpus massifs, dynamiques et non-curés (par exemple, des millions ou des milliards d'éléments web ou de catalogue) où les pools de candidats sont illimités, les distracteurs et les faux négatifs sont prévalents, et des index de recherche de plus proches voisins approximatifs (ANN - Approximate Nearest Neighbor) (par exemple, Faiss, HNSW) sont nécessaires car une attention croisée exhaustive sur toutes les paires est intractable du point de vue computationnel.

import torch
import torch.nn.functional as F

# Closed-set matching: full pairwise similarity matrix over fixed evaluation set
image_embeds = F.normalize(torch.randn(1000, 512), dim=-1)
text_embeds = F.normalize(torch.randn(1000, 512), dim=-1)
sim_matrix = torch.matmul(text_embeds, image_embeds.T)  # (1000, 1000)

# Open-world retrieval: query vector queried against an indexed corpus using ANN
# index = faiss.IndexHNSWFlat(512, 32)
# distances, indices = index.search(query_embed, k=10)
Essayer de répondre à cette question avec un coach IA

Questions Middle

8Comparez les fonctions de perte contrastives de type softmax InfoNCE aux fonctions de perte sigmoïdes par paires pour l'apprentissage d'embeddings image-texte.

Les fonctions de perte contrastives de type InfoNCE (comme dans CLIP) traitent l'alignement comme un problème de classification multiclasse catégorielle. Pour chaque échantillon, elles calculent une distribution softmax sur toutes les paires négatives candidates dans le lot, normalisant les similarités sur l'ensemble du pool de lots. En revanche, les fonctions de perte contrastives sigmoïdes par paires (comme dans SigLIP) traitent chaque entrée de la matrice de similarité image-texte comme une tâche de classification binaire indépendante, appliquant une fonction sigmoïde et une perte d'entropie croisée binaire par paire (les paires positives ciblent +1, les paires négatives ciblent -1). Les différences clés sont : 1. **Couplage vs. Découplage :** InfoNCE couple tous les négatifs via le dénominateur de partition softmax global, provoquant une compétition où les négatifs les plus difficiles dominent les gradients. SigLIP découple toutes les paires, évaluant chacune indépendamment. 2. **Scalabilité et efficacité distribuées :** InfoNCE nécessite la collecte des matrices de similarité à travers les GPU pour une normalisation globale (goulot d'étranglement de communication all-gather). La perte par paires indépendante de SigLIP peut être calculée localement sans normalisation softmax inter-GPU globale, améliorant l'efficacité de la mise à l'échelle et restant stable pour des tailles de lot à la fois petites et très grandes.

import torch
import torch.nn.functional as F

def siglip_loss(sim_matrix, temperature, bias):
    # sim_matrix: [B, B] dot product of normalized embeddings
    # targets: 1 on diagonal (positive), -1 on off-diagonals (negative)
    B = sim_matrix.size(0)
    targets = 2 * torch.eye(B, device=sim_matrix.device) - 1.0
    logits = sim_matrix * temperature + bias
    # Pairwise binary cross entropy with log-sigmoid
    return -torch.mean(F.logsigmoid(targets * logits))
Essayer de répondre à cette question avec un coach IA

9Expliquez comment les négatifs difficiles et les faux négatifs affectent l'apprentissage contrastif image-texte.

Les négatifs difficiles et les faux négatifs ont des effets contrastés sur l'apprentissage contrastif image-texte : 1. **Négatifs difficiles** : Ce sont des paires non correspondantes qui sont sémantiquement ou visuellement très proches de l'ancre (par exemple, une image d'un husky sibérien associée à la légende « un malamute de l'Alaska »). Les négatifs difficiles fournissent des signaux de gradient informatifs et de forte magnitude. Ils forcent le modèle à regarder au-delà des caractéristiques de catégorie grossières et à apprendre des détails visuo-linguistiques à grain fin et des frontières de décision nettes. 2. **Faux négatifs** : Ils se produisent lorsque des paires « négatives » échantillonnées aléatoirement dans le lot sont en fait des correspondances sémantiques valides (par exemple, deux photos distinctes de golden retrievers où l'une est associée comme négatif à « un mignon golden retriever dans un parc »). Les faux négatifs pénalisent les alignements sémantiques corrects en forçant le modèle à éloigner les représentations de correspondance valides. Cela corrompt les gradients, dégrade la qualité de la représentation et supprime la synonymie légitime et la variance visuelle. Les stratégies d'atténuation des faux négatifs incluent les objectifs contrastifs avec lissage des étiquettes / soft, l'apprentissage contrastif débiaisé, la déduplication de l'ensemble de données et la correspondance multi-positive.

import torch
import torch.nn.functional as F

# Image 0 and Image 1 both depict 'a red sports car'
# Text 0: 'a red sports car', Text 1: 'a fast red car'
# In standard InfoNCE, Text 1 is treated as a negative for Image 0.
sim = torch.tensor([[0.95, 0.90],   # Image 0 similarities
                    [0.88, 0.94]])  # Image 1 similarities

loss_img0 = -F.log_softmax(sim / 0.07, dim=-1)[0, 0]
print(f'InfoNCE loss for Image 0: {loss_img0.item():.4f}')
# High similarity to false negative Text 1 (0.90) heavily penalizes the model
Essayer de répondre à cette question avec un coach IA

10Comparez l'alignement global image-texte avec les objectifs d'alignement au niveau de la région ou du jeton.

L'alignement global image-texte projette une image entière et une séquence de texte entière dans des vecteurs d'incorporation holistiques uniques (par exemple, via des caractéristiques mises en commun dans CLIP) et les aligne à l'aide d'un objectif contrastif comme InfoNCE. Cela offre d'excellentes propriétés de mise à l'échelle, des représentations rapidement indexables pour la récupération et un fort regroupement sémantique. Cependant, il souffre d'une granularité spatiale grossière, a du mal avec les détails visuels à grain fin, la compositionnalité, le comptage et les relations spatiales, et présente fréquemment des problèmes de liaison d'attributs. En revanche, l'alignement au niveau de la région ou du jeton (par exemple, jetons de patch, caractéristiques de boîtes englobantes d'objets) fonctionne à des granularités sub-image et sub-phrase (par exemple, jetons de mots ou de sous-mots) à grain fin. Des méthodes comme FILIP, GLIP ou VinVL alignent les jetons via des pertes contrastives à grain fin (telles que la similarité maximale par jeton ou la similarité de Chamfer) ou le transport optimal / l'alignement par attention croisée. Cela préserve explicitement les détails compositionnels spatiaux et linguistiques, permettant la détection d'objets, l'ancrage visuel et la liaison précise d'attributs, mais au prix d'une complexité computationnelle et de mémoire plus élevée, d'une latence d'inférence plus lourde et de signaux d'alignement plus bruyants.

import torch
import torch.nn.functional as F

# visual_tokens: [B, N_v, D], text_tokens: [B, N_t, D]
def token_level_maxsim_similarity(visual_tokens, text_tokens):
    v_norm = F.normalize(visual_tokens, dim=-1)
    t_norm = F.normalize(text_tokens, dim=-1)
    # Compute similarity matrix between all visual and text tokens: [B, N_t, N_v]
    sim_matrix = torch.bmm(t_norm, v_norm.transpose(1, 2))
    # Text-to-image: For each word token, find maximum visual token similarity and average
    t2i_sim = sim_matrix.max(dim=-1).values.mean(dim=-1) # [B]
    return t2i_sim
Essayer de répondre à cette question avec un coach IA

11Comparez la fusion précoce, la fusion tardive, la fusion intermédiaire, la fusion par attention croisée, la fusion à portes et la concaténation pour les modèles multimodaux.

Les stratégies de fusion multimodale intègrent les signaux visuels et linguistiques à différentes profondeurs et configurations structurelles : 1. **Fusion précoce (Early Fusion)** : Les caractéristiques brutes ou de bas niveau (par exemple, les intégrations de patchs d'image et les intégrations de jetons de mots) sont fusionnées au stade de l'entrée et alimentées dans un unique réseau de base (backbone) partagé. Cela permet des interactions intermodales profondes dès la première couche, mais est coûteux en calcul et rend plus difficile la réutilisation du pré-entraînement unimodal. 2. **Fusion tardive (Late Fusion)** : Les modalités sont traitées indépendamment par des réseaux de base unimodaux profonds en vecteurs de représentation globale, qui sont combinés uniquement à la toute fin via une agrégation simple (par exemple, produit scalaire, similarité cosinus ou un MLP (réseau neuronal multi-couches) peu profond). C'est extrêmement efficace et idéal pour la récupération indexable, mais ne peut pas capturer les interactions intermodales fines. 3. **Fusion intermédiaire (Intermediate Fusion)** : Les réseaux de base unimodaux traitent les entrées pendant plusieurs couches, et la fusion se produit à des étapes intermédiaires à travers des couches partagées ou des connexions latérales, trouvant un équilibre entre spécialisation unimodale et interaction multimodale. 4. **Fusion par attention croisée (Cross-Attention Fusion)** : Utilise l'attention multi-têtes (multi-head attention) où une modalité fournit les requêtes (queries) et l'autre fournit les clés/valeurs (keys/values). Elle offre une grande capacité de représentation avec un conditionnement jeton à jeton, s'adaptant à des longueurs de séquence hétérogènes. 5. **Fusion à portes (Gated Fusion)** : Utilise des mécanismes de gating appris (par exemple, des portes sigmoïdes ou tanh) pour pondérer dynamiquement la contribution de chaque modalité ou couche de fusion basée sur la confiance contextuelle, empêchant une modalité de dominer ou de corrompre les poids pré-entraînés. 6. **Concaténation (Concatenation)** : Fusionne des vecteurs de caractéristiques ou des séquences de jetons le long de la dimension des caractéristiques (concaténation de caractéristiques) ou de la dimension de la longueur de séquence (concaténation de jetons avant un transformeur unifié). C'est simple et non paramétrique, mais la concaténation de caractéristiques nécessite des dimensions spatiales/temporelles alignées, tandis que la concaténation de jetons scale quadratiquement avec la longueur totale de la séquence dans l'auto-attention.

import torch
import torch.nn as nn
import torch.nn.functional as F

# 1. Concatenation along feature dimension
z_concat = torch.cat([img_feat, txt_feat], dim=-1) # [B, D_img + D_txt]

# 2. Gated Fusion
gate = torch.sigmoid(gate_layer(z_concat)) # [B, D]
z_gated = gate * img_proj + (1 - gate) * txt_proj

# 3. Late Fusion (Score level)
similarity = torch.sum(F.normalize(img_feat, dim=-1) * F.normalize(txt_feat, dim=-1), dim=-1)
Essayer de répondre à cette question avec un coach IA

12Comparez les modèles de récupération à double encodeur (dual-encoder retrieval models) avec les re-rankers à encodeur croisé (cross-encoder rerankers) pour la correspondance image-texte en termes de capacité d'interaction, de précision et de latence.

Les modèles à double encodeur (ou bi-encodeur) et les re-rankers à encodeur croisé représentent deux paradigmes distincts pour la correspondance image-texte, présentant des compromis fondamentaux entre la capacité d'interaction, la précision et la latence : 1. **Capacité d'interaction :** * **Double-encodeurs** (par exemple, CLIP) : Traitent l'image et le texte via des backbones séparés et découplés. L'interaction multimodale est strictement tardive et superficielle, limitée à un seul produit scalaire ou une similarité cosinus entre des vecteurs regroupés globalement. Ils manquent d'interactions cross-modales au niveau des tokens. * **Encodeurs croisés** (par exemple, UNITER, ViLT, branche multimodale ALBEF) : Concatènent les tokens visuels et textuels dans un transformateur partagé ou utilisent des couches d'attention croisée. Chaque token visuel peut interagir avec chaque token textuel à travers plusieurs couches, permettant un raisonnement cross-modal profond. 2. **Précision :** * Les double-encodeurs atteignent une précision inférieure sur les requêtes compositionnelles complexes, les relations spatiales, la négation et la correspondance d'attributs à grain fin en raison du goulot d'étranglement des représentations à vecteur unique. * Les encodeurs croisés atteignent une précision significativement plus élevée sur les tâches de correspondance image-texte complexes, à grain fin et compositionnelles. 3. **Latence et Scalabilité :** * Les double-encodeurs permettent de pré-calculer et d'indexer les embeddings d'image hors ligne dans une base de données vectorielle (par exemple, Milvus, FAISS). Au moment de l'inférence, seule la requête textuelle est encodée, et la recherche parmi des millions de candidats ne nécessite que de légers produits scalaires du plus proche voisin approximatif (ANN) (latence de l'ordre de la sous-milliseconde). * Les encodeurs croisés nécessitent d'exécuter le réseau neuronal joint complet pour chaque paire candidate (image, texte) au moment de la requête (O(N) passages avant pour N candidats), ce qui entraîne une latence supérieure de plusieurs ordres de grandeur et les rend prohibitives en termes de calcul pour la récupération de première étape sur de grands corpus. Dans les systèmes de production pratiques, un pipeline à deux étapes est standard : un double-encodeur récupère les K meilleurs candidats (par exemple, K=100) avec une faible latence, suivi d'un encodeur croisé qui les reclasse pour une grande précision.

# Stage 1: Dual-Encoder First-Stage Retrieval (Fast, Vector Index)
query_emb = text_encoder(query_text) # [1, D]
# Cosine similarity over pre-indexed image embeddings [N, D]
scores = query_emb @ precomputed_image_embeddings.T # [1, N]
top_k_indices = torch.topk(scores, k=100).indices[0]

# Stage 2: Cross-Encoder Reranker (Accurate, Token Interaction)
candidate_images = [load_image(idx) for idx in top_k_indices]
rerank_scores = cross_encoder(candidate_images, [query_text] * 100) # Full cross-attention
final_ranking = top_k_indices[torch.argsort(rerank_scores, descending=True)]
Essayer de répondre à cette question avec un coach IA

Questions Senior

13Concevez un système RAG multimodal sur des fichiers PDF (Portable Document Format) ou des manuels contenant du texte, des tableaux, des graphiques, des captures d'écran, des diagrammes et des images intégrées.

Un système RAG (Retrieval Augmented Generation) multimodal de bout en bout pour les documents visuels complexes (PDF, manuels, rapports) s'étend sur quatre étapes architecturales principales : 1. **Ingestion et Analyse Sensible à la Mise en Page** : Les pages PDF sont traitées via des modèles de documents sensibles à la mise en page (par exemple, LayoutLM, DocTR) ou des pipelines d'analyse visuelle pour segmenter le contenu en blocs structurés : passages de texte, tableaux structurés (convertis en HTML (HyperText Markup Language)/Markdown avec des étendues de cellules), images de graphiques rendus avec des séries de données, et diagrammes ou captures d'écran autonomes avec des boîtes englobantes spatiales. 2. **Indexation Multimodale et Double Représentation** : * **Actifs Visuels (Graphiques, Captures d'écran, Diagrammes)** : Stockés sous forme de recadrages d'images avec des embeddings multimodaux denses (par exemple, SigLIP, CLIP, ou jetons de patch visuel ColPali) ainsi que des résumés textuels synthétiques et du texte OCR (Optical Character Recognition) généré par un VLM (Vision-Language Model), stockés dans un index de texte dense. * **Tableaux** : Stockés en Markdown/HTML structuré dans des index vectoriels de texte et BM25 (Best Matching 25). * **Texte** : Découpé par section sémantique et indexé via des embeddings denses et des mots-clés épars. 3. **Récupération Hybride et Re-classement Multimodal** : * **Récupération de Première Étape** : Exécute une récupération parallèle à travers les indices BM25 épars (mots-clés, texte OCR, balisage de tableau), les vecteurs de texte denses et les indices d'embedding visuels (recherche ANN (Approximate Nearest Neighbor)). * **Fusion et Re-classement** : Fusionne les candidats (par exemple, via Reciprocal Rank Fusion) et évalue les meilleurs éléments en utilisant un cross-encoder multimodal ou un modèle d'interaction visuelle tardive (évaluant le texte de la requête par rapport aux recadrages d'images haute résolution et au texte analysé). 4. **Assemblage de Contexte Multimodal et Génération Fondée** : Le contexte multimodal Top-$k$ — patchs d'images rendus, schémas de tableaux et passages de texte avec métadonnées de document/page — est passé à un VLM (Vision-Language Model) réglé par instruction (par exemple, GPT-4o, Claude 3.5 Sonnet, ou Qwen2-VL open source). L'invite de génération impose la provenance de la source en exigeant des citations explicites (numéros de page, numéros de figure ou boîtes englobantes).

from dataclasses import dataclass
from typing import Optional, List

@dataclass
class MultimodalChunk:
    chunk_id: str
    document_id: str
    page_number: int
    modality_type: str  # 'text', 'table', 'chart', 'diagram'
    text_payload: str   # Raw text or structured Markdown/HTML
    vlm_caption: Optional[str] = None  # Synthetic summary of visual content
    bbox: Optional[List[float]] = None  # [x0, y0, x1, y1]
    image_crop_path: Optional[str] = None
    dense_embedding: Optional[List[float]] = None

# Indexing strategy: Text search covers text_payload + vlm_caption;
# Multimodal search matches dense_embedding or visual tokens.
Essayer de répondre à cette question avec un coach IA

14Expliquez comment l'évaluation RAG multimodal (Retrieval Augmented Generation) devrait mesurer séparément la qualité de la récupération, l'utilisation des preuves, la provenance et la fidélité de la réponse finale.

L'évaluation du RAG multimodal nécessite de décomposer le système en quatre dimensions d'évaluation découplées pour déterminer si les erreurs proviennent de la récupération, de la consommation de contexte, de la précision de la citation ou de la génération : 1. Qualité de la récupération : Évalue si le système de récupération identifie les morceaux visuels et textuels nécessaires. Les métriques clés incluent Recall@K, NDCG@K et MRR multimodaux. Pour les éléments visuels, cela inclut également l'IoU visuel / Rappel de boîtes englobantes (si le recadrage d'image récupéré contient le diagramme/graphique pertinent) et l'Équilibre du rappel de modalité (garantissant que les modalités non textuelles comme les tableaux et les graphiques ne sont pas systématiquement omises). 2. Utilisation des preuves (Suffisance et Nécessité) : Mesure si le modèle de génération s'appuie réellement sur les preuves multimodales récupérées plutôt que de générer des réponses purement à partir de la mémoire paramétrique. Ceci est mesuré via la Pertinence du contexte (précision des tokens visuels/textuels récupérés soutenant la question), la Nécessité des preuves / Tests d'ablation (masquer ou supprimer le graphique/tableau récupéré pour vérifier si la réponse échoue), et l'analyse d'attribution par attention croisée. 3. Provenance et Précision de la citation : Mesure si les attributions de source sont précises et vérifiables. Évalué via la Précision, le Rappel et le F1 sur les citations (noms de documents, numéros de page, identifiants de figures ou coordonnées de boîtes englobantes). Des vérifications automatisées s'assurent que la boîte englobante ou la page citée contient réellement la preuve de vérité terrain nécessaire pour répondre à la question. 4. Fidélité et Exactitude de la réponse finale : - Fidélité / Ancrage : Évalue si chaque affirmation générée est impliquée par le contexte multimodal récupéré sans hallucination (généralement évalué via un VLM (grand modèle visuel-linguistique) comme juge vérifiant l'implication des affirmations par rapport aux textes et aux recadrages visuels). - Exactitude factuelle : Évalue si la réponse générée correspond à la vérité terrain. - Robustesse au refus : Teste si le modèle refuse correctement de répondre lorsque le contexte récupéré est non pertinent ou contradictoire.

# Evaluation record schema for a single Multimodal RAG query:
eval_record = {
    'retrieval_quality': {
        'hit_at_k': True,          # Top-3 chunks contain target diagram
        'visual_bbox_iou': 0.85    # Retrieved crop overlap with true figure region
    },
    'evidence_utilization': {
        'necessity_ablation_passed': True  # Removing chart causes answer to fail
    },
    'provenance': {
        'page_match': True,        # Cited Page 12 (Ground Truth Page 12)
        'figure_id_match': True    # Cited 'Figure 4'
    },
    'faithfulness': {
        'claim_entailment_score': 1.0,  # All claims entailed by context
        'hallucination_detected': False
    }
}
all_passed = all(all(metrics.values()) for metrics in eval_record.values())
print(f'System passes all decoupled checks: {all_passed}')
Essayer de répondre à cette question avec un coach IA

15Réfléchissez à la mise à jour des modèles de récupération multimodaux en production lorsque les embeddings et les index de la galerie doivent être rafraîchis à grande échelle.

La mise à jour d'un système de récupération multimodal à grande échelle présente un problème de dérive de représentation : les embeddings nouvellement générés résident dans un espace latent géométrique différent et ne peuvent pas être comparés directement aux embeddings de galerie existants sans une dégradation sévère du rappel. Par conséquent, les mises à jour sans temps d'arrêt nécessitent soit des déploiements bleu/vert à double index, soit un apprentissage de compatibilité (tel qu'un entraînement rétrocompatible ou des adaptateurs de transformation), soit des pipelines de réindexation par étapes. Dans un flux de travail de réindexation bleu/vert standard, des tâches par lots hors ligne calculent de nouveaux embeddings pour toute la galerie et construisent un nouvel index vectoriel (tel que HNSW ou IVF). Pendant que la reconstruction s'exécute, le trafic de recherche en direct continue d'interroger l'index hérité actif. Les nouveaux éléments entrants sont gérés via une double écriture ou des journaux de capture de données modifiées (CDC) en streaming afin que les deux index restent à jour. Une fois le nouvel index validé via le trafic fantôme et chauffé en mémoire, le trafic bascule atomiquement vers le nouvel encodeur et index, après quoi l'ancien index est décommissionné. Alternativement, l'apprentissage rétrocompatible contraint le nouvel encodeur de requête à s'aligner avec l'espace de galerie hérité, permettant des mises à niveau immédiates du modèle de requête tout en remplissant la galerie de manière asynchrone au fil du temps.

class MultimodalRetrievalRouter:
    def __init__(self, v1_service, v2_service, dual_write=True):
        self.v1 = v1_service  # Model v1 + Index v1
        self.v2 = v2_service  # Model v2 + Index v2
        self.active_version = "v1"
        self.dual_write = dual_write

    def search(self, query_multimodal):
        # Route query strictly to the encoder matching the active index
        if self.active_version == "v1":
            return self.v1.search(query_multimodal)
        return self.v2.search(query_multimodal)

    def ingest_new_item(self, item):
        # Dual-write during migration window so the new index is up-to-date at cutover
        self.v1.index_item(item)
        if self.dual_write and self.v2.is_ready_for_ingest:
            self.v2.index_item(item)
Essayer de répondre à cette question avec un coach IA