Scalare la ricerca con Milvus: gestire enormi set di dati con facilità
Spesso le persone mi chiedono: "Perché dovrei usare un database vettoriale come Milvus quando posso semplicemente usare NumPy o FAISS?" Ci sono molte ragioni: scalabilità, facilità di gestione, persistenza dei dati e una delle più importanti: scala. Quando hai a che fare con milioni o miliardi di vettori, hai bisogno di una soluzione costruita per gestire quel tipo di volume.
In questo post del blog, vedremo come possiamo lavorare con un caso d’uso di esempio di 40 milioni di vettori con Milvus. Dimostreremo anche come funzionalità come il filtraggio dei metadati possano migliorare significativamente i risultati della tua ricerca—una capacità essenziale spesso assente nei database vettoriali non purpose-built, il che rappresenta un grande svantaggio.
Milvus: un database vettoriale costruito per scalare
Milvus è un popolare database vettoriale open-source che alimenta applicazioni di IA con una ricerca di similarità vettoriale altamente performante e scalabile.
Alcune delle funzionalità chiave che rendono possibile la ricerca vettoriale su larga scala includono:
- Un’architettura distribuita: Milvus ha un’architettura distribuita che gli consente di scalare orizzontalmente senza problemi e distribuire dati e carico di lavoro su più nodi. Questa capacità garantisce elevata disponibilità e resilienza, anche sotto carico intenso.
- Indicizzazione ottimizzata: Milvus supporta diverse tecniche di indicizzazione come IVF_FLAT e HNSW, ma anche un indice GPU per accelerare le velocità di ricerca. Supporta anche DiskANN se hai bisogno di ridurre il costo del tuo Vector DB; la ricerca sarebbe un po’ più lenta, ma significativamente più economica.
- Ricerca tra miliardi: Una delle caratteristiche distintive di Milvus è la sua capacità di gestire e cercare tra miliardi di vettori in modo efficiente. Questa capacità è cruciale per applicazioni che richiedono ricerche di similarità vettoriale ad alta velocità e ad alto volume.
- Diverse opzioni di calcolo: Milvus può sfruttare la potenza di GPU e CPU, allocando intelligentemente i compiti all’hardware più adatto per prestazioni ottimali. Questa capacità consente l’elaborazione parallela e significativi miglioramenti di velocità, specialmente per operazioni computazionalmente intensive.
Il dataset: milioni di embedding di articoli di Wikipedia
Stiamo utilizzando un dataset di Wikipedia che è stato trasformato con un modello di embedding Cohere, è disponibile gratuitamente su Hugging Face.
Anteprima del dataset
Figura 1: Anteprima del dataset
Ogni esempio contiene un articolo completo di Wikipedia con pulizia per rimuovere markdown e sezioni indesiderate (riferimenti, ecc.).
Il dataset contiene più di 300 lingue, ma per il nostro caso d’uso ci concentreremo sull’inglese, che contiene 41,5M vettori. La parte interessante è che gli embedding sono cross-lingual! Questo significa che puoi effettuare ricerche su più lingue e fare affidamento sulla capacità del modello di trovare significati simili, anche in lingue diverse.
Multilingual vs Cross-lingual.png
Figura 2: Multilingue vs cross-lingual (Fonte dell’immagine)
Guida introduttiva a Milvus
In questa sezione, ti mostreremo come iniziare con Milvus, inclusa l'installazione del Milvus SDK o la configurazione di Zilliz Cloud, la connessione a Milvus, la creazione di collection ecc.
Installazione del Milvus SDK
Inizia installando Milvus SDK eseguendo pip install pymilvus. Per semplicità, distribuiremo Milvus su Zilliz Cloud (la versione completamente gestita di Milvus). In base alla scala dei dati che utilizzi, puoi distribuire Milvus su Kubernetes oppure usare Zilliz Cloud.
- Se hai una scala di dati più ampia, ad esempio più di un milione di vettori, puoi configurare un server Milvus più performante su Docker o Kubernetes. In questa configurazione, utilizza il server uri, ad es.
http://localhost:19530, come tuo uri. - Se vuoi usare Zilliz Cloud, il servizio cloud completamente gestito per Milvus, modifica
urietoken, che corrispondono al Public Endpoint e API key in Zilliz Cloud.
Una guida passo passo
- Connettiti a Milvus: Per prima cosa, stabilisci una connessione alla tua istanza Milvus:
from pymilvus import MilvusClient
client = MilvusClient(uri=<ZILLIZ_CLOUD_URI>, token=<ZILLIZ_TOKEN>)
- Crea uno Schema: Definisci lo Schema che verrà utilizzato per creare la nostra Collection 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},
]
- Crea una Collection: Ora creiamo la Collection che useremo per archiviare gli 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)
- Crea un Index: Per rendere efficiente la Vector Search, dobbiamo creare un indice sul campo vettoriale che ci interessa. Un vector index è un tipo specializzato di indice progettato per archiviare e cercare vettori.
# 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)
- Inserisci i dati: Popola la collection
cohere_embeddingscon il Dataset da Hugging Face. A seconda delle risorse disponibili, potresti voler scaricarne un sottoinsieme, ad es. solo una lingua specifica, caricarlo in un Bucket come S3 o GCP, oppure puoi anche trasmetterlo in streaming da Hugging Face.
Quando un dataset è in modalità streaming, puoi iterare direttamente su di esso senza dover scaricare l'intero dataset. I dati vengono scaricati progressivamente mentre iteri sul dataset; questo è utile se non hai abbastanza spazio sul disco per scaricare il dataset, oppure se non vuoi aspettare che il dataset venga scaricato prima di utilizzarlo.
# 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)
Filtraggio scalare: uno strumento potente su larga scala
Quando hai a che fare con milioni o miliardi di vettori, il filtraggio diventa più di un semplice optional: è essenziale. Ed è qui che Milvus mostra davvero i muscoli.
Ecco perché l'approccio di Milvus al filtraggio è una svolta:
- Magia dei bitset: Milvus utilizza bitset compatti per rappresentare quali vettori soddisfano i tuoi criteri di filtro. Questi bitset possono essere manipolati più velocemente di quanto tu possa dire "ricerca di similarità vettoriale", grazie a operazioni CPU di basso livello. È come avere un supercomputer che può ordinare istantaneamente miliardi di punti dati.
- Riduzione dello spazio di ricerca: A differenza di alcune altre soluzioni (ad es. pgvector) che offrono solo il post-filtraggio, Milvus applica i filtri sui metadati prima di eseguire la ricerca di similarità vettoriale. Riduce drasticamente il numero di vettori che deve elaborare. Ti consente inoltre di restringere la ricerca da miliardi di vettori a poche migliaia che contano davvero, in millisecondi.
- Indicizzazione scalare (Quando ne hai bisogno): Per quei campi su cui filtri frequentemente, Milvus ti consente di creare indici scalari. Pensalo come dare a Milvus un foglio di suggerimenti per i tuoi dati. Sebbene non siano sempre presenti per impostazione predefinita, quando configurati correttamente, questi indici possono accelerare enormemente le prestazioni del tuo filtraggio.
La bellezza di Milvus è che non si limita a offrire queste funzionalità — le fa funzionare su larga scala. Che tu stia lavorando con 40 milioni di vettori o 40 miliardi.
Ricerca con filtraggio esatto
Trova documenti con un titolo specifico.
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)
Questo restituisce documenti sul 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'}
Ricerca con filtraggio per prefisso/infisso/suffisso
Cerca documenti contenenti una parola specifica.
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)
Questo restituisce documenti contenenti la parola "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'}
Ricerca con filtro con "Not In"
Escludi titoli specifici dalla tua ricerca.
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)
Questo restituisce documenti i cui titoli non sono "British Arab Commercial Bank" o "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: una potente combinazione che rende la ricerca di similarità vettoriale più semplice ed efficiente
Eseguiamo una ricerca di similarità usando gli embeddings Cohere. Incorporeremo la query Who founded Wikipedia e la useremo per cercare nella nostra collection Milvus. Questo è lo stesso modello di embedding usato per codificare gli Wikipedia Embeddings.
Useremo l’integrazione tra Milvus e Cohere tramite PyMilvus Model, installala con 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 = 'Chi ha fondato Wikipedia'
embedded_query = cohere_ef.encode_queries([query])
response = embedded_query[0]
print(response[:10])
Questo restituisce gli articoli di Wikipedia più pertinenti sui fondatori di Wikipedia.
res = milvus_client.search(data=response, collection_name=collection_name, output_fields=["text"], limit=3)
for elt in res:
pprint(elt)
Il che produce quanto segue:
[{'distance': 0.7344469428062439,
'entity': {'text': 'Larry Sanger e Jimmy Wales sono coloro che hanno avviato '
'Wikipedia. A Wales viene attribuito il merito di aver definito gli obiettivi '
'del progetto. Sanger ha creato la strategia di usare un wiki '
"per raggiungere l'obiettivo di Wales. Il 10 gennaio 2001, Larry Sanger "
'propose nella mailing list di Nupedia di creare un wiki come '
'progetto "feeder" per Nupedia. Wikipedia fu lanciata '
'il 15 gennaio 2001. Fu lanciata come edizione '
'in lingua inglese su www.wikipedia.com, e '
'annunciata da Sanger nella mailing list di Nupedia. '
'La politica di Wikipedia del "punto di vista neutrale" fu '
'applicata nei suoi mesi iniziali ed era simile alla '
'precedente politica "nonbiased" di Nupedia. Altrimenti, inizialmente '
"non c'erano molte regole, e Wikipedia "
'operava indipendentemente da Nupedia.'},
'id': 450933285241797095},
{'distance': 0.7239157557487488,
'entity': {'text': 'Wikipedia fu originariamente concepita come complemento a '
'Nupedia, un’enciclopedia online gratuita fondata da Jimmy '
'Wales, con articoli scritti da collaboratori altamente qualificati '
'e valutati tramite un elaborato processo di revisione paritaria. '
'La scrittura dei contenuti per Nupedia si rivelò '
'estremamente lenta, con solo 12 articoli completati durante '
'il primo anno, nonostante una mailing list di editor interessati '
'e la presenza di un caporedattore a tempo pieno '
'reclutato da Wales, Larry Sanger. Venuti a conoscenza del concetto di wiki, '
'Wales e Sanger decisero di provare a creare un '
'sito web collaborativo per fornire un’ulteriore fonte di '
'bozze di articoli prodotte rapidamente che potessero essere rifinite '
'per l’uso su Nupedia.'},
'id': 450933285225827849},
{'distance': 0.7191773653030396,
'entity': {'text': "La creazione della fondazione fu annunciata ufficialmente da "
'Jimmy Wales, cofondatore di Wikipedia, che gestiva '
'Wikipedia all’interno della sua azienda Bomis, il 20 giugno 2003.'},
'id': 450933285242058780}]
Controlliamo le metriche delle prestazioni del nostro cluster, concentrandoci sulla latenza delle nostre query di ricerca. Useremo l'API Zilliz Cloud per recuperare sia i valori di latenza media sia quelli del 99° percentile (P99).
Per prima cosa, controlleremo la latenza media:
> 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"}]}]
Questa query restituisce una latenza media di 2,05 millisecondi.
Ora, controlliamo la latenza 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"}]}]
La latenza P99 è riportata come 4,95 millisecondi.
Questi risultati mostrano prestazioni impressionanti: la nostra latenza media delle query è appena superiore a 2 millisecondi, con il 99% delle query completate in meno di 5 millisecondi. Questo dimostra l'efficienza del nostro cluster Milvus nella gestione delle operazioni di ricerca, anche su larga scala.
Creare un sistema RAG di base con Milvus
Retrieval Augmented Generation (RAG) è una tecnica avanzata di IA per mitigare le allucinazioni nei modelli linguistici di grandi dimensioni (LLMs) come ChatGPT.
In questo esempio, possiamo usare i risultati di Milvus per creare un semplice sistema RAG. Ciò consente a un LLM di accedere e utilizzare le informazioni archiviate in 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.
Oltre le basi: funzionalità avanzate di Milvus per una scalabilità migliorata
Milvus offre funzionalità ancora più avanzate per gestire dataset enormi:
- Partizionamento dei dati: Per le raccolte contenenti dati di più utenti o tenant, ad esempio, Milvus offre chiavi e nomi di partizione per segregare logicamente i dati. Questa funzionalità consente un filtraggio efficiente dei metadati, ad esempio per ID utente o nome dell'organizzazione.
- Range Search: Trova in modo efficiente vettori entro un intervallo di distanza specificato da un vettore di query, consentendo ricerche di similarità più precise e flessibili in spazi ad alta dimensionalità.
- Hybrid Search: Consente agli utenti di cercare su più colonne vettoriali in una singola query. Ad esempio, puoi combinare vettore di testo e vettore di immagine per dati multimodali, oppure vettore denso e vettore sparso per utilizzare la ricerca semantica e la ricerca full-text. Questa funzionalità offre una capacità di ricerca versatile e flessibile.
Per maggiori dettagli, consulta la Documentazione di Milvus.
Conclusione
Milvus fornisce una soluzione robusta e scalabile per lavorare con miliardi di vettori. Le sue potenti funzionalità, come il filtraggio e l'architettura distribuita, lo rendono una scelta perfetta per applicazioni di IA esigenti.
I nostri test di prestazioni hanno evidenziato le impressionanti capacità di Milvus:
- Latenza media delle query: 2,05 millisecondi
- Latenza al 99° percentile (P99): 4,95 millisecondi
Questi risultati dimostrano che Milvus può offrire costantemente tempi di ricerca inferiori a 5 ms, anche quando gestisce milioni di vettori. Quindi, se stai cercando di creare applicazioni in grado di gestire dataset enormi e fornire risultati di ricerca fulminei, vale sicuramente la pena esplorare Milvus.
Se ti piace questo post del blog, ti invitiamo a darci una stella su GitHub. Sei anche il benvenuto a condividere le tue esperienze con la community di Milvus unendoti al nostro Discord.
Ulteriori risorse
- Che cos’è la Retrieval Augmented Generation (RAG)?
- Creare RAG con Milvus, vLLM e Llama 3.1 di Meta
- Generative AI Resource Hub | Zilliz
- I modelli AI più performanti per le tue app GenAI | Zilliz
- Scegliere il modello di embedding giusto per i tuoi dati
- Il panorama dell’ecosistema GenAI: oltre gli LLM e i database vettoriali
Continua a leggere

DeepSeek-OCR Explained: Optical Compression for Scalable Long-Context and RAG Systems
Discover how DeepSeek-OCR uses visual tokens and Contexts Optical Compression to boost long-context LLM efficiency and reshape RAG performance.

How to Build an Enterprise-Ready RAG Pipeline on AWS with Bedrock, Zilliz Cloud, and LangChain
Build production-ready enterprise RAG with AWS Bedrock, Nova models, Zilliz Cloud, and LangChain. Complete tutorial with deployable code.

What is the K-Nearest Neighbors (KNN) Algorithm in Machine Learning?
KNN is a supervised machine learning technique and algorithm for classification and regression. This post is the ultimate guide to KNN.



