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
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.
DataObj
Classe 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()
.
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 etFaissBaseBinaryIndex
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
Recherche par force brute
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
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
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.
Ajoutez le nom du nouvel index dans
IndexEnum
. Le type de données est une chaîne.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.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 deVecIndex
.Ajoutez la logique de construction de l'index pour le nouvel index dans
VecIndexFactory::CreateVecIndex()
.Ajoutez le test unitaire dans le répertoire
unittest
.
Prochaines étapes
Après avoir appris comment Knowhere fonctionne dans Milvus, vous voudrez peut-être.. :
Découvrir les différents types d'index pris en charge par Milvus.
En savoir plus sur le mécanisme des bitsets.
Comprendre comment les données sont traitées dans Milvus.