Apresentando o Cardinal: O mecanismo de melhor desempenho para buscas vetoriais
Esta publicação foi escrita por Alexandr Guzhva e Li Liu.
Em bancos de dados, 'desempenho' é uma métrica crítica, especialmente em bancos de dados vetoriais. Ele é fundamental para processar com eficiência um alto volume de solicitações de usuários com recursos limitados. Embora a latência de acesso possa não ser uma preocupação em algumas situações, para um banco de dados vetorial, o desempenho continua sendo essencial por vários motivos.
A busca vetorial, dependente da Busca Aproximada do Vizinho Mais Próximo (ANNS), pode trocar um pequeno grau de precisão por desempenho aprimorado. O desempenho aprimorado, por sua vez, permite maior precisão.
Um desempenho excepcional, mantido sob uma latência de consulta consistente, facilita uma taxa de transferência mais alta usando os mesmos recursos, acomodando uma base de usuários maior.
Além disso, o desempenho aprimorado se traduz na necessidade de menos recursos computacionais para oferecer suporte a cenários de uso idênticos.
Bancos de dados vetoriais são inerentemente intensivos em computação, com uma parte significativa do uso de recursos—frequentemente excedendo 80%—dedicada a cálculos de distância vetorial. Como resultado, o mecanismo de busca vetorial, responsável por lidar com tarefas de busca vetorial, torna-se um fator crítico para determinar o desempenho geral de um banco de dados vetorial.
A Zilliz prioriza consistentemente o aprimoramento do desempenho de bancos de dados vetoriais. O Milvus de código aberto e o Zilliz Cloud totalmente gerenciado demonstram desempenho superior em comparação com produtos semelhantes. O mecanismo de busca vetorial do Milvus Knowhere, desempenha um papel significativo na conquista desse sucesso ao estabelecer a base para um novo mecanismo de busca.
No centro da versão mais recente do Zilliz Cloud está o Cardinal, um novo mecanismo de busca vetorial que construímos. Este mecanismo de busca já demonstrou um aumento de três vezes no desempenho em comparação com a versão anterior, oferecendo um desempenho de busca (QPS) que chega a dez vezes o do Milvus.
Avaliamos o desempenho do Zilliz Cloud mais recente por meio da ferramenta de benchmark de bancos de dados vetoriais de código aberto e comparamos seu desempenho com o Milvus e o Zilliz Cloud com um mecanismo antigo. Os resultados da avaliação são mostrados nos gráficos abaixo.
O que é o Cardinal?
Cardinal é um mecanismo de busca vetorial proprietário, multi-threaded, moderno, baseado em templates C++, que implementa os métodos ANNS mais práticos e amplamente usados. O Cardinal foi projetado e escrito do zero para usar os recursos computacionais disponíveis com eficiência.
O Cardinal é capaz de:
realizar busca por força bruta,
criar e modificar índices ANNS,
realizar busca Top-K por índice e busca por intervalo em índice,
trabalhar com vários formatos de dados de entrada, incluindo FP32, FP16 e BF16,
trabalhar com dados em memória ou com dados mapeados em memória,
filtrar os resultados durante a busca com base em critérios fornecidos pelo usuário.
O Cardinal inclui:
Uma implementação de métodos ANN que permite a configuração fácil de vários parâmetros internos. No entanto, o ponto operacional padrão é consistentemente ajustado para maximizar a velocidade de busca (QPS, consultas por segundo), mantendo uma precisão razoável (taxa de recall).
Implementação eficiente de vários algoritmos que dão suporte a métodos ANNS. Por exemplo, aqueles que fornecem recursos de filtragem de amostras.
Kernels otimizados especializados de baixo nível para as operações mais intensivas em computação usadas durante a busca ou construção. Várias plataformas de hardware são suportadas. Além de kernels que calculam distâncias para várias métricas, o Cardinal também contém kernels fundidos e kernels para pré-processamento de dados.
Recursos de suporte, como operações assíncronas, capacidades de I/O mapeado em memória, cache, alocadores de memória, logging, etc.
Knowhere vs Cardinal
A biblioteca Knowhere é um núcleo interno do Milvus open-source, responsável pela busca vetorial. Knowhere é baseada em versões modificadas de bibliotecas open-source padrão da indústria, como Faiss, DiskANN e hnswlib.
Vamos apresentar uma comparação entre Knowhere e Cardinal:
| Recurso | Knowhere | Cardinal |
|---|---|---|
| Prontidão para Produção | Sim | Sim |
| Capacidades de Escalabilidade | Sim | Sim |
| Filosofia de Design | Experimentação e Flexibilidade | Escopo restrito, priorizando o aprimoramento de recursos existentes para desempenho |
| Compatibilidade com Host | Todos os Tipos de Host | Otimizado para o Ambiente de Host do Zilliz Cloud |
| Dependência | Depende de Bibliotecas e Implementações OSS Conhecidas | Contém Modificações e Otimizações Não Triviais |
Ambos estão prontos para produção e fornecem todas as capacidades de escalabilidade de que o Milvus e o Zilliz Cloud precisam.
Knowhere é projetado com experimentação e flexibilidade em mente. Cardinal tem escopo mais restrito, priorizando o aprimoramento de recursos existentes para melhorar a velocidade e o desempenho, em vez de introduzir uma ampla nova funcionalidade.
Como Knowhere é open-source e pode ser implantado em muitos ambientes diferentes, ele roda em todos os tipos de host. Cardinal é otimizado para o ambiente de host do Zilliz Cloud.
Knowhere depende de bibliotecas e implementações OSS conhecidas(como Faiss, DiskANN e hnswlib). Cardinal contém modificações e otimizações não triviais.
O que torna o Cardinal tão rápido
Cardinal implementa várias otimizações relacionadas a algoritmos, engenharia e baixo nível. Cardinal introduz o mecanismo AUTOINDEX, que seleciona automaticamente a melhor estratégia de busca e índice para o conjunto de dados. Isso elimina a necessidade de ajuste manual, economizando tempo e esforço dos desenvolvedores.
Vamos nos aprofundar nos detalhes.
Otimizações de algoritmo
Essa forma de otimização melhora significativamente a precisão e a eficácia do processo de busca, um pipeline multifacetado que envolve vários algoritmos trabalhando em conjunto. Diversos algoritmos dentro desse pipeline podem ser refinados para impulsionar o desempenho geral. Candidatos notáveis para otimizações de algoritmo dentro do Cardinal incluem:
Algoritmos de busca, abrangendo abordagens baseadas em IVF e baseadas em grafos,
Algoritmos projetados para ajudar a busca a manter a taxa de recall exigida, independentemente da porcentagem de amostras filtradas,
Iterações avançadas de algoritmos de busca best-first,
Algoritmos personalizados para uma estrutura de dados de fila de prioridade.
Algoritmos parametrizáveis oferecem a flexibilidade para compensações, como equilibrar desempenho versus uso de RAM. Como resultado, as otimizações de algoritmo para Cardinal também envolvem a seleção de pontos operacionais ideais dentro do espaço de parâmetros.
Otimizações de engenharia
Embora os algoritmos sejam inicialmente projetados com máquinas de Turing abstratas em mente, a implementação no mundo real enfrenta desafios como latências de rede, restrições de provedores de nuvem sobre IOPS e limitações de RAM da máquina, um recurso valioso, porém finito.
Otimizações de engenharia garantem que o pipeline de busca vetorial do Cardinal permaneça prático e alinhado às restrições de computação, RAM e outros recursos. No desenvolvimento do Cardinal, combinamos práticas padrão e técnicas inovadoras. Essa abordagem permite que o compilador C++ gere código compilado computacionalmente ideal, mantendo ao mesmo tempo um código-fonte limpo, passível de benchmark e facilmente extensível, que facilita a rápida adição de novos recursos.
Aqui estão alguns exemplos de práticas de engenharia implementadas no Cardinal, destacando otimizações específicas:
Alocadores de memória especializados e pools de memória,
Código multithread implementado corretamente,
Uma estrutura hierárquica de componentes que facilita a combinação de elementos em vários pipelines de busca,
Customização de código para casos de uso específicos e críticos.
Otimizações de baixo nível
A maior parte do tempo de busca é gasta em partes relativamente pequenas de código conhecidas como kernels. O exemplo mais simples é um kernel que calcula a distância L2 entre dois vetores.
O Cardinal inclui numerosos kernels de computação para diferentes finalidades, cada um escrito e otimizado especificamente para uma plataforma de hardware e caso de uso específicos.
O Cardinal oferece suporte a plataformas de hardware x86 e ARM, mas outras plataformas podem ser facilmente adicionadas.
Para a plataforma x86, os kernels do Cardinal usam as extensões F, CD, VL, BW, DQ, VPOPCNTDQ, VBMI, VBMI2, VNNI, BF16 e FP16 do AVX-512. Além disso, estamos explorando o uso de um novo conjunto de instruções AMX.
Para a plataforma ARM, os kernels do Cardinal estão disponíveis para os conjuntos de instruções NEON e SVE.
Garantimos que o Cardinal obtenha o código mais ideal para os kernels de computação. Não dependemos apenas de um compilador C++ moderno para fazer o trabalho:
Usamos ferramentas dedicadas, como o perf do Linux, para analisar hotspots e métricas de CPU
Usamos ferramentas de análise de código de máquina, como GodBolt Compiler Explorer e uiCA, para garantir o uso ideal dos ‘recursos’ de hardware, como o número de acessos à RAM/cache, instruções de CPU usadas, registradores, portas de computação.
Usamos uma abordagem iterativa que intercala as etapas de design, benchmarking, profiling e análise de código assembler.
Um kernel de computação devidamente otimizado pode proporcionar aceleração de 2x ou 3x em comparação com um kernel ingênuo, mas não otimizado. Isso pode se traduzir ainda em um valor de QPS 2x maior ou requisitos de memória 20% menores em uma máquina host na nuvem.
AutoIndex: seleção de estratégia de busca
A busca vetorial é um processo complexo que envolve muitos componentes independentes, incluindo quantização, construção de índice, algoritmos de busca, estruturas de dados e muito mais. Cada componente tem uma infinidade de parâmetros ajustáveis. Juntos, eles formam uma gama altamente variada de estratégias de busca vetorial, e diferentes conjuntos de dados e cenários exigem diferentes estratégias de busca.
Para aproveitar melhor o potencial de melhoria de desempenho, o Cardinal, além de oferecer suporte a múltiplas estratégias em cada componente, implementou um conjunto de mecanismos de seleção dinâmica de estratégia baseados em IA conhecidos como AUTOINDEX. Ele escolhe adaptativamente a estratégia mais adequada com base na distribuição do conjunto de dados fornecido, na consulta fornecida e na configuração de hardware. Isso nos ajuda a alcançar desempenho ideal enquanto atendemos às demandas dos usuários por qualidade de busca.
Benchmark do Cardinal
Adotamos o ANN-benchmarks para dar suporte ao Cardinal em nosso ambiente de testes. O ANN benchmarks é uma ferramenta padrão de benchmarking para avaliar implementações de ANNS, e é executado em vários conjuntos de dados padrão que usam diferentes métricas de distância. Cada avaliação de desempenho é conduzida dentro de um contêiner docker restrito ao uso de uma única thread. As métricas são baseadas em várias iterações de avaliação, que utilizam inúmeras solicitações de consulta única. Os resultados de cada framework avaliado são agregados em uma fronteira de Pareto recall-vs-QPS.
Todos os testes foram realizados no mesmo tipo de máquina do ann-benchmarks de referência (em jan. de 2024), que é uma máquina Amazon EC2 r6i.16xlarge com a seguinte configuração:
CPU: Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz
Número de núcleos de CPU: 32
Hyperthreading está desativado
RAM: 512 GB
SO: Ubuntu 22.04.3 LTS com kernel Linux 6.2.0-1017-aws
O suporte a huge pages não foi ativado.
Os testes foram executados com a opção `--parallelism=31`.
O Cardinal foi compilado usando o compilador clang 17.0.6.
Os resultados de benchmark apresentados abaixo são apenas para o mecanismo Cardinal e não incluem otimizações adicionais que não sejam de índice fornecidas pela Zilliz Cloud.
Observação: Resultados que incluem otimizações específicas da Zilliz Cloud são fornecidos acima, no início do artigo.
Os gráficos a seguir foram produzidos pegando as imagens dos gráficos com resultados apresentados na página do ANN-benchmark no GitHub e adicionando precisamente uma curva extra do Cardinal por cima.
Em todos os benchmarks fornecidos, o Cardinal apresenta resultados muito competitivos. E há espaço para melhorias adicionais.
O que vem a seguir?
O futuro nos trará novos desafios, sem dúvida. Requisitos diferentes, gargalos diferentes, conjuntos de dados maiores. Continuamos trabalhando para tornar o Cardinal ainda melhor.
O caminho está iluminado. A rota está clara. Precisamos apenas da força para segui-la :)
Continue lendo

Introducing Customer-Managed Encryption Keys (CMEK) on Zilliz Cloud
We're announcing the general availability of Customer-Managed Encryption Keys (CMEK) on Zilliz Cloud.

Context Engineering Strategies for AI Agents: A Developer’s Guide
Learn practical context engineering strategies for AI agents. Explore frameworks, tools, and techniques to improve reliability, efficiency, and cost.

Our Journey to 35K+ GitHub Stars: The Real Story of Building Milvus from Scratch
Join us in celebrating Milvus, the vector database that hit 35.5K stars on GitHub. Discover our story and how we’re making AI solutions easier for developers.



