HNSW_PRQ

HNSW_PRQ aprovecha los gráficos Hierarchical Navigable Small World (HNSW) con Product Residual Quantization (PRQ), ofreciendo un método avanzado de indexación de vectores que permite ajustar con precisión el equilibrio entre el tamaño del índice y la precisión. PRQ va más allá de la cuantificación de producto (PQ) tradicional al introducir un paso de cuantificación residual (RQ) para capturar información adicional, lo que da como resultado una mayor precisión o índices más compactos en comparación con los métodos basados puramente en PQ. Sin embargo, los pasos adicionales pueden suponer una mayor carga computacional durante la creación y búsqueda de índices.

Resumen

HNSW_PRQ combina dos técnicas de indexación: HSNW para una navegación rápida basada en grafos y PRQ para una compresión vectorial eficiente.

HNSW

HNSW construye un grafo multicapa en el que cada nodo corresponde a un vector del conjunto de datos. En este grafo, los nodos se conectan en función de su similitud, lo que permite recorrer rápidamente el espacio de datos. La estructura jerárquica permite al algoritmo de búsqueda reducir el número de vecinos candidatos, lo que acelera considerablemente el proceso de búsqueda en espacios de gran dimensión.

Para más información, consulte HNSW.

PRQ

PRQ es un método de compresión vectorial multietapa que combina dos técnicas complementarias: PQ y RQ. Al dividir primero un vector de alta dimensión en subvectores más pequeños (mediante PQ) y cuantificar después cualquier diferencia restante (mediante RQ), PRQ consigue una representación compacta pero precisa de los datos originales.

La siguiente figura muestra cómo funciona.

Hnsw Prq Hnsw Prq

  1. Cuantización del producto (PQ)

    En esta fase, el vector original se divide en subvectores más pequeños, y cada subvector se asigna a su centroide más cercano en un libro de códigos aprendido. Esta asignación reduce significativamente el tamaño de los datos, pero introduce algunos errores de redondeo, ya que cada subvector se aproxima a un único centroide. Para más información, consulte IVF_PQ.

  2. Cuantificación residual (RQ)

    Tras la etapa PQ, la RQ cuantiza el residuo (la diferencia entre el vector original y su aproximación basada en PQ) utilizando libros de códigos adicionales. Como este residuo suele ser mucho más pequeño, puede codificarse con mayor precisión sin un gran aumento del almacenamiento.

    El parámetro nrq determina cuántas veces se cuantifica iterativamente este residuo, lo que permite ajustar con precisión el equilibrio entre eficacia y precisión de la compresión.

  3. Representación final de la compresión

    Una vez que RQ termina de cuantizar el residuo, los códigos enteros de PQ y RQ se combinan en un único índice comprimido. Al capturar detalles refinados que PQ por sí solo podría pasar por alto, RQ mejora la precisión sin causar un aumento significativo en el almacenamiento. Esta sinergia entre PQ y RQ es lo que define a PRQ.

HNSW + PRQ

Al combinar HNSW con PRQ, HNSW_PRQ conserva la búsqueda rápida basada en grafos de HNSW al tiempo que aprovecha la compresión multietapa de PRQ. El flujo de trabajo es el siguiente

  1. Compresión de datos: Cada vector se transforma primero mediante PQ a una representación gruesa y, a continuación, los residuos se cuantifican mediante RQ para un mayor refinamiento. El resultado es un conjunto de códigos compactos que representan cada vector.

  2. Construcción de gráficos: Los vectores comprimidos (incluidos los códigos PQ y RQ) constituyen la base para construir el gráfico HNSW. Como los datos se almacenan de forma compacta, el gráfico requiere menos memoria y la navegación por él se acelera.

  3. Recuperación de candidatos: Durante la búsqueda, HNSW utiliza las representaciones comprimidas para recorrer el grafo y recuperar un conjunto de candidatos. Esto reduce drásticamente el número de vectores que hay que considerar.

  4. (Opcional) Perfeccionamiento de resultados: Los resultados iniciales de los candidatos pueden refinarse para obtener una mayor precisión, basándose en los siguientes parámetros:

    • refine: Controla si se activa este paso de refinamiento. Cuando se establece en true, el sistema recalcula las distancias utilizando representaciones de mayor precisión o sin comprimir.

    • refine_type: Especifica el nivel de precisión de los datos utilizados durante el refinamiento (por ejemplo, SQ6, SQ8, BF16). Una elección de mayor precisión, como FP32, puede producir resultados más precisos, pero requiere más memoria. Debe superar la precisión del conjunto de datos comprimido original en sq_type.

    • refine_k: Actúa como factor de ampliación. Por ejemplo, si su k superior es 100 y refine_k es 2, el sistema vuelve a clasificar los 200 candidatos superiores y devuelve los 100 mejores, mejorando la precisión general.

Para obtener una lista completa de parámetros y valores válidos, consulte Parámetros del índice.

Crear un índice

Para construir un índice HNSW_PRQ sobre un campo vectorial en Milvus, utilice el método add_index(), especificando los parámetros index_type, metric_type, y parámetros adicionales para el índice.

from pymilvus import MilvusClient

# Prepare index building params
index_params = MilvusClient.prepare_index_params()

index_params.add_index(
    field_name="your_vector_field_name", # Name of the vector field to be indexed
    index_type="HNSW_PRQ", # Type of the index to create
    index_name="vector_index", # Name of the index to create
    metric_type="L2", # Metric type used to measure similarity
    params={
        "M": 30, # Maximum number of neighbors each node can connect to in the graph
        "efConstruction": 360, # Number of candidate neighbors considered for connection during index construction
        "m": 384, 
        "nbits": 8,
        "nrq": 1,
        "refine": true, # Whether to enable the refinement step
        "refine_type": "SQ8" # Precision level of data used for refinement
    } # Index building params
)

En esta configuración:

  • index_type: El tipo de índice a construir. En este ejemplo, establezca el valor HNSW_PQ.

  • metric_type: El método utilizado para calcular la distancia entre vectores. Los valores soportados incluyen COSINE, L2, y IP. Para más detalles, consulte Tipos de métricas.

  • params: Opciones de configuración adicionales para construir el índice. Para más información, consulte Parámetros de creación de índices.

Una vez configurados los parámetros del índice, puede crear el índice utilizando el método create_index() directamente o pasando los parámetros del índice en el método create_collection. Para más detalles, consulte Crear colección.

Búsqueda en el índice

Una vez creado el índice e insertadas las entidades, puede realizar búsquedas de similitud en el índice.

search_params = {
    "params": {
        "ef": 10, # Parameter controlling query time/accuracy trade-off
        "refine_k": 1 # The magnification factor
    }
}

res = MilvusClient.search(
    collection_name="your_collection_name", # Collection name
    anns_field="vector_field",  # Vector field name
    data=[[0.1, 0.2, 0.3, 0.4, 0.5]],  # Query vector
    limit=3,  # TopK results to return
    search_params=search_params
)

En esta configuración:

Parámetros del índice

Esta sección proporciona una visión general de los parámetros utilizados para construir un índice y realizar búsquedas en el índice.

Parámetros de creación de índices

En la siguiente tabla se enumeran los parámetros que se pueden configurar en params al crear un índice.

Parámetro

Descripción

Rango de valores

Sugerencia de ajuste

HNSW

M

Número máximo de conexiones (o aristas) que puede tener cada nodo en el grafo, incluyendo tanto las aristas salientes como las entrantes. Este parámetro afecta directamente tanto a la construcción del índice como a la búsqueda.

Tipo: Entero Rango: [2, 2048]

Valor por defecto: 30 (hasta 30 aristas salientes y 30 entrantes por nodo)

Un valor mayor de M suele dar lugar a una mayor precisión, pero aumenta la sobrecarga de memoria y ralentiza tanto la construcción del índice como la búsqueda. Considere la posibilidad de aumentar M para conjuntos de datos con una alta dimensionalidad o cuando una alta recuperación sea crucial.

Considere reducir M cuando el uso de memoria y la velocidad de búsqueda sean las principales preocupaciones.

En la mayoría de los casos, se recomienda establecer un valor dentro de este intervalo: [5, 100].

efConstruction

Número de vecinos candidatos considerados para la conexión durante la construcción del índice. Se evalúa un grupo mayor de candidatos para cada elemento nuevo, pero el número máximo de conexiones realmente establecidas sigue estando limitado por M.

Tipo: Entero Rango: [1, int_max]

Valor por defecto: 360

Un efConstruction más alto suele dar como resultado un índice más preciso, ya que se exploran más conexiones potenciales. Sin embargo, esto también conlleva un mayor tiempo de indexación y un mayor uso de memoria durante la construcción. Considere aumentar efConstruction para mejorar la precisión, especialmente en escenarios en los que el tiempo de indexación es menos crítico.

Considere la posibilidad de reducir efConstruction para acelerar la construcción del índice cuando las limitaciones de recursos sean un problema.

En la mayoría de los casos, se recomienda establecer un valor dentro de este intervalo: [50, 500].

PRQ

m

Número de subvectores (utilizados para la cuantificación) en los que se dividirá cada vector de alta dimensión durante el proceso de cuantificación.

Tipo: Entero Rango: [1, 65536]

Valor por defecto: Ninguno

Un valor más alto de m puede mejorar la precisión, pero también aumenta la complejidad computacional y el uso de memoria. m debe ser un divisor de la dimensión del vector(D) para garantizar una descomposición adecuada. Un valor comúnmente recomendado es m = D/2.

En la mayoría de los casos, se recomienda establecer un valor dentro de este rango: [D/8, D].

nbits

El número de bits utilizados para representar el índice del centroide de cada subvector en la forma comprimida. Determina directamente el tamaño de cada libro de códigos. Cada libro de códigos contendrá centroides de 2nbits. Por ejemplo, si nbits se establece en 8, cada subvector estará representado por un índice centroide de 8 bits. Esto permite28 (256) centroides posibles en el libro de códigos para ese subvector.

Tipo: Entero Rango: [1, 24]

Valor por defecto: 8

Un valor más alto de nbits permite libros de códigos más grandes, lo que potencialmente conduce a representaciones más precisas de los vectores originales. Sin embargo, también implica el uso de más bits para almacenar cada índice, lo que se traduce en una menor compresión. En la mayoría de los casos, se recomienda establecer un valor dentro de este rango: [1, 16].

nrq

Controla cuántos subcuantizadores residuales se utilizan en la etapa RQ. Con más subcuantizadores se consigue potencialmente una mayor compresión, pero puede introducir más pérdida de información.

Tipo: Entero Rango: [1, 16]

Valor por defecto: 2

Un valor más alto de nrq permite pasos adicionales de subcuantización residual, lo que potencialmente conduce a una reconstrucción más precisa de los vectores originales. Sin embargo, también implica almacenar y calcular más subcuantizadores, lo que resulta en un tamaño de índice mayor y una mayor sobrecarga computacional.

refine

Un indicador booleano que controla si se aplica un paso de refinamiento durante la búsqueda. El refinamiento consiste en volver a clasificar los resultados iniciales calculando las distancias exactas entre el vector de consulta y los candidatos.

Tipo: Booleano Rango: [true, false]

Valor por defecto: false

Establezca true si la alta precisión es esencial y puede tolerar tiempos de búsqueda ligeramente más lentos. Utilice false si la velocidad es una prioridad y es aceptable un compromiso menor en la precisión.

refine_type

Determina la precisión de los datos utilizados durante el proceso de refinamiento. Esta precisión debe ser superior a la de los vectores comprimidos (como se establece en los parámetros m y nbits ).

Tipo: Cadena Rango:[ SQ6, SQ8, BF16, FP16, FP32 ]

Valor por defecto: Ninguno

Utilice FP32 para obtener la máxima precisión con un mayor coste de memoria, o SQ6/SQ8 para obtener una mejor compresión. BF16 y FP16 ofrecen una alternativa equilibrada.

Parámetros de búsqueda específicos del índice

La siguiente tabla enumera los parámetros que pueden configurarse en search_params.params cuando se realizan búsquedas en el índice.

Parámetro

Descripción

Rango de valores

Sugerencia de ajuste

HNSW

ef

Controla la amplitud de la búsqueda durante la recuperación del vecino más cercano. Determina cuántos nodos son visitados y evaluados como vecinos más cercanos potenciales. Este parámetro sólo afecta al proceso de búsqueda y se aplica exclusivamente a la capa inferior del gráfico.

Tipo: Integer Rango: [1, int_max]

Valor por defecto: limit (TopK vecinos más cercanos a devolver)

Un valor mayor de ef suele aumentar la precisión de la búsqueda, ya que se tienen en cuenta más vecinos potenciales. Sin embargo, también aumenta el tiempo de búsqueda. Considere la posibilidad de aumentar ef cuando sea fundamental lograr una alta recuperación y la velocidad de búsqueda sea menos importante.

Considere la posibilidad de reducir ef para dar prioridad a las búsquedas más rápidas, especialmente en situaciones en las que sea aceptable una ligera reducción de la precisión.

En la mayoría de los casos, se recomienda establecer un valor dentro de este rango: [K, 10K].

PRQ

refine_k

El factor de ampliación que controla cuántos candidatos adicionales se examinan durante la etapa de refinamiento (reordenación), en relación con los K resultados principales solicitados.

Tipo: Float Rango: [1, float_max)

Valor por defecto: 1

Los valores más altos de refine_k pueden mejorar la recuperación y la precisión, pero también aumentarán el tiempo de búsqueda y el uso de recursos. Un valor de 1 significa que el proceso de refinamiento sólo tiene en cuenta los K primeros resultados iniciales.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

¿Fue útil esta página?