Cette page explique comment effectuer des recherches hybrides vectorielles et en texte intégral dans Spanner. La recherche hybride combine la précision de la correspondance de mots clés (recherche en texte intégral) avec le rappel de la correspondance sémantique (recherche vectorielle) pour produire des résultats de recherche très pertinents.
Spanner est compatible avec les modèles de recherche hybrides suivants, qui sont divisés en trois catégories principales :
| Catégorie | Description | Objectif principal |
| Fusion | Fusion récupère et classe les documents de manière indépendante à l'aide de la recherche par mots clés et vectorielle, puis combine (fusionne) les résultats. | Obtenez un rappel et une pertinence maximaux en combinant plusieurs signaux de score. |
| Filtré | Les mots clés permettent de filtrer ou d'affiner l'espace de recherche. | Assurez-vous que la correspondance des mots clés est une exigence tout en tirant parti de la pertinence sémantique. |
| Reclassement par ML | Un modèle de machine learning affine un ensemble initial de candidats pour obtenir un classement final plus précis. | Obtenez la précision la plus élevée possible pour un petit ensemble final de résultats. |
Recherche fusionnée
La recherche par fusion consiste à exécuter la recherche FTS et la recherche vectorielle de manière indépendante sur le même corpus de données. Il fusionne ensuite les résultats pour créer une liste classée unique, unifiée et très pertinente.
Bien que vous puissiez exécuter des requêtes indépendantes côté client, la recherche hybride dans Spanner offre les avantages suivants :
- Simplifie la logique d'application en gérant les requêtes parallèles et la fusion des résultats sur le serveur.
- Cela évite de transférer des ensembles de résultats intermédiaires potentiellement volumineux au client.
Vous pouvez utiliser SQL pour créer des méthodes de fusion dans Spanner. Cette section fournit des exemples de fusion par rang réciproque et de fusion par score relatif. Toutefois, nous vous recommandons d'évaluer différentes stratégies de fusion pour déterminer celle qui répond le mieux aux exigences de votre application.
Fusion basée sur le classement
Utilisez la fusion basée sur le classement lorsque les scores de pertinence de différentes méthodes de récupération (tels que les scores FTS et les distances vectorielles) sont difficiles à comparer ou à normaliser, car ils sont mesurés dans des espaces différents. Cette méthode utilise la position de chaque document de chaque récupérateur pour générer un score et un classement finaux.
La fusion de classement réciproque (RRF) est une fonction de fusion basée sur le classement. Le score RRF d'un document est la somme des inverses de ses rangs provenant de plusieurs systèmes de récupération. Il est calculé comme suit :
\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]
Où :
- d est le document.
- R est l'ensemble des récupérateurs (recherche vectorielle et FTS).
- k est une constante (souvent définie sur 60) utilisée pour modérer l'influence des documents très bien classés.
- w correspond au rang du document à partir du récupérateur r.
Implémenter RRF dans une requête Spanner
Les métriques vectorielles (telles que APPROX_DOT_PRODUCT) et les scores de recherche de texte (tels que SCORE_NGRAMS) fonctionnent sur des échelles incompatibles. Pour résoudre ce problème, l'exemple suivant implémente RRF afin de normaliser les données en fonction de la position dans le classement plutôt que des scores bruts.
La requête utilise UNNEST(ARRAY(...) WITH OFFSET pour attribuer un classement aux 100 premiers candidats de chaque méthode. Il calcule ensuite un score standardisé à l'aide de l'inverse de ces classements et agrège les résultats pour renvoyer les cinq premiers résultats.
SELECT SUM(1 / (60 + rank)) AS rrf_score, key
FROM (
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY APPROX_DOT_PRODUCT(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
UNION ALL
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'foo')
ORDER BY SCORE_NGRAMS(text_tokens_ngrams, 'foo') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
)
GROUP BY key
ORDER BY rrf_score DESC
LIMIT 5;
Fusion basée sur les scores
La fusion basée sur les scores est efficace lorsque les scores de pertinence de différentes méthodes sont comparables ou que vous pouvez les normaliser. Cela peut permettre un classement plus précis qui intègre le poids de pertinence réel de chaque méthode.
La fusion des scores relatifs (RSF) est une méthode basée sur les scores qui normalise les scores de différentes méthodes par rapport aux scores les plus élevés et les plus bas de chaque méthode, généralement à l'aide des fonctions MIN() et MAX(). Le score RSF d'un document récupéré par un ensemble de récupérateurs est calculé comme suit :
\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]
Où :
- d est le document.
- R est l'ensemble des récupérateurs (recherche vectorielle et FTS).
- w correspond à la pondération attribuée à un récupérateur spécifique.
Implémenter RSF dans une requête Spanner
Pour implémenter RSF, vous devez normaliser les scores du vecteur et de FTS sur une échelle commune. L'exemple suivant calcule les scores minimum et maximum dans des clauses WITH distinctes pour obtenir les facteurs de normalisation. Il combine ensuite les résultats à l'aide d'un FULL OUTER JOIN, en additionnant les scores normalisés de la recherche ANN (voisins approximatifs les plus proches) (convertis à partir de cosine_distance) et de la FTS.
WITH ann AS (
SELECT key, APPROX_COSINE_DISTANCE(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') AS cosine_distance,
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY cosine_distance
LIMIT 100
),
fts AS (
SELECT key, SCORE_NGRAMS(text_tokens_ngrams, 'Green') AS score,
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'Green')
ORDER BY score DESC
LIMIT 100
),
ann_min AS (
SELECT MIN(1 - cosine_distance) AS min
FROM ann
),
ann_max AS (
SELECT MAX(1 - cosine_distance) AS max
FROM ann
),
fts_min AS (
SELECT MIN(score) AS min
FROM fts
),
fts_max AS (
SELECT MAX(score) AS max
FROM fts
)
SELECT IFNULL(ann.key, fts.key),
IFNULL(((1 - ann.cosine_distance) - ann_min.min) /
(ann_max.max - ann_min.min), 0) +
IFNULL((fts.score - fts_min.min) /
(fts_max.max - fts_min.min), 0) AS score
FROM ann
FULL OUTER JOIN fts
ON ann.key = fts.key
CROSS JOIN ann_min
CROSS JOIN ann_max
CROSS JOIN fts_min
CROSS JOIN fts_max
ORDER BY score DESC
LIMIT 5;
Recherche filtrée
Les recherches filtrées utilisent la recherche en texte intégral pour créer un filtre qui réduit l'ensemble des documents pris en compte pour une recherche vectorielle des k plus proches voisins (KNN). Vous pouvez éventuellement utiliser un pré-tri pour limiter la taille de l'ensemble de résultats.
Implémenter la recherche filtrée dans une requête Spanner
L'exemple de recherche de cette section suit les étapes suivantes pour affiner l'espace de recherche vectoriel au sous-ensemble de données correspondant aux mots clés :
- Utilise
SEARCH (text_tokens, 'Green')pour trouver les lignes où la colonnetext_tokenscontient le texteGreen. Les 1 000 premières lignes sont renvoyées par un ordre de tri défini par l'index de recherche. - Utilise une fonction vectorielle,
DOT_PRODUCT(@vector, embedding), pour calculer la similarité entre le vecteur de requête (@vector) et le vecteur de document (embedding) stocké. Il trie ensuite les résultats et renvoie les 10 meilleurs résultats finaux.
SELECT key
FROM (
SELECT key, embedding
FROM hybrid_search
WHERE SEARCH (text_tokens, 'Green')
ORDER BY presort
LIMIT 1000)
ORDER BY DOT_PRODUCT(@vector, embedding) DESC
LIMIT 10;
Réorganisation par ML
Le reclassement basé sur le ML est une approche très précise, mais qui nécessite beaucoup de ressources de calcul. Il applique un modèle de machine learning à un petit ensemble de candidats qui a été réduit par la recherche en texte intégral, la recherche vectorielle ou une combinaison des deux. Pour en savoir plus sur l'intégration de Vertex AI dans Spanner, consultez la présentation de l'intégration de Vertex AI dans Spanner.
Vous pouvez intégrer le reranking de ML à l'aide de la fonction ML.PREDICT de Spanner avec un modèle Vertex AI déployé.
Implémenter le reranking basé sur le ML
- Déployez un modèle de reranking (par exemple, depuis HuggingFace) sur un point de terminaison Vertex AI.
Créez un objet
MODELSpanner qui pointe vers le point de terminaison Vertex AI. Par exemple, dans l'exemple de modèleRerankersuivant :text ARRAY<string(max)>correspond aux documents.text_pair ARRAY<string(max)>correspond au texte de la requête dans l'exemple.scorecorrespond aux scores de pertinence attribués par le modèle de ML pour les paires de textes d'entrée.
CREATE MODEL Reranker INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>) OUTPUT (score FLOAT32) REMOTE OPTIONS ( endpoint = '...' );Utilisez une sous-requête pour récupérer les candidats initiaux (par exemple, les 100 premiers résultats d'une recherche ANN) et transmettez-les à
ML.PREDICT. La fonction renvoie une nouvelle colonne de score pour le classement final.SELECT key FROM ML.PREDICT( MODEL Reranker, ( SELECT key, text, "gift for 8-year-old" AS text_pair FROM hybrid_search WHERE embedding IS NOT NULL ORDER BY APPROX_DOT_PRODUCT(@vector, embedding, options=>JSON '{"num_leaves_to_search": 50}') DESC LIMIT 100) ) ORDER BY score DESC LIMIT 3;
Étapes suivantes
- Personnalisez votre moteur de recherche grâce à la recherche hybride optimisée par l'IA dans Spanner.
- En savoir plus sur la recherche en texte intégral