milvus-logo
LFAI
Home
  • Concepts

Knowhere

Cette rubrique présente Knowhere, le moteur d'exécution vectorielle de Milvus.

Vue d'ensemble

Knowhere est le moteur d'exécution vectorielle central de Milvus, qui intègre plusieurs bibliothèques de recherche de similarités vectorielles, notamment Faiss, Hnswlib et Annoy. Knowhere est également conçu pour prendre en charge l'informatique hétérogène. Il contrôle sur quel matériel (CPU ou GPU) exécuter la construction de l'index et les requêtes de recherche. C'est ainsi que Knowhere tire son nom : savoir où exécuter les opérations. D'autres types de matériel, notamment les DPU et TPU, seront pris en charge dans les prochaines versions.

Knowhere dans l'architecture Milvus

La figure ci-dessous illustre la position de Knowhere dans l'architecture Milvus.

Knowhere Knowhere

La couche la plus basse est le matériel du système. Au-dessus se trouvent les bibliothèques d'indexation de tiers. À la couche supérieure, Knowhere interagit avec le nœud d'index et le nœud de requête via CGO, qui permet aux paquets Go d'appeler du code C.

Avantages de Knowhere

Voici les avantages de Knowhere par rapport à Faiss.

Prise en charge de BitsetView

Milvus introduit un mécanisme de bitset pour réaliser la "suppression douce". Un vecteur supprimé en douceur existe toujours dans la base de données mais ne sera pas calculé lors d'une recherche ou d'une requête de similarité vectorielle.

Chaque bit d'un jeu de bits correspond à un vecteur indexé. Si un vecteur est marqué "1" dans l'ensemble de bits, cela signifie que ce vecteur est supprimé et qu'il ne sera pas pris en compte lors d'une recherche de vecteurs. Le paramètre de bitset est appliqué à toutes les API de requête d'index Faiss exposées dans Knowhere, y compris les index CPU et GPU.

Pour plus d'informations sur le mécanisme de bitset, consultez bitset.

Prise en charge de plusieurs mesures de similarité pour l'indexation de vecteurs binaires

Knowhere supporte Hamming, Jaccard, Tanimoto, Superstructure et Substructure. Jaccard et Tanimoto peuvent être utilisés pour mesurer la similarité entre deux ensembles d'échantillons, tandis que Superstructure et Substructure peuvent être utilisés pour mesurer la similarité des structures chimiques.

Prise en charge du jeu d'instructions AVX512

Outre AArch64, SSE4.2 et AVX2, les jeux d'instructions déjà pris en charge par Faiss, Knowhere prend également en charge AVX512, qui peut améliorer les performances de construction d'index et d'interrogation de 20 à 30 % par rapport à AVX2.

Sélection automatique des instructions SIMD

Knowhere permet d'invoquer automatiquement les instructions SIMD appropriées (par exemple, SIMD SSE, AVX, AVX2 et AVX512) sur n'importe quel processeur (à la fois sur les plates-formes sur site et en nuage), de sorte que les utilisateurs n'ont pas besoin de spécifier manuellement le drapeau SIMD (par exemple, "-msse4") pendant la compilation.

Knowhere est construit en remaniant la base de code de Faiss. Les fonctions communes (par exemple, le calcul de similarité) qui dépendent des accélérations SIMD sont supprimées. Ensuite, pour chaque fonction, quatre versions (SSE, AVX, AVX2, AVX512) sont implémentées et chacune est placée dans un fichier source séparé. Les fichiers sources sont ensuite compilés individuellement avec le drapeau SIMD correspondant. Ainsi, au moment de l'exécution, Knowhere peut automatiquement choisir les instructions SIMD les mieux adaptées en fonction des drapeaux actuels de l'unité centrale et lier les bons pointeurs de fonction à l'aide de l'accrochage.

Autres optimisations des performances

Lisez Milvus : A Purpose-Built Vector Data Management System pour en savoir plus sur l'optimisation des performances de Knowhere.

Structure du code de Knowhere

Le calcul dans Milvus implique principalement des opérations vectorielles et scalaires. Knowhere ne gère que les opérations d'indexation des vecteurs.

Un index est une structure de données indépendante des données vectorielles d'origine. En général, l'indexation nécessite quatre étapes : créer un index, former des données, insérer des données et construire un index. Dans certaines applications d'intelligence artificielle, la formation des ensembles de données est séparée de la recherche vectorielle. Les données des ensembles de données sont d'abord formées, puis insérées dans une base de données vectorielles telle que Milvus pour la recherche de similarités. Par exemple, les jeux de données ouverts sift1M et sift1B différencient les données pour la formation et les données pour les tests.

Cependant, dans Knowhere, les données pour l'entraînement et pour la recherche sont les mêmes. Knowhere forme toutes les données d'un segment, puis insère toutes les données formées et construit un index pour elles.

DataObjClasse de base

DataObj est la classe de base de toutes les structures de données dans Knowhere. Size() est la seule méthode virtuelle dans DataObj. La classe Index hérite de DataObj avec un champ nommé "size_". La classe Index possède également deux méthodes virtuelles - Serialize() et Load(). La classe VecIndex dérivée de Index est la classe de base virtuelle pour tous les index vectoriels. VecIndex fournit des méthodes, notamment Train(), Query(), GetStatistics() et ClearStatistics().

base class classe de base

D'autres types d'index sont énumérés à droite dans la figure ci-dessus.

  • L'index Faiss a deux classes de base : FaissBaseIndex pour tous les index sur les vecteurs à virgule flottante et FaissBaseBinaryIndex pour tous les index sur les vecteurs binaires.

  • GPUIndex est la classe de base pour tous les index GPU de Faiss.

  • OffsetBaseIndex est la classe de base pour tous les index auto-développés. Étant donné que seuls les ID des vecteurs sont stockés dans un fichier d'index, la taille du fichier pour les vecteurs à 128 dimensions peut être réduite de deux ordres de grandeur.

IDMAP IDMAP

Techniquement parlant, IDMAP n'est pas un index, mais est plutôt utilisé pour la recherche par force brute. Lorsque les vecteurs sont insérés dans la base de données, il n'est pas nécessaire de procéder à un apprentissage des données ni à la construction d'un index. Les recherches seront effectuées directement sur les données vectorielles insérées.

Toutefois, pour des raisons de cohérence du code, IDMAP hérite également de la classe VecIndex et de toutes ses interfaces virtuelles. L'utilisation de IDMAP est la même que celle des autres indices.

Indices IVF

IVF IVF

Les indices IVF (fichier inversé) sont les plus fréquemment utilisés. La classe IVF est dérivée de VecIndex et FaissBaseIndex, et s'étend à IVFSQ et IVFPQ. GPUIVF est dérivée de GPUIndex et IVF. Puis GPUIVF s'étend à GPUIVFSQ et GPUIVFPQ.

IVFSQHybrid est un indice hybride que nous avons développé nous-mêmes. Un quantificateur grossier est exécuté sur le GPU tandis que la recherche dans le seau est effectuée sur le CPU. Ce type d'index peut réduire la fréquence des copies de mémoire entre le CPU et le GPU en tirant parti de la puissance de calcul du GPU. IVFSQHybrid a le même taux de rappel que GPUIVFSQ mais offre de meilleures performances.

La structure des classes de base pour les indices binaires est relativement simple. BinaryIDMAP et BinaryIVF sont dérivés de FaissBaseBinaryIndex et VecIndex.

Indices de tiers

third-party indices Indices de tiers

Actuellement, seuls deux types d'indices tiers sont pris en charge en dehors de Faiss : l'indice basé sur les arbres Annoy et l'indice basé sur les graphes HNSW. Ces deux indices tiers courants et fréquemment utilisés sont tous deux dérivés de VecIndex.

Ajout d'index à Knowhere

Si vous souhaitez ajouter de nouveaux indices à Knowhere, vous pouvez d'abord vous référer aux indices existants :

  • Pour ajouter des indices basés sur la quantification, consultez IVF_FLAT.

  • Pour ajouter des indices basés sur des graphes, consultez HNSW.

  • Pour ajouter des index basés sur des arbres, consultez Annoy.

Après avoir fait référence à l'index existant, vous pouvez suivre les étapes ci-dessous pour ajouter un nouvel index à Knowhere.

  1. Ajoutez le nom du nouvel index dans IndexEnum. Le type de données est une chaîne.

  2. Ajoutez un contrôle de validation des données sur le nouvel index dans le fichier ConfAdapter.cpp. Le contrôle de validation sert principalement à valider les paramètres de formation des données et de requête.

  3. Créez un nouveau fichier pour le nouvel index. La classe de base du nouvel index doit inclure VecIndex et l'interface virtuelle nécessaire de VecIndex.

  4. Ajoutez la logique de construction de l'index pour le nouvel index dans VecIndexFactory::CreateVecIndex().

  5. Ajoutez le test unitaire dans le répertoire unittest.

Prochaines étapes

Après avoir appris comment Knowhere fonctionne dans Milvus, vous voudrez peut-être.. :

Traduit parDeepLogo

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Cette page a-t - elle été utile ?