Filtros em consultas de vetor

Você pode definir um modo de filtro de vetor em uma consulta de vetor para especificar se deseja filtrar antes ou depois da execução da consulta.

Os filtros determinam o escopo de uma consulta de vetor. Os filtros são definidos e iteram em cadeia de caracteres não vetorial e campos numéricos atribuídos como filterable no índice, mas o objetivo de um filtro determina o que a consulta de vetor executa: todo o espaço pesquisável ou o conteúdo de um resultado de pesquisa.

Este artigo descreve cada modo de filtro e fornece diretrizes sobre quando usar cada um deles.

Modo de pré-filtro

A pré-filtragem aplica filtros antes da execução da consulta, reduzindo a área da superfície de pesquisa sobre a qual o algoritmo da busca em vetores procura conteúdo semelhante. Em uma consulta de vetor, preFilter é o padrão.

Diagram of prefilters.

Modo de pós-filtro

A pós-filtragem aplica filtros após a execução da consulta, restringindo os resultados da pesquisa.

Diagram of post-filters.

Teste de comparação dos modos de filtro de vetor

Para entender as condições sob as quais um modo de filtro tem um desempenho melhor que o outro, executamos uma série de testes para avaliar os resultados da consulta em índices pequenos, médios e grandes.

  • Pequeno (100.000 documentos, índice de 2,5 GB, 1536 dimensões)
  • Médio (1 milhão de documentos, índice de 25 GB, 1536 dimensões)
  • Grande (1 bilhão de documentos, índice de 1,9 TB, 96 dimensões)

Para as cargas de trabalho pequenas e médias, usamos um serviço Standard 2 (S2) com uma partição e uma réplica. Para a carga de trabalho grande, usamos um serviço Standard 3 (S3) com 12 partições e uma réplica.

Os índices tinham uma construção idêntica: um campo de chave, um campo de vetor, um campo de texto e um campo numérico filtrável. O índice a seguir é definido usando a sintaxe 2023-07-01-preview.

def get_index_schema(self, index_name, dimensions):
    return {
        "name": index_name,
        "fields": [
            {"name": "id", "type": "Edm.String", "key": True, "searchable": True},
            {"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
              "searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
              "vectorSearchConfiguration": "defaulthnsw"},
            {"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
              "sortable": False, "facetable": False},
            {"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
              "retrievable": True, "sortable": True, "facetable": True}
        ],
        "vectorSearch":
        {
            "algorithmConfigurations": [
                {"name": "defaulthnsw", "kind": "hnsw", "hnswParameters": {"metric": "euclidean"}}
            ]
        }
    }

Nas consultas, usamos um filtro idêntico para operações de pré-filtro e pós-filtro. Usamos um filtro simples para garantir que as variações no desempenho fossem devido ao modo de filtragem e não à complexidade do filtro.

Os resultados foram medidos em consultas por segundo (QPS).

Observações

  • A pré-filtragem é quase sempre mais lenta do que a pós-filtragem, exceto em índices pequenos, nos quais o desempenho é aproximadamente igual.

  • Em conjuntos de dados maiores, a pré-filtragem é significativamente mais lenta em ordens de magnitude.

  • Então, por que o pré-filtro é o padrão se é quase sempre mais lento? A pré-filtragem garante que resultados k sejam retornados se existirem no índice, onde o viés favorece o recall e a precisão em vez da velocidade.

  • A pós-filtragem é para clientes que:

    • priorizam a velocidade sobre a seleção (a pós-filtragem pode retornar menos de k resultados)
    • usam filtros que não são excessivamente seletivos
    • têm índices de tamanho suficiente, de modo que o desempenho da pré-filtragem é inaceitável

Detalhes

  • Dado um conjunto de dados com 100.000 vetores em 1536 dimensões:

    • Ao filtrar mais de 30% do conjunto de dados, a pré-filtragem e a pós-filtragem eram comparáveis.
    • Ao filtrar menos de 0,1% do conjunto de dados, a pré-filtragem era cerca de 50% mais lenta do que a pós-filtragem.
  • Dado um conjunto de dados com 1 milhão de vetores em 1536 dimensões:

    • Ao filtrar mais de 30% do conjunto de dados, a pré-filtragem era cerca de 30% mais lenta.
    • Ao filtrar menos de 2% do conjunto de dados, a pré-filtragem era cerca de sete vezes mais lenta.
  • Dado um conjunto de dados com 1 bilhão de vetores em 96 dimensões:

    • Ao filtrar mais de 5% do conjunto de dados, a pré-filtragem era cerca de 50% mais lenta.
    • Ao filtrar menos de 10% do conjunto de dados, a pré-filtragem era cerca de sete vezes mais lenta.

O grafo a seguir mostra o QPS relativo do pré-filtro, computado como QPS de pré-filtro dividido pelo QPS do pós-filtro.

Chart showing QPS performance for small, medium, and large indexes for relative QPS.

O eixo vertical é a QPS de pré-filtragem sobre a QPS de pós-filtragem. Por exemplo, um valor de 0,0 significa que a pré-filtragem é 100% mais lenta; 0,5 no eixo vertical significa que a pré-filtragem é 50% mais lenta; 1,0 significa que a pré-filtragem e a pós-filtragem são equivalentes.

O eixo horizontal representa a taxa de filtragem ou o percentual de documentos candidatos após a aplicação do filtro. Por exemplo, 1.00% significa que um por cento do corpus de pesquisa foi selecionado pelos critérios do filtro.