Dimensionando a Pesquisa com Milvus: Lidando com Conjuntos de Dados Massivos com Facilidade
As pessoas frequentemente me perguntam: "Por que se dar ao trabalho de usar um banco de dados vetorial como o Milvus quando posso simplesmente usar NumPy ou FAISS?" Há muitos motivos: escalabilidade, facilidade de gerenciamento, persistência de dados e um dos mais importantes: escala. Quando você está lidando com milhões ou bilhões de vetores, precisa de uma solução criada para lidar com esse tipo de volume.
Nesta publicação do blog, veremos como podemos trabalhar com um exemplo de caso de uso de 40 milhões de vetores com o Milvus. Também demonstraremos como recursos como filtragem por metadados podem melhorar significativamente seus resultados de busca — uma capacidade essencial frequentemente ausente em bancos de dados vetoriais que não foram criados para esse propósito, o que é uma grande desvantagem.
Milvus: um Banco de Dados Vetorial Criado para Escala
Milvus é um popular banco de dados vetorial open-source que impulsiona aplicações de IA com busca por similaridade vetorial altamente performática e escalável.
Alguns dos principais recursos que tornam possível a busca vetorial em escala incluem:
- Uma Arquitetura Distribuída: O Milvus tem uma arquitetura distribuída que permite escalar horizontalmente de forma contínua e distribuir dados e carga de trabalho entre múltiplos nós. Essa capacidade garante alta disponibilidade e resiliência, mesmo sob carga pesada.
- Indexação Otimizada: O Milvus oferece suporte a diferentes técnicas de indexação, como IVF_FLAT e HNSW, mas também a um Índice GPU para acelerar as velocidades de busca. Ele também oferece suporte ao DiskANN se você precisar reduzir o custo do seu Vector DB; a busca seria um pouco mais lenta, mas seria significativamente mais barata.
- Busca em Bilhões: Um dos recursos de destaque do Milvus é sua capacidade de lidar com bilhões de vetores e pesquisar neles com eficiência. Essa capacidade é crucial para aplicações que exigem buscas por similaridade vetorial em alta velocidade e alto volume.
- Diferentes Opções de Computação: O Milvus pode aproveitar o poder de GPUs e CPUs, alocando tarefas de forma inteligente ao hardware mais adequado para desempenho ideal. Essa capacidade permite processamento paralelo e melhorias significativas de velocidade, especialmente para operações computacionalmente intensivas.
O Dataset: Milhões de Embeddings de Artigos da Wikipedia
Estamos usando um dataset da Wikipedia que foi transformado com um Modelo de Embedding da Cohere, ele está disponível gratuitamente no Hugging Face.
Prévia do dataset
Figura 1: Prévia do dataset
Cada exemplo contém um artigo completo da Wikipedia com limpeza para remover markdown e seções indesejadas (referências etc.).
O dataset contém mais de 300 idiomas, mas para nosso caso de uso focaremos no inglês, que contém 41,5M vetores. A parte interessante é que os embeddings são cross-lingual! Isso significa que você pode pesquisar em múltiplos idiomas e confiar na capacidade do modelo de encontrar significados semelhantes, mesmo em idiomas diferentes.
Multilíngue vs Cross-lingual.png
Figura 2: Multilíngue vs Cross-lingual (Fonte da imagem)
Primeiros passos com o Milvus
Nesta seção, mostraremos como começar a usar o Milvus, incluindo a instalação do SDK do Milvus ou a configuração do Zilliz Cloud, a conexão ao Milvus, a criação de coleções etc.
Instalando o SDK do Milvus
Comece instalando o SDK do Milvus executando pip install pymilvus. Para simplificar, implantaremos o Milvus no Zilliz Cloud (a versão totalmente gerenciada do Milvus). Dada a escala dos dados que você usa, você pode Implantar o Milvus no Kubernetes ou usar o Zilliz Cloud.
- Se você tiver uma escala maior de dados, digamos mais de um milhão de vetores, poderá configurar um servidor Milvus mais performático no Docker ou Kubernetes. Nesta configuração, use o uri do servidor, por exemplo,
http://localhost:19530, como seu uri. - Se você quiser usar o Zilliz Cloud, o serviço de nuvem totalmente gerenciado para o Milvus, ajuste o
urie otoken, que correspondem ao Public Endpoint e à API key no Zilliz Cloud.
Um guia passo a passo
- Conecte-se ao Milvus: Primeiro, estabeleça uma conexão com sua instância do Milvus:
from pymilvus import MilvusClient
client = MilvusClient(uri=<ZILLIZ_CLOUD_URI>, token=<ZILLIZ_TOKEN>)
- Crie um Schema: Defina o Schema que será usado para criar nossa Collection do Milvus.
# Define the schema for the collection
embedding_dim = 1024
schema = [
{"name": "id", "dtype": "int64", "is_primary": True, "auto_id": True},
{"name": "text_vector", "dtype": "float_vector", "dim": embedding_dim},
{"name": "title", "dtype": "varchar", "max_length": 5000},
{"name": "text", "dtype": "varchar", "max_length": 5000},
]
- Crie uma Collection: Agora, criamos a Collection que usaremos para armazenar os Embeddings.
# Create the collection if it doesn't exist
collection_name = "cohere_embeddings"
if not client.has_collection(collection_name):
client.create_collection(collection_name=collection_name, schema=schema)
- Crie um Index: Para tornar a Vector Search eficiente, precisamos criar um index no campo vetorial em que estamos interessados. Um vector index é um tipo especializado de index projetado para armazenar e pesquisar vetores.
# Define and create index
index_params = {
"metric_type": "COSINE",
"index_type": "HNSW",
"params": {"M": 8, "efConstruction": 64},
}
client.create_index(collection_name=collection_name, field_name="text_vector", index_params=index_params)
# Load the collection
client.load_collection(collection_name=collection_name)
- Insira dados: Preencha a collection
cohere_embeddingscom o Dataset do Hugging Face. Dependendo dos recursos que você tem disponíveis, talvez queira baixar um subconjunto dele, por exemplo, apenas um idioma específico, carregá-lo em um Bucket como S3 ou GCP, ou também pode transmiti-lo a partir do Hugging Face.
Quando um dataset está em modo de streaming, você pode iterar sobre ele diretamente sem precisar baixar o dataset inteiro. Os dados são baixados progressivamente à medida que você itera sobre o dataset; isso é útil se você não tiver espaço suficiente em disco para baixar o dataset, ou se não quiser esperar que seu dataset seja baixado antes de usá-lo.
# Insert data into our collection
def insert_batch(client, collection_name, batch_data):
client.insert(collection_name=collection_name, data=batch_data)
batch_data.clear()
# Get the data from HuggingFace and create some batch
def insert_data(client, collection_name):
batch_size = 1000 # Adjust the batch size as needed
batch_data = []
docs = load_dataset(
"Cohere/wikipedia-2023-11-embed-multilingual-v3",
"en", # English only
split="train",
streaming=True, # Allows us to iterate over the dataset
)
for doc in tqdm(docs, desc="Streaming and preparing data for Milvus"):
title = doc["title"][:4500] # Titles can be very long
text = doc["text"][:4500] # Text can be very long
emb = doc["emb"] # The embedding vector
batch_data.append({"title": title, "text_vector": emb, "text": text})
if len(batch_data) >= batch_size:
insert_batch(client, collection_name, batch_data)
if batch_data:
insert_batch(client, collection_name, batch_data)
Filtragem Escalar: Uma Ferramenta Poderosa em Escala
Quando você está lidando com milhões ou bilhões de vetores, a filtragem se torna mais do que apenas algo desejável — é essencial. E é aqui que o Milvus realmente mostra sua força.
Veja por que a abordagem do Milvus para filtragem é revolucionária:
- Magia dos Bitsets: O Milvus usa bitsets compactos para representar quais vetores correspondem aos seus critérios de filtro. Esses bitsets podem ser manipulados mais rápido do que você consegue dizer "busca por similaridade vetorial", graças a operações de CPU de baixo nível. É como ter um supercomputador que pode classificar instantaneamente bilhões de pontos de dados.
- Redução do Espaço de Busca: Ao contrário de algumas outras soluções (por exemplo, pgvector) que oferecem apenas pós-filtragem, o Milvus aplica filtros de metadados antes de executar a busca por similaridade vetorial. Isso reduz drasticamente o número de vetores que ele precisa processar. Também permite restringir sua busca de bilhões de vetores para apenas os milhares que realmente importam — em milissegundos.
- Indexação Escalar (Quando Você Precisa): Para aqueles campos nos quais você filtra com frequência, o Milvus permite criar índices escalares. Pense nisso como dar ao Milvus uma folha de dicas para seus dados. Embora nem sempre estejam presentes por padrão, quando configurados corretamente, esses índices podem turbinar o desempenho da sua filtragem.
A beleza do Milvus é que ele não apenas oferece esses recursos — ele os faz funcionar em escala. Seja lidando com 40 milhões de vetores ou 40 bilhões.
Busca com Filtragem Exata
Encontre documentos com um título específico.
FILTER_TITLE = "British Arab Commercial Bank"
res = milvus_client.query(
collection_name=collection_name,
filter=f'title like "{FILTER_TITLE}"',
output_fields=["title", "text"]
)
for elt in res:
pprint(elt)
Isso retorna documentos sobre o British Arab Commercial Bank
{'id': 450933285225527270,
'text': 'The British Arab Commercial Bank PLC (BACB) is an international '
'wholesale bank incorporated in the United Kingdom that is authorised '
'by the Prudential Regulation Authority (PRA) and regulated by the '
'PRA and the Financial Conduct Authority (FCA). It was founded in '
'1972 as UBAF Limited, adopted its current name in 1996, and '
'registered as a public limited company in 2009. The bank has clients '
'trading in and out of developing markets in the Middle East and '
'Africa.',
'title': 'British Arab Commercial Bank'}
{'id': 450933285225527271,
'text': 'BACB has a head office in London, and three representative offices '
'in Algiers in Algeria, Tripoli in Libya and Abidjan in the Cote '
"D'Ivoire. The bank has 17 sister banks across Europe, Asia and "
'Africa. It is owned by three main shareholders - the Libyan Foreign '
'Bank (87.80%), Banque Centrale Populaire (6.10%) and Banque '
"Extérieure d'Algérie (6.10%).",
'title': 'British Arab Commercial Bank'}
Busca com Filtragem por Prefixo/Infixo/Sufixo
Pesquise documentos que contenham uma palavra específica.
res = milvus_client.query(
collection_name=collection_name,
filter='text like "%Calectasia%"', # Infix
# filter='text like "Calect%"', # Suffix
# filter='text like "%lectasia"', # Prefix
output_fields=["title", "text"],
limit=5,
)
for elt in res:
pprint(elt)
Isso retorna documentos contendo a palavra "Calectasia."
{'id': 450933285225527360,
'text': 'Calectasia is a genus of about fifteen species of flowering plants '
'in the family Dasypogonaceae and is endemic to south-western '
'Australia. Plants is this genus are small, erect shrubs with '
'branched stems covered by leaf sheaths. The flowers are star-shaped, '
'lilac-blue to purple and arranged singly on the ends of short '
'branchlets.',
'title': 'Calectasia'}
{'id': 450933285225527361,
'text': 'Plants in the genus Calectasia are small, often rhizome-forming '
'shrubs with erect, branched stems with sessile leaves arranged '
'alternately along the stems, long and about wide, the base held '
'closely against the stem and the tip pointed. The flowers are '
'arranged singly on the ends of branchlets and are bisexual, the '
'three sepals and three petals are similar to each other, and joined '
'at the base forming a short tube but spreading, forming a star-like '
'pattern with a metallic sheen. Six bright yellow or orange stamens '
'form a tube in the centre of the flower with a thin style extending '
'beyond the centre of the tube.',
'title': 'Calectasia'}
Pesquisa com filtragem com "Not In"
Exclua títulos específicos da sua pesquisa.
res = milvus_client.query(
collection_name=collection_name,
filter='title not in ["British Arab Commercial Bank", "Calectasia"]',
output_fields=["title", "text"],
limit=10,
)
for elt in res:
pprint(elt)
Isso retorna documentos cujos títulos não são "British Arab Commercial Bank" nem "Calectasia."
{'id': 450933285225527281,
'text': 'The Commonwealth Skyranger, first produced as the Rearwin Skyranger, '
'was the last design of Rearwin Aircraft before the company was '
'purchased by a new owner and renamed Commonwealth Aircraft. It was '
'a side-by-side, two-seat, high-wing taildragger.',
'title': 'Commonwealth Skyranger'}
{'id': 450933285225527282,
'text': 'The Rearwin company had specialized in aircraft powered by small '
'radial engines, such as their Sportster and Cloudster, and had even '
'purchased the assets of LeBlond Engines to make small radial engines '
'in-house in 1937. By 1940, however, it was clear Rearwin would need '
'a design powered by a small horizontally opposed engine to remain '
'competitive. Intended for sport pilots and flying businessmen, the '
'"Rearwin Model 165" first flew on April 9, 1940. Originally named '
'the "Ranger," Ranger Engines (who also sold several engines named '
'"Ranger") protested, and Rearwin renamed the design "Skyranger." The '
'overall design and construction methods allowed Rearwin to take '
'orders for Skyrangers then deliver the aircraft within 10 weeks.',
'title': 'Commonwealth Skyranger'}
Cohere 🤝 Milvus: Uma combinação poderosa que torna a busca por similaridade vetorial mais fácil e eficiente
Vamos realizar uma busca por similaridade usando embeddings da Cohere. Vamos incorporar a consulta Who founded Wikipedia e usá-la para pesquisar nossa coleção Milvus. Este é o mesmo modelo de embedding que foi usado para codificar os Wikipedia Embeddings.
Usaremos a integração entre Milvus e Cohere por meio do PyMilvus Model; instale-a com pip install "pymilvus[model]" .
from pymilvus.model.dense import CohereEmbeddingFunction
cohere_ef = CohereEmbeddingFunction(
model_name="embed-multilingual-v3.0",
input_type="search_query",
embedding_types=["float"]
)
query = 'Quem fundou a Wikipedia'
embedded_query = cohere_ef.encode_queries([query])
response = embedded_query[0]
print(response[:10])
Isso retorna os artigos da Wikipedia mais relevantes sobre os fundadores da Wikipedia.
res = milvus_client.search(data=response, collection_name=collection_name, output_fields=["text"], limit=3)
for elt in res:
pprint(elt)
O que resulta no seguinte:
[{'distance': 0.7344469428062439,
'entity': {'text': 'Larry Sanger e Jimmy Wales são os que começaram a '
'Wikipedia. Wales é creditado por definir os objetivos do '
'projeto. Sanger criou a estratégia de usar uma wiki '
"para alcançar o objetivo de Wales. Em 10 de janeiro de 2001, Larry Sanger "
'propôs na lista de e-mails da Nupedia criar uma wiki como '
'um projeto "alimentador" para a Nupedia. A Wikipedia foi lançada '
'em 15 de janeiro de 2001. Foi lançada como uma '
'edição em língua inglesa em www.wikipedia.com, e '
'anunciada por Sanger na lista de e-mails da Nupedia. '
'A política da Wikipedia de "ponto de vista neutro" foi '
'aplicada em seus meses iniciais e era semelhante à '
'política anterior "não enviesada" da Nupedia. Caso contrário, não '
"havia muitas regras inicialmente, e a Wikipedia "
'operava independentemente da Nupedia.'},
'id': 450933285241797095},
{'distance': 0.7239157557487488,
'entity': {'text': 'A Wikipedia foi originalmente concebida como um complemento à '
'Nupedia, uma enciclopédia on-line gratuita fundada por Jimmy '
'Wales, com artigos escritos por colaboradores altamente '
'qualificados e avaliados por um elaborado processo de revisão '
'por pares. A escrita de conteúdo para a Nupedia provou ser '
'extremamente lenta, com apenas 12 artigos concluídos durante '
'o primeiro ano, apesar de uma lista de e-mails de editores '
'interessados e da presença de um editor-chefe em tempo integral '
'recrutado por Wales, Larry Sanger. Ao aprenderem sobre o conceito '
'de wiki, Wales e Sanger decidiram tentar criar um '
'site colaborativo para fornecer uma fonte adicional de '
'artigos preliminares produzidos rapidamente que poderiam ser polidos '
'para uso na Nupedia.'},
'id': 450933285225827849},
{'distance': 0.7191773653030396,
'entity': {'text': "A criação da fundação foi oficialmente anunciada pelo "
'cofundador da Wikipedia Jimmy Wales, que estava operando '
'a Wikipedia dentro de sua empresa Bomis, em 20 de junho de 2003.'},
'id': 450933285242058780}]
Vamos verificar as métricas de desempenho do nosso cluster, com foco na latência das nossas consultas de pesquisa. Usaremos a API do Zilliz Cloud para recuperar os valores de latência média e do percentil 99 (P99).
Primeiro, verificaremos a latência média:
> curl --request POST \
--url https://api.cloud.zilliz.com/v2/clusters/<cluster_id>/metrics/query \
[...]
"metricQueries": [
{
"name": "REQ_SEARCH_LATENCY",
"stat": "AVG"
}
}'
[{"name":"REQ_SEARCH_LATENCY","stat":"AVG","unit":"millisecond","values":[{"timestamp":"2024-08-26T11:09:53Z","value":"2.0541596873255163"}]}]
Esta consulta retorna uma latência média de 2,05 milissegundos.
Em seguida, vamos verificar a latência P99:
> curl --request POST \
--url https://api.cloud.zilliz.com/v2/clusters/<cluster_id>/metrics/query \
[...]
"metricQueries": [
{
"name": "REQ_SEARCH_LATENCY",
"stat": "P99"
}
}'
[{"name":"REQ_SEARCH_LATENCY","stat":"P99","unit":"millisecond","values":[{"timestamp":"2024-08-26T11:09:53Z","value":"4.949999999999999"}]}]
A latência P99 é relatada como 4,95 milissegundos.
Esses resultados mostram um desempenho impressionante: nossa latência média de consulta é pouco acima de 2 milissegundos, com 99% das consultas sendo concluídas em menos de 5 milissegundos. Isso demonstra a eficiência do nosso cluster Milvus ao lidar com operações de busca, mesmo em escala.
Crie um Sistema RAG Básico com Milvus
Retrieval Augmented Generation (RAG) é uma técnica avançada de IA para mitigar alucinações em grandes modelos de linguagem (LLMs) como o ChatGPT.
Neste exemplo, podemos usar os resultados do Milvus para criar um sistema RAG simples. Isso permite que um LLM acesse e utilize informações armazenadas no Milvus.
context = "\n".join(
[line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)
question = "Who created Wikipedia?"
SYSTEM_PROMPT = """
Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided.
"""
USER_PROMPT = f"""
Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.
<context>
{context}
</context>
<question>
{question}
</question>
"""
from openai import OpenAI
client = OpenAI(
base_url = 'http://localhost:11434/v1',
api_key='ollama', # required, but unused
)
response = client.chat.completions.create(
model="llama3.1",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": USER_PROMPT},
],
)
print(response.choices[0].message.content)
According to the provided context, Larry Sanger and Jimmy Wales are the ones who started Wikipedia. Specifically, Jimmy Wales defined the goals of the project, while Larry Sanger created the strategy of using a wiki to achieve those goals.
Além do Básico: Recursos Avançados do Milvus para Maior Escalabilidade
O Milvus oferece recursos ainda mais avançados para lidar com conjuntos de dados massivos:
- Particionamento de Dados: Para coleções que contêm dados de múltiplos usuários ou locatários, por exemplo, o Milvus oferece chaves e nomes de partição para segregar dados logicamente. Esse recurso permite uma filtragem eficiente de metadados, como por ID de usuário ou nome da organização.
- Busca por Intervalo: Encontre vetores com eficiência dentro de um intervalo de distância especificado a partir de um vetor de consulta, permitindo buscas de similaridade mais precisas e flexíveis em espaços de alta dimensão.
- Busca Híbrida: Permite que os usuários pesquisem em várias colunas vetoriais em uma única consulta. Por exemplo, você pode combinar vetor de texto e vetor de imagem para dados multimodais, ou vetor denso e vetor esparso para usar busca semântica e busca de texto completo. Esse recurso oferece funcionalidade de busca versátil e flexível.
Para mais detalhes, consulte a Documentação do Milvus.
Conclusão
O Milvus fornece uma solução robusta e escalável para trabalhar com bilhões de vetores. Seus recursos poderosos, como filtragem e arquitetura distribuída, fazem dele uma escolha perfeita para aplicações de IA exigentes.
Nossos testes de desempenho demonstraram as capacidades impressionantes do Milvus:
- Latência média de consulta: 2,05 milissegundos
- Latência do percentil 99 (P99): 4,95 milissegundos
Estes resultados demonstram que o Milvus pode oferecer consistentemente tempos de busca inferiores a 5 ms, mesmo ao lidar com milhões de vetores. Portanto, se você está procurando criar aplicações que possam lidar com conjuntos de dados massivos e entregar resultados de busca extremamente rápidos, vale definitivamente a pena explorar o Milvus.
Se você gostou deste post do blog, considere nos dar uma estrela no GitHub. Você também é bem-vindo para compartilhar suas experiências com a comunidade Milvus participando do nosso Discord.
Recursos adicionais
- O que é Geração Aumentada por Recuperação (RAG)?
- Criando RAG com Milvus, vLLM e Llama 3.1 da Meta
- Hub de Recursos de IA Generativa | Zilliz
- Modelos de IA com Melhor Desempenho para Seus Apps GenAI | Zilliz
- Escolhendo o Modelo de Embedding Certo para Seus Dados
- O Panorama do Ecossistema GenAI: Além de LLMs e Bancos de Dados Vetoriais
Continue lendo

8 Latest RAG Advancements Every Developer Should Know
Explore eight advanced RAG variants that can solve real problems you might be facing: slow retrieval, poor context understanding, multimodal data handling, and resource optimization.

Zilliz Cloud Introduces Advanced BYOC-I Solution for Ultimate Enterprise Data Sovereignty
Explore Zilliz Cloud BYOC-I, the solution that balances AI innovation with data control, enabling secure deployments in finance, healthcare, and education sectors.

Cosmos World Foundation Model Platform for Physical AI
NVIDIA's Cosmos platform enables safe, digital twin training of GenAI models for physical applications, overcoming data scarcity and safety challenges.



