Les embeddings, ou plongements vectoriels en français, aident à représenter efficacement des données complexes comme le texte, les images ou l’audio.
Il s’agit concrètement de vecteurs denses de taille fixe. Voici par exemple deux phrases, et deux embeddings calculés pour ces phrases.
phrase_1="Bienvenue sur le blog de LBKE"
embedding_1=[1,0,4]
phrase_2="Bonjour !"
embedding_2=[7,2,9]
Nous avons déjà défini les embeddings dans notre lexique de l’IA générative. Cependant, il s’agit d’une notion complexe qui mérite son propre article : voici une définition détaillée de ce qu’est un embedding.
Des vecteurs sémantiques
Les embeddings représentent le texte ou les images avec un vecteur de taille fixe, mais surtout, ils capturent la signification sémantique des données : deux embeddings proches représentent des concepts proches.
Par exemple “la mer”, “l’océan” et “je vais me baigner à Saint-Tropez” auront des vecteurs très proches dans l’espace de plongement.
Voici un autre exemple d’embeddings, en trois dimensions :
# 🐱 miaou
chat = [1, 0, 1]
# 🐶 Proche du chat mais différent
chien = [1, 0, 2]
# 🐢 Proche des animaux mais plus éloigné du chat et du chien
tortue = [1, 0, 7]
avion = [25, 42, 0] # ✈️ Très différent des animaux
En représentant les mots, les phrases ou les documents sous forme de vecteurs, l’IA peut effectuer des opérations comme la recherche sémantique, la classification et la recommandation de contenu sans s’appuyer sur une correspondance exacte des mots-clés.
Denses ou creux ?
Ces vecteurs denses contiennent parfois des centaines ou des milliers de dimensions, chaque combinaison de dimension contribuant à un aspect de la signification.
Mathématiquement, il s’agit de directions dans l’espace de plongement, l’espace qui contient tous les embeddings possibles pour une taille de vecteur donnée.
On parle de vecteurs denses car il existe aussi des vecteurs creux (“sparse” en anglais), avec de nombreux zéros. Les vecteurs creux sont utilisés dans d’autres contextes, par exemple la recherche de mots-clés exacts dans la base Milvus.
Pour aller plus loin, cet article d’IBM donne une très bonne introduction aux principe des embeddings.
Comment sont générés les embeddings
Les embeddings proviennent de modèles d’apprentissage profond : les LLM représentent typiquement leurs entrées et sorties sous forme d’embeddings.
C’est un peu leur langage interne, tout comme notre cerveau transforme l’information en signaux électrique qui ne correspondent pas vraiment à une langue donnée.
Un robot pensant en embeddings, généré par Mistral AI (via le modèle Flux de Black Forest)
Les embeddings ne sont pas créés directement mais émergent de modèles entraînés sur des tâches génériques comme la classification ou la génération de texte.
Il existe tout de même des modèles créés spécifiquement pour générer des embeddings de qualité, on parle alors d’apprentissage de représentation. OpenAI utilise par exemple l’algorithme open-source Matryoshka (“poupées russes”) pour créer des embeddings.
Les modèles d’embeddings peuvent aussi utiliser l’architecture Transformers, tout comme les LLM.
Recherche documentaire et similarité sémantique
Les embeddings sont extrêmement utiles pour créer des moteurs de recherche sémantiques, qui comprennent vraiment le sens de nos recherches. Ou en tout cas font mieux qu’un moteur de recherche par mots-clés exacts.
En effet, les embeddings permettent de trouver des informations pertinentes sans passer par un système de mots-clés, qui ne gère pas les synonymes et nécessite de maintenir un index inversé dans la base de données.
Par exemple, la requête “adopter un chat” aura un vecteur d’embedding proche de “trouver un refuge pour animaux” malgré l’absence de mots en commun.
L’implémentation de cette approche implique la comparaison d’embeddings en utilisant la similarité cosinus et des algorithmes de plus proches voisins (k-NN).
Voici un exemple de code effectuant un tel calcul :
from openai import OpenAI
import numpy as np
client = OpenAI()
# Générer des embeddings pour deux textes sémantiquement similaires
request = client.embeddings.create(
model="text-embedding-3-small",
input="adopter un chat"
)
possible_response = client.embeddings.create(
model="text-embedding-3-small",
input="trouver un refuge pour animaux"
)
# Extraire les vecteurs d'embedding
embedding1 = request.data[0].embedding
embedding2 = possible_response.data[0].embedding
# Calculer la similarité cosinus (plus élevée = plus similaire)
# (équivalent à un produit vectoriel si les vecteurs sont normalisés)
similarity = np.dot(embedding1, embedding2) / (np.linalg.norm(embedding1) * np.linalg.norm(embedding2))
# Devrait être élevée malgré l'absence de mots communs
print(f"Similarité : {similarity}")
Bases de données vectorielles : une infrastructure pour les embeddings
Pour gérer un grand volume d’embeddings, par exemple pour représenter tous les documents d’une entreprise, une infrastructure spécialisée devient rapidement nécessaire.
Les bases de données vectorielles sont optimisées pour ce type de données et permettent des recherches de similarité à grande échelle.
En effet, une implémentation naïve de l’algorithme de plus proches voisins ne suffirait pas. Il faudrait comparer chaque requête de l’utilisateur à tous les documents de la base, ce qui n’est pas viable (complexité linéaire).
Une base de données vectorielle implémente donc des algorithmes ANN (Approximate Nearest Neighbors) tels que HNSW, qui est très bien décrit par Pinecone.
En plus de Pinecone, on peut citer comme bases vectorielles open source Chroma, Milvus, ou encore le plugin pgvector pour PostgreSQL
AWS a souligné au sens large le rôle important des “vector stores” dans les applications d’IA génératives.
LLM + recherche sémantique = RAG
Que se passe-t-il lorsque l’on réunit un LLM et une recherche sémantique ? On obtient l’architecture RAG, “retrieval-assisted generation”.
En ajoutant les résultats d’une recherche sémantique à la requête de l’utilisateur, on fournit un contexte utile au LLM qui en retour génère des réponses beaucoup plus précises et avec moins d’hallucinations.
Si vous souhaitez apprendre à implémenter des systèmes RAG avec des vecteurs d’embedding, LBKE propose une formation LangGraph et LangChain qui couvre la création d’embeddings, le stockage vectoriel et la contextualisation des prompts dans les applications Python.
Choisir ses embeddings
Lorsqu’ils créent un moteur de recherche sémantique ou un RAG, les développeurs peuvent choisir entre des modèles d’embedding pré-entraînés et personnalisés.
Les modèles pré-entraînés sont des modèles génériques, qui ne sont pas optimisés pour un problème en particulier mais fournissent des résultats plutôt satisfaisants quel que soit le type de texte.
OpenAI a récemment lancé des modèles d’embedding améliorés : text-embedding-3-small
et text-embedding-3-large
, qui offrent de meilleures performances et des prix plus bas par rapport aux versions précédentes.
Ce sont des embeddings génériques, applicables à de nombreuses tâches mais non optimisés pour une tâche spécifique.
On peut donc vouloir mettre en place un “fine-tuning” ou choisir un modèle spécialisé si l’on doit traiter des données avec une structure particulière.
Par exemple Codestral Embed de Mistral AI est comme son nom l’indique spécialisé dans l’embedding de code informatique.
Aussi la taille des embeddings a un impact sur les performances : des plongements plus grands sont plus précis, mais aussi plus coûteux à stocker et récupérer.
La puissance de la représentation sémantique
Les embeddings permettent aux algorithmes de saisir des relations sémantiques et des similitudes que seule la compréhension humaine pouvait cerner jusqu’à récemment.
En transformant l’information en vecteurs sémantiques de taille fixe très simples à manipuler, les modèles d’embedding ouvrent la voie à de nombreux usages utiles pour l’IA en entreprise : construire des moteurs de recherche précis, des chatbots fiables, ou encore trier des documents complexes.
🧑⚡ Cet article a été co-écrit avec l’IA Claude d’Anthropic, sur la base des supports de formation de LBKE, et à l’aide du moteur de recherche pour LLM Tavily.