• Acerca de Milvus
  • Comenzar
  • Conceptos
  • Guía del usuario
    • Colecciones
    • Esquema y campos de datos
    • Insertar y eliminar
    • Índices
      • Índices de vectores flotantes
      • Índices vectoriales binarios
      • Índices de vectores dispersos
      • Índices escalares
      • Índices habilitados para GPU
    • Buscar en
    • Embeddings y reordenación
    • Optimización del almacenamiento
  • Importación de datos
  • Herramientas de IA
  • Guía de administración
  • Herramientas
  • Integraciones
  • Tutoriales
  • Preguntas frecuentes
  • API Reference

Explicación de los índices

Un índice es una estructura adicional construida sobre los datos. Su estructura interna depende del algoritmo de búsqueda aproximada por vecino más próximo que se utilice. Un índice acelera la búsqueda, pero requiere más tiempo de preprocesamiento, espacio y memoria RAM durante la búsqueda. Además, el uso de un índice suele reducir la tasa de recuperación (aunque el efecto es insignificante, sigue siendo importante). Por lo tanto, este artículo explica cómo minimizar los costes del uso de un índice y maximizar sus beneficios.

Visión general

En Milvus, los índices son específicos de los campos, y los tipos de índice aplicables varían en función de los tipos de datos de los campos de destino. Como base de datos vectorial profesional, Milvus se centra en mejorar tanto el rendimiento de las búsquedas vectoriales como el filtrado escalar, razón por la cual ofrece varios tipos de índice.

La siguiente tabla muestra la relación entre los tipos de datos de campo y los tipos de índice aplicables.

Tipo de datos de campo

Tipos de índice aplicables

  • FLOAT_VECTOR

  • VECTOR_FLOAT16

  • BFLOAT16_VECTOR

  • VECTOR_INT8

  • FLAT

  • IVF_FLAT

  • IVF_SQ8

  • IVF_PQ

  • IVF_RABITQ

  • HNSW

  • HNSW_SQ

  • HNSW_PQ

  • HNSW_PRQ

  • DISKANN

  • SCANN

  • AISAQ

  • GPU_CAGRA

  • GPU_IVF_FLAT

  • GPU_IVF_PQ

  • GPU_BRUTE_FORCE

BINARY_VECTOR

  • BIN_FLAT

  • BIN_IVF_FLAT

  • MINHASH_LSH

SPARSE_FLOAT_VECTOR

SPARSE_INVERTED_INDEX

VARCHAR

  • INVERTED (Recomendado)

  • BITMAP

  • Trie

BOOL

  • BITMAP (Recomendado)

  • INVERTIDO

  • INT8

  • INT16

  • INT32

  • INT64

  • INVERTIDO

  • STL_SORT

  • FLOAT

  • DOUBLE

INVERTIDO

ARRAY (elementos de tipo BOOL, INT8/16/32/64 y VARCHAR)

BITMAP (recomendado)

ARRAY (elementos de tipo BOOL, INT8/16/32/64, FLOAT, DOUBLE y VARCHAR)

INVERTIDO

JSON

INVERTIDO

Este artículo se centra en cómo seleccionar los índices vectoriales adecuados. Para los campos escalares, siempre se puede utilizar el tipo de índice recomendado.

La selección de un tipo de índice apropiado para una búsqueda vectorial puede afectar significativamente al rendimiento y al uso de recursos. Al elegir un tipo de índice para un campo vectorial, es esencial tener en cuenta varios factores, como la estructura de datos subyacente, el uso de memoria y los requisitos de rendimiento.

Anatomía de un índice vectorial

Como se muestra en el siguiente diagrama, un tipo de índice en Milvus consta de tres componentes principales, a saber, estructura de datos, cuantificación y refinador. La cuantificación y el refinador son opcionales, pero se utilizan ampliamente debido a un importante equilibrio entre beneficios y costes.

Vector Index Anatomy Anatomía del índice vectorial

Durante la creación del índice, Milvus combina la estructura de datos y el método de cuantificación elegidos para determinar un índice de expansión óptimo. En el momento de la consulta, el sistema recupera topK × expansion rate vectores candidatos, aplica el refinador para recalcular las distancias con mayor precisión y, por último, devuelve los resultados más exactos topK. Este enfoque híbrido equilibra velocidad y precisión al restringir el refinamiento, que consume muchos recursos, a un subconjunto filtrado de candidatos.

Estructura de datos

La estructura de datos constituye la base del índice. Los tipos más comunes son:

  • Archivo invertido (IVF)

    Los tipos de índice de la serie IVF permiten a Milvus agrupar vectores en cubos mediante la partición basada en centroides. Generalmente es seguro asumir que todos los vectores en un cubo probablemente estén cerca del vector de consulta si el centroide del cubo está cerca del vector de consulta. Basándose en esta premisa, Milvus explora únicamente las incrustaciones de vectores en aquellos cubos cuyos centroides están cerca del vector de consulta, en lugar de examinar todo el conjunto de datos. Esta estrategia reduce los costes computacionales al tiempo que mantiene una precisión aceptable.

    Este tipo de estructura de datos de índice es ideal para conjuntos de datos a gran escala que requieren un rendimiento rápido.

  • Estructura gráfica

    Una estructura de datos basada en grafos para la búsqueda vectorial, como Hierarchical Navigable Small World(HNSW), construye un grafo en capas en el que cada vector se conecta con sus vecinos más cercanos. Las consultas recorren esta jerarquía, partiendo de capas superiores gruesas y pasando por capas inferiores, lo que permite una complejidad de búsqueda eficiente en tiempo logarítmico.

    Este tipo de estructura de datos de índices destaca en espacios de gran dimensión y en escenarios que exigen consultas de baja latencia.

Cuantificación

La cuantificación reduce la huella de memoria y los costes computacionales mediante una representación más gruesa:

  • La cuantificación escalar (por ejemplo, SQ8) permite a Milvus comprimir cada dimensión vectorial en un único byte (8 bits), lo que reduce el uso de memoria en un 75% en comparación con los datos flotantes de 32 bits, al tiempo que se mantiene una precisión razonable.

  • La cuantificación de productos(PQ) permite a Milvus dividir los vectores en subvectores y codificarlos mediante la agrupación basada en libros de códigos. De este modo se consiguen mayores ratios de compresión (por ejemplo, de 4 a 32 veces) a costa de una reducción marginal de la recuperación, lo que lo hace adecuado para entornos con limitaciones de memoria.

Refinador

La cuantificación tiene pérdidas intrínsecas. Para mantener la tasa de recuperación, la cuantización produce sistemáticamente más candidatos top-K de los necesarios, lo que permite a los refinadores utilizar una mayor precisión para seleccionar los resultados top-K de entre estos candidatos, mejorando la tasa de recuperación.

Por ejemplo, el refinador FP32 opera sobre los candidatos a resultados de búsqueda devueltos por la cuantización recalculando las distancias utilizando la precisión FP32 en lugar de los valores cuantizados.

Esto es fundamental para las aplicaciones que requieren un equilibrio entre la eficiencia de la búsqueda y la precisión, como la búsqueda semántica o los sistemas de recomendación, en los que pequeñas variaciones en la distancia afectan significativamente a la calidad de los resultados.

Resumen

Esta arquitectura escalonada (filtrado grueso mediante estructuras de datos, cálculo eficiente mediante cuantificación y ajuste de precisión mediante refinamiento) permite a Milvus optimizar el equilibrio entre precisión y rendimiento de forma adaptativa.

Compromisos de rendimiento

Al evaluar el rendimiento, es fundamental equilibrar el tiempo de compilación, las consultas por segundo (QPS) y la tasa de recuperación. Las reglas generales son las siguientes:

  • Los tipos de índice basados en grafos suelen superar a las variantes IVF en términos de QPS.

  • Lasvariantes IVF encajan especialmente en los escenarios con un topK grande (por ejemplo, más de 2.000).

  • PQ suele ofrecer un mejor índice de recuperación con índices de compresión similares en comparación con SQ, aunque este último proporciona un rendimiento más rápido.

  • El uso de discos duros para parte del índice (como en DiskANN) ayuda a gestionar grandes conjuntos de datos, pero también introduce posibles cuellos de botella de IOPS.

Capacidad

La capacidad normalmente implica la relación entre el tamaño de los datos y la RAM disponible. Cuando hablemos de capacidad, tenga en cuenta lo siguiente:

  • Si una cuarta parte de sus datos brutos cabe en la memoria, considere DiskANN por su latencia estable.

  • Si todos sus datos brutos caben en memoria, considere los tipos de índice basados en memoria y mmap.

  • Puede utilizar los tipos de índice aplicados a la cuantificación y mmap para intercambiar precisión por la máxima capacidad.

El mmap no es siempre la solución. Cuando la mayoría de los datos están en disco, DiskANN proporciona una mejor latencia.

Recall

El recall suele implicar el ratio de filtrado, que se refiere a los datos que se filtran antes de las búsquedas. Cuando se trata de recall, hay que tener en cuenta lo siguiente:

  • Si la relación de filtrado es inferior al 85%, los tipos de índice basados en gráficos superan a las variantes IVF.

  • Si el porcentaje de filtrado está entre el 85% y el 95%, utilice variantes IVF.

  • Si el ratio de filtrado es superior al 98%, utilice la fuerza bruta (FLAT) para obtener los resultados de búsqueda más precisos.

Los puntos anteriores no siempre son correctos. Se recomienda ajustar la recuperación con distintos tipos de índice para determinar qué tipo de índice funciona mejor.

Rendimiento

El rendimiento de una búsqueda suele implicar el top-K, que se refiere al número de registros que devuelve la búsqueda. En cuanto al rendimiento, hay que tener en cuenta lo siguiente:

  • Para una búsqueda con un top-K pequeño (por ejemplo, 2.000) que requiera un alto índice de recuperación, los tipos de índice basados en grafos superan a las variantes IVF.

  • Para una búsqueda con un top-K grande (comparado con el número total de incrustaciones vectoriales), las variantes IVF son una mejor opción que los tipos de índice basados en grafos.

  • Para una búsqueda con un top-K de tamaño medio y un ratio de filtrado alto, las variantes FIV son mejores opciones.

Matriz de decisión: Elección del tipo de índice más adecuado

La siguiente tabla es una matriz de decisión que le servirá de referencia a la hora de elegir un tipo de índice adecuado.

Escenario

Índice recomendado

Notas

Los datos brutos caben en la memoria

HNSW, IVF + Refinamiento

Utilizar HNSW para bajak/alta recuperación.

Datos brutos en disco, SSD

DiskANN

Óptimo para consultas sensibles a la latencia.

Datos brutos en disco, RAM limitada

IVFPQ/SQ + mmap

Equilibra el acceso a la memoria y al disco.

Alto ratio de filtrado (>95%)

Fuerza bruta (FLAT)

Evita la sobrecarga del índice para conjuntos de candidatos diminutos.

k grande (≥1% del conjunto de datos)

FIV

La poda de grupos reduce los cálculos.

Tasa de recuperación extremadamente alta (>99%)

Fuerza bruta (FLAT) + GPU

--

Estimación del consumo de memoria

Esta sección se centra en el cálculo del consumo de memoria de un tipo de índice específico e incluye muchos detalles técnicos. Puede saltarse esta sección sin problemas si no se ajusta a sus intereses.

El consumo de memoria de un índice está influido por su estructura de datos, la tasa de compresión a través de la cuantización y el refinador en uso. En términos generales, los índices basados en grafos suelen tener un mayor consumo de memoria debido a la estructura del grafo (por ejemplo, HNSW), lo que suele implicar una notable sobrecarga de espacio por vector. Por el contrario, el IVF y sus variantes son más eficientes en términos de memoria, ya que la sobrecarga de espacio por vector es menor. Sin embargo, técnicas avanzadas como DiskANN permiten que partes del índice, como el gráfico o el refinador, residan en disco, lo que reduce la carga de memoria al tiempo que mantiene el rendimiento.

En concreto, el uso de memoria de un índice puede calcularse de la siguiente manera:

Uso de memoria del índice IVF

Los índices IVF equilibran la eficiencia de la memoria con el rendimiento de la búsqueda particionando los datos en clusters. A continuación se muestra un desglose de la memoria utilizada por 1 millón de vectores de 128 dimensiones indexados mediante variantes IVF.

  1. Calcular la memoria utilizada por los centroides.

    Los tipos de índice de la serie IVF permiten a Milvus agrupar vectores en cubos utilizando particiones basadas en centroides. Cada centroide se incluye en el índice en la incrustación de vectores sin procesar. Cuando se dividen los vectores en 2.000 clusters, el uso de memoria se puede calcular de la siguiente manera:

    2,000 clusters × 128 dimensions × 4 bytes = 1.0 MB
    
  2. Calcular la memoria utilizada por las asignaciones de cluster.

    Cada incrustación vectorial se asigna a un cluster y se almacena como IDs enteros. Para 2.000 clusters, basta con un número entero de 2 bytes. El uso de memoria puede calcularse del siguiente modo:

    1,000,000 vectors × 2 bytes = 2.0 MB
    
  3. Calcular la compresión causada por la cuantización.

    Las variantes de IVF suelen utilizar PQ y SQ8, y el uso de memoria puede calcularse del siguiente modo:

    • Utilizando PQ con 8 subcuantizadores

      1,000,000 vectors × 8 bytes = 8.0 MB
      
    • Utilización de SQ8

      1,000,000 vectors × 128 dimensions × 1 byte = 128 MB 
      

    La siguiente tabla muestra el uso de memoria estimado con diferentes configuraciones:

    Configuración

    Estimación de memoria

    Memoria total

    IVF-PQ (sin refinamiento)

    1,0 MB + 2,0 MB + 8,0 MB

    11,0 MB

    IVF-PQ + 10% refinamiento bruto

    1,0 MB + 2,0 MB + 8,0 MB + 51,2 MB

    62,2 MB

    IVF-SQ8 (sin refinamiento)

    1,0 MB + 2,0 MB + 128 MB

    131,0 MB

    IVF-FLAT (vectores completos sin refinar)

    1,0 MB + 2,0 MB + 512 MB

    515,0 MB

  4. Calcular la sobrecarga de refinamiento.

    Las variantes de FIV suelen combinarse con un refinador para volver a clasificar a los candidatos. Para una búsqueda que recupere los 10 primeros resultados con un índice de expansión de 5, la sobrecarga de refinamiento puede calcularse del siguiente modo:

    10 (topK) x 5 (expansion rate) = 50 candidates
    50 candidates x 128 dimensions x 4 bytes = 25.6 KB
    

Uso de memoria de índices basados en gráficos

Los índices basados en grafos, como el HNSW, requieren una cantidad significativa de memoria para almacenar tanto la estructura del grafo como las incrustaciones de vectores sin procesar. A continuación se muestra un desglose detallado de la memoria consumida por 1 millón de vectores de 128 dimensiones indexados mediante el tipo de índice HNSW.

  1. Calcular la memoria utilizada por la estructura gráfica.

    Cada vector en HNSW mantiene conexiones con sus vecinos. Con un grado de grafo (aristas por nodo) de 32, la memoria consumida puede calcularse del siguiente modo:

    1,000,000 vectors × 32 links × 4 bytes (for 32-bit integer storage) = 128 MB  
    
  2. Calcular la memoria utilizada por los vectores sin comprimir.

    La memoria consumida por el almacenamiento de vectores FP32 sin comprimir se puede calcular de la siguiente manera:

    1,000,000 vectors × 128 dimensions × 4 bytes = 512 MB  
    

    Cuando se utiliza HNSW para indexar el millón de incrustaciones vectoriales de 128 dimensiones, la memoria total en uso sería de 128 MB (gráfico) + 512 MB (vectores) = 640 MB.

  3. Calcule la compresión causada por la cuantización.

    La cuantización reduce el tamaño de los vectores. Por ejemplo, el uso de PQ con 8 subcuantizadores (8 bytes por vector) produce una compresión drástica. La memoria consumida por las incrustaciones vectoriales comprimidas puede calcularse del siguiente modo:

    1,000,000 vectors × 8 bytes = 8 MB
    

    De este modo se consigue una tasa de compresión 64 veces superior a la de las incrustaciones vectoriales en bruto, y la memoria total utilizada por el tipo de índice HNSWPQ sería de 128 MB (gráfico) + 8 MB (vector comprimido) = 136 MB.

  4. Calcular la sobrecarga de refinamiento.

    El refinamiento, como la reclasificación con vectores sin procesar, carga temporalmente datos de alta precisión en la memoria. Para una búsqueda que recupere los 10 primeros resultados con una tasa de expansión de 5, la sobrecarga de refinamiento puede calcularse del siguiente modo:

    10 (topK) x 5 (expansion rate) = 50 candidates
    50 candidates x 128 dimensions x 4 bytes = 25.6 KB
    

Otras consideraciones

Mientras que los índices IVF y basados en gráficos optimizan el uso de la memoria mediante la cuantificación, los archivos mapeados en memoria (mmap) y DiskANN abordan situaciones en las que los conjuntos de datos superan la memoria de acceso aleatorio (RAM) disponible.

DiskANN

DiskANN es un índice basado en el grafo Vamana que conecta puntos de datos para una navegación eficiente durante la búsqueda, al tiempo que aplica PQ para reducir el tamaño de los vectores y permitir un rápido cálculo aproximado de la distancia entre vectores.

El grafo Vamana se almacena en disco, lo que permite a DiskANN manejar grandes conjuntos de datos que, de otro modo, serían demasiado grandes para caber en memoria. Esto es especialmente útil para conjuntos de datos de miles de millones de puntos.

Archivos mapeados en memoria (mmap)

El mapeo de memoria (Mmap) permite el acceso directo en memoria a archivos de gran tamaño en disco, lo que permite a Milvus almacenar índices y datos tanto en memoria como en discos duros. Este enfoque ayuda a optimizar las operaciones de E/S reduciendo la sobrecarga de las llamadas de E/S en función de la frecuencia de acceso, ampliando así la capacidad de almacenamiento de las colecciones sin afectar significativamente al rendimiento de la búsqueda.

En concreto, puede configurar Milvus para que mapee en memoria los datos sin procesar de determinados campos en lugar de cargarlos completamente en memoria. De este modo, puede obtener acceso directo a la memoria de los campos sin preocuparse por los problemas de memoria y ampliar la capacidad de la colección.