Gerar e pesquisar embeddings multimodais

Neste tutorial, orientamos você no processo completo de criação de embeddings multimodais para imagens e texto e, em seguida, na realização de uma pesquisa de texto para imagem em várias modalidades.

Este tutorial abrange as seguintes tarefas:

Neste tutorial, usamos as imagens de arte de domínio público do The Metropolitan Museum of Art que estão disponíveis no bucket público gcs-public-data--met do Cloud Storage.

Permissões necessárias

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

  • Para criar uma conexão, é preciso ser membro do papel Administrador de conexão do BigQuery (roles/bigquery.connectionAdmin).

  • Para conceder permissões à conta de serviço da conexão, você precisa da seguinte permissão resourcemanager.projects.setIamPolicy:

  • Para criar e executar notebooks, você precisa das seguintes permissões do IAM:

    • resourcemanager.projects.get
    • resourcemanager.projects.list
    • bigquery.config.get
    • bigquery.jobs.create
    • bigquery.readsessions.create
    • bigquery.readsessions.getData
    • bigquery.readsessions.update
    • resourcemanager.projects.get
    • resourcemanager.projects.list
    • dataform.locations.get
    • dataform.locations.list
    • dataform.repositories.create

    • dataform.repositories.list

    • dataform.collections.create

    • dataform.collections.list

    • aiplatform.notebookRuntimeTemplates.apply

    • aiplatform.notebookRuntimeTemplates.get

    • aiplatform.notebookRuntimeTemplates.list

    • aiplatform.notebookRuntimeTemplates.getIamPolicy

    • aiplatform.notebookRuntimes.assign

    • aiplatform.notebookRuntimes.get

    • aiplatform.notebookRuntimes.list

    • aiplatform.operations.list

    É possível conseguir essas permissões com os seguintes papéis do IAM:

    • Usuário de sessão de leitura do BigQuery (roles/bigquery.readSessionUser)
    • Usuário do BigQuery Studio (roles/bigquery.studioUser)
  • As permissões do IAM necessárias neste tutorial para as demais operações do BigQuery estão incluídas nos dois papéis a seguir:

    • Editor de dados do BigQuery (roles/bigquery.dataEditor) para criar modelos, tabelas e índices.
    • Usuário do BigQuery (roles/bigquery.user) para executar jobs do BigQuery.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

  • BigQuery ML: You incur costs for the data that you process in BigQuery.
  • Vertex AI: You incur costs for calls to the Vertex AI service that's represented by the remote model.

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Para mais informações, consulte Preços do BigQuery na documentação do BigQuery.

Para mais informações sobre preços da Vertex AI, consulte esta página.

Antes de começar

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery, BigQuery Connection, and Vertex AI APIs.

    Enable the APIs

  4. Ative o BigQuery Studio.

Criar um conjunto de dados

Crie um conjunto de dados do BigQuery para armazenar o modelo de ML:

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

    Acesse 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.

    Criar conjunto de dados.

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

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

    • 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.

      Página Criar conjunto de dados.

Criar uma conexão

Crie uma Conexão de recursos do Cloud e tenha acesso ao ID da conta de serviço da conexão. Crie a conexão no mesmo local do conjunto de dados criado na etapa anterior.

Selecione uma das seguintes opções:

Console

  1. Acessar a página do BigQuery.

    Acessar o BigQuery

  2. Para criar uma conexão, clique em Adicionar e em Conexões com fontes de dados externas.

  3. Na lista Tipo de conexão, selecione Modelos remotos da Vertex AI, funções remotas e BigLake (Cloud Resource).

  4. No campo ID da conexão, insira um nome para a conexão.

  5. Clique em Criar conexão.

  6. Clique em Ir para conexão.

  7. No painel Informações da conexão, copie o ID da conta de serviço para uso em uma etapa posterior.

bq

  1. Em um ambiente de linha de comando, crie uma conexão:

    bq mk --connection --location=REGION --project_id=PROJECT_ID \
        --connection_type=CLOUD_RESOURCE CONNECTION_ID

    O parâmetro --project_id substitui o projeto padrão.

    Substitua:

    • REGION: sua região de conexão
    • PROJECT_ID: o ID do projeto do Google Cloud
    • CONNECTION_ID: um ID para sua conexão

    Quando você cria um recurso de conexão, o BigQuery cria uma conta de serviço do sistema exclusiva e a associa à conexão.

    Solução de problemas: se você receber o seguinte erro de conexão, atualize o SDK Google Cloud:

    Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
    
  2. Recupere e copie o ID da conta de serviço para uso em uma etapa posterior:

    bq show --connection PROJECT_ID.REGION.CONNECTION_ID

    O resultado será assim:

    name                          properties
    1234.REGION.CONNECTION_ID     {"serviceAccountId": "connection-1234-9u56h9@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}
    

Terraform

Use o recurso google_bigquery_connection.

Para autenticar no BigQuery, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

O exemplo a seguir cria uma conexão de recurso do Cloud chamada my_cloud_resource_connection na região US:


# This queries the provider for project information.
data "google_project" "default" {}

# This creates a cloud resource connection in the US region named my_cloud_resource_connection.
# Note: The cloud resource nested object has only one output field - serviceAccountId.
resource "google_bigquery_connection" "default" {
  connection_id = "my_cloud_resource_connection"
  project       = data.google_project.default.project_id
  location      = "US"
  cloud_resource {}
}

Para aplicar a configuração do Terraform em um projeto do Google Cloud, conclua as etapas nas seções a seguir.

Preparar o Cloud Shell

  1. Inicie o Cloud Shell.
  2. Defina o projeto padrão do Google Cloud em que você quer aplicar as configurações do Terraform.

    Você só precisa executar esse comando uma vez por projeto, e ele pode ser executado em qualquer diretório.

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    As variáveis de ambiente serão substituídas se você definir valores explícitos no arquivo de configuração do Terraform.

Preparar o diretório

Cada arquivo de configuração do Terraform precisa ter o próprio diretório, também chamado de módulo raiz.

  1. No Cloud Shell, crie um diretório e um novo arquivo dentro dele. O nome do arquivo precisa ter a extensão .tf, por exemplo, main.tf. Neste tutorial, o arquivo é chamado de main.tf.
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. Se você estiver seguindo um tutorial, poderá copiar o exemplo de código em cada seção ou etapa.

    Copie o exemplo de código no main.tf recém-criado.

    Se preferir, copie o código do GitHub. Isso é recomendado quando o snippet do Terraform faz parte de uma solução de ponta a ponta.

  3. Revise e modifique os parâmetros de amostra para aplicar ao seu ambiente.
  4. Salve as alterações.
  5. Inicialize o Terraform. Você só precisa fazer isso uma vez por diretório.
    terraform init

    Opcionalmente, para usar a versão mais recente do provedor do Google, inclua a opção -upgrade:

    terraform init -upgrade

Aplique as alterações

  1. Revise a configuração e verifique se os recursos que o Terraform vai criar ou atualizar correspondem às suas expectativas:
    terraform plan

    Faça as correções necessárias na configuração.

  2. Para aplicar a configuração do Terraform, execute o comando a seguir e digite yes no prompt:
    terraform apply

    Aguarde até que o Terraform exiba a mensagem "Apply complete!".

  3. Abra seu projeto do Google Cloud para ver os resultados. No console do Google Cloud, navegue até seus recursos na IU para verificar se foram criados ou atualizados pelo Terraform.

Conceder permissões para a conta de serviço do portal

Conceda à conta de serviço da conexão as funções adequadas para acessar os serviços do Cloud Storage e da Vertex AI. É necessário conceder essas funções no mesmo projeto que você criou ou selecionou na seção Antes de começar. Conceder os papéis em um projeto diferente resulta no erro bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource.

Para conceder as funções adequadas, siga estas etapas:

  1. Acessar a página AM e administrador

    Acessar IAM e administrador

  2. Clique em Conceder acesso.

  3. No campo Novos principais, digite o ID da conta de serviço que você copiou anteriormente.

  4. No campo Selecionar um papel, escolha Vertex AI e, em seguida, selecione Usuário da Vertex AI.

  5. Clique em Adicionar outro papel.

  6. No campo Selecionar papel, escolha Cloud Storage e, em seguida, Visualizador de objetos do Storage.

  7. Clique em Salvar.

Criar a tabela de objetos

Crie uma tabela de objetos sobre as imagens de arte no bucket gcs-public-data--met público do Cloud Storage. Com a tabela de objetos, é possível analisar as imagens sem movê-las do Cloud Storage.

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

    Acessar o BigQuery

  2. No Editor de consultas, execute esta consulta:

    CREATE OR REPLACE EXTERNAL TABLE `bqml_tutorial.met_images`
    WITH CONNECTION `LOCATION.CONNECTION_ID`
    OPTIONS
      ( object_metadata = 'SIMPLE',
        uris = ['gs://gcs-public-data--met/*']
      );

    Substitua:

    • LOCATION: o local da conexão.
    • CONNECTION_ID: o ID da sua conexão do BigQuery.

      Quando você visualiza os detalhes da conexão no console do Google Cloud, esse é o valor na última seção do ID da conexão totalmente qualificado, mostrado em ID da conexão, por exemplo projects/myproject/locations/connection_location/connections/myconnection.

Analise os dados da imagem

Crie um notebook Colab Enterprise no BigQuery para explorar os dados da imagem.

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

    Acessar o BigQuery

  2. Crie um notebook usando o editor do BigQuery.

  3. Conecte o notebook ao ambiente de execução padrão.

  4. Configure o notebook:

    1. Adicione uma célula de código ao notebook.
    2. Copie e cole o seguinte código na célula de código:

      #@title Set up credentials
      
      from google.colab import auth
      auth.authenticate_user()
      print('Authenticated')
      
      PROJECT_ID='PROJECT_ID'
      from google.cloud import bigquery
      client = bigquery.Client(PROJECT_ID)
      

      Substitua PROJECT_ID pelo nome do projeto que você está usando para este tutorial.

    3. Execute a célula de código.

  5. Ative a exibição da tabela:

    1. Adicione uma célula de código ao notebook.
    2. Copie e cole o seguinte código na célula de código:

      #@title Enable data table display
      %load_ext google.colab.data_table
      
    3. Execute a célula de código.

  6. Crie uma função para mostrar as imagens:

    1. Adicione uma célula de código ao notebook.
    2. Copie e cole o seguinte código na célula de código:

      #@title Util function to display images
      import io
      from PIL import Image
      import matplotlib.pyplot as plt
      import tensorflow as tf
      
      def printImages(results):
       image_results_list = list(results)
       amt_of_images = len(image_results_list)
      
       fig, axes = plt.subplots(nrows=amt_of_images, ncols=2, figsize=(20, 20))
       fig.tight_layout()
       fig.subplots_adjust(hspace=0.5)
       for i in range(amt_of_images):
         gcs_uri = image_results_list[i][0]
         text = image_results_list[i][1]
         f = tf.io.gfile.GFile(gcs_uri, 'rb')
         stream = io.BytesIO(f.read())
         img = Image.open(stream)
         axes[i, 0].axis('off')
         axes[i, 0].imshow(img)
         axes[i, 1].axis('off')
         axes[i, 1].text(0, 0, text, fontsize=10)
       plt.show()
      
    3. Execute a célula de código.

  7. Mostre as imagens:

    1. Adicione uma célula de código ao notebook.
    2. Copie e cole o seguinte código na célula de código:

      #@title Display Met images
      
      inspect_obj_table_query = """
      SELECT uri, content_type
      FROM bqml_tutorial.met_images
      WHERE content_type = 'image/jpeg'
      Order by uri
      LIMIT 10;
      """
      printImages(client.query(inspect_obj_table_query))
      
    3. Execute a célula de código.

      A resposta deve ficar assim:

      Imagens que mostram objetos do Metropolitan Museum of Art.

  8. Salve o notebook como met-image-analysis.

Criar o modelo remoto

Crie um modelo remoto que represente um modelo de incorporação multimodal hospedado da Vertex AI:

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

    Acessar o BigQuery

  2. No Editor de consultas, execute esta consulta:

    CREATE OR REPLACE MODEL `bqml_tutorial.multimodal_embedding_model`
      REMOTE WITH CONNECTION `LOCATION.CONNECTION_ID`
      OPTIONS (ENDPOINT = 'multimodalembedding@001');

    Substitua:

    • LOCATION: o local da conexão.
    • CONNECTION_ID: o ID da sua conexão do BigQuery.

      Quando você visualiza os detalhes da conexão no console do Google Cloud, esse é o valor na última seção do ID da conexão totalmente qualificado, mostrado em ID da conexão, por exemplo projects/myproject/locations/connection_location/connections/myconnection.

    A consulta leva alguns segundos para ser concluída. Depois disso, o modelo multimodal_embedding_model aparece no conjunto de dados bqml_tutorial no painel Explorer. Como a consulta usa uma instrução CREATE MODEL para criar um modelo, não há resultados de consulta.

Gerar embeddings de imagem

Gere embeddings das imagens na tabela de objetos usando a função ML.GENERATE_EMBEDDING. Depois, grave-os em uma tabela para usar em uma etapa a seguir. A geração de embedding é uma operação cara. Por isso, a consulta usa uma cláusula LIMIT para limitar a geração de embeddings a 10.000 imagens, em vez de incorporar o conjunto de dados completo de 601.294 imagens. Isso também ajuda a manter o número de imagens abaixo do limite de 25.000 para a função ML.GENERATE_EMBEDDING. Essa consulta leva aproximadamente 40 minutos para ser executada.

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

    Acessar o BigQuery

  2. No Editor de consultas, execute esta consulta:

    CREATE OR REPLACE TABLE `bqml_tutorial.met_image_embeddings`
    AS
    SELECT *
    FROM
      ML.GENERATE_EMBEDDING(
        MODEL `bqml_tutorial.multimodal_embedding_model`,
        (SELECT * FROM `bqml_tutorial.met_images` WHERE content_type = 'image/jpeg' LIMIT 10000))

Corrigir erros de geração de embedding

Verifique e corrija erros de geração de incorporação. A geração de embeddings pode falhar por causa das cotas de IA generativa na Vertex AI ou da indisponibilidade de serviços.

A função ML.GENERATE_EMBEDDING retorna detalhes do erro na coluna ml_generate_embedding_status. Essa coluna estará vazia se a geração de incorporação tiver sido bem-sucedida ou conterá uma mensagem de erro se a geração de incorporação falhar.

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

    Acessar o BigQuery

  2. No editor de consultas, execute a seguinte consulta para ver se houve alguma falha na geração de incorporação:

    SELECT DISTINCT(ml_generate_embedding_status),
      COUNT(uri) AS num_rows
    FROM bqml_tutorial.met_image_embeddings
    GROUP BY 1;
  3. Se forem retornadas linhas com erros, elimine todas as linhas em que a geração de incorporação falhou:

    DELETE FROM `bqml_tutorial.met_image_embeddings`
    WHERE ml_generate_embedding_status = 'A retryable error occurred: RESOURCE_EXHAUSTED error from remote service/endpoint.';

Criar um índice vetorial

Também é possível usar a instrução CREATE VECTOR INDEX para criar o índice de vetor met_images_index na coluna ml_generate_embedding_result da tabela met_images_embeddings. Um índice vetorial permite realizar uma pesquisa de vetor mais rapidamente, com a desvantagem de reduzir o recall e retornar resultados mais aproximados.

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

    Acessar o BigQuery

  2. No Editor de consultas, execute esta consulta:

    CREATE OR REPLACE
      VECTOR INDEX `met_images_index`
    ON
      bqml_tutorial.met_image_embeddings(ml_generate_embedding_result)
      OPTIONS (
        index_type = 'IVF',
        distance_type = 'COSINE');
  3. O índice de vetor é criado de forma assíncrona. Para verificar se o índice de vetor foi criado, consulte a visualização INFORMATION_SCHEMA.VECTOR_INDEXES e confirme se o valor de coverage_percentage é maior que 0. e o valor de last_refresh_time não for NULL:

    SELECT table_name, index_name, index_status,
      coverage_percentage, last_refresh_time, disable_reason
    FROM bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES
    WHERE index_name = 'met_images_index';

Gerar um embedding para o texto de pesquisa

Para pesquisar imagens que correspondam a uma string de pesquisa de texto especificada, primeiro crie um embedding de texto para essa string. Use o mesmo modelo remoto para criar o embedding de texto usado para gerar os embeddings de imagem e, em seguida, grave o embedding de texto em uma tabela para uso em uma etapa seguinte. A string de pesquisa é pictures of white or cream colored dress from victorian era.

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

    Acessar o BigQuery

  2. No Editor de consultas, execute esta consulta:

    CREATE OR REPLACE TABLE `bqml_tutorial.search_embedding`
    AS
    SELECT * FROM ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.multimodal_embedding_model`,
      (
        SELECT 'pictures of white or cream colored dress from victorian era' AS content
      )
    );

Use as VECTOR_SEARCH função para procurar imagens que melhor correspondem à string de pesquisa representada pelo embedding de texto e, em seguida, gravá-las em uma tabela para uso em uma etapa a seguir.

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

    Acessar o BigQuery

  2. No Editor de consultas, execute esta consulta:

    CREATE OR REPLACE TABLE `bqml_tutorial.vector_search_results` AS
    SELECT base.uri AS gcs_uri, distance
    FROM
      VECTOR_SEARCH(
        TABLE `bqml_tutorial.met_image_embeddings`,
        'ml_generate_embedding_result',
        TABLE `bqml_tutorial.search_embedding`,
        'ml_generate_embedding_result',
        top_k => 3);

Visualizar os resultados da pesquisa de vetor

Visualizar os resultados da pesquisa de vetor usando um notebook.

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

    Acessar o BigQuery

  2. Abra o notebook met-image-analysis que você criou anteriormente.

  3. Visualize os resultados da pesquisa de vetor:

    1. Adicione uma célula de código ao notebook.
    2. Copie e cole o seguinte código na célula de código:

      query = """
        SELECT * FROM `bqml_tutorial.vector_search_results`
        ORDER BY distance;
      """
      
      printImages(client.query(query))
      
    3. Execute a célula de código.

      A resposta deve ficar assim:

      Imagens retornadas de uma consulta de pesquisa de vetor multimodal.

Limpar

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.