Exécution de la recherche de similarité de vecteurs

Ce sujet présente comment utiliser Milvus pour rechercher des entités.

Dans Milvus, la recherche de similarité de vecteurs calcule la distance entre le vecteur de requête et les vecteurs de la collection (en utilisant une mesure de similarité spécifiée) et renvoie les résultats les plus similaires. Vous pouvez exécuter une recherche mixte en spécifiant une expression booléenne pour filtrer les champs scalaires ou clés primaires.

L'exemple suivant montre comment effectuer une recherche de similarité de vecteurs sur un ensemble de données contenant 2000 lignes de données, comprenant l'identifiant du livre (clé primaire), le nombre de mots (champ scalaire), et la synopsis du livre (champ vectoriel), pour simuler la recherche de livres spécifiques en fonction de leurs descriptions vectorisées. Milvus renverra les résultats les plus similaires en fonction du vecteur de requête et des paramètres de recherche que vous avez définis.

Chargement de la collection

Toutes les opérations de recherche et de requête dans Milvus sont exécutées en mémoire. Avant d'effectuer une recherche de similarité de vecteurs, chargez la collection en mémoire.

from pymilvus import Collection
collection = Collection("book")      # Obtenir la collection existante.
collection.load()

Préparation des paramètres de recherche

Préparez les paramètres correspondants pour votre scénario de recherche. L'exemple suivant définit les paramètres que la recherche utilisera pour calculer la distance à l'aide de la distance euclidienne et récupérer les vecteurs des dix clusters les plus proches construits par l'index IVF_FLAT.

search_params = {
    "metric_type": "L2",
    "offset": 5,
    "ignore_growing": False,
    "params": {"nprobe": 10}
}
Paramètre Description
metric_type La méthode utilisée pour mesurer la distance entre les vecteurs lors de la recherche. Il doit être le même que la méthode spécifiée lors du processus de construction de l'index. Référez-vous aux mesures de similarité pour plus d'informations.
offset Le nombre d'entités à sauter lors de la recherche. La somme de cette valeur et de la limit de la méthode search doit être inférieure à 16384. Par exemple, si vous souhaitez interroger les 9ème et 10ème voisins les plus proches du vecteur de requête, définissez limit sur 2 et offset sur 8.
ignore_growing Indique si les segments croissants doivent être ignorés lors de la recherche de similarité. La valeur par défaut est False, indiquant que la recherche inclut les segments croissants.
params Paramètres de recherche spécifiques au type d'index spécifié. Référez-vous à l'index vectoriel pour plus d'informations. Les options possibles incluent : - nprobe indique le nombre d'unités de regroupement à rechercher. Ce paramètre est uniquement disponible lors du réglage de index_type sur IVF_FLAT, IVF_SQ8, ou IVF_PQ. La valeur doit être inférieure à la valeur nlist spécifiée pendant le processus de construction de l'index. - ef indique la plage de recherche. Ce paramètre est uniquement disponible lors du réglage de l'index_type sur HNSW. La valeur doit être comprise entre top_k et 32768. - radius indique l'angle où se trouvent les vecteurs avec la similarité la plus basse. - range_filter indique le filtre utilisé pour filtrer les valeurs de champ vectoriel dont la similarité avec le vecteur de requête se situe dans une plage spécifique.

Réalisation de la recherche vectorielle

Utilise Milvus pour la recherche vectorielle. Pour rechercher dans une partition spécifique, spécifie une liste de noms de partitions.

Milvus prend en charge le réglage d'un niveau de cohérence pour les recherches. L'exemple dans ce sujet définit le niveau de cohérence sur "Fort". Tu peux également régler le niveau de cohérence sur "Borné", "Session" ou "Éventuellement". Pour plus d'informations sur les quatre niveaux de cohérence dans Milvus, voir Cohérence.

results = collection.search(
    data=[[0.1, 0.2]], 
    anns_field="book_intro", 
    param=search_params,
    limit=10,
    expr=None,
    output_fields=['title'],
    consistency_level="Fort"
)

results[0].ids

results[0].distances

hit = results[0][0]
hit.entity.get('title')
Paramètre Description
data Vecteurs utilisés pour la recherche.
anns_field Nom du champ à rechercher.
param Paramètres de recherche spécifiques à l'index. Pour plus d'informations, voir Index vectoriel.
limit Nombre de résultats à retourner. Cette valeur, plus le offset dans param, doit être inférieur à 16 384.
expr Expression booléenne pour filtrer les propriétés. Pour plus d'informations, voir Règles d'expression booléenne.
output_fields (optionnel) Noms des champs à retourner. Les champs de vecteurs ne sont actuellement pas pris en charge.
consistency_level (optionnel) Niveau de cohérence pour la recherche.

Vérifie les valeurs de clé primaire et les distances des vecteurs les plus similaires.

results[0].ids
results[0].distances

Une fois la recherche terminée, libère la collection chargée dans Milvus pour réduire la consommation de mémoire.

collection.release()

Limitations

Fonctionnalité Limite maximale
Longueur du nom de la collection 255 caractères
Nombre de partitions dans une collection 4 096
Nombre de champs dans une collection 256
Nombre de shards dans une collection 256
Dimension du vecteur 32 768
Top K 16 384
Vecteurs d'entrée 16 384

Réalisation de la recherche mixte

La recherche mixte est essentiellement une recherche vectorielle avec filtrage par attributs. En spécifiant une expression booléenne utilisée pour filtrer les champs scalaires ou les champs de clé primaire, les recherches peuvent être limitées dans des conditions spécifiques.

L'exemple suivant montre comment réaliser une recherche mixte basée sur la recherche vectorielle régulière. Supposons que tu souhaites rechercher certains livres en fonction des résumés vectorisés, mais que tu souhaites uniquement rechercher dans une plage spécifique de nombre de mots. Tu peux alors spécifier une expression booléenne dans les paramètres de recherche pour filtrer le champ word_count. Milvus ne recherchera que des vecteurs similaires dans les entités qui correspondent à l'expression.

En spécifiant une expression booléenne, tu peux filtrer les champs scalaires des entités lors de la recherche vectorielle. L'exemple suivant limite la portée de la recherche aux vecteurs dans la plage de valeurs de word_count spécifiée.

Tu peux également utiliser des champs dynamiques dans l'expression de filtrage et utiliser des champs de sortie dans la requête de recherche. Par exemple, réfère-toi au motif dynamique.

search_param = {
  "data": [[0.1, 0.2]],
  "anns_field": "book_intro",
  "param": {"metric_type": "L2", "params": {"nprobe": 10}, "offset": 0},
  "limit": 10,
  "expr": "word_count <= 11000",
}
res = collection.search(**search_param)

Vérifie les résultats retournés.

assert len(res) == 1
hits = res[0]
assert len(hits) == 2
print(f"- Total des résultats : {len(hits)}, identifiants des résultats : {hits.ids} ")
print(f"- Top1 identifiant du résultat : {hits[0].id}, distance : {hits[0].distance}, score : {hits[0].score} ")

Réalisation de la recherche par intervalle

La recherche par intervalle est une méthode de filtrage des résultats de recherche basée sur la distance entre le vecteur de requête et les valeurs de champ vectoriel. Différentes distances métriques peuvent être utilisées pour mesurer la distance.

Lors de la réalisation de la recherche par intervalle, Milvus effectue d'abord une recherche de similarité vectorielle. Ensuite, il exécute un filtrage de vecteurs basé sur les conditions de distance spécifiées et renvoie les vecteurs dont la distance se situe dans une plage spécifique.

L'exemple suivant montre comment réaliser une recherche par intervalle basée sur une recherche vectorielle régulière.

Chargement de la collection

Toutes les opérations de recherche et de requête dans Milvus sont exécutées en mémoire. Avant d'effectuer une recherche de similarité vectorielle, la collection doit être chargée en mémoire.

from pymilvus import Collection
collection = Collection("book")      # Obtenir une collection existante
collection.load()

Configuration des Plages de Filtrage des Vecteurs

Par rapport à la recherche de vecteurs régulière, la recherche de plage dans Milvus est contrôlée par l'introduction de deux nouveaux paramètres, rayon et range_filter, pour obtenir les résultats de recherche souhaités dans une plage de recherche spécifique.

Le paramètre rayon spécifie l'angle minimum auquel les vecteurs sont considérés comme similaires. Un range_filter facultatif peut être utilisé conjointement avec le rayon pour filtrer les valeurs des champs de vecteurs en fonction de la similarité avec le vecteur de requête dans une plage spécifique. Les deux paramètres rayon et range_filter ont un type de données FLOAT. Le réglage de ces deux paramètres équilibre efficacement l'exactitude et l'efficacité de la recherche.

En général, la similarité est mesurée par la distance entre la valeur du champ de vecteur et le vecteur de requête. Le choix de différentes métriques de distance aura un impact significatif sur la configuration de rayon et range_filter.

Par exemple, dans le cas de la distance L2, les résultats de recherche doivent être filtrés en fonction des valeurs des champs de vecteurs avec une distance inférieure à rayon. Cela est dû au fait que, dans la distance L2, les distances plus petites indiquent une plus grande similarité. Avec cette connaissance, si vous souhaitez filtrer certains des vecteurs les plus similaires, vous pouvez spécifier une valeur de range_filter efficace qui est inférieure à rayon.

search_params = {
    "metric_type": "L2",
    "params": {
        "radius": 10.0,
        "range_filter" : 5.0
    }
}

Dans le cas de la distance IP, le scénario est différent. Avec la distance IP, une distance plus grande signifie une plus grande similarité. Par conséquent, contrairement à la distance L2, les valeurs de rayon et range_filter dans la distance IP sont opposées. En d'autres termes, lors de l'utilisation de range_filter pour filtrer certains des vecteurs les plus similaires en fonction de la distance IP, la valeur efficace de range_filter doit être supérieure à rayon, et la distance des vecteurs résultants doit être supérieure à rayon mais inférieure ou égale à range_filter.

search_params = {
    "metric_type": "IP",
    "params": {
        "radius": 0.8,
        "range_filter" : 1.0
    }
}

Effectuer une Recherche de Plage

En spécifiant rayon et range_filter en fonction du type de mesure de distance, vous pouvez définir la plage de vecteurs de résultats à renvoyer.

Effectuer une recherche de plage sur la similarité dans la plage de 5.0 et 10.0 basée sur la distance L2 :

search_param = {
  "data": [[0.1, 0.2]], # Vecteur de requête
  "anns_field": "book_intro", # Champ à rechercher
  "param": { "metric_type": "L2", "params": { "nprobe": 10, "radius": 10.0, "range_filter" : 5.0 }, "offset": 0 },
  "limit": 2,
  "output_fields": ["int64", "float"]  # Champs à renvoyer
}

res = collection.search(**search_param)

Effectuer une recherche de plage sur la similarité dans la plage de 1.0 et 0.8 basée sur la distance IP :

search_param = {
  "data": [[0.1, 0.2]], # Vecteur de requête
  "anns_field": "book_intro", # Champ à rechercher
  "param": {"metric_type": "IP", "params": { "nprobe": 10, "radius": 0.8, "range_filter" : 1.0 }, "offset": 0 },
  "limit": 2,
  "output_fields": ["int64", "float"]  # Champs à renvoyer
}

res = collection.search(**search_param)

Résumé

Dans Milvus, la recherche de plage peut renvoyer des résultats de vecteurs similaires dans la plage de distance spécifiée. Cette fonctionnalité est activée en spécifiant rayon et range_filter dans les paramètres de recherche. Le tableau ci-dessous résume la configuration de ces deux paramètres pour différents types de mesure de distance.

Type de Mesure de Distance Configuration
L2 et autres distances range_filter <= distance < rayon
IP et distances cosinus rayon < distance <= range_filter