AISAQCompatible with Milvus 2.6.4+
AISAQ est un index vectoriel sur disque qui étend DISKANN pour traiter des ensembles de données à l'échelle du milliard avec une empreinte DRAM minimale.
Contrairement à DISKANN, qui conserve les vecteurs compressés en mémoire, AISAQ est conçu avec une "architecture DRAM proche de zéro", ce qui signifie que toutes les structures de données sont conservées sur le disque SSD.
AISAQ permet d'exécuter des bases de données à très grande échelle en utilisant des serveurs standard, tout en offrant des modes de fonctionnement permettant d'équilibrer les performances et les coûts de stockage.
Comment fonctionne l'AISAQ
Le diagramme ci-dessus compare les dispositions de stockage de DISKANN, AISAQ-Performance et AISAQ-Scale, en montrant comment les données (vecteurs bruts, listes de bords et codes PQ) sont réparties entre la RAM et le disque.
Aisaq Vs Diskann
Fondation : Récapitulatif de DISKANN
Dans DISKANN, les vecteurs bruts et les listes de bords sont stockés sur le disque, tandis que les vecteurs compressés PQ sont conservés en mémoire (DRAM).
Lorsque DISKANN accède à un nœud (par exemple, le vecteur 0) :
Il charge le vecteur brut(raw_vector_0) et sa liste de bords(edgelist_0) à partir du disque.
La liste des arêtes indique les voisins à visiter ensuite (nœuds 2, 3 et 5 dans cet exemple).
Le vecteur brut est utilisé pour calculer la distance exacte par rapport au vecteur de requête pour le classement.
Les données PQ en mémoire sont utilisées pour le filtrage de la distance approximative afin de guider la traversée suivante.
Comme les données PQ sont déjà mises en cache dans la DRAM, chaque visite de nœud ne nécessite qu'une seule entrée/sortie de disque, ce qui permet d'obtenir une vitesse d'interrogation élevée avec une utilisation modérée de la mémoire.
Pour une explication détaillée de ces composants et paramètres, voir DISKANN.
Modes de fonctionnement de l'AISAQ
AISAQ propose deux modes de fonctionnement pour répondre à deux cas d'utilisation distincts :
Mode performance : optimisé pour les applications qui nécessitent une faible latence et un débit élevé à grande échelle, telles que la recherche sémantique en ligne.
Mode échelle : optimisé pour les applications avec des contraintes de latence plus souples, telles que RAG et la recherche sémantique hors ligne, tout en permettant une expansion rentable des ensembles de données à une échelle ultra-élevée.
Mode AISAQ-performance
Le modeAISAQ-performance permet d'obtenir une "empreinte DRAM quasi nulle" en déplaçant les données PQ de la mémoire vers le disque tout en maintenant un faible taux d'IOPS grâce à la colocalisation et à la redondance des données.
Le vecteur brut de chaque nœud, la liste des arêtes et les données PQ de ses voisins sont stockés ensemble sur le disque.
Cette disposition garantit que la visite d'un nœud (par exemple, le vecteur 0) ne nécessite toujours qu'une seule E/S sur disque.
Comme les données PQ sont stockées de manière redondante à proximité de plusieurs nœuds, la taille du fichier d'index augmente de manière significative, ce qui consomme plus d'espace disque.
Mode AISAQ-scale
Lemode AISAQ-scale se concentre sur la réduction de l'utilisation de l'espace disque tout en répondant aux exigences de performance des applications cibles.
Dans ce mode :
Les données PQ sont stockées séparément sur le disque, sans redondance.
Cette conception minimise la taille de l'index mais entraîne davantage d'opérations d'E/S lors de la traversée du graphe.
Pour atténuer la surcharge d'IOPS, AISAQ introduit deux optimisations :
Un algorithme de réarrangement qui trie les vecteurs PQ par priorité afin d'améliorer la localité des données.
Un cache PQ dans la DRAM (pq_read_page_cache_size) qui met en cache les données PQ fréquemment accédées.
Exemple de configuration
# milvus.yaml
knowhere:
AISAQ:
build:
max_degree: 56 # Controls the maximum number of connections (edges) each data point can have in the Vamana graph
search_list_size: 100 # During index construction, this parameter defines the size of the candidate pool used when searching for the nearest neighbors for each node. For every node being added to the graph, the algorithm maintains a list of the search_list_size best candidates found so far. The search for neighbors stops when this list can no longer be improved. From this final candidate pool, the top max_degree nodes are selected to form the final edges
inline_pq: -1 # Number of PQ vectors stored inline per Index node (read when node is accessed, to reduce IO)
rearrange: true # Re-arrange the PQ vectors data structure to improve data locality and reduce disk accesses during search (ignored in performance mode)
num_entry_points: 100 # Number of candidate entry points to optimize search entry-point selection
pq_code_budget_gb_ratio: 0.125 # Controls the size of the PQ codes (compressed representations of data points) compared to the size of the uncompressed data
disk_pq_code_budget_gb_ratio: 0.25 # Controls the size of the PQ codes of the high precision vectors stored in the index (used for re-ranking), compared to the size of the uncompressed data
pq_cache_size: 0 # PQ vectors cache size in DRAM (bytes). The PQ vectors cache is loaded during Index load and used during search to reduce IOs (ignored in performance mode)
search_cache_budget_gb_ratio: 0 # Controls the amount of DRAM to be used for caching frequently accessed index nodes. This cache is loaded during index load and used during search to reduce IOs
search:
search_list: 16 # During a search operation, this parameter determines the size of the candidate pool that the algorithm maintains as it traverses the graph. A larger value increases the chances of finding the true nearest neighbors (higher recall) but also increases search latency
beamwidth: 8 # Controls the degree of parallelism during search by determining the maximum number of parallel disk I/O requests to read the index nodes
vectors_beamwidth: 1 # Controls the degree of parallelism during search by determining the maximum number of parallel disk I/O requests to read groups of neighboring PQ vectors (ignored in performance mode)
pq_read_page_cache_size: 5242880 (5MiB) # PQ read cache size in DRAM per search thread (bytes). It caches frequently accessed data pages containing PQ vectors (ignored in performance mode and applicable only when rearrange is true). The PQ read cache memory is reused across all AISAQ segments
Paramètres de l'AISAQ
AISAQ hérite de certains paramètres de DISKANN - max_degree, search_list_size, et pq_code_budget_gb_ratio.
Paramètres de construction d'index
Ces paramètres influencent la manière dont l'index AISAQ est construit. Leur réglage peut affecter la taille de l'index, le temps de construction et la qualité de la recherche.
Paramètre |
Description de la valeur |
Plage de valeurs |
Suggestion de réglage |
|---|---|---|---|
|
Contrôle le nombre maximum de connexions (arêtes) que chaque point de données peut avoir dans le graphe Vamana. |
Type: Entier Plage de valeurs: [1, 512] Valeur par défaut: |
Des valeurs plus élevées créent des graphiques plus denses, ce qui peut augmenter la mémorisation (trouver des résultats plus pertinents), mais aussi l'utilisation de la mémoire et le temps de construction. Dans la plupart des cas, nous vous recommandons de définir une valeur comprise dans cette fourchette : [10, 100]. |
|
Lors de la construction de l'index, ce paramètre définit la taille du groupe de candidats utilisé lors de la recherche des voisins les plus proches pour chaque nœud. Pour chaque nœud ajouté au graphe, l'algorithme maintient une liste des meilleurs candidats trouvés jusqu'à présent. La recherche de voisins s'arrête lorsque cette liste ne peut plus être améliorée. À partir de cette liste finale de candidats, les nœuds de degré maximal les plus élevés sont sélectionnés pour former les arêtes finales. |
Type: Entier Plage de valeurs: [1, 512] Valeur par défaut: |
Une taille de liste de recherche plus importante augmente la probabilité de trouver les vrais voisins les plus proches pour chaque nœud, ce qui peut conduire à un graphe de meilleure qualité et à de meilleures performances de recherche (rappel). Cependant, cela se fait au prix d'un temps de construction de l'index beaucoup plus long. Cette valeur doit toujours être supérieure ou égale à max_degree. |
|
Nombre de vecteurs PQ stockés en ligne par nœud d'index (lus lors de l'accès au nœud, pour réduire les entrées-sorties) |
Type: Entier Plage de valeurs: [0, max_degree] Valeur par défaut: |
Des valeurs plus élevées de Définissez Définissez Réglez
|
|
Réorganiser la structure des données des vecteurs PQ pour améliorer la localité des données et réduire les accès au disque pendant la recherche (ignoré en mode performance). |
Type: Booléen Portée: [true, false] Valeur par défaut: |
Lorsque vrai, réduit les entrées-sorties pendant la recherche avec une augmentation mineure de la mémoire et du temps de construction de l'index. |
|
Nombre de points d'entrée candidats pour optimiser la sélection du point d'entrée de la recherche. |
Type: Entier Plage de valeurs: [0, 1000] Valeur par défaut: |
Des valeurs élevées peuvent réduire le temps de recherche en démarrant la recherche à partir d'un point d'entrée plus proche. Définir des valeurs plus élevées pour les segments de grande taille (par exemple, pour les vecteurs de 10M et plus, utiliser la valeur 1000). |
|
Contrôle la taille des codes PQ (représentations compressées des points de données) par rapport à la taille des données non compressées. |
Type: Flottant Plage: (0,0, 0,25) Valeur par défaut: |
Un ratio plus élevé permet d'obtenir des résultats de recherche plus précis, en stockant effectivement plus d'informations sur les vecteurs d'origine, mais augmente la complexité de calcul pendant la recherche. Dans la plupart des cas, nous vous recommandons de définir une valeur comprise dans cette fourchette : (0,0417, 0,25). |
|
Contrôle la taille des codes PQ des vecteurs de haute précision stockés dans l'index (utilisés pour le reclassement), par rapport à la taille des données non compressées. |
Type: Flottant Plage de valeurs: [0, 0.25] Valeur par défaut: |
Avec la valeur par défaut de 0,25, les vecteurs seront quantifiés à 25 % de leur taille d'origine (compression 4×), ce qui réduit l'empreinte disque avec un impact relativement minime sur la précision. La valeur 0 permet de stocker les vecteurs de pleine précision dans l'index du disque en vue d'un reclassement. Une valeur plus élevée permet d'obtenir un taux de rappel plus élevé, mais augmente l'utilisation du disque. |
|
Taille du cache des vecteurs PQ en DRAM (octets). Le cache des vecteurs PQ est chargé lors du chargement de l'index et utilisé lors de la recherche pour réduire les entrées-sorties (ignoré en mode performance). |
Type: Entier Plage de valeurs: [0, 1073741824] Valeur par défaut: |
Un cache plus important améliore les performances des requêtes mais augmente l'utilisation de la DRAM. |
|
Contrôle la quantité de DRAM à utiliser pour la mise en cache des nœuds d'index fréquemment accédés Ce cache est chargé lors du chargement de l'index et utilisé lors de la recherche pour réduire les entrées-sorties. |
Type: Flottant Plage de valeurs: [0.0, 0.3) Valeur par défaut: |
Une valeur élevée alloue plus de mémoire pour la mise en cache, ce qui réduit les entrées-sorties sur le disque mais consomme plus de mémoire système. Une valeur plus faible utilise moins de mémoire pour la mise en cache, ce qui peut augmenter les besoins d'accès au disque. |
Paramètres de recherche d'index
Ces paramètres influencent la manière dont l'AISAQ effectue les recherches. Leur réglage peut avoir un impact sur la vitesse de recherche, la latence et l'utilisation des ressources.
Paramètre |
Description du paramètre |
Plage de valeurs |
Suggestion de réglage |
|---|---|---|---|
|
Au cours d'une opération de recherche, ce paramètre détermine la taille du groupe de candidats que l'algorithme maintient lorsqu'il parcourt le graphe. Une valeur plus élevée augmente les chances de trouver les vrais voisins les plus proches (rappel plus élevé), mais augmente également la latence de la recherche. |
Type: Entier Plage de valeurs: [topk, int32_max] Valeur par défaut: |
Pour un bon équilibre entre les performances et la précision, il est recommandé de fixer cette valeur à un niveau égal ou légèrement supérieur au nombre de résultats que vous souhaitez récupérer (top_k). |
|
Contrôle le degré de parallélisme pendant la recherche en déterminant le nombre maximal de demandes d'E/S parallèles sur disque pour lire les nœuds d'index. |
Type: Entier Plage de valeurs: [1, 16] Valeur par défaut: |
Des valeurs plus élevées augmentent le parallélisme, ce qui peut accélérer la recherche sur les systèmes dotés de CPU et de SSD puissants. Toutefois, une valeur trop élevée peut entraîner une contention excessive des ressources. Dans la plupart des cas, nous vous recommandons de définir une valeur de 2. |
|
Contrôle le degré de parallélisme pendant la recherche en déterminant le nombre maximal de demandes d'E/S parallèles sur disque pour lire des groupes de vecteurs PQ voisins (ignoré en mode performance). |
Type: Entier Plage de valeurs: [1, 4] doit être <= beamwidth Valeur par défaut: |
Des valeurs plus élevées augmentent le parallélisme, ce qui peut accélérer la recherche sur les systèmes dotés d'unités centrales et de disques SSD puissants. Toutefois, une valeur trop élevée peut entraîner une contention excessive des ressources, car chaque groupe de vecteurs PQ voisin peut contenir jusqu'à max_degree vectors. Dans la plupart des cas, nous vous recommandons de définir une valeur de 1. |
|
Taille du cache de lecture PQ en DRAM par fil de recherche (octets). Elle met en cache les pages de données fréquemment consultées contenant des vecteurs PQ (ignorée en mode performance et applicable uniquement lorsque rearrange est vrai). La mémoire cache de lecture PQ est réutilisée dans tous les segments AISAQ. |
Type: Entier Plage de valeurs: [0, 33554432] Valeur par défaut: |
Un cache plus important améliore les performances des requêtes mais augmente l'utilisation de la DRAM. Les valeurs recommandées sont de 2 Mio pour les petits segments (1 M de vecteurs), 5 Mio pour les segments moyens (50 M de vecteurs) et 10 Mio pour les grands segments (250 M de vecteurs). |