Rechercher les voisins les plus proches approximatifs (ANN) et interroger les embeddings vectoriels

Cette page explique comment trouver les voisins les plus proches approximatifs (ANN) et interroger les embeddings vectoriels à l'aide des fonctions de distance ANN.

Lorsqu'un ensemble de données est petit, vous pouvez utiliser K-nearest neighbors (KNN) pour trouver les k-vecteurs les plus proches exacts. Toutefois, à mesure que votre ensemble de données augmente, la latence et le coût d'une recherche KNN augmentent également. Vous pouvez utiliser ANN pour trouver les k-plus proches voisins approximatifs avec une latence et des coûts considérablement réduits.

Dans une recherche ANN, les k vecteurs renvoyés ne sont pas les k voisins les plus proches, car la recherche ANN calcule des distances approximatives et peut ne pas examiner tous les vecteurs de l'ensemble de données. Il arrive que quelques vecteurs qui ne figurent pas parmi les k-voisins les plus proches soient renvoyés. C'est ce qu'on appelle la perte de couverture. La perte de rappel acceptable dépend du cas d'utilisation, mais dans la plupart des cas, perdre un peu de rappel en échange d'une amélioration des performances de la base de données est un compromis acceptable.

Pour en savoir plus sur les fonctions de distance approximative compatibles avec Spanner, consultez les pages de référence GoogleSQL suivantes :

Interroger les embeddings vectoriels

Spanner accélère les recherches vectorielles approximatives du voisin le plus proche (ANN) en utilisant un index vectoriel. Vous pouvez utiliser un index vectoriel pour interroger des embeddings vectoriels. Pour interroger des embeddings vectoriels, vous devez d'abord créer un index vectoriel. Vous pouvez ensuite utiliser l'une des trois fonctions de distance approximative pour trouver l'ANN.

Les restrictions suivantes s'appliquent lorsque vous utilisez les fonctions de distance approximative :

  • La fonction de distance approximative doit calculer la distance entre une colonne d'embedding et une expression constante (par exemple, un paramètre ou un littéral).
  • La sortie de la fonction de distance approximative doit être utilisée dans une clause ORDER BY comme seule clé de tri, et un LIMIT doit être spécifié après le ORDER BY.
  • La requête doit filtrer explicitement les lignes qui ne sont pas indexées. Dans la plupart des cas, cela signifie que la requête doit inclure une clause WHERE <column_name> IS NOT NULL qui correspond à la définition de l'index vectoriel, sauf si la colonne est déjà marquée comme NOT NULL dans la définition de la table.

Pour obtenir la liste détaillée des limites, consultez la page de référence sur la fonction de distance approximative.

Exemples

Prenons l'exemple d'une table Documents qui comporte une colonne DocEmbedding d'embeddings de texte précalculés à partir de la colonne DocContents d'octets et une colonne NullableDocEmbedding renseignée à partir d'autres sources qui peuvent être nulles.

CREATE TABLE Documents (
UserId       INT64 NOT NULL,
DocId        INT64 NOT NULL,
Author       STRING(1024),
DocContents  BYTES(MAX),
DocEmbedding ARRAY<FLOAT32> NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>,
WordCount    INT64
) PRIMARY KEY (UserId, DocId);

Pour rechercher les 100 vecteurs les plus proches de [1.0, 2.0, 3.0] :

SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
  ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
  options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100

Si la colonne d'embedding peut avoir une valeur nulle :

SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
  ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
  options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100

Étapes suivantes