Index avec GPU
Ce guide décrit les étapes pour construire un index avec la prise en charge du GPU dans Milvus, ce qui peut améliorer de manière significative les performances de recherche dans les scénarios à haut débit et à fort rappel. Pour plus de détails sur les types d'index GPU pris en charge par Milvus, voir Index GPU.
Configurer les paramètres Milvus pour le contrôle de la mémoire GPU
Milvus utilise un pool de mémoire graphique global pour allouer la mémoire GPU.
Il prend en charge deux paramètres initMemSize
et maxMemSize
dans le fichier de configuration de Milvus. La taille du pool est initialement fixée à initMemSize
et sera automatiquement étendue à maxMemSize
si cette limite est dépassée.
La valeur par défaut de initMemSize
est égale à la moitié de la mémoire GPU disponible au démarrage de Milvus, et la valeur par défaut de maxMemSize
est égale à la totalité de la mémoire GPU disponible.
Jusqu'à Milvus 2.4.1 (y compris la version 2.4.1), Milvus utilisait un pool de mémoire GPU unifié. Pour les versions antérieures à 2.4.1 (y compris la version 2.4.1), il était recommandé de définir les deux valeurs à 0.
gpu:
initMemSize: 0 #set the initial memory pool size.
maxMemSize: 0 #maxMemSize sets the maximum memory usage limit. When the memory usage exceed initMemSize, Milvus will attempt to expand the memory pool.
A partir de la version 2.4.1 de Milvus, le pool de mémoire GPU n'est utilisé que pour les données GPU temporaires pendant les recherches. Par conséquent, il est recommandé de le définir à 2048 et 4096.
gpu:
initMemSize: 2048 #set the initial memory pool size.
maxMemSize: 4096 #maxMemSize sets the maximum memory usage limit. When the memory usage exceed initMemSize, Milvus will attempt to expand the memory pool.
Création d'un index
Les exemples suivants montrent comment construire des index GPU de différents types.
Préparer les paramètres de l'index
Lors de la configuration des paramètres de l'index GPU, définissez index_type, metric_type et params:
index_type(chaîne) : Le type d'index utilisé pour accélérer la recherche vectorielle. Les options valides sont GPU_CAGRA, GPU_IVF_FLAT, GPU_IVF_PQ et GPU_BRUTE_FORCE.
metric_type(chaîne) : Le type de métrique utilisé pour mesurer la similarité des vecteurs. Les options valides sont IP et L2.
params(dict) : Les paramètres de construction spécifiques à l'index. Les options valides pour ce paramètre dépendent du type d'index.
Voici des exemples de configurations pour différents types d'index :
IndexGPU_CAGRA
index_params = { "metric_type": "L2", "index_type": "GPU_CAGRA", "params": { 'intermediate_graph_degree': 64, 'graph_degree': 32 } }
Les options possibles pour params sont les suivantes
intermediate_graph_degree(int) : Affecte le rappel et le temps de construction en déterminant le degré du graphe avant l'élagage. Les valeurs recommandées sont 32 ou 64.
graph_degree(int) : Affecte les performances de recherche et le rappel en déterminant le degré du graphe après l'élagage. En règle générale, il est égal à la moitié du degré intermédiaire du graphe. Une plus grande différence entre ces deux degrés se traduit par un temps de construction plus long. Sa valeur doit être inférieure à la valeur de intermediate_graph_degree.
build_algo(chaîne) : Sélectionne l'algorithme de génération de graphe avant l'élagage. Options possibles :
IVF_PQ: offre une meilleure qualité mais un temps de construction plus lent.
NN_DESCENT: Permet une construction plus rapide avec un rappel potentiellement plus faible.
cache_dataset_on_device(string, "true" | "false"): Décide si le jeu de données original doit être mis en cache dans la mémoire du GPU. La valeur "true" permet d'améliorer le rappel en affinant les résultats de la recherche, tandis que la valeur "false" permet d'économiser la mémoire du GPU.
IndexGPU_IVF_FLAT ou GPU_IVF_PQ
index_params = { "metric_type": "L2", "index_type": "GPU_IVF_FLAT", # Or GPU_IVF_PQ "params": { "nlist": 1024 } }
Les options params sont identiques à celles utilisées dans IVF_FLAT et IVF_PQ.
IndexGPU_BRUTE_FORCE
index_params = { 'index_type': 'GPU_BRUTE_FORCE', 'metric_type': 'L2', 'params': {} }
Aucune configuration paramétrique supplémentaire n'est requise.
Construction de l'index
Après avoir configuré les paramètres de l'index dans index_params, appelez la méthode create_index()
pour construire l'index.
# Get an existing collection
collection = Collection("YOUR_COLLECTION_NAME")
collection.create_index(
field_name="vector", # Name of the vector field on which an index is built
index_params=index_params
)
Recherche
Une fois que vous avez construit votre index GPU, l'étape suivante consiste à préparer les paramètres de recherche avant d'effectuer une recherche.
Préparer les paramètres de recherche
Vous trouverez ci-dessous des exemples de configurations pour différents types d'index :
IndexGPU_BRUTE_FORCE
search_params = { "metric_type": "L2", "params": {} }
Aucune configuration supplémentaire n'est nécessaire.
IndexGPU_CAGRA
search_params = { "metric_type": "L2", "params": { "itopk_size": 128, "search_width": 4, "min_iterations": 0, "max_iterations": 0, "team_size": 0 } }
Les principaux paramètres de recherche sont les suivants
itopk_size: Détermine la taille des résultats intermédiaires conservés pendant la recherche. Une valeur plus élevée peut améliorer le rappel au détriment des performances de la recherche. Elle doit être au moins égale à la valeur finale du top-k(limite) et est généralement une puissance de 2 (par exemple, 16, 32, 64, 128).
search_width: spécifie le nombre de points d'entrée dans le graphe CAGRA pendant la recherche. L'augmentation de cette valeur peut améliorer la mémorisation mais peut avoir un impact sur les performances de la recherche.
min_iterations / max_iterations: Ces paramètres contrôlent le processus d'itération de la recherche. Par défaut, ils sont fixés à 0, et le CAGRA détermine automatiquement le nombre d'itérations en fonction de itopk_size et de search_width. L'ajustement manuel de ces valeurs peut aider à équilibrer la performance et la précision.
team_size: Spécifie le nombre de threads CUDA utilisés pour calculer la distance métrique sur le GPU. Les valeurs courantes sont une puissance de 2 jusqu'à 32 (par exemple, 2, 4, 8, 16, 32). Cette valeur a un impact mineur sur les performances de recherche. La valeur par défaut est 0, Milvus sélectionnant automatiquement la taille de l'équipe en fonction de la dimension du vecteur.
IndexGPU_IVF_FLAT ou GPU_IVF_PQ
search_params = { "metric_type": "L2", "params": {"nprobe": 10} }
Les paramètres de recherche pour ces deux types d'index sont similaires à ceux utilisés pour IVF_FLAT et IVF_PQ. Pour plus d'informations, reportez-vous à la section Effectuer une recherche de similarité vectorielle.
Effectuer une recherche
Utilisez la méthode search()
pour effectuer une recherche de similarité vectorielle sur l'index GPU.
# Load data into memory
collection.load()
collection.search(
data=[[query_vector]], # Your query vector
anns_field="vector", # Name of the vector field
param=search_params,
limit=100 # Number of the results to return
)
Limites
Lorsque vous utilisez des index GPU, vous devez tenir compte de certaines contraintes :
Pour GPU_IVF_FLAT, la valeur maximale de la limite est de 1024.
Pour GPU_IVF_PQ et GPU_CAGRA, la valeur maximale de la limite est de 1024.
Bien qu'il n'y ait pas de limite fixée pour GPU_BRUTE_FORCE, il est recommandé de ne pas dépasser 4096 pour éviter les problèmes de performance.
Actuellement, les index GPU ne prennent pas en charge la distance COSINE. Si la distance COSINE est requise, les données doivent d'abord être normalisées, puis la distance du produit intérieur (IP) peut être utilisée comme substitut.
La protection OOM du chargement pour les index GPU n'est pas entièrement prise en charge, une trop grande quantité de données peut entraîner le blocage du QueryNode.
Les index GPU ne prennent pas en charge les fonctions de recherche telles que la recherche par plage et la recherche par groupement.
FAQ
Quand est-il approprié d'utiliser un index GPU ?
Un index GPU est particulièrement utile dans les situations qui requièrent un débit élevé ou une forte mémorisation. Par exemple, lorsqu'il s'agit de lots importants, le débit de l'indexation GPU peut être jusqu'à 100 fois supérieur à celui de l'indexation CPU. Dans les scénarios avec des lots plus petits, les index GPU surpassent toujours de manière significative les index CPU en termes de performance. En outre, s'il est nécessaire d'insérer rapidement des données, l'intégration d'un GPU peut accélérer considérablement le processus de construction des index.
Dans quels scénarios les index GPU tels que CAGRA, GPU_IVF_PQ, GPU_IVF_FLAT et GPU_BRUTE_FORCE sont-ils les plus adaptés ?
Les index CAGRA sont idéaux pour les scénarios qui exigent des performances accrues, mais au prix d'une plus grande consommation de mémoire. Pour les environnements où la conservation de la mémoire est une priorité, l'index GPU_IVF_PQ peut aider à minimiser les besoins en stockage, bien qu'il s'accompagne d'une plus grande perte de précision. L'index GPU_IVF_FLAT est une option équilibrée, offrant un compromis entre les performances et l'utilisation de la mémoire. Enfin, l'index GPU_BRUTE_FORCE est conçu pour des opérations de recherche exhaustive, garantissant un taux de rappel de 1 en effectuant des recherches transversales.