← L'édition
IANouveau4 min de lecture

Sentence Transformers ajoute les embeddings multi-vecteurs pour la recherche sémantique plus précise

Sentence Transformers v6.0 ajoute un quatrième type de modèle : `MultiVectorEncoder`, compatible avec les checkpoints ColBERT, PyLate et ColPali. L’idée est simple à retenir : au lieu d’un seul vecteur par texte, le modèle garde un vecteur par token, ce qui améliore la recherche quand une requête contient plusieurs contraintes ou un terme très spécifique.

Fil « Embeddings multi-vecteurs avec Sentence Transformers »

Illustration de l'article — huggingface.co
Image : huggingface.co

Sentence Transformers, la bibliothèque Python utilisée pour les embeddings (représentations vectorielles) et les rerankers (modèles de reclassement), prend désormais en charge les modèles multi-vecteurs via MultiVectorEncoder. Le billet de Hugging Face précise que cela couvre les checkpoints PyLate, ColBERT et certains modèles de recherche documentaire visuelle, avec une API commune à côté des modèles denses, spars et rerankers déjà connus. (huggingface.co)

Ce qui change techniquement

Un embedding dense classique résume tout un texte dans un seul vecteur de taille fixe. Le multi-vecteur garde un vecteur par token (un token est un morceau de mot ou un mot, selon le découpage du modèle), puis compare requête et document plus tard, au moment du score : c’est la late interaction (interaction tardive). Le score utilisé est MaxSim : pour chaque token de la requête, on prend la meilleure similarité avec n’importe quel token du document, puis on additionne ces maxima. Hugging Face explique que cette approche conserve des indices fins, comme un identifiant précis, un nom propre ou une clause importante, que la compression d’un seul vecteur peut diluer. (huggingface.co)

Le gain n’est pas gratuit : l’index grossit. Sur un exemple de 4 874 passages Natural Questions, le billet indique 608 414 vecteurs tokenisés pour LateOn, contre 4 874 vecteurs pour un modèle dense comme all-MiniLM-L6-v2. En taille brute float32, cela donne 311,5 MB pour le multi-vecteur, contre 7,5 MB pour MiniLM et 15,0 MB pour gte-modernbert-base. Le billet note toutefois qu’un index compressé fast-plaid tombe à 92 MB sur ce même corpus. (huggingface.co)

Ce que ça change dans une stack de recherche

Concrètement, l’intérêt pour une équipe produit est double. D’abord, on peut garder un index plus classique et utiliser le multi-vecteur seulement sur un petit nombre de candidats : le billet montre un schéma retrieve then rerank (récupérer puis reclasser) où seuls les 50 premiers résultats d’un premier moteur sont réencodés en multi-vecteurs, ce qui évite de transformer toute la collection. Ensuite, plusieurs bases vectorielles savent déjà indexer ou scorer ce format nativement : Qdrant depuis v1.10, Weaviate depuis v1.29, Vespa, LanceDB depuis v0.15.0, VectorChord pour Postgres, et Milvus depuis v2.6.4. (huggingface.co)

Le billet insiste aussi sur la recherche documentaire visuelle : là, les modèles ColPali peuvent faire correspondre une requête texte à une image de page, avec tableaux, mise en page et graphiques, sans étape d’OCR (reconnaissance optique de caractères). C’est la partie la plus nette pour des usages de veille documentaire ou de recherche dans des PDF scannés. Pour les équipes qui veulent réduire le coût, la technique de token pooling (regroupement de tokens) remplace plusieurs vecteurs proches par leur moyenne ; HierarchicalTokenPooling conserve environ 1 / pool_factor des tokens. (huggingface.co)

Ce qu’il faut retenir pour une équipe d’ingénierie

Le message pratique du billet est clair : si votre problème ressemble à “retrouver un passage qui satisfait plusieurs contraintes précises”, le multi-vecteur vaut le détour, mais il faut prévoir le coût en stockage et mesurer le compromis sur vos propres données. Côté exécution, Sentence Transformers expose déjà les optimisations habituelles — torch (PyTorch), onnx, openvino, demi-précision (float16), Flash Attention et torch.compile — et le billet indique qu’en GPU, float16 avec Flash Attention a été la meilleure configuration mesurée, avec un gain de 2,44x de débit par rapport au fp32 sans perte mesurable de qualité de recherche. (huggingface.co)

Voici le point d’entrée minimal montré dans l’article :

from sentence_transformers import MultiVectorEncoder

model = MultiVectorEncoder("lightonai/LateOn")

Et pour un pipeline de type “récupérer puis reclasser”, l’exemple du billet fait simplement : encoder la requête, récupérer les meilleurs candidats, puis scorer ces candidats avec similarity sur les embeddings multi-vecteurs. Pour une équipe qui utilise déjà des assistants de code et des agents, le changement concret est donc moins un nouveau modèle “magique” qu’un nouveau format de représentation à intégrer dans l’architecture de recherche, avec des API déjà alignées sur le reste de Sentence Transformers. (huggingface.co)