Faire évoluer la recherche avec Milvus : gérer facilement des ensembles de données massifs
Les gens me demandent souvent : « Pourquoi utiliser une base de données vectorielle comme Milvus alors que je peux simplement utiliser NumPy ou FAISS ? » Il y a de nombreuses raisons : l’évolutivité, la facilité de gestion, la persistance des données, et l’une des plus importantes : l’échelle. Lorsque vous traitez des millions ou des milliards de vecteurs, vous avez besoin d’une solution conçue pour gérer ce type de volume.
Dans cet article de blog, nous verrons comment travailler avec un exemple de cas d’utilisation de 40 millions de vecteurs avec Milvus. Nous montrerons également comment des fonctionnalités comme le filtrage des métadonnées peuvent améliorer considérablement vos résultats de recherche — une capacité essentielle souvent absente des bases de données vectorielles non conçues à cet effet, ce qui constitue un inconvénient majeur.
Milvus : une base de données vectorielle conçue pour l’échelle
Milvus est une base de données vectorielle open-source populaire qui alimente les applications d’IA grâce à une recherche de similarité vectorielle hautement performante et évolutive.
Parmi les fonctionnalités clés qui rendent possible la recherche vectorielle à grande échelle, on trouve :
- Une architecture distribuée : Milvus possède une architecture distribuée qui lui permet de s’étendre horizontalement de manière fluide et de répartir les données et la charge de travail sur plusieurs nœuds. Cette capacité garantit une haute disponibilité et résilience, même sous forte charge.
- Indexation optimisée : Milvus prend en charge différentes techniques d’indexation telles que IVF_FLAT et HNSW, mais aussi un index GPU pour accélérer les vitesses de recherche. Il prend également en charge DiskANN si vous devez réduire le coût de votre Vector DB ; la recherche serait un peu plus lente, mais elle serait nettement moins chère.
- Recherche parmi des milliards : L’une des fonctionnalités remarquables de Milvus est sa capacité à gérer et à rechercher efficacement parmi des milliards de vecteurs. Cette capacité est cruciale pour les applications qui nécessitent des recherches de similarité vectorielle à haute vitesse et à très grand volume.
- Différentes options de calcul : Milvus peut exploiter la puissance des GPU et des CPU, en attribuant intelligemment les tâches au matériel le plus adapté pour des performances optimales. Cette capacité permet un traitement parallèle et des améliorations significatives de la vitesse, en particulier pour les opérations intensives en calcul.
Le jeu de données : des millions d’embeddings d’articles Wikipedia
Nous utilisons un jeu de données provenant de Wikipedia qui a été transformé avec un modèle d’embedding Cohere ; il est disponible gratuitement sur Hugging Face.
Aperçu du jeu de données
Figure 1 : Aperçu du jeu de données
Chaque exemple contient un article Wikipedia complet, avec un nettoyage visant à supprimer le markdown et les sections indésirables (références, etc.).
Le jeu de données contient plus de 300 langues, mais pour notre cas d’utilisation, nous nous concentrerons sur l’anglais, qui contient 41,5 M de vecteurs. Ce qui est intéressant, c’est que les embeddings sont interlingues ! Cela signifie que vous pouvez effectuer des recherches dans plusieurs langues et vous appuyer sur la capacité du modèle à trouver des sens similaires, même dans des langues différentes.
Multilingue vs interlingue.png
Figure 2 : Multilingue vs interlingue (Source de l’image)
Premiers pas avec Milvus
Dans cette section, nous allons vous montrer comment démarrer avec Milvus, notamment en installant le SDK Milvus ou en configurant Zilliz Cloud, en vous connectant à Milvus, en créant des collections, etc.
Installation du SDK Milvus
Commencez par installer le SDK Milvus en exécutant pip install pymilvus. Par souci de simplicité, nous déploierons Milvus sur Zilliz Cloud (la version entièrement gérée de Milvus). Selon l’échelle des données que vous utilisez, vous pouvez soit Déployer Milvus sur Kubernetes, soit utiliser Zilliz Cloud.
- Si vous disposez d’un volume de données plus important, par exemple plus d’un million de vecteurs, vous pouvez configurer un serveur Milvus plus performant sur Docker ou Kubernetes. Dans cette configuration, veuillez utiliser l’URI du serveur, par exemple
http://localhost:19530, comme URI. - Si vous souhaitez utiliser Zilliz Cloud, le service cloud entièrement géré pour Milvus, ajustez le
uriet letoken, qui correspondent au point de terminaison public et à la clé API dans Zilliz Cloud.
Un guide étape par étape
- Se connecter à Milvus : Tout d’abord, établissez une connexion à votre instance Milvus :
from pymilvus import MilvusClient
client = MilvusClient(uri=<ZILLIZ_CLOUD_URI>, token=<ZILLIZ_TOKEN>)
- Créer un schéma : Définissez le schéma qui sera utilisé pour créer notre 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},
]
- Créer une collection : Maintenant, nous créons la collection que nous utiliserons pour stocker les 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)
- Créer un index : Pour rendre la recherche vectorielle efficace, nous devons créer un index sur le champ vectoriel qui nous intéresse. Un index vectoriel est un type d’index spécialisé conçu pour stocker et rechercher des vecteurs.
# 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)
- Insérer des données : Alimentez la collection
cohere_embeddingsavec le jeu de données de Hugging Face. Selon les ressources dont vous disposez, vous pouvez soit en télécharger un sous-ensemble, par exemple seulement une langue spécifique, le téléverser vers un bucket comme S3 ou GCP, ou vous pouvez également le diffuser en streaming depuis Hugging Face.
Lorsqu’un jeu de données est en mode streaming, vous pouvez l’itérer directement sans avoir à télécharger l’ensemble du jeu de données. Les données sont téléchargées progressivement à mesure que vous parcourez le jeu de données, ce qui est utile si vous n’avez pas assez d’espace sur votre disque pour télécharger le jeu de données, ou si vous ne voulez pas attendre que votre jeu de données soit téléchargé avant de l’utiliser.
# 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)
Filtrage scalaire : un outil puissant à grande échelle
Lorsque vous travaillez avec des millions ou des milliards de vecteurs, le filtrage devient plus qu’un simple plus : il est essentiel. Et c’est là que Milvus montre vraiment toute sa puissance.
Voici pourquoi l’approche de Milvus en matière de filtrage change la donne :
- Magie des bitsets : Milvus utilise des bitsets compacts pour représenter les vecteurs qui correspondent à vos critères de filtrage. Ces bitsets peuvent être manipulés plus vite que vous ne pouvez dire « recherche de similarité vectorielle », grâce à des opérations CPU de bas niveau. C’est comme disposer d’un superordinateur capable de trier instantanément des milliards de points de données.
- Réduction de l’espace de recherche : Contrairement à certaines autres solutions (par ex. pgvector) qui proposent uniquement un post-filtrage, Milvus applique les filtres de métadonnées avant d’exécuter la recherche de similarité vectorielle. Cela réduit considérablement le nombre de vecteurs qu’il doit traiter. Cela vous permet également de restreindre votre recherche de milliards de vecteurs à seulement quelques milliers réellement pertinents, en quelques millisecondes.
- Indexation scalaire (quand vous en avez besoin) : Pour les champs sur lesquels vous filtrez fréquemment, Milvus vous permet de créer des index scalaires. Voyez cela comme une antisèche que vous donnez à Milvus pour vos données. Bien qu’ils ne soient pas toujours présents par défaut, lorsqu’ils sont correctement configurés, ces index peuvent décupler les performances de votre filtrage.
La beauté de Milvus, c’est qu’il ne se contente pas d’offrir ces fonctionnalités — il les fait fonctionner à grande échelle. Que vous travailliez avec 40 millions de vecteurs ou 40 milliards.
Recherche avec filtrage exact
Trouver des documents avec un titre spécifique.
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)
Cela renvoie des documents sur la 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'}
Recherche avec filtrage par préfixe/infixe/postfixe
Rechercher des documents contenant un mot spécifique.
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)
Cela renvoie les documents contenant le mot "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'}
Recherche avec filtrage avec "Not In"
Excluez des titres spécifiques de votre recherche.
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)
Cela renvoie les documents dont les titres ne sont pas "British Arab Commercial Bank" ou "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 : une combinaison puissante qui rend la recherche de similarité vectorielle plus simple et plus efficace
Effectuons une recherche de similarité à l’aide des embeddings Cohere. Nous allons intégrer la requête Who founded Wikipedia et l’utiliser pour rechercher dans notre collection Milvus. Il s’agit du même modèle d’embedding que celui qui a été utilisé pour encoder les Wikipedia Embeddings.
Nous utiliserons l’intégration entre Milvus et Cohere via PyMilvus Model, installez-la avec 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 = 'Who founded Wikipedia'
embedded_query = cohere_ef.encode_queries([query])
response = embedded_query[0]
print(response[:10])
Cela renvoie les articles Wikipédia les plus pertinents sur les fondateurs de Wikipédia.
res = milvus_client.search(data=response, collection_name=collection_name, output_fields=["text"], limit=3)
for elt in res:
pprint(elt)
Ce qui donne le résultat suivant :
[{'distance': 0.7344469428062439,
'entity': {'text': 'Larry Sanger and Jimmy Wales are the ones who started '
'Wikipedia. Wales is credited with defining the goals of '
'the project. Sanger created the strategy of using a wiki '
"to reach Wales' goal. On January 10, 2001, Larry Sanger "
'proposed on the Nupedia mailing list to create a wiki as '
'a "feeder" project for Nupedia. Wikipedia was launched '
'on January 15, 2001. It was launched as an '
'English-language edition at www.wikipedia.com, and '
'announced by Sanger on the Nupedia mailing list. '
'Wikipedia\'s policy of "neutral point-of-view" was '
'enforced in its initial months and was similar to '
'Nupedia\'s earlier "nonbiased" policy. Otherwise, there '
"weren't very many rules initially, and Wikipedia "
'operated independently of Nupedia.'},
'id': 450933285241797095},
{'distance': 0.7239157557487488,
'entity': {'text': 'Wikipedia was originally conceived as a complement to '
'Nupedia, a free on-line encyclopedia founded by Jimmy '
'Wales, with articles written by highly qualified '
'contributors and evaluated by an elaborate peer review '
'process. The writing of content for Nupedia proved to be '
'extremely slow, with only 12 articles completed during '
'the first year, despite a mailing-list of interested '
'editors and the presence of a full-time editor-in-chief '
'recruited by Wales, Larry Sanger. Learning of the wiki '
'concept, Wales and Sanger decided to try creating a '
'collaborative website to provide an additional source of '
'rapidly produced draft articles that could be polished '
'for use on Nupedia.'},
'id': 450933285225827849},
{'distance': 0.7191773653030396,
'entity': {'text': "The foundation's creation was officially announced by "
'Wikipedia co-founder Jimmy Wales, who was running '
'Wikipedia within his company Bomis, on June 20, 2003.'},
'id': 450933285242058780}]
Vérifions les métriques de performance de notre cluster, en nous concentrant sur la latence de nos requêtes de recherche. Nous utiliserons l’API Zilliz Cloud pour récupérer à la fois les valeurs de latence moyenne et du 99e centile (P99).
Tout d’abord, nous allons vérifier la latence moyenne :
> 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"}]}]
Cette requête renvoie une latence moyenne de 2,05 millisecondes.
Ensuite, vérifions la latence 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 latence P99 est indiquée comme étant de 4,95 millisecondes.
Ces résultats montrent des performances impressionnantes : notre latence moyenne de requête est d’un peu plus de 2 millisecondes, avec 99 % des requêtes terminées en moins de 5 millisecondes. Cela démontre l’efficacité de notre cluster Milvus dans la gestion des opérations de recherche, même à grande échelle.
Créer un système RAG de base avec Milvus
La génération augmentée par récupération (RAG) est une technique d’IA avancée permettant d’atténuer les hallucinations dans les grands modèles de langage (LLMs) comme ChatGPT.
Dans cet exemple, nous pouvons utiliser les résultats de Milvus pour créer un système RAG simple. Cela permet à un LLM d’accéder aux informations stockées dans Milvus et de les utiliser.
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.
Au-delà des bases : fonctionnalités avancées de Milvus pour une évolutivité améliorée
Milvus offre des fonctionnalités encore plus avancées pour gérer des ensembles de données massifs :
- Partitionnement des données : Pour les collections contenant des données provenant de plusieurs utilisateurs ou locataires, par exemple, Milvus propose des clés et des noms de partition pour séparer logiquement les données. Cette fonctionnalité permet un filtrage efficace des métadonnées, par exemple par ID utilisateur ou nom d’organisation.
- Recherche par plage : Trouvez efficacement des vecteurs situés dans une plage de distance spécifiée par rapport à un vecteur de requête, permettant des recherches de similarité plus précises et flexibles dans des espaces à haute dimension.
- Recherche hybride : Permet aux utilisateurs d’effectuer une recherche sur plusieurs colonnes vectorielles en une seule requête. Par exemple, vous pouvez combiner un vecteur de texte et un vecteur d’image pour des données multimodales, ou un vecteur dense et un vecteur creux pour utiliser la recherche sémantique et la recherche plein texte. Cette fonctionnalité offre une recherche polyvalente et flexible.
Pour plus de détails, consultez la documentation Milvus.
Conclusion
Milvus fournit une solution robuste et évolutive pour travailler avec des milliards de vecteurs. Ses fonctionnalités puissantes, comme le filtrage et l’architecture distribuée, en font un choix parfait pour les applications d’IA exigeantes.
Nos tests de performance ont mis en évidence les capacités impressionnantes de Milvus :
- Latence moyenne de requête : 2,05 millisecondes
- Latence au 99e centile (P99) : 4,95 millisecondes
Ces résultats démontrent que Milvus peut constamment offrir des temps de recherche inférieurs à 5 ms, même lorsqu’il traite des millions de vecteurs. Donc, si vous cherchez à créer des applications capables de gérer des ensembles de données massifs et de fournir des résultats de recherche ultra-rapides, Milvus vaut vraiment la peine d’être exploré.
Si vous aimez cet article de blog, pensez à nous donner une étoile sur GitHub. Vous êtes également les bienvenus pour partager vos expériences avec la communauté Milvus en rejoignant notre Discord.
Ressources supplémentaires
- Qu’est-ce que la génération augmentée par récupération (RAG) ?
- Créer un RAG avec Milvus, vLLM et Llama 3.1 de Meta
- Centre de ressources sur l’IA générative | Zilliz
- Les modèles d’IA les plus performants pour vos applications GenAI | Zilliz
- Choisir le bon modèle d’embedding pour vos données
- Le paysage de l’écosystème GenAI : au-delà des LLM et des bases de données vectorielles
Continuer à lire

We spent 8 years making vector databases faster. Then we stopped.
Rarely queried embeddings still need to stay searchable. See how Vector Lakebase enables on-demand vector search without always-on compute costs.

Will Amazon S3 Vectors Kill Vector Databases—or Save Them?
AWS S3 Vectors aims for 90% cost savings for vector storage. But will it kill vectordbs like Milvus? A deep dive into costs, limits, and the future of tiered storage.

Vector Databases vs. Key-Value Databases
Use a vector database for AI-powered similarity search; use a key-value database for high-throughput, low-latency simple data lookups.



