¿Cómo programa Milvus las tareas de consulta?
En este artículo, analizaremos cómo Milvus programa las tareas de consulta. También hablaremos sobre problemas, soluciones y orientaciones futuras para implementar la programación de Milvus.
Contexto
Sabemos por Managing Data in Massive-Scale Vector Search Engine que la búsqueda de similitud vectorial se implementa mediante la distancia entre dos vectores en un espacio de alta dimensión. El objetivo de la búsqueda vectorial es encontrar K vectores que sean los más cercanos al vector objetivo.
Hay muchas formas de medir la distancia vectorial, como la distancia euclidiana:
Distancia euclidiana.
donde x e y son dos vectores. n es la dimensión de los vectores.
Para encontrar los K vectores más cercanos en un conjunto de datos, es necesario calcular la distancia euclidiana entre el vector objetivo y todos los vectores del conjunto de datos que se va a buscar. Luego, los vectores se ordenan por distancia para obtener los K vectores más cercanos. El trabajo computacional es directamente proporcional al tamaño del conjunto de datos. Cuanto mayor sea el conjunto de datos, más trabajo computacional requiere una consulta. Una GPU, especializada en el procesamiento de gráficos, resulta tener muchos núcleos para proporcionar la potencia de cómputo requerida. Por lo tanto, el soporte multi-GPU también se tiene en cuenta durante la implementación de Milvus.
Conceptos básicos
Bloque de datos(TableFile)
Para mejorar el soporte para la búsqueda de datos a escala masiva, optimizamos el almacenamiento de datos de Milvus. Milvus divide los datos de una tabla por tamaño en múltiples bloques de datos. Durante la búsqueda vectorial, Milvus busca vectores en cada bloque de datos y fusiona los resultados. Una operación de búsqueda vectorial consta de N operaciones independientes de búsqueda vectorial (N es el número de bloques de datos) y N-1 operaciones de fusión de resultados.
Cola de tareas(TaskTable)
Cada Resource tiene un arreglo de tareas, que registra las tareas pertenecientes al Resource. Cada tarea tiene diferentes estados, incluidos Start, Loading, Loaded, Executing y Executed. El Loader y el Executor en un dispositivo de cómputo comparten la misma cola de tareas.
Programación de consultas
Programación de consultas.
- Cuando se inicia el servidor de Milvus, Milvus lanza el GpuResource correspondiente mediante los parámetros
gpu_resource_configen el archivo de configuraciónserver_config.yaml. DiskResource y CpuResource aún no se pueden editar enserver_config.yaml. GpuResource es la combinación desearch_resourcesybuild_index_resourcesy se denomina{gpu0, gpu1}en el siguiente ejemplo:
Código de ejemplo.
Ejemplo.
- Milvus recibe una solicitud. Los metadatos de la tabla se almacenan en una base de datos externa, que es SQLite o MySQl para un solo host y MySQL para distribuido. Después de recibir una solicitud de búsqueda, Milvus valida si la tabla existe y si la dimensión es consistente. Luego, Milvus lee la lista TableFile de la tabla.
Milvus lee la lista tablefile.
- Milvus crea una SearchTask. Debido a que el cálculo de cada TableFile se realiza de forma independiente, Milvus crea una SearchTask para cada TableFile. Como unidad básica de la programación de tareas, una SearchTask contiene los vectores objetivo, los parámetros de búsqueda y los nombres de archivo de TableFile.
Creador de tareas de lista de archivos de tabla.
- Milvus elige un dispositivo de cómputo. El dispositivo en el que una SearchTask realiza el cálculo depende del tiempo de finalización estimado para cada dispositivo. El tiempo de finalización estimado especifica el intervalo estimado entre la hora actual y el momento estimado en que se completa el cálculo.
Por ejemplo, cuando un bloque de datos de un SearchTask se carga en la memoria de la CPU, el siguiente SearchTask está esperando en la cola de tareas de cómputo de la CPU y la cola de tareas de cómputo de la GPU está inactiva. El tiempo estimado de finalización para la CPU es igual a la suma del costo de tiempo estimado del SearchTask anterior y el SearchTask actual. El tiempo estimado de finalización para una GPU es igual a la suma del tiempo para que los bloques de datos se carguen en la GPU y el costo de tiempo estimado del SearchTask actual. El tiempo estimado de finalización para un SearchTask en un Resource es igual al tiempo de ejecución promedio de todos los SearchTasks en el Resource. Luego, Milvus elige un dispositivo con el menor tiempo estimado de finalización y asigna SearchTask al dispositivo.
Aquí asumimos que el tiempo estimado de finalización para GPU1 es menor.
GPU1 con menor tiempo estimado de finalización.
Milvus agrega SearchTask a la cola de tareas de DiskResource.
Milvus mueve SearchTask a la cola de tareas de CpuResource. El hilo de carga en CpuResource carga cada tarea desde la cola de tareas de forma secuencial. CpuResource lee los bloques de datos correspondientes en la memoria de la CPU.
Milvus mueve SearchTask a GpuResource. El hilo de carga en GpuResource copia los datos de la memoria de la CPU a la memoria de la GPU. GpuResource lee los bloques de datos correspondientes en la memoria de la GPU.
Milvus ejecuta SearchTask en GpuResource. Debido a que el resultado de un SearchTask es relativamente pequeño, el resultado se devuelve directamente a la memoria de la CPU.
Planificador.
- Milvus fusiona el resultado de SearchTask con el resultado completo de la búsqueda.
Milvus fusiona los resultados de las tareas de búsqueda.
Después de que todos los SearchTasks se completan, Milvus devuelve el resultado completo de la búsqueda al cliente.
Construcción de índices
La construcción de índices es básicamente igual que el proceso de búsqueda sin el proceso de fusión. No hablaremos de esto en detalle.
Optimización del rendimiento
Caché
Como se mencionó antes, los bloques de datos deben cargarse en los dispositivos de almacenamiento correspondientes, como la memoria de la CPU o la memoria de la GPU, antes del cómputo. Para evitar la carga repetitiva de datos, Milvus introduce la caché LRU (Least Recently Used). Cuando la caché está llena, los nuevos bloques de datos desplazan a los bloques de datos antiguos. Puedes personalizar el tamaño de la caché mediante el archivo de configuración según el tamaño actual de la memoria. Se recomienda una caché grande para almacenar datos de búsqueda a fin de ahorrar eficazmente tiempo de carga de datos y mejorar el rendimiento de la búsqueda.
Superposición de carga de datos y cómputo
La caché no puede satisfacer nuestras necesidades de un mejor rendimiento de búsqueda. Los datos deben recargarse cuando la memoria es insuficiente o el tamaño del conjunto de datos es demasiado grande. Necesitamos disminuir el efecto de la carga de datos en el rendimiento de la búsqueda. La carga de datos, ya sea del disco a la memoria de la CPU o de la memoria de la CPU a la memoria de la GPU, pertenece a las operaciones de E/S y apenas necesita trabajo computacional de los procesadores. Por lo tanto, consideramos realizar la carga de datos y el cómputo en paralelo para un mejor uso de los recursos.
Dividimos el cómputo en un bloque de datos en 3 etapas (carga del disco a la memoria de la CPU, cómputo en la CPU, fusión de resultados) o 4 etapas (carga del disco a la memoria de la CPU, carga de la memoria de la CPU a la memoria de la GPU, cómputo en la GPU y recuperación de resultados, y fusión de resultados). Tomando como ejemplo el cómputo de 3 etapas, podemos lanzar 3 hilos responsables de las 3 etapas para que funcionen como canalización de instrucciones. Debido a que los conjuntos de resultados son en su mayoría pequeños, la fusión de resultados no toma mucho tiempo. En algunos casos, la superposición de carga de datos y cómputo puede reducir el tiempo de búsqueda a la mitad.
Carga superpuesta secuencial en Milvus.
Problemas y soluciones
Diferentes velocidades de transmisión
Anteriormente, Milvus usaba la estrategia Round Robin para la programación de tareas multi-GPU. Esta estrategia funcionó perfectamente en nuestro servidor de 4 GPU y el rendimiento de búsqueda fue 4 veces mejor. Sin embargo, para nuestros hosts de 2 GPU, el rendimiento no fue 2 veces mejor. Hicimos algunos experimentos y descubrimos que la velocidad de copia de datos para una GPU era de 11 GB/s. Sin embargo, para otra GPU, era de 3 GB/s. Después de consultar la documentación de la placa base, confirmamos que la placa base estaba conectada a una GPU mediante PCIe x16 y a otra GPU mediante PCIe x4. Es decir, estas GPU tienen diferentes velocidades de copia. Más tarde, añadimos el tiempo de copia para medir el dispositivo óptimo para cada SearchTask.
Trabajo futuro
Entorno de hardware con mayor complejidad
En condiciones reales, el entorno de hardware puede ser más complicado. Para entornos de hardware con múltiples CPU, memoria con arquitectura NUMA, NVLink y NVSwitch, la comunicación entre CPU/GPU ofrece muchas oportunidades de optimización.
Optimización de consultas
Durante la experimentación, descubrimos algunas oportunidades para mejorar el rendimiento. Por ejemplo, cuando el servidor recibe múltiples consultas para la misma tabla, las consultas pueden fusionarse bajo ciertas condiciones. Mediante el uso de la localidad de datos, podemos mejorar el rendimiento. Estas optimizaciones se implementarán en nuestro desarrollo futuro. Ahora ya sabemos cómo se programan y ejecutan las consultas para el escenario de un solo host y múltiples GPU. Continuaremos presentando más mecanismos internos de Milvus en los próximos artículos.
Sigue leyendo

How to Choose the Best Embedding Model for RAG in 2026: 10 Models Benchmarked
We benchmarked 10 embedding models on cross-modal, cross-lingual, long-document, and dimension compression tasks. See which one fits your RAG pipeline.

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.

Legal Document Analysis: Harnessing Zilliz Cloud's Semantic Search and RAG for Legal Insights
Enhance legal document analysis with Zilliz Cloud’s Semantic Search and RAG. Improve accuracy, efficiency, and scalability for contracts, case law, and compliance.



