Pesquisa de vetores

Pesquisa ANN filtrada com índices de vetores compostos (Parte 1)

Esta postagem dá início a uma série de várias partes sobre indexação de vetores compostos no Couchbase. Começaremos com a construção da intuição e, em seguida, mergulharemos progressivamente em aspectos internos, otimizações de execução e desempenho.

A série abrangerá:

  1. Por que os índices vetoriais compostos são importantes, incluindo conceitos, terminologia e motivação do desenvolvedor. Um sistema inteligente de recomendação de compras será usado como exemplo.
  2. Como os índices de vetor composto são implementados no Serviço de Indexação do Couchbase.
  3. Como o pushdown ORDER BY funciona para consultas de vetor composto.
  4. Comportamento de desempenho no mundo real e resultados de benchmarking.

Sistema inteligente de recomendação de compras com RNA filtrada

Imagine que você esteja criando um aplicativo de recomendação de compras.

Um usuário o abre em uma manhã de domingo e digita:

“Adoro chocolate amargo para barrar, mas estou tentando cortar o açúcar e adicionar mais proteína. O que mais devo comprar?”

Nesse momento, seu sistema precisa entender a intenção do usuário, comparar semanticamente os itens alimentares e aplicar filtros nutricionais rigorosos.

É exatamente aí que entra o Filtered Approximate Nearest Neighbor (ANN filtrado):

  • Sua camada ANN primeiro encontra itens/alimentos semanticamente semelhantes que “se parecem” com o chocolate amargo espalhado em termos de perfil de sabor, textura ou categoria.  
  • Em seguida, sua camada de filtragem entra em ação para remover qualquer coisa com alto teor de açúcar, manter os itens acima de um determinado limite de proteína e talvez impor preferências dietéticas (vegana, cetônica, sem nozes).

O resultado? Um mecanismo de recomendação que entende tanto o significado quanto as restrições, assim como um funcionário de loja inteligente que conhece seu gosto e considera suas metas.

Antes de chegarmos à FANN, vamos desenvolver a intuição

NN (vizinho mais próximo): Encontrando o coisa mais semelhante com o que você tem. É como perguntar: “Qual alimento da minha lista tem o gosto mais parecido com essa pasta de chocolate?”

ANN (Approximate Nearest Neighbor): Encontrar algo muito semelhante, mas mais rápido. É como dizer: “Não preciso do perfeito correspondência, apenas algo que é suficientemente próximo rapidamente”.”

FANN (Filtered Approximate Nearest Neighbor): Encontrar algo suficientemente próximo mas somente entre itens que atendam a determinadas regras. É como dizer: “Mostre-me alimentos semelhantes à pasta de chocolate, mas apenas os que têm baixo teor de açúcar e alto teor de proteína”.”

Os algoritmos ANN trocam um pouco de eficácia (precisão) para um nível muito maior de eficiência (velocidade e memória).

A índice composto é um índice construído sobre vários campos (colunas) juntos, não apenas um. Para ePor exemplo, é como classificar uma planilha primeiro por Categoria, depois por Açúcar e depois por Proteína. Esse método de pedido agrupa todas as pastas de chocolate primeiro. Dentro desse grupo, você pode encontrar rapidamente produtos com baixo teor de açúcar e alto teor de proteína sem precisar examinar tudo.

Por que os índices tradicionais falham

Suponha que você tenha um pequeno subconjunto do conjunto de dados World Food Facts carregado na memória como:

Para encontrar alimentos, como pastas de chocolate amargo, com baixo teor de açúcar e alto teor de proteína, você pode usar uma consulta como a que está abaixo:

Para acelerar a consulta, você pode usar um índice secundário composto, como o mostrado abaixo: 

Os índices secundários compostos podem ser vistos como listas ordenadas de chaves concatenadas que permitem pesquisas mais rápidas de valores específicos ou iteração em um intervalo de valores baixos a altos (ou seja, varredura de intervalo). Esses valores de pesquisa, bem como os valores altos e baixos, são construídos no momento da consulta usando os predicados de consulta.

Os índices compostos funcionam muito bem para pesquisas estruturadas.

Mas um filtro de categoria nunca consegue encontrar:

  • manteigas de nozes com sabor de chocolate
  • pastas de chocolate e proteínas
  • misturas de cacau com avelã
  • barras de proteína de chocolate

...mesmo que um ser humano saiba imediatamente que eles são parentes das pastas de chocolate.

Os índices tradicionais correspondem apenas à estrutura, não ao significado. É por isso que as varreduras de intervalo baseadas em categorias falham.

Como funciona a RNA filtrada

Você pode converter a consulta e os dados em vetores

A frase do usuário é alimentada em um modelo de incorporação (por exemplo, OpenAI, Cohere ou um modelo específico do domínio).  

O resultado é um vetor denso que captura conceitos como:

  • sabor de chocolate  
  • Textura espalhável  
  • categoria sobremesa/snack  

Esse vetor representa o que o usuário deseja, em vez de apenas as palavras literais.

Em seguida, você pode encontrar os vizinhos mais próximos (similaridade semântica).

Os candidatos podem incluir:

  • Pasta de cacau com avelã  
  • Manteiga de chocolate e amêndoas  
  • Pasta de proteína de cacau  
  • Tahini de chocolate  

Mas nem todas são opções saudáveis, e o usuário pediu especificamente baixo teor de açúcar e alto teor de proteína.

Você pode aplicar filtros rígidos, que é a parte “Filtrada” de Filtered ANN.

Você pode filtrar os itens:

  • Açúcar > limite (por exemplo, >5g por porção)  
  • Proteína < limite (por exemplo, <8g por porção)  

Seu sistema também pode combinar filtros de metadados:

  • Somente veganos  
  • Sem óleo de palma  
  • Sem nozes  
  • Abaixo de $10  

O que resta é um conjunto de itens que correspondem tanto ao significado quanto às restrições.

Por que o uso exclusivo de filtros não funciona

Usando apenas filtros, você obteria:

  • Qualquer produto com alto teor de proteína e baixo teor de açúcar  
  • Assim como itens não relacionados ao chocolate (como tofu, iogurte grego, peito de frango)

Mas o usuário deseja algo “semelhante a uma pasta de chocolate”.”

RNA filtrada = personalização + restrições. Ele imita a forma como um funcionário humano da loja responderia à solicitação: “Se você quiser algo parecido com uma pasta de chocolate, mas mais saudável, experimente isto...”

No entanto, nos bastidores, seu mecanismo de recomendação enfrenta um problema sutil, mas sério. Os bancos de dados vetoriais modernos dizem que podem fazer “pesquisa híbrida”, mas geralmente mantêm os campos escalares, como açúcar ou proteína, de lado, como metadados simples. O índice ANN não tem ideia de como usá-los.

Então, o que acontece?

O sistema primeiro extrai um grande lote de candidatos semelhantes a vetores... e só então começa a verificar as regras de nutrição, como sugars_100g 10.

É como se um funcionário de uma loja trouxesse todos os produtos relacionados a chocolate da sala dos fundos, colocasse-os no balcão e dissesse:

“Ah, espere, você queria baixo teor de açúcar? Com alto teor de proteína? Deixe-me jogar fora a maior parte destes”.”

Alguns sistemas vetoriais tentam filtrar mais cedo durante a travessia do gráfico, mas ainda não conseguem fazer a filtragem de intervalo real ou a poda de prefixo. Eles precisam buscar e decodificar cada candidato antes de decidir se devem descartá-lo.

O que isso significa para seu aplicativo?

  • Mais leituras de disco
  • Mais cálculos de distância
  • Mais latência

...E muito trabalho desperdiçado para resultados que o usuário nunca verá.

É exatamente por isso que um índice vetorial composto que mescla a similaridade vetorial e a poda escalar no mesmo índice é um divisor de águas.

Índices vetoriais compostos - Visão geral

Etapa 1: Camada de incorporação - Criar incorporação de vetores

A descrição de texto de cada produto (tags, nome do produto, categoria, ingredientes) é convertida em um vetor de alta dimensão usando um modelo de linguagem. Produtos com significados semelhantes terão vetores semelhantes.

Por exemplo, embeddings para nomes de produtos:

  •  “chocolate amargo para barrar” → [0,23, -0,15, 0,87, ...] (384 dimensões)
  •  “chocolate hazelnut butter” → [0.25, -0.12, 0.85, ...] (vetor semelhante)
  •  “barra de proteína de chocolate” → [0,18, -0,08, 0,79, ...] (algo semelhante)

Etapa 2: Índice FANN: Criar um índice de vetor composto

Crie um índice vetorial (por exemplo, Couchbase Vector Index, FAISS) que possa localizar rapidamente os vizinhos mais próximos no espaço de incorporação.

Como os vetores são diferentes de outros tipos de dados em um índice de vetor composto?

  • Os vetores não têm ordem total natural, portanto, a ordem de classificação dos campos de vetores não pode ser determinada no momento do índice para a construção do índice.
    • Os campos de vetor não são compatíveis com predicados de comparação convencionais (como filtros de igualdade ou de intervalo) na cláusula WHERE.
    • Mas os campos de vetores são usados em ORDER BY com funções de distância de vetores e podem participar do planejamento de consultas por meio dessas expressões.
  • A ordenação é feita no momento da varredura usando a similaridade com um vetor de consulta. A função de similaridade é escolhida pelo usuário conforme necessário para os dados e o aplicativo.
    • APPROX_VECTOR_DISTANCE pode ser usado na cláusula ORDER BY e tem suporte eficiente quando existe um índice de vetor compatível; caso contrário, resulta em uma varredura completa.
  • Como cada dimensão em um vetor não tem nenhum significado independente, você só pode fazer perguntas como “quão semelhantes são dois vetores”. Portanto, você só pode encontrar o vizinho mais próximo ou elementos semelhantes.
    • Da mesma forma, a função e a consulta precisam ser fornecidas como entrada no momento da consulta.
  • A pesquisa do vizinho mais próximo é um problema computacionalmente intensivo que só piora com o aumento das dimensões do vetor. Portanto, você precisa de uma solução eficiente em termos de tempo e espaço para obter resultados aproximados.
    • Os métodos de quantização são fornecidos na descrição da DDL.
  • Você terá que reduzir o número de comparações no momento da consulta para que a consulta seja mais rápida.
    • O número de centroides e o valor de nprobes ajudam a reduzir o espaço de pesquisa.

O Composite Vector Index é um índice em que pelo menos uma das chaves tem um atributo de vetor, enquanto outros atributos, como dimensão, similaridade e descrição, etc., são fornecidos para qualificar o vetor.

Nessa definição, a palavra-chave VECTOR marca explicitamente text_vector como um atributo de vetor. Isso é necessário porque, no nível JSON, uma incorporação de vetor é armazenada como uma matriz simples de números de ponto flutuante. Sem a anotação de vetor, o GSI trataria o campo como uma matriz comum e aplicaria a semântica de indexação padrão.

Ao declarar um campo como um vetor, o usuário estabelece um contrato explícito com o serviço GSI que:

  • O índice conterá uma única chave de vetor, e essa chave representa a incorporação usada para a pesquisa de similaridade de vetor nesse índice
  • O aplicativo é responsável por gerar a incorporação do vetor (por exemplo, usando um modelo de incorporação externo) e mantê-la no campo de documento especificado.
  • O serviço GSI deve interpretar o campo semanticamente como uma incorporação de vetor e criar estruturas de índice com reconhecimento de vetor otimizadas para a pesquisa ANN (Approximate Nearest Neighbor), em vez de usar a lógica convencional de indexação de escalas ou matrizes.

No índice vetorial DDL, o usuário deve especificar alguns parâmetros extras, como

  • Dimensão: comprimento dos embeddings vetoriais criados
  • Similaridade: métrica usada para pesquisa ANN
  • Descrição: Descrição semelhante ao índice FAISS para especificar a troca entre precisão e velocidade

No exemplo acima:

  • Criamos os 384 embeddings dimensionais para tags, nome do produto, categoria e campos de ingredientes usando o modelo sentence-transformers/all-MiniLM-L6-v2 e os armazenamos no campo text_vector do documento. 
  • Usamos o quantizador grosseiro IVF com o número padrão de centroides e a quantização SQ8.

Etapa 3: Consulta ANN filtrada

Em vez de filtrar por categoria exata, nós:

  • Gerar uma incorporação para a consulta “chocolate amargo para barrar”.”
    • query_text = “chocolate amargo para barrar”
    • query_embedding = [0.23, -0.15, 0.87, 0.42, ..., -0.31] # Vetor de 384 dimensões
  • Encontre os k produtos mais semelhantes usando a pesquisa ANN (por exemplo, os 10 principais) que atendam aos nossos critérios (sugars_100g 10).
  • Retornar as principais correspondências.

Exemplo de SQL++ (Couchbase):

Principais vantagens

Essa abordagem encontra produtos que são:

  • Semanticamente semelhante a “dark chocolate spread” (usando a pesquisa vetorial).
  • Atender aos filtros nutricionais (baixo teor de açúcar, alto teor de proteína).
  • Pode incluir produtos de diferentes categorias, como “barras de proteína de chocolate”, “pastas de manteiga de nozes” ou “lanches com sabor de chocolate”, que são semelhantes em significado, mas não correspondem ao filtro da categoria “pastas de chocolate”.

Saiba mais sobre os índices vetoriais compostos na próxima parte desta série, na qual responderemos a perguntas práticas, como:

  • Como as incorporações de vetores são armazenadas e organizadas de forma eficiente dentro da camada de índice?
  • Um índice vetorial composto pode responder a consultas somente escalares sem ler o documento completo?
  • A ordem dos campos escalares e dos campos vetoriais na definição do índice é importante?

Aprofunde-se na mecânica da indexação de vetores compostos verificando o segunda postagem nesta série, na qual exploramos sua implementação no Couchbase.

Compartilhe este artigo
Receba atualizações do blog do Couchbase em sua caixa de entrada
Esse campo é obrigatório.

Autor

Postado por Sai Kommaraju

Deixe um comentário

Pronto para começar a usar o Couchbase Capella?

Iniciar a construção

Confira nosso portal do desenvolvedor para explorar o NoSQL, procurar recursos e começar a usar os tutoriais.

Use o Capella gratuitamente

Comece a trabalhar com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Deseja saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.