AISAQCompatible with Milvus 2.6.4+

AISAQ es un índice vectorial basado en disco que amplía DISKANN para manejar conjuntos de datos a escala de miles de millones con una huella DRAM mínima.

A diferencia de DISKANN, que mantiene los vectores comprimidos en memoria, AISAQ está diseñado con una "arquitectura DRAM casi nula", lo que significa mantener todas las estructuras de datos en SSD.

AISAQ permite ejecutar bases de datos a escala ultraelevada utilizando servidores estándar, al tiempo que ofrece modos de funcionamiento para equilibrar el rendimiento y los costes de almacenamiento.

Cómo funciona AISAQ

El diagrama anterior compara las disposiciones de almacenamiento de DISKANN, AISAQ-Performance y AISAQ-Scale, mostrando cómo se distribuyen los datos (vectores en bruto, listas de aristas y códigos PQ) entre la RAM y el disco.

Aisaq Vs Diskann Aisaq vs Diskann

Fundación: Resumen de DISKANN

En DISKANN, los vectores en bruto y las listas de aristas se almacenan en disco, mientras que los vectores comprimidos PQ se guardan en memoria (DRAM).

Cuando DISKANN llega a un nodo (por ejemplo, el vector 0):

  • Carga el vector en bruto(raw_vector_0) y su lista de aristas(edgelist_0) desde el disco.

  • La lista de aristas indica qué vecinos visitar a continuación (los nodos 2, 3 y 5 en este ejemplo).

  • El vector en bruto se utiliza para calcular la distancia exacta al vector de consulta para la clasificación.

  • Los datos PQ en memoria se utilizan para filtrar la distancia aproximada y guiar el siguiente recorrido.

Dado que los datos PQ ya están almacenados en caché en la DRAM, cada visita a un nodo sólo requiere una E/S de disco, con lo que se consigue una alta velocidad de consulta con un uso moderado de la memoria.

Para una explicación detallada de estos componentes y parámetros, consulte DISKANN.

Modos de funcionamiento de AISAQ

AISAQ ofrece dos modos de funcionamiento para abordar dos casos de uso distintos:

Modo de rendimiento: optimizado para aplicaciones que requieren baja latencia y alto rendimiento a escala, como la búsqueda semántica en línea.

Modo de escala: optimizado para aplicaciones con restricciones de latencia más relajadas, como la búsqueda semántica RAG y fuera de línea, al tiempo que permite una expansión rentable de los conjuntos de datos a escala ultraalta.

Modo AISAQ-performance

El modo AISAQ-performance consigue una "huella DRAM casi nula" trasladando los datos PQ de la memoria al disco, al tiempo que mantiene unos IOPS bajos gracias a la colocación y redundancia de los datos.

  • El vector bruto de cada nodo, la lista de bordes y los datos PQ de sus vecinos se almacenan juntos en el disco.

  • Esta disposición garantiza que visitar un nodo (por ejemplo, el vector 0) sólo requiera una única E/S de disco.

  • Dado que los datos PQ se almacenan de forma redundante cerca de varios nodos, el tamaño del archivo de índice aumenta significativamente, consumiendo más espacio en disco.

Modo AISAQ-scale

AISAQ-scale se centra en reducir el uso de espacio en disco al tiempo que satisface los requisitos de rendimiento de sus aplicaciones objetivo.

En este modo

  • Los datos PQ se almacenan por separado en el disco, sin redundancia.

  • Este diseño minimiza el tamaño del índice, pero conlleva más operaciones de E/S durante el recorrido del gráfico.

  • Para mitigar la sobrecarga de IOPS, AISAQ introduce dos optimizaciones:

    • Un algoritmo de reorganización que ordena los vectores PQ por prioridad para mejorar la localización de los datos.

    • Una caché PQ en DRAM (pq_read_page_cache_size) que almacena en caché los datos PQ a los que se accede con frecuencia.

Ejemplo de configuración

# milvus.yaml
knowhere:
  AISAQ:
    build:
      max_degree: 56 # Controls the maximum number of connections (edges) each data point can have in the Vamana graph
      search_list_size: 100 # During index construction, this parameter defines the size of the candidate pool used when searching for the nearest neighbors for each node. For every node being added to the graph, the algorithm maintains a list of the search_list_size best candidates found so far. The search for neighbors stops when this list can no longer be improved. From this final candidate pool, the top max_degree nodes are selected to form the final edges
      inline_pq: -1 # Number of PQ vectors stored inline per Index node (read when node is accessed, to reduce IO)
      rearrange: true # Re-arrange the PQ vectors data structure to improve data locality and reduce disk accesses during search (ignored in performance mode)
      num_entry_points: 100 # Number of candidate entry points to optimize search entry-point selection
      pq_code_budget_gb_ratio: 0.125 # Controls the size of the PQ codes (compressed representations of data points) compared to the size of the uncompressed data
      disk_pq_code_budget_gb_ratio: 0.25 # Controls the size of the PQ codes of the high precision vectors stored in the index (used for re-ranking), compared to the size of the uncompressed data
      pq_cache_size: 0 # PQ vectors cache size in DRAM (bytes). The PQ vectors cache is loaded during Index load and used during search to reduce IOs (ignored in performance mode)
      search_cache_budget_gb_ratio: 0 # Controls the amount of DRAM to be used for caching frequently accessed index nodes. This cache is loaded during index load and used during search to reduce IOs
    search:
      search_list: 16 # During a search operation, this parameter determines the size of the candidate pool that the algorithm maintains as it traverses the graph. A larger value increases the chances of finding the true nearest neighbors (higher recall) but also increases search latency
      beamwidth: 8 # Controls the degree of parallelism during search by determining the maximum number of parallel disk I/O requests to read the index nodes
      vectors_beamwidth: 1 # Controls the degree of parallelism during search by determining the maximum number of parallel disk I/O requests to read groups of neighboring PQ vectors (ignored in performance mode)
      pq_read_page_cache_size: 5242880 (5MiB) # PQ read cache size in DRAM per search thread (bytes). It caches frequently accessed data pages containing PQ vectors (ignored in performance mode and applicable only when rearrange is true). The PQ read cache memory is reused across all AISAQ segments

Parámetros de AISAQ

AISAQ hereda algunos parámetros de DISKANN - max_degree, search_list_size, y pq_code_budget_gb_ratio.

Parámetros de creación de índices

Estos parámetros influyen en cómo se construye el índice AISAQ. Su ajuste puede afectar al tamaño del índice, al tiempo de construcción y a la calidad de la búsqueda.

Parámetro

Descripción

Rango de valores

Sugerencia de ajuste

max_degree

Controla el número máximo de conexiones (aristas) que puede tener cada punto de datos en el gráfico Vamana.

Tipo: Entero

Rango: [1, 512]

Valor por defecto: 56

Los valores más altos crean gráficos más densos, aumentando potencialmente la recuperación (encontrando resultados más relevantes) pero también incrementando el uso de memoria y el tiempo de construcción. En la mayoría de los casos, se recomienda establecer un valor dentro de este intervalo: [10, 100].

search_list_size

Durante la construcción del índice, este parámetro define el tamaño del grupo de candidatos utilizado cuando se buscan los vecinos más cercanos para cada nodo. Para cada nodo que se añade al grafo, el algoritmo mantiene una lista de los mejores candidatos search_list_size encontrados hasta el momento. La búsqueda de vecinos se detiene cuando esta lista ya no puede mejorarse. De esta lista final de candidatos, se seleccionan los nodos con mayor grado_máximo para formar las aristas finales.

Tipo: Entero

Rango: [1, 512]

Valor por defecto: 100

Un tamaño mayor de search_list_size aumenta la probabilidad de encontrar los verdaderos vecinos más cercanos para cada nodo, lo que puede conducir a un gráfico de mayor calidad y un mejor rendimiento de búsqueda (recall). Sin embargo, esto tiene el coste de un tiempo de construcción del índice significativamente mayor. Debe establecerse siempre a un valor mayor o igual que max_degree.

inline_pq

Número de vectores PQ almacenados en línea por nodo del índice (se leen cuando se accede al nodo, para reducir el IO)

Tipo: Entero

Rango: [0, grado_máx]

Valor por defecto: -1

Los valores más altos de inline_pq mejoran el rendimiento pero aumentan el espacio en disco.

Establezca inline_pq=0 para AISAQ en modo de escala.

Establezca inline_pq=-1 para rellenar automáticamente cualquier espacio no utilizado en el índice con vectores PQ para una mayor optimización de AISAQ en modo de escala.

Establezca inline_pq=grado_máx para AISAQ en modo de rendimiento.

inline_pq Los ajustes entre 0 y max_degree permiten un equilibrio ajustable entre rendimiento y consumo de espacio en disco.

rearrange

Reorganizar la estructura de datos de los vectores PQ para mejorar la localidad de los datos y reducir los accesos al disco durante la búsqueda (se ignora en el modo de rendimiento).

Tipo: Booleano

Rango: [true, false]

Valor por defecto: true

Cuando es true, reduce las IOs durante la búsqueda con un incremento menor en memoria y en el tiempo de construcción del índice.

num_entry_points

Número de puntos de entrada candidatos para optimizar la selección del punto de entrada de la búsqueda.

Tipo: Entero

Rango: [0, 1000]

Valor por defecto: 100

Valores altos pueden reducir el tiempo de búsqueda iniciando la búsqueda desde un punto de entrada más cercano.

Establezca valores más altos para segmentos grandes (por ejemplo, para vectores de 10M y superiores utilice el valor 1000).

pq_code_budget_gb_ratio

Controla el tamaño de los códigos PQ (representaciones comprimidas de los puntos de datos) en comparación con el tamaño de los datos sin comprimir.

Tipo: Float

Rango: (0.0, 0.25]

Valor por defecto: 0.125

Una relación más alta conduce a resultados de búsqueda más precisos, almacenando efectivamente más información sobre los vectores originales, pero aumenta la complejidad computacional durante la búsqueda.

En la mayoría de los casos, se recomienda establecer un valor dentro de este rango: (0,0417, 0,25].

disk_pq_code_budget_gb_ratio

Controla el tamaño de los códigos PQ de los vectores de alta precisión almacenados en el índice (utilizados para la reclasificación), en comparación con el tamaño de los datos sin comprimir.

Tipo: Float

Rango: [0, 0.25]

Valor por defecto: 0.25

Con el valor por defecto de 0,25, los vectores se cuantizarán al 25% de su tamaño original (compresión 4×), reduciendo el espacio en disco con un impacto relativamente mínimo en la precisión.

Establezca el valor 0 para almacenar los vectores de precisión completa en el índice del disco para volver a clasificarlos. Un valor mayor ofrece una mayor tasa de recuperación, pero aumenta el uso de disco.

pq_cache_size

Tamaño de la caché de vectores PQ en DRAM (bytes). La caché de vectores PQ se carga durante la carga del índice y se utiliza durante la búsqueda para reducir las IO (se ignora en el modo de rendimiento).

Tipo: Entero

Rango: [0, 1073741824]

Valor por defecto: 0

Una caché más grande mejora el rendimiento de la consulta pero aumenta el uso de DRAM.

search_cache_budget_gb_ratio

Controla la cantidad de DRAM que se utilizará para almacenar en caché los nodos de índice a los que se accede con frecuencia.

Esta caché se carga durante la carga del índice y se utiliza durante la búsqueda para reducir las IOs.

Tipo: Float

Rango: [0.0, 0.3)

Valor por defecto: 0

Un valor más alto asigna más memoria para el almacenamiento en caché, reduciendo los IOs de disco pero consumiendo más memoria del sistema. Un valor más bajo utiliza menos memoria para el almacenamiento en caché, aumentando potencialmente la necesidad de acceso al disco.

Parámetros de búsqueda de índices

Estos parámetros influyen en la forma en que AISAQ realiza las búsquedas. Su ajuste puede influir en la velocidad de búsqueda, la latencia y el uso de recursos.

Parámetro

Descripción

Rango de valores

Sugerencia de ajuste

search_list

Durante una operación de búsqueda, este parámetro determina el tamaño del grupo de candidatos que el algoritmo mantiene mientras recorre el gráfico. Un valor mayor aumenta las posibilidades de encontrar a los verdaderos vecinos más cercanos (mayor recall), pero también aumenta la latencia de la búsqueda.

Tipo: Entero

Rango: [topk, int32_max]

Valor por defecto: 16

Para un buen equilibrio entre rendimiento y precisión, se recomienda establecer este valor igual o ligeramente superior al número de resultados que se desea recuperar (top_k).

beamwidth

Controla el grado de paralelismo durante la búsqueda determinando el número máximo de peticiones de E/S de disco paralelas para leer los nodos del índice.

Tipo: Entero

Rango: [1, 16]

Valor por defecto: 8

Los valores más altos aumentan el paralelismo, lo que puede acelerar la búsqueda en sistemas con CPUs y SSDs potentes. Sin embargo, un valor demasiado alto puede provocar una excesiva contención de recursos.

En la mayoría de los casos, se recomienda establecer un valor de 2.

vectors_beamwidth

Controla el grado de paralelismo durante la búsqueda determinando el número máximo de solicitudes de E/S de disco paralelas para leer grupos de vectores PQ vecinos (se ignora en el modo de rendimiento).

Tipo: Entero

Rango: [1, 4] debe ser <= beamwidth

Valor por defecto: 1

Los valores más altos aumentan el paralelismo, lo que puede acelerar la búsqueda en sistemas con CPUs y SSDs potentes. Sin embargo, un valor demasiado alto puede provocar una excesiva contención de recursos, ya que cada grupo de vectores PQ vecino puede contener hasta vectores de grado_máximo.

En la mayoría de los casos, recomendamos establecer un valor de 1.

pq_read_page_cache_size

Tamaño de caché de lectura PQ en DRAM por hilo de búsqueda (bytes). Almacena en caché las páginas de datos a las que se accede con frecuencia y que contienen vectores PQ (se ignora en el modo de rendimiento y sólo se aplica cuando rearrange es true).

La memoria caché de lectura PQ se reutiliza en todos los segmentos AISAQ.

Tipo: Entero

Rango: [0, 33554432]

Valor por defecto: 5242880 (5MiB)

Una caché más grande mejora el rendimiento de la consulta pero aumenta el uso de DRAM.

Los valores recomendados oscilan entre 2 MiB para segmentos pequeños (1 M de vectores), 5 MiB para segmentos medianos (50 M de vectores) y 10 MiB para segmentos grandes (250 M de vectores).