De la recherche vectorielle aux puissantes API REST, Elasticsearch offre aux développeurs la boîte à outils de recherche la plus complète. Explorez nos notebooks d’exemples sur GitHub pour tester de nouveaux cas d’usage. Vous pouvez également démarrer votre essai gratuit ou exécuter Elasticsearch en local dès aujourd’hui.
L'utilisation d'enchâssements pour améliorer la pertinence et la précision de la recherche d'informations s'est considérablement développée au fil des ans. Des outils comme Elasticsearch ont évolué pour prendre en charge ce type de données grâce à des types de champs spécialisés tels que les vecteurs denses, les vecteurs épars et le texte sémantique. Cependant, pour obtenir de bons résultats, il est essentiel de comprendre comment faire correspondre correctement les embeddings aux types de champs Elasticsearch disponibles : semantic_text, dense_vector, et sparse_vector.
Dans cet article, nous examinerons ces types de champs, quand utiliser chacun d'entre eux et comment ils sont liés à la génération d'encarts et aux stratégies d'utilisation, à la fois lors de l'indexation et de l'interrogation.
Type de vecteur dense
Le type de champ dense_vector dans Elasticsearch est utilisé pour stocker des vecteurs denses, qui sont des représentations numériques de données telles que du texte, des images et de l'audio, où presque toutes les dimensions sont pertinentes... Ces vecteurs sont générés à l'aide de modèles d'intégration fournis par des plateformes telles que OpenAI, Cohere ou Hugging Face, et sont conçus pour capturer la signification sémantique globale des données, même si elles ne partagent pas de termes exacts avec d'autres documents.
Dans Elasticsearch, les vecteurs denses peuvent avoir jusqu'à 4096 dimensions en fonction du modèle utilisé. Par exemple, le modèle all-MiniLM-L6-v2 génère des vecteurs de 384 dimensions, tandis que le modèle text-embedding-ada-002 d'OpenAI produit des vecteurs de 1536 dimensions.
Le champ dense_vector est généralement adopté comme type par défaut pour stocker ce type d'intégration lorsqu'un plus grand contrôle est nécessaire, comme l'utilisation de vecteurs pré-générés, l'application de fonctions de similarité personnalisées ou l'intégration avec des modèles externes.
Quand et pourquoi utiliser le type dense_vector ?
Les vecteurs denses sont excellents pour capturer la similarité sémantique entre des phrases, des paragraphes ou des documents entiers. Ils fonctionnent très bien lorsque l'objectif est de comparer le sens global des textes, même s'ils ne partagent pas les mêmes termes.
Le champ de vecteurs denses est idéal lorsque vous disposez déjà d'un pipeline externe de génération d'incrustations utilisant des modèles fournis par des plateformes telles que OpenAI, Cohere ou Hugging Face et que vous souhaitez uniquement stocker et interroger ces vecteurs manuellement. Ce type de champ offre une grande compatibilité avec les modèles d'intégration et une souplesse totale en matière de génération et d'interrogation, ce qui permet de contrôler la manière dont les vecteurs sont produits, indexés et utilisés lors de la recherche.
En outre, il prend en charge différentes formes de recherche sémantique, avec des requêtes telles que k-NN ou script_score pour les cas où il est nécessaire d'ajuster la logique de classement. Ces possibilités font du vecteur dense un outil idéal pour des applications telles que RAG (Retrieval-Augmented Generation), les systèmes de recommandation et les recherches personnalisées basées sur la similarité.
Enfin, le champ vous permet de personnaliser la logique de pertinence, en utilisant des fonctions telles que cosineSimilarity, dotProduct ou l2norm pour adapter le classement aux besoins de votre cas d'utilisation.
Les vecteurs denses restent la meilleure option pour ceux qui ont besoin de flexibilité, de personnalisation et de compatibilité avec des cas d'utilisation avancés comme ceux mentionnés ci-dessus.
Comment utiliser la requête pour un type de vecteur dense ?
Les recherches sur les champs définis comme dense_vector utilisent la requête des k-voisins les plus proches. Cette requête est chargée de trouver les documents dont le vecteur dense est le plus proche du vecteur de la requête. Vous trouverez ci-dessous un exemple d'application d'une requête k-NN à un champ vectoriel dense :
Outre la requête k-NN, s'il est nécessaire de personnaliser la notation des documents, il est également possible d'utiliser la requête script_score, en la combinant avec des fonctions de comparaison vectorielle telles que cosineSimilarity, dotProduct ou l2norm pour calculer la pertinence d'une manière plus contrôlée. Voir l'exemple :
Si vous souhaitez aller plus loin, je vous recommande d'explorer l'article Comment configurer la recherche vectorielle dans Elasticsearch.
Type de vecteur épars
Le type de champ sparse_vector est utilisé pour stocker des vecteurs épars, qui sont des représentations numériques où la plupart des valeurs sont nulles et où seuls quelques termes ont des poids significatifs. Ce type de vecteur est courant dans les modèles basés sur les termes tels que SPLADE ou ELSER (Elastic Learned Sparse EncodeR).
Quand et pourquoi utiliser un type de vecteur peu dense ?
Les vecteurs épars sont idéaux lorsque vous avez besoin d'une recherche plus précise en termes lexicaux, sans sacrifier l'intelligence sémantique. Ils représentent le texte sous forme de paires jeton/valeur, en ne mettant en évidence que les termes les plus pertinents avec les poids associés, ce qui permet de gagner en clarté, en contrôle et en efficacité.
Ce type de champ est particulièrement utile lorsque vous générez des vecteurs basés sur des termes, comme dans les modèles ELSER ou SPLADE, qui attribuent des poids différents à chaque mot en fonction de son importance relative dans le texte.
Pour les cas où vous souhaitez contrôler l'influence de mots spécifiques dans la requête, les types de vecteurs épars vous permettent d'ajuster manuellement le poids des termes afin d'optimiser le classement des résultats.
Parmi les principaux avantages, citons la transparence de la recherche, puisqu'il est possible de comprendre clairement pourquoi un document a été jugé pertinent, et l'efficacité du stockage, puisque seuls les jetons dont la valeur n'est pas nulle sont enregistrés, contrairement aux vecteurs denses qui stockent toutes les dimensions.
En outre, les vecteurs épars sont le complément idéal des stratégies de recherche hybrides et peuvent même être combinés avec des vecteurs denses pour associer la précision lexicale à la compréhension sémantique.
Comment utiliser l'interrogation pour le type de vecteur épars ?
La requête sparse_vector vous permet de rechercher des documents sur la base d'un vecteur de requête au format jeton/valeur. Vous trouverez ci-dessous un exemple de requête :
Si vous préférez utiliser un modèle formé, il est possible d'utiliser un point final d'inférence qui transforme automatiquement le texte de la requête en un vecteur peu dense :
Pour approfondir ce sujet, je vous suggère de lire Understanding sparse vector embeddings with trained ML models (Comprendre les encastrements de vecteurs épars avec des modèles ML formés).
Type de texte sémantique
Le type de champ semantic_text est le moyen le plus simple et le plus direct d'utiliser la recherche sémantique dans Elasticsearch. Il gère automatiquement la génération de l'intégration, à la fois au moment de l'indexation et de l'interrogation, par le biais d'un point final d'inférence. Cela signifie que vous n'avez pas à vous soucier de générer ou de stocker des vecteurs manuellement.
Quand et pourquoi utiliser le texte sémantique ?
Le champ semantic_text est idéal pour ceux qui veulent commencer avec un minimum d'effort technique et sans avoir à manipuler les vecteurs manuellement. Ce champ automatise des étapes telles que la génération de l'encastrement et le mappage de la recherche vectorielle, ce qui rend l'installation plus rapide et plus pratique.
Vous devriez envisager d'utiliser semantic_text si vous appréciez la simplicité et l'abstraction, car il élimine la complexité de la configuration manuelle des mappings, de la génération d'embedding et des pipelines d'ingestion. Il suffit de sélectionner le modèle d'inférence et Elasticsearch s'occupe du reste.
Parmi les principaux avantages, citons la génération automatique de l'intégration, effectuée à la fois pendant l'indexation et l'interrogation, et le mappage prêt à l'emploi, qui est préconfiguré pour prendre en charge le modèle d'inférence sélectionné.
En outre, le champ offre une prise en charge native du découpage automatique des textes longs (text chunking), ce qui permet de diviser les textes volumineux en passages plus petits, chacun ayant sa propre intégration, ce qui améliore la précision de la recherche. La productivité s'en trouve grandement améliorée, en particulier pour les équipes qui souhaitent fournir rapidement de la valeur ajoutée sans avoir à s'occuper de l'ingénierie sous-jacente de la recherche sémantique.
Cependant, bien que semantic_text offre rapidité et simplicité, cette approche présente certaines limites. Il permet d'utiliser des modèles standard du marché, pour autant qu'ils soient disponibles en tant que points de terminaison d'inférence dans Elasticsearch. Cependant, il ne prend pas en charge les encastrements générés de l'extérieur, comme c'est le cas avec le champ dense_vector.
Si vous avez besoin de plus de contrôle sur la manière dont les vecteurs sont générés, si vous souhaitez utiliser vos propres incorporations ou si vous devez combiner plusieurs champs pour des stratégies avancées, les champs dense_vector et sparse_vector offrent la flexibilité nécessaire pour des scénarios plus personnalisés ou spécifiques à un domaine.
Comment utiliser la requête pour le type de texte sémantique ?
Avant semantic_text, il était nécessaire d'utiliser une requête différente selon le type d'intégration (dense ou éparse). Une requête sparse_vector a été utilisée pour les champs peu denses, tandis que les champs dense_vector ont nécessité des requêtes KNN.
Avec le type de texte sémantique, la recherche est effectuée à l'aide de la requête sémantique, qui génère automatiquement le vecteur de la requête et le compare avec les enchâssements des documents indexés. Le type semantic_text vous permet de définir un point final d'inférence pour intégrer la requête, mais si aucun n'est spécifié, le même point final que celui utilisé lors de l'indexation sera appliqué à la requête.
Pour en savoir plus, je vous propose de lire l'article Elasticsearch new semantic_text mapping : Simplifier la recherche sémantique.
Conclusion
Lors du choix de la méthode de mappage des embeddings dans Elasticsearch, il est essentiel de comprendre comment vous souhaitez générer les vecteurs et quel est le niveau de contrôle dont vous avez besoin sur ceux-ci. Si vous recherchez la simplicité, le champ de texte sémantique permet une recherche sémantique automatique et évolutive, ce qui le rend idéal pour de nombreux cas d'utilisation initiaux. Lorsqu'un contrôle plus poussé, des performances plus fines ou une intégration avec des modèles personnalisés sont nécessaires, les champs de vecteurs denses et de vecteurs clairsemés offrent la flexibilité nécessaire.
Le type de champ idéal dépend de votre cas d'utilisation, de l'infrastructure disponible et de la maturité de votre pile d'apprentissage automatique. Plus important encore, Elastic offre les outils nécessaires pour construire des systèmes de recherche modernes et hautement adaptables.
Références
- Type de champ texte sémantique
- Type de champ vectoriel épars
- Type de champ vectoriel dense
- Requête sémantique
- Requête sur les vecteurs épars
- Recherche kNN
- Nouveau mappage semantic_text d'Elasticsearch : Simplifier la recherche sémantique
- Comprendre les encastrements de vecteurs épars à l'aide de modèles ML entraînés




