HNSW_SQ
O HNSW_SQ combina gráficos Hierarchical Navigable Small World (HNSW) com Scalar Quantization (SQ), criando um método avançado de indexação vetorial que oferece um compromisso controlável entre tamanho e precisão. Em comparação com o HNSW padrão, este tipo de índice mantém uma elevada velocidade de processamento de consultas, embora introduza um ligeiro aumento no tempo de construção do índice.
Visão geral
O HNSW_SQ combina duas técnicas de indexação: HNSW para uma navegação rápida baseada em grafos e SQ para uma compressão vetorial eficiente.
HNSW
O HNSW constrói um gráfico de várias camadas em que cada nó corresponde a um vetor no conjunto de dados. Neste gráfico, os nós são ligados com base na sua semelhança, permitindo uma rápida deslocação através do espaço de dados. A estrutura hierárquica permite que o algoritmo de pesquisa reduza os vizinhos candidatos, acelerando significativamente o processo de pesquisa em espaços de elevada dimensão.
Para mais informações, consulte HNSW.
SQ
SQ é um método de compressão de vectores, representando-os com menos bits. Por exemplo:
SQ8 usa 8 bits, mapeando valores em 256 níveis. Para mais informações, consulte IVF_SQ8.
SQ6 utiliza 6 bits para representar cada valor de vírgula flutuante, resultando em 64 níveis discretos.
Hnsw Sq
Esta redução na precisão diminui drasticamente o espaço de memória e acelera o cálculo, mantendo a estrutura essencial dos dados.
SQ4UCompatible with Milvus 2.6.8+
Para cenários que exigem uma velocidade de consulta extrema e uma utilização mínima de memória, Milvus introduz SQ4U, uma Quantização Escalar Uniforme de 4 bits. Esta é uma forma agressiva de quantização escalar que comprime o valor de ponto flutuante de cada dimensão num inteiro sem sinal de 4 bits.
O "U" em SQ4U significa Uniforme. Ao contrário da Quantização escalar não uniforme, que normalmente calcula os valores mínimo e máximo independentemente para cada dimensão (Quantização por dimensão), o SQ4U aplica uma estratégia de Quantização uniforme global:
Estatísticas Globais: O sistema calcula um único valor mínimo
vmine um único intervalo de valoresvdiffque se aplica a todas as dimensões do vetor (ou a todo o segmento do vetor).Mapeamento uniforme: O intervalo de valores globais é dividido em 16 intervalos iguais. Cada valor de vírgula flutuante no vetor, independentemente da dimensão a que pertence, é mapeado para um inteiro de 4 bits (0-15) utilizando estes parâmetros partilhados.
Vantagens de desempenho:
Rácio de compressão de 8x: Reduz o tamanho em 8x em comparação com
FP32e 2x em comparação comSQ8, diminuindo significativamente a pressão da largura de banda da memória - frequentemente o gargalo na pesquisa de vetores.Otimização SIMD: A estrutura compacta permite que as CPUs modernas (AVX2/AVX-512) processem mais dimensões por ciclo. Crucialmente, o uso de parâmetros globais elimina a necessidade de carregar valores variáveis de escala/offset durante o cálculo da distância, mantendo o pipeline de instruções totalmente saturado.
Eficiência da cache: Tamanhos menores de vetor significam que mais dados cabem no cache da CPU, reduzindo a latência causada pelo acesso à memória.
Devido à partilha global de parâmetros, o SQ4U tem um melhor desempenho em dados normalizados ou conjuntos de dados com distribuições de valores consistentes entre dimensões.
HNSW + SQ
O HNSW_SQ combina os pontos fortes do HNSW e do SQ para permitir uma pesquisa eficiente do vizinho mais próximo aproximado. Veja como o processo funciona:
Compressão de dados: O SQ comprime os vectores utilizando o
sq_type(por exemplo, SQ6 ou SQ8), o que reduz a utilização de memória. Esta compressão pode diminuir a precisão, mas permite que o sistema lide com conjuntos de dados maiores.Construção de gráficos: Os vectores comprimidos são utilizados para construir um gráfico HNSW. Como os dados são comprimidos, o gráfico resultante é mais pequeno e mais rápido de pesquisar.
Recuperação de candidatos: Quando é fornecido um vetor de consulta, o algoritmo utiliza os dados comprimidos para identificar rapidamente um conjunto de vizinhos candidatos a partir do gráfico HNSW.
(Opcional) Refinamento de resultados: Os resultados candidatos iniciais podem ser refinados para uma melhor precisão, com base nos seguintes parâmetros:
refine: Controla se esta etapa de refinamento está activada. Quando definido paratrue, o sistema recalcula as distâncias utilizando representações de maior precisão ou não comprimidas.refine_type: Especifica o nível de precisão dos dados utilizados durante o refinamento (por exemplo, SQ6, SQ8, BF16). Uma escolha de maior precisão, comoFP32, pode produzir resultados mais exactos, mas requer mais memória. Isto deve exceder a precisão do conjunto de dados comprimido original emsq_type.refine_k: Actua como um fator de ampliação. Por exemplo, se o seu top k for 100 erefine_kfor 2, o sistema volta a classificar os 200 principais candidatos e devolve os 100 melhores, aumentando a precisão geral.
Para obter uma lista completa de parâmetros e valores válidos, consulte Parâmetros do índice.
Criar índice
Para construir um índice HNSW_SQ num campo vetorial em Milvus, utilize o método add_index(), especificando os parâmetros index_type, metric_type, e parâmetros adicionais para o í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_SQ", # 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": 64, # Maximum number of neighbors each node can connect to in the graph
"efConstruction": 100, # Number of candidate neighbors considered for connection during index construction
"sq_type": "SQ6", # Scalar quantizer type
"refine": true, # Whether to enable the refinement step
"refine_type": "SQ8" # Precision level of data used for refinement
} # Index building params
)
Nesta configuração:
index_type: O tipo de índice a construir. Neste exemplo, defina o valor paraHNSW_SQ.metric_type: O método utilizado para calcular a distância entre vectores. Os valores suportados incluemCOSINE,L2, eIP. Para obter detalhes, consulte Tipos de métricas.params: Opções de configuração adicionais para criar o índice. Para obter detalhes, consulte Parâmetros de construção de índice.
Assim que os parâmetros do índice estiverem configurados, pode criar o índice utilizando diretamente o método create_index() ou passando os parâmetros do índice no método create_collection. Para obter detalhes, consulte Criar coleção.
Pesquisar no índice
Depois de o índice ser criado e as entidades serem inseridas, pode efetuar pesquisas de semelhança no í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
)
Nesta configuração:
params: Opções de configuração adicionais para pesquisar no índice. Para obter detalhes, consulte Parâmetros de pesquisa específicos do índice.
Parâmetros de índice
Esta secção fornece uma visão geral dos parâmetros utilizados para criar um índice e executar pesquisas no índice.
Parâmetros de construção de índice
A tabela seguinte lista os parâmetros que podem ser configurados em params ao construir um índice.
Parâmetro |
Descrição |
Intervalo de valores |
Sugestão de ajuste |
|
|---|---|---|---|---|
HNSW |
|
Número máximo de ligações (ou arestas) que cada nó pode ter no gráfico, incluindo as arestas de saída e de entrada. Este parâmetro afecta diretamente a construção e a pesquisa de índices. |
Tipo: Inteiro Range: [2, 2048] Valor por defeito: |
Um Considere o aumento de Considere diminuir Na maioria dos casos, recomendamos que defina um valor dentro deste intervalo: [5, 100]. |
|
Número de vizinhos candidatos considerados para conexão durante a construção do índice. Um conjunto maior de candidatos é avaliado para cada novo elemento, mas o número máximo de conexões realmente estabelecidas ainda é limitado por |
Tipo: Integer Range: [1, int_max] Valor predefinido: |
Um Considere aumentar Considere diminuir Na maioria dos casos, recomendamos que defina um valor dentro deste intervalo: [50, 500]. |
|
SQ |
|
Especifica o método de quantização escalar para comprimir vectores. Cada opção oferece um equilíbrio diferente entre compressão e precisão:
|
Tipo: String Range: [ Valor por defeito: |
A escolha de |
|
Um sinalizador booleano que controla se uma etapa de refinamento é aplicada durante a pesquisa. O refinamento envolve uma nova classificação dos resultados iniciais através do cálculo de distâncias exactas entre o vetor de consulta e os candidatos. |
Tipo: Booleano Range: [ Valor predefinido: |
Defina para |
|
|
Determina a precisão dos dados utilizados para o refinamento. Esta precisão tem de ser superior à dos vectores comprimidos (conforme definido por |
Tipo: String Intervalo:[ Valor por defeito: Nenhum |
Utilize |
Parâmetros de pesquisa específicos do índice
A tabela seguinte lista os parâmetros que podem ser configurados em search_params.params ao pesquisar no índice.
Parâmetro |
Descrição |
Intervalo de valores |
Sugestão de ajuste |
|
|---|---|---|---|---|
HNSW |
|
Controla a amplitude da pesquisa durante a recuperação do vizinho mais próximo. Ele determina quantos nós são visitados e avaliados como possíveis vizinhos mais próximos. Este parâmetro afecta apenas o processo de pesquisa e aplica-se exclusivamente à camada inferior do gráfico. |
Tipo: Inteiro Intervalo: [1, int_max] Valor por defeito: limite (TopK vizinhos mais próximos a devolver) |
Um Considere aumentar Considere diminuir Na maioria dos casos, recomendamos que defina um valor dentro deste intervalo: [K, 10K]. |
SQ |
|
O fator de ampliação que controla quantos candidatos extra são examinados durante a fase de refinamento, relativamente aos K resultados principais solicitados. |
Tipo: Flutuante Intervalo: [1, float_max) Valor predefinido: 1 |
Valores mais altos de |