Présentation de Cardinal : le moteur le plus performant pour les recherches vectorielles
Cet article est rédigé par Alexandr Guzhva et Li Liu.
Dans les bases de données, la « performance » est une métrique critique, en particulier dans les bases de données vectorielles. Elle est essentielle pour traiter efficacement un volume élevé de requêtes utilisateur avec des ressources limitées. Bien que la latence d’accès puisse ne pas être un problème dans certaines situations, pour une base de données vectorielle, la performance reste essentielle pour diverses raisons.
La recherche vectorielle, qui repose sur la recherche approximative du plus proche voisin (ANNS), peut échanger un léger degré de précision contre de meilleures performances. L’amélioration des performances permet, à son tour, une plus grande précision.
Des performances exceptionnelles, maintenues avec une latence de requête constante, facilitent un débit plus élevé avec les mêmes ressources, permettant d’accueillir une base d’utilisateurs plus large.
De plus, l’amélioration des performances se traduit par un besoin réduit en ressources de calcul pour prendre en charge des scénarios d’utilisation identiques.
Les bases de données vectorielles sont intrinsèquement intensives en calcul, une part importante de l’utilisation des ressources — souvent supérieure à 80 % — étant consacrée aux calculs de distance vectorielle. Par conséquent, le moteur de recherche vectorielle, responsable de la gestion des tâches de recherche vectorielle, devient un facteur critique pour déterminer la performance globale d’une base de données vectorielle.
Zilliz accorde constamment la priorité à l’amélioration des performances des bases de données vectorielles. Le projet open source Milvus et le service entièrement géré Zilliz Cloud affichent des performances supérieures à celles de produits similaires. Le moteur de recherche vectorielle de Milvus, Knowhere, joue un rôle important dans ce succès en posant les bases d’un nouveau moteur de recherche.
Au cœur de la dernière version de Zilliz Cloud se trouve Cardinal, un nouveau moteur de recherche vectorielle que nous avons développé. Ce moteur de recherche a déjà démontré une multiplication par trois des performances par rapport à la version précédente, offrant une performance de recherche (QPS) qui atteint dix fois celle de Milvus.
Nous avons évalué les performances de la dernière version de Zilliz Cloud au moyen de l’outil de benchmark open source pour bases de données vectorielles et comparé ses performances avec celles de Milvus et de Zilliz Cloud doté d’un ancien moteur. Les résultats de l’évaluation sont présentés dans les graphiques ci-dessous.
Qu’est-ce que Cardinal ?
Cardinal est un moteur de recherche vectorielle propriétaire, moderne, multithread, basé sur des templates C++, qui implémente les méthodes ANNS les plus pratiques et les plus largement utilisées. Cardinal a été conçu et écrit de zéro afin d’utiliser efficacement les ressources de calcul disponibles.
Cardinal est capable de :
effectuer une recherche par force brute,
créer et modifier des index ANNS,
effectuer une recherche Top-K indexée et une recherche par plage indexée,
fonctionner avec différents formats de données d’entrée, notamment FP32, FP16 et BF16,
fonctionner avec des données en mémoire ou avec des données mappées en mémoire,
filtrer les résultats pendant la recherche sur la base de critères fournis par l’utilisateur.
Cardinal comprend :
Une implémentation de méthodes ANN qui permet de configurer facilement divers paramètres internes. Cependant, le point de fonctionnement par défaut est systématiquement réglé pour maximiser la vitesse de recherche (QPS, requêtes par seconde) tout en maintenant une précision raisonnable (taux de rappel).
Une implémentation efficace de divers algorithmes qui prennent en charge les méthodes ANNS. Par exemple, ceux qui fournissent des capacités de filtrage d’échantillons.
Des noyaux optimisés spécialisés de bas niveau pour la plupart des opérations les plus intensives en calcul utilisées pendant la recherche ou la construction. Plusieurs plateformes matérielles sont prises en charge. Outre les noyaux qui calculent les distances pour diverses métriques, Cardinal contient également des noyaux fusionnés et des noyaux pour le prétraitement des données.
Des fonctionnalités de support, telles que les opérations asynchrones, les capacités d’E/S mappées en mémoire, la mise en cache, les allocateurs de mémoire, la journalisation, etc.
Knowhere vs Cardinal
La bibliothèque Knowhere est un noyau interne de Milvus open source, responsable de la recherche vectorielle. Knowhere est basée sur des versions modifiées de bibliothèques open source standard de l’industrie, telles que Faiss, DiskANN et hnswlib.
Fournissons une comparaison entre Knowhere et Cardinal :
| Fonctionnalité | Knowhere | Cardinal |
|---|---|---|
| Prêt pour la production | Oui | Oui |
| Capacités de scalabilité | Oui | Oui |
| Philosophie de conception | Expérimentation et flexibilité | Portée restreinte, priorité à l’amélioration des fonctionnalités existantes pour la performance |
| Compatibilité hôte | Tous les types d’hôtes | Optimisé pour l’environnement hôte de Zilliz Cloud |
| Dépendance | S’appuie sur des bibliothèques et implémentations OSS reconnues | Contient des modifications et optimisations non triviales |
Les deux sont prêts pour la production et fournissent toutes les capacités de scalabilité dont Milvus et Zilliz Cloud ont besoin.
Knowhere est conçu en gardant à l’esprit l’expérimentation et la flexibilité. Cardinal a une portée plus restreinte, donnant la priorité à l’amélioration des fonctionnalités existantes pour une vitesse et des performances accrues plutôt qu’à l’introduction de nombreuses nouvelles fonctionnalités.
Comme Knowhere est open source et peut être déployé dans de nombreux environnements différents, il fonctionne sur tous les types d’hôtes. Cardinal est optimisé pour l’environnement hôte de Zilliz Cloud.
Knowhere s’appuie sur des bibliothèques et implémentations OSS reconnues(telles que Faiss, DiskANN et hnswlib). Cardinal contient des modifications et optimisations non triviales.
Ce qui rend Cardinal si rapide
Cardinal met en œuvre diverses optimisations liées aux algorithmes, à l’ingénierie et de bas niveau. Cardinal introduit le mécanisme AUTOINDEX, qui sélectionne automatiquement la meilleure stratégie de recherche et le meilleur index pour le jeu de données. Cela élimine le besoin d’un réglage manuel, ce qui fait gagner du temps et des efforts aux développeurs.
Entrons dans les détails.
Optimisations algorithmiques
Cette forme d’optimisation améliore considérablement la précision et l’efficacité du processus de recherche, un pipeline multifacette impliquant divers algorithmes fonctionnant de concert. De nombreux algorithmes au sein de ce pipeline peuvent être affinés afin d’améliorer les performances globales. Parmi les candidats notables aux optimisations algorithmiques dans Cardinal figurent :
Les algorithmes de recherche, englobant à la fois les approches basées sur IVF et celles basées sur des graphes,
Les algorithmes conçus pour aider la recherche à maintenir le taux de rappel requis, indépendamment du pourcentage d’échantillons filtrés,
Des itérations avancées des algorithmes de recherche best-first,
Des algorithmes personnalisés pour une structure de données de file de priorité.
Les algorithmes paramétrables offrent la flexibilité nécessaire aux compromis, comme l’équilibrage entre performance et utilisation de la RAM. Par conséquent, les optimisations algorithmiques pour Cardinal impliquent également la sélection de points de fonctionnement optimaux dans l’espace des paramètres.
Optimisations d’ingénierie
Si les algorithmes sont initialement conçus en pensant à des machines de Turing abstraites, leur implémentation dans le monde réel se heurte à des défis tels que les latences réseau, les restrictions des fournisseurs cloud sur les IOPS et les limitations de la RAM des machines, une ressource précieuse mais finie.
Les optimisations d’ingénierie garantissent que le pipeline de recherche vectorielle de Cardinal reste pratique et s’aligne sur les contraintes de calcul, de RAM et d’autres ressources. Dans le développement de Cardinal, nous combinons pratiques standard et techniques innovantes. Cette approche permet au compilateur C++ de générer du code compilé optimal sur le plan computationnel tout en conservant un code source propre, mesurable par benchmark et facilement extensible, qui facilite l’ajout rapide de nouvelles fonctionnalités.
Voici quelques exemples de pratiques d’ingénierie mises en œuvre dans Cardinal, illustrant des optimisations spécifiques :
Allocateurs de mémoire spécialisés et pools de mémoire,
Code multithread correctement implémenté,
Structure hiérarchique de composants facilitant la combinaison d’éléments dans divers pipelines de recherche,
Personnalisation du code pour des cas d’utilisation spécifiques et critiques.
Optimisations de bas niveau
La majeure partie du temps de recherche est consacrée à des morceaux de code relativement petits appelés kernels. L’exemple le plus simple est un kernel qui calcule la distance L2 entre deux vecteurs.
Cardinal inclut de nombreux kernels de calcul à différentes fins, chacun étant écrit et optimisé spécifiquement pour une plateforme matérielle et un cas d’utilisation spécifiques.
Cardinal prend en charge les plateformes matérielles x86 et ARM, mais d’autres plateformes peuvent être facilement ajoutées.
Pour la plateforme x86, les kernels Cardinal utilisent les extensions F, CD, VL, BW, DQ, VPOPCNTDQ, VBMI, VBMI2, VNNI, BF16 et FP16 de AVX-512. Nous explorons également l’utilisation du nouveau jeu d’instructions AMX.
Pour la plateforme ARM, les kernels Cardinal sont disponibles pour les jeux d’instructions NEON et SVE.
Nous veillons à ce que Cardinal obtienne le code le plus optimal pour les kernels de calcul. Nous ne nous contentons pas de compter sur un compilateur C++ moderne pour faire le travail :
Nous utilisons des outils dédiés, tels que Linux perf, pour analyser les points chauds et les métriques CPU
Nous utilisons des outils d’analyse du code machine, tels que GodBolt Compiler Explorer et uiCA, afin de garantir l’utilisation optimale des « ressources » matérielles, telles que le nombre d’accès à la RAM/au cache, les instructions CPU utilisées, les registres et les ports de calcul.
Nous utilisons une approche itérative qui entrelace les étapes de conception, de benchmarking, de profilage et d’analyse du code assembleur.
Un kernel de calcul correctement optimisé peut offrir une accélération de 2x ou 3x par rapport à un kernel naïf mais non optimisé. Cela peut ensuite se traduire par une valeur de QPS 2x plus élevée ou des besoins en mémoire inférieurs de 20 % sur une machine hôte cloud.
AutoIndex : sélection de la stratégie de recherche
La recherche vectorielle est un processus complexe impliquant de nombreux composants indépendants, notamment la quantification, la construction d’index, les algorithmes de recherche, les structures de données, et plus encore. Chaque composant dispose d’une multitude de paramètres ajustables. Ensemble, ils forment une gamme très variée de stratégies de recherche vectorielle, et différents jeux de données et scénarios nécessitent différentes stratégies de recherche.
Pour mieux exploiter le potentiel d’amélioration des performances, Cardinal, en plus de prendre en charge plusieurs stratégies dans chaque composant, a implémenté un ensemble de mécanismes de sélection dynamique de stratégie basés sur l’IA, appelés AUTOINDEX. Il choisit de manière adaptative la stratégie la plus adaptée en fonction de la distribution du jeu de données donné, de la requête fournie et de la configuration matérielle. Cela nous aide à atteindre des performances optimales tout en répondant aux exigences des utilisateurs en matière de qualité de recherche.
Benchmark Cardinal
Nous avons adopté ANN-benchmarks afin de prendre en charge Cardinal dans notre environnement de test. ANN benchmarks est un outil de benchmarking standard pour évaluer les implémentations ANNS, et il est exécuté sur plusieurs jeux de données standard qui utilisent différentes métriques de distance. Chaque évaluation des performances est effectuée à l’intérieur d’un conteneur docker limité à l’utilisation d’un seul thread. Les métriques sont basées sur plusieurs itérations d’évaluation, qui utilisent de nombreuses requêtes à requête unique. Les résultats de chaque framework évalué sont agrégés dans une frontière de Pareto rappel-vs-QPS.
Tous les tests ont été réalisés sur le même type de machine que la référence ann-benchmarks (en janvier 2024), à savoir une machine Amazon EC2 r6i.16xlarge avec la configuration suivante :
CPU : Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz
Nombre de cœurs CPU : 32
L’hyperthreading est désactivé
RAM : 512 Go
OS : Ubuntu 22.04.3 LTS avec le noyau Linux 6.2.0-1017-aws
La prise en charge des huge pages n’a pas été activée.
Les tests ont été exécutés avec l’option `--parallelism=31`.
Cardinal a été compilé à l’aide du compilateur clang 17.0.6.
Les résultats de benchmark présentés ci-dessous concernent uniquement le moteur Cardinal et n’incluent pas les optimisations non liées à l’index fournies par Zilliz Cloud.
Remarque : Les résultats qui incluent les optimisations spécifiques à Zilliz Cloud sont fournis ci-dessus au début de l’article.
Les graphiques suivants ont été produits en prenant les images des graphiques avec les résultats présentés sur la page GitHub ANN-benchmark et en ajoutant précisément une courbe Cardinal supplémentaire par-dessus.
Pour tous les benchmarks fournis, Cardinal affiche des résultats très compétitifs. Et il reste une marge d’amélioration.
Et ensuite ?
L’avenir nous apportera de nouveaux défis, sans aucun doute. Des exigences différentes, des goulots d’étranglement différents, des jeux de données plus volumineux. Nous continuons à travailler pour rendre Cardinal encore meilleur.
La voie est éclairée. Le chemin est clair. Il ne nous faut que la force de le suivre :)
Continuer à lire

Zilliz Cloud Just Landed in Claude Code
The Zilliz Cloud Plugin brings the full power of Zilliz Cloud directly into your Claude Code terminal as natural-language conversations.

Zilliz Cloud Now Available in AWS Europe (Ireland)
Zilliz Cloud launches in AWS eu-west-1 (Ireland) — bringing low-latency vector search, EU data residency, and full GDPR-ready infrastructure to European AI teams. Now live across 30 regions on five cloud providers.

Introducing Zilliz MCP Server: Natural Language Access to Your Vector Database
Developers can easily manage and query vector databases with natural language via Zilliz MCP Server in AI-native environments.



