Medir a recuperação da consulta de vetor

Esta página descreve como medir a recuperação de consultas de vetor no AlloyDB para PostgreSQL. No contexto da pesquisa vetorial, recall se refere à porcentagem de vetores que o índice retorna, que são vizinhos mais próximos reais. Por exemplo, se uma consulta de vizinho mais próximo de 20 vizinhos mais próximos retornar 19 dos vizinhos mais próximos, o recall será de 19/20x100 = 95%.

Em uma consulta vetorial, a recuperação é importante porque mede a porcentagem de resultados relevantes recuperados de uma pesquisa. O recall ajuda a avaliar a precisão dos resultados de uma pesquisa de vizinho mais próximo aproximado (ANN) em comparação com os resultados de uma pesquisa de vizinhos mais próximos (KNN).

O ANN é um algoritmo que encontra pontos de dados semelhantes a um determinado ponto de consulta e melhora a velocidade ao encontrar os vizinhos aproximados em vez dos vizinhos reais. Ao usar a ANN, você equilibra a velocidade com o recall.

KNN é um algoritmo que encontra os "k" vetores mais semelhantes a um determinado vetor de consulta em um conjunto de dados com base em uma métrica de similaridade. k é o número de vizinhos que você quer que a consulta retorne.

É possível medir a recuperação da consulta de pesquisa de vetor para diferentes índices de vetor, incluindo:

  • Vizinho mais próximo escalonável (ScaNN, na sigla em inglês): um algoritmo para pesquisa de similaridade de vetores eficiente.
  • Hierarchical Navigable Small World (HNSW): um algoritmo baseado em gráfico usado para uma pesquisa eficiente de vizinho mais próximo aproximado em bancos de dados de vetores.
  • Arquivo invertido com compactação plana (IVFFLAT) e arquivo invertido plano (IVF): tipos de índices de vetor usados para pesquisas de ANN, principalmente em bancos de dados como a extensão pgvector do PostgreSQL.

Nesta página, presumimos que você esteja familiarizado com o PostgreSQL, o AlloyDB e a pesquisa de vetores.

Antes de começar

  1. Instale ou atualize a extensão pgvector.

    1. Se a extensão pgvector não estiver instalada, instale a versão vector da extensão 0.8.0.google-3 ou mais recente para armazenar as embeddings geradas como valores vector. A extensão vector inclui funções e operadores pgvector. O Google estendeu essa versão de pgvector com otimizações para o AlloyDB.

      CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';
      

      Para mais informações, consulte Armazenar, indexar e consultar vetores.

    2. Se a extensão pgvector já estiver instalada, atualize a extensão vector para a versão 0.8.0.google-3 ou mais recente para ter os recursos do avaliador de recuperação.

      ALTER EXTENSION vector UPDATE TO '0.8.0.google-3';
      
  2. Para criar índices ScaNN, instale a extensão alloydb_scann.

    CREATE EXTENSION IF NOT EXISTS alloydb_scann;
    

Avaliar o recall de consultas de vetor em um índice vetorial

É possível encontrar o recall de uma consulta vetorial em um índice vetorial para uma determinada configuração usando a função evaluate_query_recall. Essa função permite ajustar os parâmetros para conseguir os resultados de recuperação de consulta de vetor que você quer. O recall é a métrica usada para a qualidade da pesquisa e é definido como a porcentagem dos resultados retornados que são objetivamente mais próximos dos vetores de consulta. A função evaluate_query_recall fica ativada por padrão.

Encontrar a recuperação de uma consulta de vetor

  1. Abra um editor SQL no AlloyDB Studio ou abra um cliente psql.
  2. Crie um índice vetorial ScaNN, HNSW ou IVFFLAT.

  3. Confira se a flag enable_indexscan está ativada. Se a flag estiver desativada, nenhum verificação de índice será escolhido e a recuperação de todos os índices será 1.

  4. Execute a função evaluate_query_recall, que recebe a consulta como parâmetro e retorna a solicitação de recuperação a seguir:

    SELECT * FROM evaluate_query_recall( QUERY_TEXT, QUERY_TIME_CONFIGURATIONS, INDEX_METHODS )
    

    Antes de executar este comando, faça as seguintes substituições:

    • QUERY_TEXT: a consulta SQL, incluída em $$.
    • QUERY_TIME_CONFIGURATIONS: Optional: the configuration that you can set for the ANN query. This must be in JSON format. The default value is NULL.
    • INDEX_METHODS: Optional: a text array that contains different vector index methods for which you want to calculate the recall. If you set an index method for which a corresponding index doesn't exist, the recall is 1. The input must be a subset of {scann, hnsw, ivf, ivfflat}. If no value is provided, the ScaNN method is used.

      To view differences between query recall and execution time, change the query time parameters for your index.

      The following table lists query time parameters for ScaNN, HNSW, and IVF/IVFFLAT index methods. The parameters are formatted as {"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10, "hnsw.ef_search": 1}.

      Index type Parameters
      ScaNN
      • scann.num_leaves_to_search
      • scann.pre_reordering_num_neighbors
      • scann.pct_leaves_to_search
      • scann.num_search_threads
      HNSW
      • hnsw.ef_search
      • hnsw.iterative_scan
      • hnsw.max_scan_tuples
      • hnsw.scan_mem_multiplier
      IVF
      • ivf.probes
      • ivf.iterative_scan
      • ivf.max_probes
      IVFFLAT
      • ivfflat.probes
      • ivfflat.iterative_scan
      • ivfflat.max_probes

      For more information about ScaNN index methods, see AlloyDB ScaNN Index reference. For more information about HNSW and IVF/IVFFLAT index methods, see pgvector.

  5. Optional: You can also add configurations from pg_settings to the QUERY_TIME_CONFIGURATIONS. For example, to run a query with columnar engine scan enabled, add the following config from pg_settings as {"google_columnar_engine.enable_columnar_scan" : on}.

    The configurations are set locally in the function. Adding these configurations doesn't impact the configurations that you set in your session. If you don't set any configurations, AlloyDB uses all of the configurations that you set in the session. You can also set only those configurations that are best suited for your use case.

  6. Optional: To view the default configuration settings, run the SHOW command or view the pg_settings.

  7. Optional: If you have a ScaNN index for which you want to tune the recall, see the tuning parameters in ScaNN index reference.

    The following is an example output, where ann_execution_time is the time that it takes a vector query to execute using index scans. ground_truth_execution_time is the time that it takes the query to run using a sequential scan.

    ann_execution_time and ground_truth_execution_time are different from but directly dependent on Execution time in the query plan. Execution time is the total time to execute the query from the client.

    t=# SELECT * FROM evaluate_query_recall( $$ SELECT id FROM t1 ORDER BY val <=> '[1000,1000,49000]' LIMIT 10 $$, '{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10, "hnsw.ef_search": 1}', ARRAY['scann', 'hnsw']);
    NOTICE:  Recall is 1. This might mean that the vector index is not present on the table or index scan not chosen during query execution.
    id|               query                                               |                                         configurations                                         |  recall |ann_execution_time | ground_truth_execution_time |  index_type
    ----+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------+--------+--------------------+-----------------------------+------------
    1 |  SELECT id FROM t1 ORDER BY val <=> '[1000,1000,49000]' LIMIT 10  | {"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10, "hnsw.ef_search": 1} |    0.5 |               4.23 |                     118.211 | scann
    2 |  SELECT id FROM t1 ORDER BY val <=> '[1000,1000,49000]' LIMIT 10  | {"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10, "hnsw.ef_search": 1} |      1 |            107.198 |                     118.211 | hnsw
    (2 rows)
    
    

    Se o resultado for Recall is 1 (o recall da consulta é 1), isso pode indicar que o índice vetorial não está presente na tabela ou que ele não foi escolhido durante a execução da consulta. Essa situação ocorre quando não há um índice de vetor na tabela ou quando o planejador não escolhe a verificação do índice de vetor.

    Se a consulta for select id, name from table order by embedding <->'[1,2,3]' LIMIT 10;. e o valor esperado do nome da coluna for NULL, mude a consulta para uma das seguintes opções:

    select id, COALESCE(name, 'NULL') as name from table order by embedding <-> '[1,2,3]' LIMIT 10;
    

    Ou

    select id from table order by embedding <-> '[1,2,3]' LIMIT 10;
    

A seguir