Compreendendo o desafio das buscas multimodais
Os mecanismos de busca convencionais enfrentam limitações significativas quando precisam lidar com diferentes tipos de conteúdo. Abordagens tradicionais dependem de buscas por palavras-chave, de embeddings textuais para processamento de linguagem natural, ou de buscas híbridas, mas nenhuma consegue processar efetivamente consultas visuais. Essa fragmentação cria uma lacuna considerável entre o que o usuário quer encontrar e o que o sistema consegue recuperar.
O problema é estrutural: arquiteturas típicas separam o processamento de conteúdo visual do textual, perdendo contexto no processo. Quando um usuário faz uma busca por texto, o sistema procura nas descrições de produtos usando correspondência de palavras-chave ou embeddings textuais. Quando tenta buscar por imagens, recorre a pipelines de visão computacional separados com integração limitada ao conteúdo textual. Essa separação complexifica toda a arquitetura e degrada a experiência do usuário.
Além disso, usar múltiplos modelos de embedding exige ciclos distintos de manutenção e otimização. Consultas que envolvem diferentes modalidades não conseguem ser processadas nativamente em um único sistema. Os escores de similaridade entre conteúdo visual e textual operam em espaços matemáticos diferentes, dificultando classificações consistentes entre tipos de conteúdo. Essa separação força mapeamentos complexos que frequentemente não funcionam bem, levando as organizações a manter sistemas de embedding isolados que criam silos de dados e limitam funcionalidades.
Em e-commerce, o desafio é ainda maior. Páginas de produtos combinam imagens, descrições, especificações e às vezes vídeos de demonstração, criando um cenário de conteúdo complexo que os buscadores tradicionais não conseguem integrar adequadamente.
O conceito de embeddings multimodais
Embeddings multimodais mapeiam texto, imagens, áudio e vídeo para um espaço vetorial compartilhado onde conteúdo semanticamente similar se agrupa naturalmente. Por exemplo, quando um modelo processa a consulta textual “vestido vermelho de verão” junto com uma imagem de um vestido vermelho, ambas as entradas geram vetores próximos um do outro no espaço de embedding, refletindo sua similaridade semântica e desbloqueando recuperação de conteúdo através de diferentes modalidades.
Utilizando embeddings multimodais, é possível buscar entre diferentes tipos de conteúdo sem precisar manter sistemas separados para cada modalidade. Isso resolve o problema dos sistemas multimodais segmentados, onde organizações gerenciam múltiplos modelos de embedding que são praticamente impossíveis de integrar efetivamente porque embeddings de diferentes modalidades simplesmente não são compatíveis entre si.
Uma arquitetura de modelo único garante que a geração de embeddings seja consistente em todos os tipos de conteúdo. Conteúdo relacionado, como imagens de produtos, vídeos e suas descrições, gera embeddings similares graças aos objetivos de treinamento conjunto. As aplicações conseguem gerar embeddings para todos os tipos de conteúdo usando pontos de extremidade idênticos da API e mesmas dimensões vetoriais, reduzindo significativamente a complexidade do sistema.
Caso de uso: buscas em e-commerce
Imagine um cliente que vê uma camiseta em um programa de TV e deseja encontrar itens similares para comprar. Ele pode fotografar o item com seu telefone ou tentar descrever o que viu em texto e usar isso para buscar um produto. Os mecanismos tradicionais lidam razoavelmente bem com buscas em texto que referenciam metadados, mas não conseguem executar quando clientes desejam usar imagens para buscar ou descrever atributos visuais de um item.
Essa experiência de “da TV para o carrinho de compras” demonstra como buscas visuais e textuais trabalham juntas. O cliente envia uma foto, e o sistema a compara contra catálogos de produtos que contêm tanto imagens quanto descrições. O fluxo de trabalho multimodal em e-commerce funciona através de etapas bem definidas: o usuário inicia com uma consulta (texto, imagem ou ambas), essa entrada é transformada em um embedding através de um modelo unificado, a similaridade é calculada contra o catálogo pré-indexado, e resultados são ranqueados pela relevância.

Como o Amazon Nova Multimodal Embeddings ajuda
Amazon Nova Multimodal Embeddings processa texto, documentos, imagens, vídeos e áudio através de uma única arquitetura de modelo. Disponível através de Amazon Bedrock, o modelo converte diferentes modalidades de entrada em embeddings numéricos dentro do mesmo espaço vetorial, permitindo cálculos diretos de similaridade independentemente do tipo de conteúdo.
O Amazon Nova lida com diferentes tipos de consultas de busca através do mesmo modelo, criando tanto novas capacidades de busca quanto vantagens técnicas. Independentemente de o usuário enviar imagens, inserir descrições em texto, ou combinar ambas as abordagens, o processo funciona da mesma maneira.
Capacidades de busca multimodal
Quando clientes enviam imagens, o sistema as converte em embeddings e busca contra o catálogo de produtos usando similaridade de cosseno. O resultado são produtos com características visuais similares, independentemente de como são descritos em texto. Consultas textuais funcionam da mesma forma — clientes conseguem descrever o que desejam e encontrar produtos visualmente similares, mesmo quando as descrições de produtos usam palavras diferentes.
Se o cliente envia uma imagem com uma descrição em texto, o sistema processa ambas as entradas através do mesmo modelo de embedding para escoring de similaridade unificado. O sistema também extrai atributos de produtos de imagens automaticamente através de marcação automática de produtos, suportando geração de tags semânticas que vai além da categorização manual.
Vantagens técnicas
A arquitetura unificada oferece vários benefícios sobre embeddings de texto e imagem separados. O design de modelo único e espaço semântico compartilhado desbloqueiam casos de uso novos que não são alcançáveis gerenciando múltiplos sistemas de embedding. Aplicações geram embeddings para todos os tipos de conteúdo usando os mesmos pontos de extremidade da API e dimensões vetoriais.
Um modelo único lida com todas as cinco modalidades, então conteúdo relacionado, como imagens de produtos e suas descrições, produz embeddings similares. É possível calcular distâncias entre qualquer combinação de texto, imagens, áudio e vídeo para medir o quão similares eles são.
O modelo Matryoshka representation learning oferece suporte a múltiplas dimensões de embedding: 3072, 1024, 384 e 256. O aprendizado de embedding Matryoshka armazena as informações mais importantes nas primeiras dimensões e detalhes menos críticos em dimensões posteriores. É possível truncar a partir do final para reduzir espaço de armazenamento mantendo precisão para o caso de uso específico.

Arquitetura da solução
Três componentes principais são necessários para construir essa abordagem: geração de embeddings, armazenamento vetorial e busca por similaridade. Catálogos de produtos passam por pré-processamento para gerar embeddings para todos os tipos de conteúdo. O processamento de consultas converte entradas do usuário em embeddings usando o mesmo modelo. A busca por similaridade compara embeddings de consultas contra embeddings de produtos armazenados.
Sistemas de armazenamento vetorial precisam suportar as dimensões de embedding escolhidas e fornecer operações eficientes de busca por similaridade. As opções incluem bancos de dados vetoriais específicos para esse propósito, bancos de dados tradicionais com extensões vetoriais, ou serviços vetoriais centrados em nuvem como Amazon S3 Vectors, um recurso de Amazon S3 que oferece suporte nativo para armazenar e consultar embeddings vetoriais diretamente dentro de S3.

Implementação prática
Pré-requisitos
Para usar a funcionalidade efetivamente, alguns aspectos-chave são necessários para essa implementação. Uma conta AWS com permissões de acesso ao Amazon Bedrock para o modelo Amazon Nova Multimodal Embeddings. Os serviços adicionais necessários incluem S3 Vectors. Um notebook está disponível no repositório de exemplos do Amazon Nova para seguir passo a passo.
Configuração de bucket e índice vetorial
O primeiro passo é criar a infraestrutura de armazenamento vetorial para embeddings. S3 Vectors é um serviço gerenciado para armazenar e consultar vetores de alta dimensionalidade em escala. O bucket atua como contêiner para os dados vetoriais, enquanto o índice define a estrutura e características de busca. O índice é configurado com métrica de distância de cosseno, que mede similaridade baseada na direção do vetor em vez de sua magnitude, tornando-o ideal para embeddings normalizados de modelos fornecidos por serviços como Amazon Nova Multimodal Embeddings.
# Configuração S3 Vectors
s3vector_bucket = "amzn-s3-demo-vector-bucket-crossmodal-search"
s3vector_index = "product"
embedding_dimension = 1024
s3vectors = boto3.client("s3vectors", region_name="us-east-1")
# Criar bucket de vetores S3
s3vectors.create_vector_bucket(vectorBucketName=s3vector_bucket)
# Criar índice
s3vectors.create_index(
vectorBucketName=s3vector_bucket,
indexName=s3vector_index,
dataType='float32',
dimension=embedding_dimension,
distanceMetric='cosine'
)
Pré-processamento do catálogo de produtos
O próximo passo é gerar embeddings. Tanto imagens de produtos quanto descrições textuais requerem geração e armazenamento de embeddings com metadados apropriados para recuperação. A API Amazon Nova Embeddings processa cada modalidade independentemente, convertendo descrições de produtos e imagens de produtos em vetores de 1024 dimensões. Esses vetores vivem em um espaço semântico unificado, o que significa que um embedding de texto e um embedding de imagem do mesmo produto estarão geometricamente próximos um do outro.
# Inicializar cliente Nova Embeddings
class NovaEmbeddings:
def __init__(self, region='us-east-1'):
self.bedrock = boto3.client('bedrock-runtime', region_name=region)
self.model_id = "amazon.nova-2-multimodal-embeddings-v1:0"
def embed_text(self, text: str, dimension: int = 1024, purpose: str = "GENERIC_INDEX"):
request_body = {
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingDimension": dimension,
"embeddingPurpose": purpose,
"text": {
"truncationMode": "END",
"value": text
}
}
}
response = self.bedrock.invoke_model(modelId=self.model_id, body=json.dumps(request_body))
result = json.loads(response['body'].read())
return result['embeddings'][0]['embedding']
def embed_image(self, image_bytes: bytes, dimension: int = 1024, purpose: str = "GENERIC_INDEX"):
request_body = {
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingDimension": dimension,
"embeddingPurpose": purpose,
"image": {
"format": "jpeg",
"source": {"bytes": base64.b64encode(image_bytes).decode()}
}
}
}
response = self.bedrock.invoke_model(modelId=self.model_id, body=json.dumps(request_body))
result = json.loads(response['body'].read())
return result['embeddings'][0]['embedding']
embeddings = NovaEmbeddings()
O código a seguir gera os embeddings e envia os dados para o armazenamento vetorial:
# Gerar embeddings e fazer upload para Amazon S3 Vectors
def get_product_text(product):
name = product.get('item_name', [{}])[0].get('value', '') if isinstance(product.get('item_name'), list) else str(product.get('item_name', ''))
brand = product.get('brand', [{}])[0].get('value', '') if product.get('brand') else ''
return f"{name}. {brand}".strip()
vectors_to_upload = []
batch_size = 10
catalog = []
for product in tqdm(sampled_products, desc="Processing products"):
img_path = get_image_path(product)
text = get_product_text(product)
product_id = product.get('item_id', str(len(catalog)))
with open(img_path, 'rb') as f:
img_bytes = f.read()
# Gerar embeddings
text_emb = embeddings.embed_text(text)
image_emb = embeddings.embed_image(img_bytes)
# Armazenar no catálogo local
catalog.append({
'text': text,
'image_path': str(img_path),
'text_emb': text_emb,
'image_emb': image_emb,
'product_id': product_id
})
# Preparar vetores para upload em S3
vectors_to_upload.extend([
{
"key": f"text-{product_id}",
"data": {"float32": text_emb},
"metadata": {"product_id": product_id, "text": text, "image_path": str(img_path), "type": "text"}
},
{
"key": f"image-{product_id}",
"data": {"float32": image_emb},
"metadata": {"product_id": product_id, "text": text, "image_path": str(img_path), "type": "image"}
},
{
"key": f"combined-{product_id}",
"data": {"float32": np.mean([text_emb, image_emb], axis=0).tolist()},
"metadata": {"product_id": product_id, "text": text, "image_path": str(img_path), "type": "combined"}
}
])
# Upload em lotes
if len(vectors_to_upload) >= batch_size * 3:
s3vectors.put_vectors(vectorBucketName=s3vector_bucket, indexName=s3vector_index, vectors=vectors_to_upload)
vectors_to_upload = []
# Upload dos vetores restantes
if vectors_to_upload:
s3vectors.put_vectors(vectorBucketName=s3vector_bucket, indexName=s3vector_index, vectors=vectors_to_upload)
Processamento de consultas
Esse código lida com entrada do cliente através da API. Consultas de texto, uploads de imagens, ou combinações se convertem no mesmo formato vetorial usado para o catálogo de produtos. Para consultas multimodais que combinam texto e imagem, é aplicada fusão por média para criar um vetor de consulta único que captura informações de ambas as modalidades.
def search_s3(query=None, query_image=None, query_type='text', search_mode='combined', top_k=5):
"""
Buscar usando S3 Vectors
query_type: 'text', 'image', ou 'both'
search_mode: 'text', 'image', ou 'combined'
"""
# Obter embedding de consulta
if query_type == 'both':
text_emb = embeddings.embed_text(query)
with open(query_image, 'rb') as f:
image_emb = embeddings.embed_image(f.read())
query_emb = np.mean([text_emb, image_emb], axis=0).tolist()
query_image_path = query_image
elif query_type == 'text':
query_emb = embeddings.embed_text(query)
query_image_path = None
else:
with open(query_image, 'rb') as f:
query_emb = embeddings.embed_image(f.read())
query_image_path = query_image
Busca por similaridade vetorial
O próximo passo é adicionar recuperação multimodal usando a API de consulta S3 Vectors. O sistema encontra a correspondência de embedding mais próxima à consulta, independentemente se foi texto ou imagem. É usado cosseno como métrica de distância, que mede o ângulo entre vetores em vez de sua distância absoluta. Essa abordagem funciona bem para embeddings normalizados e é eficiente em recursos, tornando-a adequada para catálogos grandes quando associada a algoritmos de vizinho aproximado mais próximo.
# Consultar S3 Vectors
response = s3vectors.query_vectors(
vectorBucketName=s3vector_bucket,
indexName=s3vector_index,
queryVector={"float32": query_emb},
topK=top_k,
returnDistance=True,
returnMetadata=True,
filter={"metadata.type": {"equals": search_mode}}
)
Classificação de resultados
Os escores de similaridade computados por S3 Vectors fornecem o mecanismo de classificação. A similaridade de cosseno entre embeddings de consulta e catálogo determina a ordem de resultados, com escores mais altos indicando correspondências melhores. Em sistemas de produção, normalmente seria coletado dados de cliques e julgamentos de relevância para validar que a classificação se correlaciona com comportamento real do usuário. S3 Vectors retorna valores de distância que são convertidos em escores de similaridade (1 – distância) para interpretação intuitiva onde valores mais altos indicam correspondências mais próximas.
# Extrair e classificar resultados por similaridade
ranked_results = []
for result in response['vectors']:
metadata = result['metadata']
distance = result.get('distance', 0)
similarity = 1 - distance # Converter distância em escore de similaridade
ranked_results.append({
'product_id': metadata['product_id'],
'text': metadata['text'],
'image_path': metadata['image_path'],
'similarity': similarity,
'distance': distance
})
# Resultados são classificados por S3 Vectors (melhores correspondências primeiro)
return ranked_results
Por que isso importa
Amazon Nova Multimodal Embeddings resolve o problema central de busca multimodal usando um único modelo em vez de gerenciar sistemas separados. É possível usar o Amazon Nova Multimodal Embeddings para construir buscas que funcionam independentemente de clientes enviarem imagens, inserirem descrições em texto, ou combinarem ambas as abordagens.
A implementação é direta usando as APIs do Amazon Bedrock, e as dimensões de embedding Matryoshka permitem otimizar para requisitos específicos de precisão e custo. As dimensões de embedding Matryoshka mantêm qualidade de embedding em diferentes dimensões com degradação de desempenho previsível, permitindo que aplicações se otimizem para casos de uso específicos.
Próximos passos
Amazon Nova Multimodal Embeddings está disponível em Amazon Bedrock. Consulte Usando Nova Embeddings para referências de API, exemplos de código e padrões de integração para arquiteturas comuns. O repositório de exemplos AWS contém exemplos de implementação para embeddings multimodais.
Fonte
Crossmodal search with Amazon Nova Multimodal Embeddings (https://aws.amazon.com/blogs/machine-learning/crossmodal-search-with-amazon-nova-multimodal-embeddings/)
Leave a Reply