Escalando la búsqueda con Milvus: Manejo de conjuntos de datos masivos con facilidad
La gente a menudo me pregunta: "¿Por qué molestarse en usar una base de datos vectorial como Milvus cuando puedo simplemente usar NumPy o FAISS?" Hay muchas razones: escalabilidad, facilidad de gestión, persistencia de datos y una de las más importantes: escala. Cuando estás trabajando con millones o miles de millones de vectores, necesitas una solución creada para manejar ese tipo de volumen.
En esta publicación de blog, veremos cómo podemos trabajar con un caso de uso de ejemplo de 40 millones de vectores con Milvus. También demostraremos cómo funciones como el filtrado de metadatos pueden mejorar significativamente tus resultados de búsqueda, una capacidad esencial que a menudo falta en las bases de datos vectoriales no diseñadas específicamente, lo cual es una desventaja importante.
Milvus: una base de datos vectorial creada para escalar
Milvus es una popular base de datos vectorial de código abierto que impulsa aplicaciones de IA con una búsqueda de similitud vectorial altamente eficiente y escalable.
Algunas de las características clave que hacen posible la búsqueda vectorial a escala incluyen:
- Una arquitectura distribuida: Milvus tiene una arquitectura distribuida que le permite escalar horizontalmente sin problemas y distribuir datos y carga de trabajo entre múltiples nodos. Esta capacidad garantiza una alta disponibilidad y resiliencia, incluso bajo cargas pesadas.
- Indexación optimizada: Milvus admite diferentes técnicas de indexación como IVF_FLAT y HNSW, pero también un índice GPU para acelerar las velocidades de búsqueda. También admite DiskANN si necesitas reducir el coste de tu base de datos vectorial; la búsqueda sería un poco más lenta, pero sería significativamente más barata.
- Búsqueda entre miles de millones: Una de las características destacadas de Milvus es su capacidad para manejar y buscar eficientemente entre miles de millones de vectores. Esta capacidad es crucial para aplicaciones que requieren búsquedas de similitud vectorial de alta velocidad y gran volumen.
- Diferentes opciones de computación: Milvus puede aprovechar la potencia de las GPU y las CPU, asignando inteligentemente las tareas al hardware más adecuado para un rendimiento óptimo. Esta capacidad permite el procesamiento paralelo y mejoras significativas de velocidad, especialmente para operaciones intensivas en cómputo.
El conjunto de datos: millones de embeddings de artículos de Wikipedia
Estamos usando un conjunto de datos de Wikipedia que ha sido transformado con un modelo de embeddings de Cohere, y está disponible gratuitamente en Hugging Face.
Vista previa del conjunto de datos
Figura 1: Vista previa del conjunto de datos
Cada ejemplo contiene un artículo completo de Wikipedia con limpieza para eliminar markdown y secciones no deseadas (referencias, etc.).
El conjunto de datos contiene más de 300 idiomas, pero para nuestro caso de uso nos centraremos en el inglés, que contiene 41,5 millones de vectores. ¡La parte interesante es que los embeddings son translingües! Esto significa que puedes buscar en varios idiomas y confiar en la capacidad del modelo para encontrar significados similares, incluso en diferentes idiomas.
Multilingual vs Cross-lingual.png
Figura 2: Multilingüe vs translingüe (Fuente de la imagen)
Primeros pasos con Milvus
En esta sección, te mostraremos cómo comenzar con Milvus, incluida la instalación del SDK de Milvus o la configuración de Zilliz Cloud, la conexión a Milvus, la creación de colecciones, etc.
Instalación del SDK de Milvus
Comienza instalando el SDK de Milvus ejecutando pip install pymilvus. Para simplificar, desplegaremos Milvus en Zilliz Cloud (la versión totalmente gestionada de Milvus). Dada la escala de los datos que utilizas, puedes desplegar Milvus en Kubernetes o usar Zilliz Cloud.
- Si tienes una escala de datos mayor, digamos más de un millón de vectores, puedes configurar un servidor Milvus de mayor rendimiento en Docker o Kubernetes. En esta configuración, utiliza el uri del servidor, p. ej.
http://localhost:19530, como tu uri. - Si quieres usar Zilliz Cloud, el servicio en la nube totalmente gestionado para Milvus, ajusta el
uriy eltoken, que corresponden al Endpoint público y clave de API en Zilliz Cloud.
Una guía paso a paso
- Conéctate a Milvus: Primero, establece una conexión con tu instancia de Milvus:
from pymilvus import MilvusClient
client = MilvusClient(uri=<ZILLIZ_CLOUD_URI>, token=<ZILLIZ_TOKEN>)
- Crea un esquema: Define el esquema que se utilizará para crear nuestra colección de 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 colección: Ahora, creamos la colección que usaremos para almacenar los 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 índice: Para que la búsqueda vectorial sea eficiente, necesitamos crear un índice en el campo vectorial que nos interesa. Un índice vectorial es un tipo especializado de índice diseñado para almacenar y buscar vectores.
# 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)
- Inserta datos: Rellena la colección
cohere_embeddingscon el conjunto de datos de Hugging Face. Dependiendo de los recursos que tengas disponibles, quizá quieras descargar un subconjunto, p. ej. solo un idioma específico, subirlo a un bucket como S3 o GCP, o también puedes transmitirlo desde Hugging Face.
Cuando un conjunto de datos está en modo streaming, puedes iterar sobre él directamente sin tener que descargar todo el conjunto de datos. Los datos se descargan progresivamente a medida que iteras sobre el conjunto de datos; esto es útil si no tienes suficiente espacio en tu disco para descargar el conjunto de datos, o si no quieres esperar a que tu conjunto de datos se descargue antes de usarlo.
# 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", # Solo inglés
split="train",
streaming=True, # Nos permite iterar sobre el conjunto de datos
)
for doc in tqdm(docs, desc="Transmitiendo y preparando datos para Milvus"):
title = doc["title"][:4500] # Los títulos pueden ser muy largos
text = doc["text"][:4500] # El texto puede ser muy largo
emb = doc["emb"] # El vector de incrustación
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)
Filtrado escalar: una herramienta potente a escala
Cuando trabajas con millones o miles de millones de vectores, el filtrado se vuelve más que algo deseable: es esencial. Y aquí es donde Milvus realmente muestra su fuerza.
He aquí por qué el enfoque de Milvus para el filtrado supone un cambio radical:
- Magia con bitsets: Milvus utiliza bitsets compactos para representar qué vectores coinciden con tus criterios de filtrado. Estos bitsets pueden manipularse más rápido de lo que puedes decir "búsqueda de similitud vectorial", gracias a operaciones de CPU de bajo nivel. Es como tener una supercomputadora que puede ordenar instantáneamente miles de millones de puntos de datos.
- Reducción del espacio de búsqueda: A diferencia de algunas otras soluciones (p. ej., pgvector) que solo ofrecen posfiltrado, Milvus aplica filtros de metadatos antes de ejecutar la búsqueda de similitud vectorial. Reduce drásticamente el número de vectores que necesita procesar. También te permite acotar tu búsqueda desde miles de millones de vectores hasta solo los miles que realmente importan, en milisegundos.
- Indexación escalar (cuando la necesitas): Para aquellos campos por los que filtras con frecuencia, Milvus te permite crear índices escalares. Piensa en ello como darle a Milvus una chuleta para tus datos. Aunque no siempre están presentes por defecto, cuando se configuran correctamente, estos índices pueden acelerar enormemente el rendimiento de tu filtrado.
La belleza de Milvus es que no solo ofrece estas funciones — las hace funcionar a escala. Ya sea que trabajes con 40 millones de vectores o con 40 mil millones.
Búsqueda con filtrado exacto
Encuentra documentos con un 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)
Esto devuelve documentos sobre el 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'}
Búsqueda con filtrado de prefijo/infijo/sufijo
Busca documentos que contengan una palabra 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)
Esto devuelve documentos que contienen la palabra "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'}
Búsqueda con filtrado con "Not In"
Excluya títulos específicos de su búsqueda.
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)
Esto devuelve documentos cuyos títulos no son "British Arab Commercial Bank" ni "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 combinación potente que hace que la búsqueda de similitud vectorial sea más fácil y eficiente
Realicemos una búsqueda de similitud usando embeddings de Cohere. Incrustaremos la consulta Who founded Wikipedia y la usaremos para buscar en nuestra colección de Milvus. Este es el mismo modelo de embeddings que se usó para codificar los embeddings de Wikipedia.
Usaremos la integración entre Milvus y Cohere a través de PyMilvus Model; instálela 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 = 'Who founded Wikipedia'
embedded_query = cohere_ef.encode_queries([query])
response = embedded_query[0]
print(response[:10])
Esto devuelve los artículos de Wikipedia más relevantes sobre los fundadores de Wikipedia.
res = milvus_client.search(data=response, collection_name=collection_name, output_fields=["text"], limit=3)
for elt in res:
pprint(elt)
Lo que da como resultado lo siguiente:
[{'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}]
Comprobemos las métricas de rendimiento de nuestro clúster, centrándonos en la latencia de nuestras consultas de búsqueda. Usaremos la API de Zilliz Cloud para recuperar los valores de latencia tanto promedio como del percentil 99 (P99).
Primero, comprobaremos la latencia promedio:
> 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 devuelve una latencia promedio de 2,05 milisegundos.
A continuación, comprobemos la latencia 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 latencia P99 se informa como 4,95 milisegundos.
Estos resultados muestran un rendimiento impresionante: nuestra latencia promedio de consulta es de poco más de 2 milisegundos, con el 99% de las consultas completándose en menos de 5 milisegundos. Esto demuestra la eficiencia de nuestro clúster Milvus al gestionar operaciones de búsqueda, incluso a escala.
Crear un sistema RAG básico con Milvus
La generación aumentada por recuperación (RAG) es una técnica avanzada de IA para mitigar las alucinaciones en modelos de lenguaje grandes (LLMs) como ChatGPT.
En este ejemplo, podemos usar los resultados de Milvus para crear un sistema RAG simple. Esto permite que un LLM acceda y utilice información almacenada en 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.
Más allá de lo básico: funciones avanzadas de Milvus para una escalabilidad mejorada
Milvus ofrece funciones aún más avanzadas para gestionar conjuntos de datos masivos:
- Particionamiento de datos: Para colecciones que contienen datos de múltiples usuarios o inquilinos, por ejemplo, Milvus ofrece claves y nombres de partición para segregar datos de forma lógica. Esta función permite un filtrado eficiente de metadatos, como por ID de usuario o nombre de organización.
- Búsqueda por rango: Encuentre de manera eficiente vectores dentro de un rango de distancia especificado desde un vector de consulta, lo que permite búsquedas de similitud más precisas y flexibles en espacios de alta dimensionalidad.
- Búsqueda híbrida: Permite a los usuarios buscar en varias columnas vectoriales en una sola consulta. Por ejemplo, puede combinar vector de texto y vector de imagen para datos multimodales, o vector denso y vector disperso para usar búsqueda semántica y búsqueda de texto completo. Esta función ofrece una funcionalidad de búsqueda versátil y flexible.
Para obtener más detalles, consulte la documentación de Milvus.
Conclusión
Milvus proporciona una solución robusta y escalable para trabajar con miles de millones de vectores. Sus potentes funciones, como el filtrado y la arquitectura distribuida, lo convierten en una opción perfecta para aplicaciones de IA exigentes.
Nuestras pruebas de rendimiento han mostrado las impresionantes capacidades de Milvus:
- Latencia promedio de consulta: 2,05 milisegundos
- Latencia del percentil 99 (P99): 4,95 milisegundos
Estos resultados demuestran que Milvus puede ofrecer de forma constante tiempos de búsqueda inferiores a 5 ms, incluso al trabajar con millones de vectores. Así que, si buscas crear aplicaciones que puedan manejar conjuntos de datos masivos y ofrecer resultados de búsqueda ultrarrápidos, definitivamente vale la pena explorar Milvus.
Si te gusta esta publicación del blog, considera darnos una estrella en GitHub. También te invitamos a compartir tus experiencias con la comunidad de Milvus uniéndote a nuestro Discord.
Recursos adicionales
- ¿Qué es la generación aumentada por recuperación (RAG)?
- Creación de RAG con Milvus, vLLM y Llama 3.1 de Meta
- Centro de recursos de IA generativa | Zilliz
- Modelos de IA de mayor rendimiento para tus apps de GenAI | Zilliz
- Elegir el modelo de embeddings adecuado para tus datos
- El panorama del ecosistema GenAI: más allá de los LLM y las bases de datos vectoriales
Sigue leyendo

Why and How to Migrate from Self-Hosted Milvus to Zilliz Cloud
A simple, step-by-step guide to migrating from Milvus to Zilliz Cloud. Learn both endpoint and backup methods for a smooth, scalable vector database migration.

Balancing Precision and Performance: How Zilliz Cloud's New Parameters Help You Optimize Vector Search
Optimize vector search with Zilliz Cloud’s level and recall features to tune accuracy, balance performance, and power AI applications.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.



