Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
DiskANN est un algorithme de recherche du plus proche voisin approximatif et évolutif qui permet d’effectuer efficacement une recherche vectorielle à n’importe quelle échelle. Il offre un rappel élevé, des requêtes élevées par seconde et une faible latence de requête, même pour des jeux de données à milliards de points. Ces caractéristiques en font un outil puissant pour gérer de grands volumes de données.
Pour en savoir plus sur DiskANN, consultez DiskANN : Recherche vectorielle pour la recherche à l'échelle du web et la recommandation.
L’extension pg_diskann ajoute la prise en charge de l’utilisation de DiskANN pour une indexation et une recherche efficaces des vecteurs.
Activer pg_diskann
Pour utiliser l’extension pg_diskann sur votre serveur flexible Azure Database pour PostgreSQL, vous devez autoriser l’extension au niveau du serveur. Vous devez ensuite créer l’extension sur chaque base de données dans laquelle vous souhaitez utiliser les fonctionnalités fournies par l’extension.
Étant donné que pg_diskann est dépendant de l’extension vector, vous autorisez et créez l’extension vector dans la même base de données, puis exécutez la commande suivante :
CREATE EXTENSION IF NOT EXISTS pg_diskann;
Vous pouvez également ignorer explicitement l’autorisation et la création de l’extension vector , puis exécuter à la place la commande précédente ajoutant la CASCADE clause. Cette clause PostgreSQL est destinée à exécuter de manière implicite CREATE EXTENSION sur l'extension dont elle dépend. Pour ce faire, exécutez la commande suivante :
CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;
Pour supprimer l’extension de la base de données à laquelle vous êtes actuellement connecté, exécutez la commande suivante :
DROP EXTENSION IF EXISTS pg_diskann;
Utiliser la méthode d’accès à l’index diskann
Après avoir installé l’extension, vous pouvez créer un diskann index sur une colonne de table qui contient des données vectorielles. Par exemple, pour créer un index sur la colonne embedding de la table demo, utilisez la commande suivante :
CREATE TABLE demo (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
embedding public.vector(3)
-- other columns
);
-- insert dummy data
INSERT INTO demo (embedding) VALUES
('[1.0, 2.0, 3.0]'),
('[4.0, 5.0, 6.0]'),
('[7.0, 8.0, 9.0]');
-- create a diskann index by using Cosine distance operator
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)
Après avoir créé l’index, vous pouvez exécuter des requêtes pour rechercher les voisins les plus proches.
La requête suivante recherche les cinq voisins les plus proches du vecteur [2.0, 3.0, 4.0]:
SELECT id, embedding
FROM demo
ORDER BY embedding <=> '[2.0, 3.0, 4.0]'
LIMIT 5;
Postgres décide automatiquement quand utiliser l’index DiskANN. S’il choisit de ne pas utiliser l’index dans un scénario dans lequel vous souhaitez utiliser l’index, exécutez la commande suivante :
-- Explicit Transcation block to force use for DiskANN index.
BEGIN;
SET LOCAL enable_seqscan TO OFF;
-- Similarity search queries
COMMIT;
Important
Définir enable_seqscan sur off dissuade le planificateur d’utiliser un plan de balayage séquentiel si d’autres méthodes sont disponibles. Étant donné qu’il est désactivé à l’aide de la SET LOCAL commande, le paramètre prend effet uniquement pour la transaction actuelle. Après un COMMIT ou ROLLBACK, le paramètre de niveau de session prend effet à nouveau. Si la requête implique d’autres tables, le paramètre décourage également l’utilisation d’analyses séquentielles dans toutes ces tables.
Mettre à l’échelle efficacement avec quantification (préversion)
DiskANN utilise la quantisation de produit (PQ) pour réduire considérablement l’empreinte mémoire des vecteurs. Contrairement à d’autres techniques de quantisation, l’algorithme PQ peut compresser les vecteurs plus efficacement, ce qui améliore considérablement les performances. En utilisant PQ, DiskANN peut conserver plus de données en mémoire, réduire la nécessité d’accéder à un stockage plus lent et utiliser moins de calcul lors de la comparaison des vecteurs compressés. Cela entraîne de meilleures performances et des économies significatives de coûts lors de l’utilisation de plus grandes quantités de données (> 1 million de lignes).
Important
La prise en charge de la quantisation des produits dans DiskANN est disponible à partir de pg_diskann v0.6 et versions ultérieures.
Pour réduire la taille de votre index et faire tenir plus de données en mémoire, utilisez PQ :
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann(embedding vector_cosine_ops)
WITH(
product_quantized=true
);
Améliorer la précision lors de l’utilisation du PQ avec un reclassement vectorielle
Le reclassement avec des vecteurs complets est une technique utilisée dans les systèmes de recherche approximative du plus proche voisin (ANN) tels que DiskANN avec quantification de produit (PQ) afin d'améliorer la précision des résultats en réorganisant les N premiers candidats récupérés à l'aide des vecteurs originaux non compressés (précision complète). Cette technique de reclassement est basée uniquement sur des métriques de similarité vectorielle exacte (par exemple, la similarité cosinus ou la distance euclide). Cette technique n’est pas la même que le reclassement à l’aide d’un modèle de classement.
Pour équilibrer la vitesse et la précision dans la recherche de similarité vectorielle, implémentez une stratégie de reclassement en deux étapes lors de l’interrogation avec DiskANN et la quantisation de produit pour améliorer la précision.
Recherche approximative initiale : la requête interne utilise DiskANN pour récupérer les 50 premiers voisins les plus proches en fonction de la distance de cosinus entre les incorporations stockées et le vecteur de requête. Cette étape est rapide et efficace, tirant parti des fonctionnalités d’indexation de DiskANN.
Reclassement précis : la requête externe réorganise ces 50 résultats par leur distance calculée réelle et retourne les 10 premières correspondances les plus pertinentes :
Voici un exemple de reclassement à l’aide de cette approche en deux étapes :
SELECT id
FROM (
SELECT id, embedding <=> %s::vector AS distance
FROM demo
ORDER BY embedding <=> %s::vector asc
LIMIT 50
) AS t
ORDER BY t.distance
LIMIT 10;
Note
Remplacez %s par le vecteur de requête. Vous pouvez utiliser azure_ai pour créer un vecteur de requête directement dans Postgres.
Cette approche équilibre la rapidité (grâce à une recherche approximative) et la précision (grâce à un reclassement vectoriel complet), garantissant ainsi des résultats de haute qualité sans avoir à analyser l’ensemble des données.
Prise en charge des incorporations à haute dimension
Les applications d’IA générative avancées s’appuient souvent sur des modèles d’incorporation haute dimension tels que text-embedding-3-large pour obtenir une précision supérieure. Toutefois, les méthodes d’indexation traditionnelles comme HNSW dans pgvector sont limitées aux vecteurs avec jusqu’à 2 000 dimensions, ce qui limite l’utilisation de ces modèles puissants.
À compter de pg_diskann v0.6 et versions ultérieures, DiskANN prend en charge les vecteurs d’indexation avec jusqu’à 16 000 dimensions, ce qui étend considérablement l’étendue des charges de travail IA haute précision.
Important
Activez la quantification de produit pour tirer parti de la prise en charge des dimensions élevées.
Paramètres recommandés :
-
product_quantized: définir sur true -
pq_param_num_chunks: défini sur un tiers de la dimension d’incorporation pour des performances optimales. -
pq_param_training_samples: déterminé automatiquement en fonction de la taille de la table, sauf si elle est définie explicitement.
Cette amélioration permet une recherche évolutive et efficace sur les jeux de données à vecteurs volumineux tout en conservant un rappel et une précision élevés.
Accélérer la génération d’index
Pour améliorer vos temps de génération d’index, essayez les recommandations suivantes.
Utiliser plus de mémoire
Pour accélérer la création de l’index, augmentez la mémoire allouée sur votre serveur PostgreSQL pour la build d’index. Spécifiez l’utilisation de la mémoire par le biais du maintenance_work_mem paramètre.
-- Set the parameters
SET maintenance_work_mem = '8GB'; -- Depending on your resources
La CREATE INDEX commande utilise la mémoire de travail spécifiée, en fonction des ressources disponibles, pour générer l’index.
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)
Conseil / Astuce
Effectuez un scale-up de vos ressources de mémoire pendant la génération d’index pour améliorer la vitesse d’indexation, puis effectuez un scale-down lorsque l’indexation est terminée.
Utilisation de la parallélisation
Pour accélérer la création de l’index, utilisez des processus parallèles. Spécifiez le nombre de processus de travail à l’aide du paramètre de stockage parallel_workers de l’instruction CREATE TABLE lors de la création de la table. Vous pouvez ajuster ce nombre ultérieurement à l’aide de la SET clause de l’instruction ALTER TABLE .
CREATE TABLE demo (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
embedding public.vector(3)
) WITH (parallel_workers = 4);
ALTER TABLE demo SET (parallel_workers = 8);
La commande CREATE INDEX utilise le nombre spécifié de processus parallèles, en fonction des ressources disponibles, pour créer l’index.
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)
Important
Le processus leader ne peut pas participer aux builds d’index parallèles.
Si vous souhaitez créer l’index en utilisant des workers parallèles, définissez les paramètres max_parallel_workers, max_worker_processes et max_parallel_maintenance_workers en conséquence. Pour plus d’informations sur ces paramètres, consultez les paramètres qui contrôlent les utilisations des ressources et le comportement asynchrone.
Définissez ces paramètres à différents niveaux de granularité. Par exemple, pour les définir au niveau de la session, exécutez les instructions suivantes :
-- Set the parameters
SET max_parallel_workers = 8;
SET max_worker_processes = 8; -- Note: Requires server restart
SET max_parallel_maintenance_workers = 4;
Pour en savoir plus sur les autres options de configuration de ces paramètres dans Azure Database pour PostgreSQL serveur flexible, consultez Paramètres de configuration.
Note
Le max_worker_processes paramètre nécessite qu’un redémarrage du serveur prenne effet.
Si la configuration de ces paramètres et les ressources disponibles sur le serveur n’autorisent pas le lancement des workers parallèles, PostgreSQL revient automatiquement à créer l’index en mode nonparallel.
Paramètres de configuration
Lorsque vous créez un diskann index, spécifiez différents paramètres pour contrôler son comportement.
Paramètres d’index
-
max_neighbors: nombre maximal d’arêtes par nœud dans le graphique La valeur par défaut est 32. Une valeur plus élevée peut améliorer le rappel jusqu’à un certain point. -
l_value_ib: Taille de la liste de recherche pendant la génération d’index. La valeur par défaut est 100. Une valeur plus élevée ralentit la compilation, mais l’index est de meilleure qualité. -
product_quantized: active la quantisation du produit pour une recherche plus efficace. La valeur par défaut est false. -
pq_param_num_chunks: nombre de blocs pour la quantisation du produit. La valeur par défaut est 0, ce qui signifie que le système détermine automatiquement la valeur en fonction des dimensions incorporées. Utilisez un tiers des dimensions d’incorporation d’origine. -
pq_param_training_samples: nombre de vecteurs servant à entraîner la table de pivot PQ. La valeur par défaut est 0, ce qui signifie que le système détermine automatiquement la valeur en fonction de la taille de la table.
CREATE INDEX demo_embedding_diskann_custom_idx ON demo USING diskann (embedding vector_cosine_ops)
WITH (
max_neighbors = 48,
l_value_ib = 100,
product_quantized=true,
pq_param_num_chunks = 0,
pq_param_training_samples = 0
);
Paramètres d’extension
diskann.iterative_search: contrôle le comportement de recherche.Configurations pour
diskann.iterative_search:relaxed_order(valeur par défaut) : permet à diskann d’effectuer une recherche itérative dans les lots dediskann.l_value_is, jusqu’à ce que le nombre souhaité de tuples, éventuellement limité parLIMITclause, soit généré. Cette option peut entraîner un affichage des résultats dans le désordre.strict_order: similaire àrelaxed_order, mais elle garantit que les résultats sont retournés dans un ordre strict trié par distance.off: utilise la fonctionnalité de recherche noniterative. Il tente de récupérer les tuplesdiskann.l_value_isen une étape. La recherche non itérative ne peut retourner qu’un maximum de vecteursdiskann.l_value_ispour une requête, quelle que soit la clauseLIMITou le nombre de tuples qui correspondent à la requête.
Pour modifier le comportement
strict_orderde recherche pour toutes les requêtes exécutées dans la session active, exécutez l’instruction suivante :SET diskann.iterative_search TO 'strict_order';Pour la modifier afin qu’elle affecte uniquement toutes les requêtes exécutées dans la transaction actuelle, exécutez l’instruction suivante :
BEGIN; SET LOCAL diskann.iterative_search TO 'strict_order'; -- All your queries COMMIT;diskann.l_value_is: valeur L pour l’analyse d’index (valeur par défaut 100). L’augmentation de la valeur améliore le rappel, mais peut ralentir les requêtes.Pour modifier la valeur L de l’analyse d’index sur 20 pour toutes les requêtes exécutées dans la session active, exécutez l’instruction suivante :
SET diskann.l_value_is TO 20;Pour la modifier afin qu’elle affecte uniquement toutes les requêtes exécutées dans la transaction actuelle, exécutez l’instruction suivante :
BEGIN; SET LOCAL diskann.l_value_is TO 20; -- All your queries COMMIT;
Configuration recommandée des paramètres
| Taille du jeu de données (lignes) | Type de paramètre | Nom | Valeur recommandée |
|---|---|---|---|
| <1 M | Construction de l'index | l_value_ib |
100 |
| <1 M | Construction de l'index | max_neighbors |
32 |
| <1 M | Temps de requête | diskann.l_value_is |
100 |
| 1M-50M | Construction de l'index | l_value_ib |
100 |
| 1M-50M | Construction de l'index | max_neighbors |
64 |
| 1M-50M | Construction de l'index | product_quantized |
true |
| 1M-50M | Temps de requête | diskann.l_value_is |
100 |
| >50 M | Construction de l'index | l_value_ib |
100 |
| >50 M | Construction de l'index | max_neighbors |
96 |
| >50 M | Construction de l'index | product_quantized |
true |
| >50 M | Temps de requête | diskann.l_value_is |
100 |
Note
Ces paramètres peuvent varier en fonction du jeu de données spécifique et du cas d’usage. Vous devrez peut-être expérimenter différentes valeurs de paramètres pour trouver les paramètres optimaux pour votre scénario particulier.
Progression de CREATE INDEX et REINDEX
À compter de PostgreSQL 12, vous pouvez utiliser pg_stat_progress_create_index pour vérifier la progression des opérations CREATE INDEX ou REINDEX.
SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
Pour en savoir plus sur les phases possibles à travers lesquelles une opération CREATE INDEX ou REINDEX est effectuée, consultez les phases CREATE INDEX.
Sélection de la fonction d’accès à l’index
Le type de vecteur prend en charge trois types de recherches sur les vecteurs stockés. Sélectionnez la fonction d’accès correcte pour votre index afin que la base de données puisse prendre en compte votre index lors de l’exécution de vos requêtes.
pg_diskann prend en charge les opérateurs de distance suivants :
-
vector_l2_ops:<->Distance euclidienne -
vector_cosine_ops:<=>Distance cosinus -
vector_ip_ops:<#>Produit interne
Résolution des problèmes
Erreur : : assertion left == right failed left: 40 right: 0
La version de DiskANN GA, v0.6.x introduit des changements cassants dans le format des métadonnées d’index. Les index créés avec v0.5.x ne sont pas compatibles de manière ascendante avec les opérations d’insertion de la version v0.6.x. Si vous essayez d’insérer dans une table avec un index obsolète, vous obtenez une erreur, même si l’index apparaît valide.
Lorsque vous rencontrez cette erreur, résolvez-la en procédant comme suit :
Option 1 : Exécution d'une instruction
REINDEXouREDINDEX CONCURRENTLYsur l’index.Option 2 : Reconstruction de l’index.
DROP INDEX your_index_name; CREATE INDEX your_index_name ON your_table USING diskann(your_vector_column vector_cosine_ops);
Erreur : : diskann index needs to be upgraded to version 2...
- Lorsque vous rencontrez cette erreur, résolvez-la en procédant comme suit :
Option 1 : Exécution d'une instruction
REINDEXouREDINDEX CONCURRENTLYsur l’index.Option 2 : Étant donné que
REINDEXcela peut prendre beaucoup de temps, l’extension fournit également une fonction définie par l’utilisateur appeléeupgrade_diskann_index(), qui met à niveau votre index plus rapidement, lorsque cela est possible.Pour mettre à niveau votre index, exécutez l’instruction suivante :
SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');Pour mettre à niveau tous les index diskann de la base de données vers la version actuelle, exécutez l’instruction suivante :
SELECT upgrade_diskann_index(pg_class.oid) FROM pg_class JOIN pg_am ON (pg_class.relam = pg_am.oid) WHERE pg_am.amname = 'diskann';