HNSW
L'index HNSW est un algorithme d'indexation basé sur un graphe qui peut améliorer les performances lors de la recherche de vecteurs flottants à haute dimension. Il offre une excellente précision de recherche et une faible latence, mais il nécessite une surcharge de mémoire importante pour maintenir sa structure de graphe hiérarchique.
Vue d'ensemble
L'algorithme Hierarchical Navigable Small World (HNSW) construit un graphe multicouche, un peu comme une carte avec différents niveaux de zoom. La couche inférieure contient tous les points de données, tandis que les couches supérieures sont constituées d'un sous-ensemble de points de données échantillonnés dans la couche inférieure.
Dans cette hiérarchie, chaque couche contient des nœuds représentant des points de données, reliés par des arêtes qui indiquent leur proximité. Les couches supérieures permettent des sauts à longue distance pour se rapprocher rapidement de la cible, tandis que les couches inférieures permettent une recherche fine pour obtenir les résultats les plus précis.
Voici comment cela fonctionne :
- Point d'entrée: La recherche commence à un point d'entrée fixe dans la couche supérieure, qui est un nœud prédéterminé dans le graphe.
- Recherche avide: L'algorithme se déplace avec avidité vers le voisin le plus proche de la couche actuelle jusqu'à ce qu'il ne puisse plus se rapprocher du vecteur de la requête. Les couches supérieures ont une fonction de navigation, agissant comme un filtre grossier pour localiser les points d'entrée potentiels pour la recherche plus fine aux niveaux inférieurs.
- Descente de couche: Une fois qu'un minimum local est atteint dans la couche actuelle, l'algorithme descend dans la couche inférieure, en utilisant une connexion préétablie, et répète la recherche avide.
- Raffinementfinal: Ce processus se poursuit jusqu'à ce que la couche inférieure soit atteinte, où une dernière étape d'affinage identifie les voisins les plus proches.
HNSW
Les performances de HNSW dépendent de plusieurs paramètres clés qui contrôlent à la fois la structure du graphe et le comportement de recherche. Ces paramètres sont les suivants :
M
: Le nombre maximum d'arêtes ou de connexions que chaque nœud peut avoir dans le graphe à chaque niveau de la hiérarchie. Une valeur plus élevée deM
permet d'obtenir un graphe plus dense et d'augmenter le rappel et la précision car la recherche a plus de voies à explorer, ce qui consomme également plus de mémoire et ralentit le temps d'insertion en raison des connexions supplémentaires. Comme le montre l'image ci-dessus, M = 5 indique que chaque nœud du graphe HNSW est directement connecté à un maximum de 5 autres nœuds. Cela crée une structure de graphe modérément dense où les nœuds disposent de plusieurs chemins pour atteindre d'autres nœuds.efConstruction
: Le nombre de candidats pris en compte lors de la construction de l'index. Une valeur plus élevée (efConstruction
) permet généralement d'obtenir un graphe de meilleure qualité, mais sa construction prend plus de temps.ef
: Le nombre de voisins évalués lors d'une recherche. L'augmentation deef
améliore la probabilité de trouver les voisins les plus proches, mais ralentit le processus de recherche.
Pour plus d'informations sur la manière d'adapter ces paramètres à vos besoins, reportez-vous à la section Paramètres de l'index.
Création d'un index
Pour construire un index HNSW
sur un champ de vecteurs dans Milvus, utilisez la méthode add_index()
, en spécifiant les paramètres index_type
, metric_type
et des paramètres supplémentaires pour l'index.
from pymilvus import MilvusClient
# Prepare index building params
index_params = MilvusClient.prepare_index_params()
index_params.add_index(
field_name="your_vector_field_name", # Name of the vector field to be indexed
index_type="HNSW", # Type of the index to create
index_name="vector_index", # Name of the index to create
metric_type="L2", # Metric type used to measure similarity
params={
"M": 64, # Maximum number of neighbors each node can connect to in the graph
"efConstruction": 100 # Number of candidate neighbors considered for connection during index construction
} # Index building params
)
Dans cette configuration :
index_type
: Le type d'index à construire. Dans cet exemple, la valeur estHNSW
.metric_type
: La méthode utilisée pour calculer la distance entre les vecteurs. Les valeurs prises en charge sontCOSINE
,L2
etIP
. Pour plus d'informations, reportez-vous à la section Types de métriques.params
: Options de configuration supplémentaires pour la construction de l'index.M
: Nombre maximal de voisins auxquels chaque nœud peut se connecter.efConstruction
: Nombre de voisins candidats pris en compte pour la connexion lors de la construction de l'index.
Pour en savoir plus sur les paramètres de construction disponibles pour l'index
HNSW
, reportez-vous à Paramètres de construction de l'index.
Une fois les paramètres de l'index configurés, vous pouvez créer l'index en utilisant directement la méthode create_index()
ou en passant les paramètres de l'index dans la méthode create_collection
. Pour plus d'informations, reportez-vous à la section Créer une collection.
Recherche sur l'index
Une fois l'index construit et les entités insérées, vous pouvez effectuer des recherches de similarité sur l'index.
search_params = {
"params": {
"ef": 10, # Number of neighbors to consider during the search
}
}
res = MilvusClient.search(
collection_name="your_collection_name", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector
limit=10, # TopK results to return
search_params=search_params
)
Dans cette configuration :
params
: Options de configuration supplémentaires pour la recherche sur l'index.ef
: Nombre de voisins à prendre en compte lors d'une recherche.
Pour en savoir plus sur les paramètres de recherche disponibles pour l'index
HNSW
, reportez-vous à Paramètres de recherche spécifiques à l'index.
Paramètres de l'index
Cette section donne un aperçu des paramètres utilisés pour construire un index et effectuer des recherches sur l'index.
Paramètres de construction d'index
Le tableau suivant répertorie les paramètres qui peuvent être configurés sur params
lors de la création d'un index.
Paramètre | Description de l'index | Plage de valeurs | Suggestion de réglage |
---|---|---|---|
M | Nombre maximal de connexions (ou d'arêtes) que chaque nœud peut avoir dans le graphe, y compris les arêtes sortantes et entrantes. Ce paramètre affecte directement la construction de l'index et la recherche. | Type: Entier Portée: [2, 2048] Valeur par défaut: 30 (jusqu'à 30 arêtes sortantes et 30 arêtes entrantes par nœud) | Une valeur plus élevée de M conduit généralement à une plus grande précision, mais augmente la charge de mémoire et ralentit à la fois la construction de l'index et la recherche.Envisagez d'augmenter M pour les ensembles de données à haute dimensionnalité ou lorsqu'un rappel élevé est crucial.Pensez à diminuer M lorsque l'utilisation de la mémoire et la vitesse de recherche sont des préoccupations majeures.Dans la plupart des cas, nous vous recommandons de fixer une valeur comprise dans cette fourchette : [5, 100]. |
efConstruction | Nombre de voisins candidats pris en compte pour la connexion lors de la construction de l'index. Un plus grand nombre de candidats est évalué pour chaque nouvel élément, mais le nombre maximum de connexions réellement établies est toujours limité par M . | Type: Entier Plage de valeurs: [1, int_max] Valeur par défaut: 360 | Une valeur plus élevée ( efConstruction ) permet généralement d'obtenir un index plus précis, car davantage de connexions potentielles sont explorées. Cependant, cela entraîne également un allongement du temps d'indexation et une augmentation de l'utilisation de la mémoire pendant la construction.Envisagez d'augmenter efConstruction pour améliorer la précision, en particulier dans les scénarios où le temps d'indexation est moins critique.Pensez à diminuer efConstruction pour accélérer la construction de l'index lorsque les ressources sont limitées.Dans la plupart des cas, nous vous recommandons de définir une valeur comprise dans cette fourchette : [50, 500]. |
Paramètres de recherche spécifiques à l'index
Le tableau suivant répertorie les paramètres qui peuvent être configurés dans search_params.params
lors d'une recherche dans l'index.
Paramètre | Description | Plage de valeurs | Suggestion de réglage |
---|---|---|---|
ef | Contrôle l'étendue de la recherche lors de l'extraction des plus proches voisins. Il détermine le nombre de nœuds visités et évalués en tant que voisins les plus proches potentiels. Ce paramètre n'affecte que le processus de recherche et s'applique exclusivement à la couche inférieure du graphe. | Type: Entier Plage de valeurs: [1, int_max] Valeur par défaut: limit (TopK plus proches voisins à retourner) | Une valeur plus élevée de ef permet généralement d'améliorer la précision de la recherche, car un plus grand nombre de voisins potentiels sont pris en compte. Cependant, cela augmente également le temps de recherche.Envisagez d'augmenter ef lorsqu'il est essentiel d'obtenir un rappel élevé et que la vitesse de recherche est moins importante.Pensez à diminuer ef pour privilégier les recherches plus rapides, en particulier dans les scénarios où une légère réduction de la précision est acceptable.Dans la plupart des cas, nous vous recommandons de fixer une valeur comprise dans cette fourchette : [K, 10K]. |