Pesquisar embeddings com a pesquisa de vetor

Neste tutorial, mostramos como realizar uma pesquisa de similaridade em embeddings armazenados em tabelas do BigQuery usando a função VECTOR_SEARCH e, se preferir, um índice vetorial.

Quando você usa VECTOR_SEARCH com um índice vetorial, ele usa o método do Vizinho aproximado mais perto para melhorar o desempenho da pesquisa de vetor, mas reduzindo o recall e, portanto, retornando resultados mais aproximados.VECTOR_SEARCH Sem um índice de vetor, o VECTOR_SEARCH usa a pesquisa de força bruta para medir a distância de cada registro.

Permissões necessárias

Para seguir este tutorial, você precisa das seguintes permissões do Identity and Access Management (IAM):

  • Para criar um conjunto de dados, você precisa da permissão bigquery.datasets.create.
  • Para criar uma tabela, são necessárias as seguintes permissões:

    • bigquery.tables.create
    • bigquery.tables.updateData
    • bigquery.jobs.create
  • Para criar um índice vetorial, você precisa da permissão bigquery.tables.createIndex na tabela em que está criando o índice.

  • Para remover um índice vetorial, você precisa da permissão bigquery.tables.deleteIndex na tabela da qual está removendo o índice.

Cada um dos papéis do IAM predefinidos a seguir inclui as permissões necessárias para trabalhar com índices vetoriais:

  • Proprietário de dados do BigQuery (roles/bigquery.dataOwner)
  • Editor de dados do BigQuery (roles/bigquery.dataEditor)

Custos

A função VECTOR_SEARCH usa os preços de computação do BigQuery. Você recebe uma cobrança pela pesquisa de similaridade usando preços sob demanda ou de edições.

  • Sob demanda: você recebe uma cobrança pela quantidade de bytes verificados na tabela de base, no índice e na consulta de pesquisa.
  • Preços das edições: você recebe cobranças pelos slots necessários para concluir o job na edição da sua reserva. Cálculos de similaridade maiores e mais complexos geram mais cobranças.

Para mais informações, consulte preços do BigQuery.

Antes de começar

  1. No console do Google Cloud , na página do seletor de projetos, selecione ou crie um projeto do Google Cloud .

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos (roles/resourcemanager.projectCreator), que contém a permissão resourcemanager.projects.create. Saiba como conceder papéis.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para o projeto do Google Cloud .

  3. Ative a API BigQuery.

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter o papel do IAM de administrador de uso do serviço (roles/serviceusage.serviceUsageAdmin), que contém a permissão serviceusage.services.enable. Saiba como conceder papéis.

    Ativar a API

crie um conjunto de dados

Crie um conjunto de dados do BigQuery:

  1. No Google Cloud console, acesse a página BigQuery.

    Acessar a página do BigQuery

  2. No painel Explorer, clique no nome do seu projeto.

  3. Clique em Conferir ações > Criar conjunto de dados.

    Crie um conjunto de dados para conter os objetos usados no tutorial.

  4. Na página Criar conjunto de dados, faça o seguinte:

    • Para o código do conjunto de dados, insira vector_search.

    • Em Tipo de local, selecione Multirregião e EUA (várias regiões nos Estados Unidos).

      Os conjuntos de dados públicos são armazenados na multirregião US. Para simplificar, armazene seus conjuntos de dados no mesmo local.

    • Mantenha as configurações padrão restantes e clique em Criar conjunto de dados.

Criar tabelas de teste

  1. Crie a tabela patents que contém embeddings de patentes, com base em um subconjunto do conjunto de dados público do Google Patentes:

    CREATE TABLE vector_search.patents AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE ARRAY_LENGTH(embedding_v1) > 0
     AND publication_number NOT IN ('KR-20180122872-A')
    LIMIT 1000000;
  2. Crie a tabela patents2 que contém um embedding de patente para encontrar vizinhos mais próximos:

    CREATE TABLE vector_search.patents2 AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE publication_number = 'KR-20180122872-A';

Criar um índice vetorial

  1. Crie o índice vetorial my_index na coluna embeddings_v1 da tabela patents:

    CREATE OR REPLACE VECTOR INDEX my_index ON vector_search.patents(embedding_v1)
    STORING(publication_number, title)
    OPTIONS(distance_type='COSINE', index_type='IVF');
  2. Aguarde alguns minutos até que o índice vetorial seja criado, execute a seguinte consulta e confirme se o valor coverage_percentage é 100:

    SELECT * FROM vector_search.INFORMATION_SCHEMA.VECTOR_INDEXES;

Usar a função VECTOR_SEARCH com um índice

Depois que o índice vetorial for criado e preenchido, use a função VECTOR_SEARCH para encontrar o vizinho mais próximo do embedding na coluna embedding_v1 da tabela patents2. Como essa consulta usa o índice vetorial na pesquisa, VECTOR_SEARCH ela usa um método do Vizinho aproximado mais perto para encontrar o vizinho mais próximo do embedding.

Use a função VECTOR_SEARCH com um índice:

SELECT query.publication_number AS query_publication_number,
  query.title AS query_title,
  base.publication_number AS base_publication_number,
  base.title AS base_title,
  distance
FROM
  VECTOR_SEARCH(
    TABLE vector_search.patents,
    'embedding_v1',
    TABLE vector_search.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"fraction_lists_to_search": 0.005}');

Os resultados são semelhantes aos seguintes:

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| query_publication_number |                         query_title                         | base_publication_number |                                                        base_title                                                        |      distance       |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-106599080-B          | A kind of rapid generation for keeping away big vast transfer figure based on GIS                                        | 0.14471956347590609 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-114118544-A          | Urban waterlogging detection method and device                                                                           | 0.17472108931171348 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-20200048143-A        | Method and system for mornitoring dry stream using unmanned aerial vehicle                                               | 0.17561990745619782 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-101721695-B1         | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same         | 0.17696129365559843 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-109000731-B          | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642917 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

Usar a função VECTOR_SEARCH com força bruta

Use a função VECTOR_SEARCH para encontrar o vizinho mais próximo para o embedding na coluna embedding_v1 da tabela patents2. Essa consulta não usa o índice vetorial na pesquisa. Portanto, VECTOR_SEARCH encontra o vizinho exato mais próximo do embedding.

SELECT query.publication_number AS query_publication_number,
  query.title AS query_title,
  base.publication_number AS base_publication_number,
  base.title AS base_title,
  distance
FROM
  VECTOR_SEARCH(
    TABLE vector_search.patents,
    'embedding_v1',
    TABLE vector_search.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"use_brute_force":true}');

Os resultados são semelhantes aos seguintes:

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| query_publication_number |                         query_title                         | base_publication_number |                                                        base_title                                                        |      distance       |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-106599080-B          | A kind of rapid generation for keeping away big vast transfer figure based on GIS                                        |  0.1447195634759062 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-114118544-A          | Urban waterlogging detection method and device                                                                           |  0.1747210893117136 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-20200048143-A        | Method and system for mornitoring dry stream using unmanned aerial vehicle                                               | 0.17561990745619782 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-101721695-B1         | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same         | 0.17696129365559843 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-109000731-B          | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642928 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

Avaliar o recall

Quando você realiza uma pesquisa de vetor com um índice, ela retorna resultados aproximados, mas reduzindo o recall. É possível calcular o recall comparando os resultados retornados pela pesquisa de vetor com um índice e pela pesquisa de vetor com força bruta. Nesse conjunto de dados, o valor publication_number identifica exclusivamente uma patente. Por isso, é usado para comparação.

WITH approx_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE vector_search.patents,
      'embedding_v1',
      TABLE vector_search.patents2,
      top_k => 5,
      distance_type => 'COSINE',
      options => '{"fraction_lists_to_search": 0.005}')
),
  exact_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE vector_search.patents,
      'embedding_v1',
      TABLE vector_search.patents2,
      top_k => 5,
      distance_type => 'COSINE',
      options => '{"use_brute_force":true}')
)

SELECT
  a.query_publication_number,
  SUM(CASE WHEN a.base_publication_number = e.base_publication_number THEN 1 ELSE 0 END) / 5 AS recall
FROM exact_results e LEFT JOIN approx_results a
  ON e.query_publication_number = a.query_publication_number
GROUP BY a.query_publication_number

Se o recall for menor do que o desejado, será possível aumentar o valor de fraction_lists_to_search, com a desvantagem de latência e uso de recursos potencialmente maiores. Para ajustar a pesquisa de vetor, tente várias execuções de VECTOR_SEARCH com diferentes valores de argumento, salve os resultados em tabelas e depois os compare.

Limpar

  1. No console Google Cloud , acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.