Optimización de NVIDIA CAGRA en Milvus: un enfoque híbrido GPU-CPU para acelerar la indexación y abaratar las consultas
A medida que los sistemas de IA pasan de los experimentos a la infraestructura de producción, las bases de datos vectoriales ya no tienen que lidiar con millones de incrustaciones. Ahora, miles de millones son rutinarios, y decenas de miles de millones son cada vez más comunes. A esta escala, las decisiones algorítmicas no sólo afectan al rendimiento y la recuperación, sino que también se traducen directamente en el coste de la infraestructura.
Esto nos lleva a una cuestión fundamental para las implantaciones a gran escala: ¿cómo elegir el índice adecuado para obtener una recuperación y latencia aceptables sin que el uso de recursos informáticos se descontrole?
Los índices basados en gráficos como NSW, HNSW, CAGRA y Vamana se han convertido en la respuesta más adoptada. Al navegar por grafos de vecindad preconstruidos, estos índices permiten una búsqueda rápida del vecino más próximo a escala de miles de millones, evitando el escaneo de fuerza bruta y la comparación de cada vector con la consulta.
Sin embargo, el perfil de costes de este enfoque es desigual. Consultar un grafo es relativamente barato; construirlo, no. La construcción de un gráfico de alta calidad requiere cálculos de distancias a gran escala y refinamientos iterativos en todo el conjunto de datos, cargas de trabajo que las CPU tradicionales tienen dificultades para manejar con eficiencia a medida que crecen los datos.
CAGRA de NVIDIA resuelve este cuello de botella utilizando las GPU para acelerar la construcción de gráficos a través del paralelismo masivo. Aunque esto reduce significativamente el tiempo de construcción, el hecho de depender de las GPU tanto para la construcción de índices como para el servicio de consultas introduce mayores restricciones de coste y escalabilidad en los entornos de producción.
Para equilibrar estas ventajas y desventajas, Milvus 2.6.1 adopta un diseño híbrido para los índices GPU_CAGRA: Las GPU se utilizan únicamente para la construcción de los grafos, mientras que la ejecución de las consultas se ejecuta en las CPU. Esto preserva las ventajas de calidad de los gráficos construidos en la GPU al tiempo que mantiene la escalabilidad y la rentabilidad del servicio de consultas, lo que lo hace especialmente adecuado para cargas de trabajo con actualizaciones de datos poco frecuentes, grandes volúmenes de consultas y una estricta sensibilidad a los costes.
¿Qué es CAGRA y cómo funciona?
Los índices vectoriales basados en grafos se dividen generalmente en dos categorías principales:
Construcción iterativa de grafos, representada por CAGRA (ya soportada en Milvus).
Construcción de gráficos basada en la inserción, representada por Vamana (actualmente en desarrollo en Milvus).
Estos dos enfoques difieren significativamente en sus objetivos de diseño y fundamentos técnicos, por lo que cada uno es adecuado para diferentes escalas de datos y patrones de carga de trabajo.
NVIDIA CAGRA (CUDA ANN Graph-based) es un algoritmo nativo de la GPU para la búsqueda aproximada del vecino más próximo (ANN), diseñado para construir y consultar grafos de proximidad a gran escala de forma eficiente. Al aprovechar el paralelismo de la GPU, CAGRA acelera significativamente la construcción de grafos y proporciona un alto rendimiento de consulta en comparación con enfoques basados en la CPU como HNSW.
CAGRA se basa en el algoritmo NN-Descent (Nearest Neighbor Descent), que construye un grafo k-nearest-neighbor (kNN) mediante refinamiento iterativo. En cada iteración, se evalúan y actualizan los vecinos candidatos, convergiendo gradualmente hacia relaciones de vecindad de mayor calidad en todo el conjunto de datos.
Después de cada ronda de refinamiento, CAGRA aplica técnicas adicionales de poda de grafos -como la poda de desvíos de 2 saltos- paraeliminar los bordes redundantes y preservar al mismo tiempo la calidad de la búsqueda. Esta combinación de refinamiento iterativo y poda da como resultado un grafo compacto pero bien conectado que es eficiente de recorrer en el momento de la consulta.
Mediante el refinamiento y la poda repetidos, CAGRA produce una estructura de grafos que admite una alta recuperación y una búsqueda del vecino más próximo de baja latencia a gran escala, lo que la hace especialmente adecuada para conjuntos de datos estáticos o que se actualizan con poca frecuencia.
Paso 1: Construcción del grafo inicial con NN-Descent
NN-Descent se basa en una observación simple pero poderosa: si el nodo u es vecino de v, y el nodo w es vecino de u, entonces es muy probable que w también sea vecino de v. Esta propiedad transitiva permite al algoritmo descubrir los verdaderos vecinos más próximos de forma eficaz, sin necesidad de comparar exhaustivamente cada par de vectores.
CAGRA utiliza NN-Descent como algoritmo central de construcción de grafos. El proceso es el siguiente
1. Inicialización aleatoria: Cada nodo comienza con un pequeño conjunto de vecinos seleccionados aleatoriamente, formando un grafo inicial aproximado.
2. 2. Expansión de vecinos: En cada iteración, un nodo reúne a sus vecinos actuales y a los vecinos de éstos para formar una lista de candidatos. El algoritmo calcula las similitudes entre el nodo y todos los candidatos. Dado que la lista de candidatos de cada nodo es independiente, estos cálculos pueden asignarse a bloques de hilos de GPU independientes y ejecutarse en paralelo a escala masiva.
3. 3. Actualización de la lista de candidatos: si el algoritmo encuentra candidatos más cercanos que los vecinos actuales del nodo, intercambia los vecinos más distantes y actualiza la lista kNN del nodo. A lo largo de múltiples iteraciones, este proceso produce un grafo kNN aproximado de mucha mayor calidad.
4. Comprobación de convergencia: A medida que avanzan las iteraciones, se producen menos actualizaciones de vecinos. Una vez que el número de conexiones actualizadas cae por debajo de un umbral establecido, el algoritmo se detiene, lo que indica que el grafo se ha estabilizado.
Dado que la expansión de vecinos y el cálculo de similitudes para los distintos nodos son totalmente independientes, CAGRA asigna la carga de trabajo de NN-Descent de cada nodo a un bloque de subprocesos dedicado de la GPU. Este diseño permite un paralelismo masivo y hace que la construcción de grafos sea varios órdenes de magnitud más rápida que los métodos tradicionales basados en la CPU.
Paso 2: poda del grafo con desvíos de 2 saltos
Una vez completado el proceso NN-Descent, el grafo resultante es preciso pero excesivamente denso. NN-Descent mantiene intencionadamente vecinos candidatos extra, y la fase de inicialización aleatoria introduce muchas aristas débiles o irrelevantes. Como resultado, a menudo cada nodo termina con un grado dos veces -o incluso varias veces- mayor que el grado objetivo.
Para producir un grafo compacto y eficiente, CAGRA aplica la poda de desvíos de 2 saltos.
La idea es sencilla: si el nodo A puede llegar al nodo B indirectamente a través de un vecino compartido C (formando un camino A → C → B), y la distancia de este camino indirecto es comparable a la distancia directa entre A y B, entonces la arista directa A → B se considera redundante y puede eliminarse.
Una ventaja clave de esta estrategia de poda es que la comprobación de redundancia de cada arista depende sólo de la información local: las distancias entre los dos puntos finales y sus vecinos compartidos. Dado que cada arista puede evaluarse de forma independiente, el paso de poda es altamente paralelizable y se adapta de forma natural a la ejecución por lotes en la GPU.
Como resultado, CAGRA puede podar el grafo de forma eficiente en las GPU, lo que reduce la sobrecarga de almacenamiento en un 40-50% al tiempo que preserva la precisión de la búsqueda y mejora la velocidad de recorrido durante la ejecución de la consulta.
GPU_CAGRA en Milvus: ¿en qué se diferencia?
Aunque las GPU ofrecen importantes ventajas de rendimiento para la construcción de grafos, los entornos de producción se enfrentan a un reto práctico: Los recursos de la GPU son mucho más caros y limitados que los de la CPU. Si tanto la construcción de índices como la ejecución de consultas dependen exclusivamente de las GPU, surgen rápidamente varios problemas operativos:
Baja utilización de los recursos: El tráfico de consultas suele ser irregular y en ráfagas, lo que deja las GPU inactivas durante largos periodos de tiempo y desperdicia una capacidad de cálculo muy cara.
Alto coste de implantación: La asignación de una GPU a cada instancia de consulta aumenta los costes de hardware, a pesar de que la mayoría de las consultas no aprovechan todo el rendimiento de la GPU.
Escalabilidad limitada: El número de GPU disponibles limita directamente el número de réplicas de servicio que se pueden ejecutar, lo que restringe la capacidad de escalar en función de la demanda.
Menor flexibilidad: Cuando tanto la creación de índices como las consultas dependen de las GPU, el sistema queda vinculado a la disponibilidad de GPU y no puede cambiar fácilmente las cargas de trabajo a las CPU.
Para hacer frente a estas limitaciones, Milvus 2.6.1 introduce un modo de despliegue flexible para el índice GPU_CAGRA a través del parámetro adapt_for_cpu. Este modo permite un flujo de trabajo híbrido: CAGRA utiliza la GPU para construir un índice de grafos de alta calidad, mientras que la ejecución de las consultas se ejecuta en la CPU, normalmente utilizando HNSW como algoritmo de búsqueda.
De este modo, las GPU se utilizan donde más valor aportan (en la construcción de índices rápidos y precisos), mientras que las CPU gestionan las consultas a gran escala de forma mucho más rentable y escalable.
Como resultado, este enfoque híbrido es especialmente adecuado para cargas de trabajo en las que:
Las actualizaciones de datos son poco frecuentes, por lo que las reconstrucciones de índices son poco frecuentes.
Elvolumen de consultas es elevado, por lo que se requieren muchas réplicas de bajo coste.
La sensibilidad a los costes es alta y el uso de la GPU debe controlarse estrictamente.
Entendiendo adapt_for_cpu
En Milvus, el parámetro adapt_for_cpu controla cómo se serializa un índice CAGRA en el disco durante la construcción del índice y cómo se deserializa en la memoria en el momento de la carga. Cambiando este parámetro en el momento de la construcción y en el momento de la carga, Milvus puede cambiar de forma flexible entre la construcción del índice basada en la GPU y la ejecución de la consulta basada en la CPU.
Las diferentes combinaciones de adapt_for_cpu en tiempo de compilación y carga dan lugar a cuatro modos de ejecución, cada uno diseñado para un escenario operativo específico.
Tiempo de creación (adapt_for_cpu) | Tiempo de carga (adapt_for_cpu) | Lógica de ejecución | Escenario recomendado |
|---|---|---|---|
| verdadero | verdadero | Construir con GPU_CAGRA → serializar como HNSW → deserializar como HNSW → consulta a la CPU | Cargas de trabajo sensibles a los costes; servicio de consultas a gran escala |
| verdadero | falso | Construir con GPU_CAGRA → serializar como HNSW → deserializar como HNSW → consulta a la CPU | Las consultas subsiguientes vuelven a la CPU cuando se producen desajustes en los parámetros |
| falso | true | Construir con GPU_CAGRA → serializar como CAGRA → deserializar como HNSW → consulta a la CPU | Mantener el índice CAGRA original para almacenamiento mientras se habilita una búsqueda temporal en CPU |
| falso | falso | Construir con GPU_CAGRA → serializar como CAGRA → deserializar como CAGRA → consulta GPU | Cargas de trabajo de rendimiento crítico en las que el coste es secundario |
Nota: El mecanismo adapt_for_cpu solo admite la conversión unidireccional. Un índice CAGRA puede convertirse en HNSW porque la estructura del grafo CAGRA conserva todas las relaciones de vecindad que necesita HNSW. Sin embargo, un índice HNSW no puede convertirse de nuevo a CAGRA, ya que carece de la información estructural adicional necesaria para la consulta basada en GPU. En consecuencia, la configuración del tiempo de compilación debe seleccionarse cuidadosamente, teniendo en cuenta los requisitos de despliegue y consulta a largo plazo.
Puesta a prueba de GPU_CAGRA
Para evaluar la eficacia del modelo de ejecución híbrido (que utiliza la GPU para la construcción de índices y la CPU para la ejecución de consultas), hemos llevado a cabo una serie de experimentos controlados en un entorno estandarizado. La evaluación se centra en tres dimensiones: rendimiento de la construcción de índices, rendimiento de las consultas y precisión de la recuperación.
Configuración experimental
Los experimentos se realizaron en hardware estándar ampliamente adoptado por la industria para garantizar que los resultados sigan siendo fiables y ampliamente aplicables.
CPU: Procesador MD EPYC 7R13 (16 cpus)
GPU: NVIDIA L4
1. Rendimiento de la construcción de índices
Comparamos CAGRA construido en la GPU con HNSW construido en la CPU, bajo el mismo grado de gráfico objetivo de 64.
Principales resultados
CAGRA en la GPU genera índices entre 12 y 15 veces más rápido que HNSW en la CPU. Tanto en Cohere1M como en Gist1M, CAGRA en la GPU supera significativamente a HNSW en la CPU, lo que pone de manifiesto la eficiencia del paralelismo en la GPU durante la construcción de grafos.
El tiempo de construcción aumenta linealmente con las iteraciones de NN-Descent. A medida que aumenta el número de iteraciones, el tiempo de construcción crece de forma casi lineal, lo que refleja la naturaleza de refinamiento iterativo de NN-Descent y proporciona un equilibrio predecible entre el coste de construcción y la calidad del gráfico.
2. Rendimiento de la consulta
En este experimento, el gráfico CAGRA se construye una vez en la GPU y luego se consulta utilizando dos rutas de ejecución diferentes:
Consultaen la CPU: el índice se deserializa a formato HNSW y se busca en la CPU.
Consultaen la GPU: la búsqueda se ejecuta directamente en el grafo CAGRA utilizando un recorrido basado en la GPU.
Principales resultados
El rendimiento de la búsqueda en la GPU es entre 5 y 6 veces superior al de la CPU. Tanto en Cohere1M como en Gist1M, el traversal basado en la GPU proporciona QPS sustancialmente superiores, lo que pone de manifiesto la eficiencia de la navegación paralela de grafos en las GPU.
La recuperación aumenta con las iteraciones de NN-Descent y luego se estabiliza. A medida que aumenta el número de iteraciones, la recuperación mejora tanto en la CPU como en la GPU. Sin embargo, a partir de cierto punto, las iteraciones adicionales producen ganancias decrecientes, lo que indica que la calidad del grafo ha convergido en gran medida.
3. Precisión de recuperación
En este experimento, tanto CAGRA como HNSW se consultan en la CPU para comparar la recuperación en condiciones de consulta idénticas.
Principales resultados
CAGRA consigue una mayor recuperación que HNSW en ambos conjuntos de datos, lo que demuestra que incluso cuando un índice CAGRA se construye en la GPU y se deserializa para la búsqueda en la CPU, la calidad del grafo se mantiene.
Próximos pasos: Ampliación de la construcción de índices con Vamana
El enfoque híbrido GPU-CPU de Milvus ofrece una solución práctica y rentable para las actuales cargas de trabajo de búsqueda vectorial a gran escala. Al construir gráficos CAGRA de alta calidad en las GPU y servir las consultas en las CPU, combina la construcción rápida de índices con una ejecución de consultas escalable y asequible, lo que resulta especialmenteadecuado para cargas de trabajo con actualizaciones poco frecuentes, grandes volúmenes de consultas y estrictas restricciones de costes.
A escalas aún mayores -decenaso cientos de miles de millones de vectores-, la propia construcción de índices se convierte en el cuello de botella. Cuando el conjunto completo de datos ya no cabe en la memoria de la GPU, la industria suele recurrir a métodos de construcción de grafos basados en inserciones como Vamana. En lugar de construir el gráfico de una sola vez, Vamana procesa los datos por lotes, insertando nuevos vectores de forma incremental mientras mantiene la conectividad global.
Su proceso de construcción sigue tres etapas clave
1. 1.Crecimiento geométrico por lotes: se empieza con lotes pequeños para formar un esqueleto del grafo, luego se aumenta el tamaño de los lotes para maximizar el paralelismo y, por último, se utilizan lotes grandes para perfeccionar los detalles.
2. 2.Inserción codiciosa: cada nuevo nodo se inserta navegando desde un punto de entrada central, refinando iterativamente su conjunto de vecinos.
3. 3.Actualización de aristas hacia atrás: se añaden conexiones inversas para preservar la simetría y garantizar una navegación eficaz por el grafo.
La poda se integra directamente en el proceso de construcción mediante el criterio α-RNG: si un vecino candidato v ya está cubierto por un vecino existente p′ (es decir, d(p′, v) < α × d(p, v)), entonces v se poda. El parámetro α permite un control preciso de la dispersión y la precisión. La aceleración en la GPU se consigue mediante el paralelismo en lotes y el escalado geométrico de lotes, con lo que se logra un equilibrio entre la calidad del índice y el rendimiento.
Juntas, estas técnicas permiten a los equipos gestionar el rápido crecimiento de los datos y las actualizaciones de índices a gran escala sin toparse con las limitaciones de memoria de la GPU.
El equipo de Milvus está desarrollando activamente la compatibilidad con Vamana, con un lanzamiento previsto para la primera mitad de 2026. Permanezca atento.
¿Tiene alguna pregunta o desea profundizar en alguna función de la última versión de Milvus? Únase a nuestro canal Discord o presente cuestiones en GitHub. También puede reservar una sesión individual de 20 minutos para obtener información, orientación y respuestas a sus preguntas a través de Milvus Office Hours.
Más información sobre las características de Milvus 2.6
Presentación de Milvus 2.6: Búsqueda vectorial asequible a escala de miles de millones
JSON Shredding en Milvus: Filtrado JSON 88,9 veces más rápido con flexibilidad
MinHash LSH en Milvus: El arma secreta para combatir los duplicados en los datos de formación LLM
Llevar la compresión vectorial al extremo: cómo Milvus sirve 3 veces más consultas con RaBitQ
Los puntos de referencia mienten: las bases de datos vectoriales merecen una prueba real
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



