Veja a similaridade: personalização da pesquisa visual com incorporações multimodais

DEZ 23, 2024
Anthony Tripaldi Senior Creative Technologist Creative Lab

O que são incorporações vetoriais?

Incorporações vetoriais são uma maneira de representar dados do mundo real, como texto, imagens ou áudio, matematicamente, como por pontos em um mapa multidimensional. Isso parece incrivelmente simples, mas com dimensões suficientes, elas permitem que os computadores (e, por extensão, nós) descubram e entendam os relacionamentos nesses dados.

Por exemplo, você talvez se lembre do "word2vec". Essa foi uma técnica revolucionária desenvolvida pelo Google em 2013 que transformou palavras em vetores numéricos, desbloqueando o poder da compreensão semântica para as máquinas. Essa inovação abriu caminho para inúmeros avanços no processamento de linguagem natural, desde a tradução automática até a análise de sentimento.

Desenvolvemos essa base com o lançamento de um avançado modelo de incorporação de texto chamado text-gecko, permitindo que os desenvolvedores explorassem os ricos relacionamentos semânticos dentro do texto.

A API Multimodal Embeddings da Vertex leva isso um passo adiante, permitindo que você represente texto, imagens e vídeo no mesmo espaço vetorial compartilhado, preservando o significado contextual e semântico em diferentes modalidades.

Nesta postagem, exploraremos duas aplicações práticas dessa tecnologia: pesquisa em todos os slides e apresentações criados por nossa equipe nos últimos 10 anos e uma ferramenta de pesquisa visual intuitiva projetada para artistas. Vamos nos aprofundar no código e compartilhar dicas práticas sobre como você pode desbloquear todo o potencial das incorporações multimodais.

Seção 1: Capacitação dos artistas com a pesquisa visual

Como tudo começou

Recentemente, nossa equipe esteve pensando em como poderíamos explorar a API Multimodal Embeddings lançada recentemente. Reconhecemos seu potencial para grandes conjuntos de dados corporativos e também estávamos ansiosos para explorar aplicações mais pessoais e criativas.

Khyati, uma designer de nossa equipe que também é ilustradora, ficou particularmente intrigada com a forma como essa tecnologia poderia ajudá-la a gerenciar e entender melhor seu trabalho. Nas palavras dela:

"Os artistas muitas vezes tem dificuldades para localizar trabalhos anteriores com base na semelhança visual ou em palavras-chave conceituais. Os métodos tradicionais de organização de arquivos simplesmente não estão à altura da tarefa, especialmente quando você pesquisa termos incomuns ou conceitos abstratos."

Assim nasceu nossa demonstração de incorporações multimodais de código aberto!

O repositório de demonstração é um aplicativo Svelte, criado durante um verdadeiro hackaton. Ele pode estar ainda um pouco cru, mas o README oferece uma orientação.

Uma breve visão geral técnica

Embora o conjunto de dados de Khyati fosse consideravelmente menor do que a escala de milhões de documentos referenciada na documentação da API Multimodal Embeddings, ele era um caso de teste ideal para a nova pesquisa vetorial do Cloud Firestore, anunciada no Google Cloud Next em abril.

Então, configuramos um projeto do Firebase e enviamos aproximadamente 250 ilustrações de Khyati para a API Multimodal Embeddings. Esse processo gerou incorporações de matriz flutuante com 1408 dimensões (fornecendo o máximo de contexto), que armazenamos em nosso banco de dados do Firestore:

mm_embedding_model = MultiModalEmbeddingModel.from_pretrained("multimodalembedding")
 
# create embeddings for each image:
embedding = mm_embedding_model.get_embeddings(
    image=image,
    dimension=1408,
)
 
# create a Firestore doc to store  and add to a collection
doc = {
    "name": "Illustration 1",
    "imageEmbedding": Vector(embedding.image_embedding),
    ... # other metadata
}
khyati_collection.add(doc)

Não deixe de indexar o campo imageEmbedding com a CLI do Firestore.

Esse bloco de código foi encurtado para fins de brevidade. Confira este notebook para ver um exemplo completo. Obtenha o modelo de incorporação no pacote vertexai.vision_models .


A pesquisa vetorial K-nearest neighbors (KNN) do Firestore é simples. Incorpore sua consulta (assim como você incorporou as imagens) e envie-a para a API:

// Our frontend is typescript but we have access to the same embedding API:
const myQuery = 'fuzzy'; // could also be an image
const myQueryVector = await getEmbeddingsForQuery(myQuery); // MM API call
const vectorQuery: VectorQuery = await khyati_collection.findNearest({
  vectorField: 'imageEmbedding', // name of your indexed field
  queryVector: myQueryVector,
  limit: 10, // how many documents to retrieve
  distanceMeasure: 'DOT_PRODUCT' // one of three algorithms for distance
});

Pronto! O método findNearest retorna os documentos mais próximos da sua incorporação de consulta, juntamente com todos os metadados associados, assim como em uma consulta padrão do Firestore.

Você pode encontrar nossa implementação /search de demonstração aqui. Observe como estamos usando a biblioteca NPM @google-cloud/firestore , o atual lar dessa tecnologia, em vez do regular pacote NPM firebase .


Bônus de redução de dimensão

Se você chegou até aqui e ainda não entende realmente como são esses vetores de incorporação, isso é compreensível: nós também não entendíamos, no início desse projeto. Nós existimos em um mundo tridimensional, então o espaço com 1408 dimensões parece ficção científica.

Felizmente, há muitas ferramentas disponíveis para reduzir a dimensionalidade desses vetores, incluindo uma implementação maravilhosa do pessoal do Google PAIR chamada UMAP. Semelhante ao t-SNE, você pode pegar seus vetores de incorporação multimodal e visualizá-los em três dimensões facilmente com o UMAP. Incluímos o código para lidar com isso no GitHub, inclusive um conjunto de dados de código aberto de imagens meteorológicas e suas incorporações que deve ser plug-and-play.

Seção 2: Pesquisa de documentos em escala empresarial

Enquanto criávamos a demonstração de Khyati, também estávamos explorando como exercitar a API Multimodal Embeddings em sua escala pretendida. Faz sentido que o Google se destaque no domínio das incorporações, afinal, uma tecnologia similar alimenta muitos de nossos principais produtos de pesquisa.

"Quantas apresentações nós temos?"

Mas como poderíamos fazer o teste em escala? Acontece que a prolífica criação de apresentações de nossa equipe oferecia um excelente campo de provas. Estamos falando de milhares de Apresentações Google acumuladas na última década. Pense nisso como uma escavação arqueológica digital da história das ideias de nossa equipe.

A pergunta passou a ser a seguinte: a API Multimodal Embeddings seria capaz de desenterrar tesouros escondidos dentro deste vasto arquivo? Os líderes de nossa equipe poderiam finalmente localizar "aquela ideia inicial sobre aquela coisa que alguém anotou em uma nota adesiva?" há muito tempo perdida? Nossos designers poderiam redescobrir facilmente aquele cartaz incrível que todos adoravam? Alerta de spoiler: sim!

Uma visão geral técnica ainda mais breve

A maior parte do nosso tempo de desenvolvimento foi gasta organizando as milhares de apresentações e extraindo miniaturas para cada slide usando as APIs Drive e Slides. O processo de incorporação em si foi quase idêntico ao da demonstração da artista e pode ser resumido da seguinte forma:

for preso in all_decks:
  for slide in preso.slides:
    thumbnail = slides_api.getThumbnail(slide.id, preso.id)
    slide_embedding = mm_embedding_model.get_embeddings(
      image=thumbnail,
      dimension=1408,
    )
    # store slide_embedding.image_embedding in a document

Esse processo gerou incorporações para mais de 775.000 slides em mais de 16.000 apresentações. Para armazenar e pesquisar esse enorme conjunto de dados com eficiência, recorremos à pesquisa vetorial da Vertex AI, projetada especificamente para aplicações de grande escala.

A pesquisa vetorial da Vertex AI, alimentada pela mesma tecnologia por trás da Pesquisa Google, do YouTube e do Google Play, é capaz de pesquisar bilhões de documentos em milissegundos. Ela opera com princípios semelhantes à abordagem do Firestore que usamos na demonstração da artista, mas com escala e desempenho significativamente maiores.

Para aproveitar essa incrível e poderosa tecnologia, você precisará concluir alguns passos extras antes de pesquisar:

# Vector Search relies on Indexes, created via code or UI, so first make sure your embeddings from the previous step are stored in a Cloud bucket, then:
my_index = aiplatform.MatchingEngineIndex.create_tree_ah_index(
    display_name = 'my_index_name',
    contents_delta_uri = BUCKET_URI,
    dimensions = 1408, # use same number as when you created them
    approximate_neighbors_count = 10, # 
)
 
# Create and Deploy this Index to an Endpoint
my_index_endpoint = aiplatform.MatchingEngineIndexEndpoint.create(
    display_name = "my_endpoint_name",
    public_endpoint_enabled = True
)
my_index_endpoint.deploy_index(
    index = my_index, deployed_index_id = "my_deployed_index_id"
)
 
# Once that's online and ready, you can query like before from your app!
response = my_index_endpoint.find_neighbors(
    deployed_index_id = "my_deployed_index_id",
    queries = [some_query_embedding],
    num_neighbors = 10
)

O processo é semelhante à demonstração de Khyati, mas com uma diferença fundamental: criamos um índice de pesquisa vetorial dedicado para liberar o poder do ScaNN, o algoritmo de pesquisa de similaridade vetorial altamente eficiente do Google.


Seção 3: Comparação da pesquisa vetorial da Vertex AI e do Firebase

Agora que você viu as duas opções, vamos analisar suas diferenças.

KNN versus ScaNN

Você deve ter notado que havia dois tipos de algoritmos associados a cada serviço de pesquisa vetorial: K-nearest neighbors para o Firestore e ScaNN para a implementação da Vertex AI. Começamos as duas demonstrações trabalhando com o Firestore, pois normalmente não trabalhamos com soluções de escala empresarial no dia a dia de nossa equipe.

Mas a pesquisa KNN do Firestore é um algoritmo de força bruta O(n), o que significa que ele faz o escalonamento linear com a quantidade de documentos que você adiciona ao seu índice. Então, uma vez que começamos a dividir por 10, 15, 20 mil incorporações de documentos, as coisas começaram a desacelerar drasticamente.

Essa desaceleração pode ser mitigada, no entanto, com os predicados de consulta padrão do Firestore usados em uma etapa de "pré-filtragem". Portanto, em vez de pesquisar todas as incorporações que você indexou, você pode fazer uma consulta where para limitar seu conjunto apenas a documentos relevantes. Isso requer outro índice composto nos campos que você deseja usar para filtrar.

# creating additional indexes is easy, but still needs to be considered
gcloud alpha firestore indexes composite create
--collection-group=all_slides
--query-scope=COLLECTION
--field-config=order=ASCENDING,field-path="project" # additional fields
--field-config field-path=slide_embedding,vector-config='{"dimension":"1408", "flat": "{}"}'

ScaNN

Semelhante ao KNN, mas contando com a indexação inteligente com base nos locais "aproximados" (daí o nome "Scalable Approximate Nearest Neighbor"), o ScaNN foi um avanço do Google Research lançado publicamente em 2020.

Bilhões de documentos podem ser consultados em milissegundos, mas esse poder tem um custo, especialmente em comparação com as leituras/gravações do Firestore. Além disso, os índices são enxutos por padrão, pares de chave-valor simples, exigindo pesquisas secundárias para suas outras coleções ou tabelas assim que os vizinhos mais próximos são retornados. Mas, para nossos 775.000 slides, uma pesquisa de aproximadamente 100 ms mais uma leitura de aproximadamente 50 ms no Firestore para os metadados ainda foi muitíssimo mais rápida do que o que a pesquisa vetorial do Cloud Firestore poderia fornecer nativamente.

Há também uma ótima documentação sobre como combinar a pesquisa vetorial com a pesquisa tradicional por palavras-chave em uma abordagem chamada pesquisa híbrida. Leia mais sobre isso aqui.

Formatação rápida à parte
A criação de índices para a Vertex AI também exigiu um formato de arquivo de chave/valor
jsonl que exigiu algum esforço para converter de nossa implementação original do Firestore. Se você não tiver certeza de qual usar, pode valer a pena escrever as incorporações em um formato agnóstico que possa ser facilmente ingerido por qualquer um dos sistemas, para não lidar com o horror relativo das exportações do LevelDB Firestore.


Alternativas locais/de código aberto

Se uma solução totalmente hospedada na nuvem não é para você, ainda é possível aproveitar o poder da API Multimodal Embeddings com uma solução local.

Também testamos uma nova biblioteca chamada sqlite-vec, uma implementação extremamente rápida e de dependência zero do sqlite que pode ser executada em quase qualquer lugar e lida com facilidade com os vetores de 1408 dimensões retornados pela API Multimodal Embeddings. A portabilidade de mais de 20.000 de nossos slides para um teste mostrou pesquisas na faixa de aproximadamente 200 ms. Você ainda está criando incorporações de documentos e consultas on-line, mas pode lidar com sua pesquisa onde quer que precise, uma vez que elas são criadas e armazenadas.


Algumas considerações finais

Desde os fundamentos do word2vec até a API Multimodal Embeddings de hoje, existem novas possibilidades interessantes para criar seus próprios sistemas multimodais de IA para pesquisar informações.

Escolher a solução de pesquisa vetorial certa depende das suas necessidades. O Firebase oferece uma opção fácil de usar e econômica para projetos menores, enquanto a Vertex AI oferece a escalonabilidade e o desempenho necessários para grandes conjuntos de dados e tempos de pesquisa de milissegundos. Para o desenvolvimento local, ferramentas como o sqlite-vec permitem aproveitar o poder das incorporações principalmente off-line.

Tudo pronto para explorar o futuro da pesquisa multimodal? Mergulhe em nossa demonstração de incorporações multimodais de código aberto no GitHub, experimente o código e compartilhe suas próprias criações. Mal podemos esperar para ver o que você vai criar.