Como obter os embeddings vetoriais certos
Este artigo foi publicado originalmente em The New Stack e é republicado aqui com permissão.
Uma introdução abrangente aos embeddings vetoriais e a como gerá-los com modelos populares de código aberto.
Imagem de Денис Марчук do Pixabay
Embeddings vetoriais são essenciais ao trabalhar com similaridade semântica. No entanto, um vetor é simplesmente uma série de números; um embedding vetorial é uma série de números que representa dados de entrada. Usando embeddings vetoriais, podemos estruturar dados não estruturados ou trabalhar com qualquer tipo de dado convertendo-o em uma série de números. Essa abordagem nos permite realizar operações matemáticas nos dados de entrada, em vez de depender de comparações qualitativas.
Embeddings vetoriais são influentes para muitas tarefas, especialmente para busca semântica. No entanto, é crucial obter os embeddings vetoriais apropriados antes de usá-los. Por exemplo, se você usar um modelo de imagem para vetorizar texto, ou vice-versa, provavelmente obterá resultados ruins.
Neste post, aprenderemos o que significam embeddings vetoriais, como gerar os embeddings vetoriais corretos para suas aplicações usando diferentes modelos e como aproveitar ao máximo embeddings vetoriais com bancos de dados vetoriais como Milvus e Zilliz Cloud.
Como os embeddings vetoriais são criados?
Agora que entendemos a importância dos embeddings vetoriais, vamos aprender como eles funcionam. Um embedding vetorial é a representação interna dos dados de entrada em um modelo de deep learning, também conhecido como modelos de embedding ou uma rede neural profunda. Então, como extraímos essa informação?
Obtemos vetores removendo a última camada e pegando a saída da penúltima camada. A última camada de uma rede neural geralmente produz a previsão do modelo, então pegamos a saída da penúltima camada. O embedding vetorial é o dado fornecido à camada preditiva de uma rede neural.
A dimensionalidade de um embedding vetorial é equivalente ao tamanho da penúltima camada no modelo e, portanto, intercambiável com o tamanho ou comprimento do vetor. Dimensionalidades vetoriais comuns incluem 384 (gerada pelo Sentence Transformers Mini-LM), 768 (pelo Sentence Transformers MPNet), 1.536 (pela OpenAI) e 2.048 (pelo ResNet-50).
O que significa um embedding vetorial?
Alguém uma vez me perguntou sobre o significado de cada dimensão em um embedding vetorial. A resposta curta é: nada. Uma única dimensão em um embedding vetorial não significa nada, pois é abstrata demais para determinar seu significado. No entanto, quando consideramos todas as dimensões em conjunto, elas fornecem o significado semântico dos dados de entrada.
As dimensões do vetor são representações abstratas e de alto nível de diferentes atributos. Os atributos representados dependem dos dados de treinamento e do próprio modelo. Modelos de texto e imagem geram embeddings diferentes porque são treinados para tipos de dados fundamentalmente diferentes. Até mesmo diferentes modelos de texto geram embeddings diferentes. Às vezes, eles diferem em tamanho; outras vezes, diferem nos atributos que representam. Por exemplo, um modelo treinado com dados jurídicos aprenderá coisas diferentes de um treinado com dados de saúde. Explorei esse tópico no meu post comparando embeddings vetoriais.
Gere os embeddings vetoriais corretos
Como você obtém os embeddings vetoriais adequados? Tudo começa com a identificação do tipo de dado que você deseja incorporar. Esta seção aborda a incorporação de cinco tipos diferentes de dados: imagens, texto, áudio, vídeos e dados multimodais. Todos os modelos que apresentamos aqui são de código aberto e vêm do Hugging Face ou do PyTorch.
Embeddings de imagens
O reconhecimento de imagens decolou em 2012 depois que o AlexNet entrou em cena. Desde então, o campo da visão computacional testemunhou inúmeros avanços. O modelo de reconhecimento de imagens notável mais recente é o ResNet-50, uma rede residual profunda de 50 camadas baseada na antiga arquitetura ResNet-34.
Redes neurais residuais (ResNet) resolvem o problema do gradiente evanescente em redes neurais convolucionais profundas usando conexões de atalho. Essas conexões permitem que a saída de camadas anteriores vá diretamente para camadas posteriores sem passar por todas as camadas intermediárias, evitando assim o problema do gradiente evanescente. Esse design torna a ResNet menos complexa do que a VGGNet (Visual Geometry Group), uma rede neural convolucional que anteriormente tinha desempenho de ponta.
Recomendo duas implementações da ResNet-50 como exemplos: ResNet 50 no Hugging Face e ResNet 50 no PyTorch Hub. Embora as redes sejam as mesmas, o processo de obtenção dos embeddings é diferente.
O exemplo de código abaixo demonstra como usar o PyTorch para obter embeddings vetoriais. Primeiro, carregamos o modelo a partir do PyTorch Hub. Em seguida, removemos a última camada e chamamos .eval() para instruir o modelo a se comportar como se estivesse sendo executado para inferência. Então, a função embed gera o embedding vetorial.
# Load the embedding model with the last layer removed
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True) model = torch.nn.Sequential(*(list(model.children())[:-1]))
model.eval()
def embed(data):
with torch.no_grad():
output = model(torch.stack(data[0])).squeeze()
return output
O HuggingFace usa uma configuração ligeiramente diferente. O código abaixo demonstra como obter um embedding vetorial a partir do Hugging Face. Primeiro, precisamos de um extrator de características e de um modelo da biblioteca transformers . Usaremos o extrator de características para obter entradas para o modelo e usaremos o modelo para obter saídas e extrair o último estado oculto.
# Load model directly
from transformers import AutoFeatureExtractor, AutoModelForImageClassification
extractor = AutoFeatureExtractor.from_pretrained("microsoft/resnet-50")
model = AutoModelForImageClassification.from_pretrained("microsoft/resnet-50")
from PIL import Image
image = Image.open("<image path>")
# image = Resize(size=(256, 256))(image)
inputs = extractor(images=image, return_tensors="pt")
# print(inputs)
outputs = model(**inputs)
vector_embeddings = outputs[1][-1].squeeze()
Embeddings de texto
Engenheiros e pesquisadores vêm experimentando com linguagem natural e IA desde a invenção da IA. Alguns dos primeiros experimentos incluem:
- ELIZA, o primeiro chatbot terapeuta de IA.
- O Quarto Chinês de John Searle, um experimento mental que examina se a capacidade de traduzir entre chinês e inglês requer uma compreensão da linguagem.
- Traduções baseadas em regras entre inglês e russo.
A operação da IA sobre linguagem natural evoluiu significativamente a partir de seus embeddings baseados em regras. Começando com redes neurais primárias, adicionamos relações de recorrência por meio de RNNs para acompanhar etapas no tempo. A partir daí, usamos transformers para resolver o problema de transdução de sequências.
Transformers consistem em um codificador, que codifica uma entrada em uma matriz que representa o estado, uma matriz de atenção e um decodificador. O decodificador decodifica o estado e a matriz de atenção para prever o próximo token correto para finalizar a sequência de saída. O GPT-3, o modelo de linguagem mais popular até hoje, compreende decodificadores estritos. Eles codificam a entrada e preveem o(s) próximo(s) token(s) correto(s).
Aqui estão dois modelos da biblioteca sentence-transformers da Hugging Face que você pode usar além dos embeddings da OpenAI:
- MiniLM-L6-v2: um modelo de 384 dimensões
- MPNet-Base-V2: um modelo de 768 dimensões
Você pode acessar embeddings de ambos os modelos da mesma forma.
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("<model-name>")
vector_embeddings = model.encode(“<input>”)
Embeddings multimodais
Modelos multimodais são menos desenvolvidos do que modelos de imagem ou texto. Eles frequentemente relacionam imagens a texto.
O exemplo de código aberto mais útil é o CLIP VIT, um modelo de imagem para texto. Você pode acessar os embeddings do CLIP VIT da mesma forma que acessaria um modelo de imagem, conforme mostrado no código abaixo.
# Load model directly
from transformers import AutoProcessor, AutoModelForZeroShotImageClassification
processor = AutoProcessor.from_pretrained("openai/clip-vit-large-patch14")
model = AutoModelForZeroShotImageClassification.from_pretrained("openai/clip-vit-large-patch14")
from PIL import Image
image = Image.open("<image path>")
# image = Resize(size=(256, 256))(image)
inputs = extractor(images=image, return_tensors="pt")
# print(inputs)
outputs = model(**inputs)
vector_embeddings = outputs[1][-1].squeeze()
Embeddings de áudio
A IA para áudio recebeu menos atenção do que a IA para texto ou imagens. O caso de uso mais comum para áudio é fala para texto em setores como call centers, tecnologia médica e acessibilidade. Um modelo popular de código aberto para fala para texto é o Whisper da OpenAI. O código abaixo mostra como obter embeddings vetoriais a partir do modelo de fala para texto.
import torch
from transformers import AutoFeatureExtractor, WhisperModel
from datasets import load_dataset
model = WhisperModel.from_pretrained("openai/whisper-base")
feature_extractor = AutoFeatureExtractor.from_pretrained("openai/whisper-base")
ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="pt")
input_features = inputs.input_features
decoder_input_ids = torch.tensor([[1, 1]]) * model.config.decoder_start_token_id
vector_embedding = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state
Embeddings de vídeo
Embeddings de vídeo são mais complexos do que embeddings de áudio ou imagem. Uma abordagem multimodal é necessária ao trabalhar com vídeos, pois eles incluem áudio e imagens sincronizados. Um modelo de vídeo popular é o multimodal perceiver da DeepMind. Este tutorial em notebook mostra como usar o modelo para classificar um vídeo.
Para obter os embeddings da entrada, use outputs[1][-1].squeeze() do código mostrado no notebook em vez de excluir as saídas. Eu destaco este trecho de código na função autoencode .
def autoencode_video(images, audio):
# only create entire video once as inputs
inputs = {'image': torch.from_numpy(np.moveaxis(images, -1, 2)).float().to(device),
'audio': torch.from_numpy(audio).to(device),
'label': torch.zeros((images.shape[0], 700)).to(device)}
nchunks = 128
reconstruction = {}
for chunk_idx in tqdm(range(nchunks)):
image_chunk_size = np.prod(images.shape[1:-1]) // nchunks
audio_chunk_size = audio.shape[1] // SAMPLES_PER_PATCH // nchunks
subsampling = {
'image': torch.arange(
image_chunk_size * chunk_idx, image_chunk_size * (chunk_idx + 1)),
'audio': torch.arange(
audio_chunk_size * chunk_idx, audio_chunk_size * (chunk_idx + 1)),
'label': None,
}
# forward pass
with torch.no_grad():
outputs = model(inputs=inputs, subsampled_output_points=subsampling)
output = {k:v.cpu() for k,v in outputs.logits.items()}
reconstruction['label'] = output['label']
if 'image' not in reconstruction:
reconstruction['image'] = output['image']
reconstruction['audio'] = output['audio']
else:
reconstruction['image'] = torch.cat(
[reconstruction['image'], output['image']], dim=1)
reconstruction['audio'] = torch.cat(
[reconstruction['audio'], output['audio']], dim=1)
vector_embeddings = outputs[1][-1].squeeze()
# finally, reshape image and audio modalities back to original shape
reconstruction['image'] = torch.reshape(reconstruction['image'], images.shape)
reconstruction['audio'] = torch.reshape(reconstruction['audio'], audio.shape)
return reconstruction
return None
Armazenamento, indexação e busca de embeddings vetoriais com bancos de dados vetoriais
Agora que entendemos o que são embeddings vetoriais e como gerá-los usando vários modelos de embedding poderosos, a próxima pergunta é como armazená-los e aproveitá-los. Bancos de dados vetoriais são a resposta.
Bancos de dados vetoriais como Milvus e Zilliz Cloud são criados especificamente para armazenar, indexar e pesquisar em enormes conjuntos de dados não estruturados por meio de embeddings vetoriais. Eles também são uma das infraestruturas mais críticas para diversas stacks de IA.
Bancos de dados vetoriais geralmente usam o algoritmo Vizinho Mais Próximo Aproximado (ANN) para calcular a distância espacial entre o vetor de consulta e os vetores armazenados no banco de dados. Quanto mais próximos os dois vetores estiverem localizados, mais relevantes eles serão. Em seguida, o algoritmo encontra os top k vizinhos mais próximos e os entrega ao usuário.
Bancos de dados vetoriais são populares em casos de uso como geração aumentada por recuperação com LLM (RAG), sistemas de perguntas e respostas, sistemas de recomendação, buscas semânticas e buscas por similaridade de imagem, vídeo e áudio.
Para saber mais sobre embeddings vetoriais, dados não estruturados e bancos de dados vetoriais, considere começar com a série Vector Database 101 .
Resumo
Vetores são uma ferramenta poderosa para trabalhar com dados não estruturados. Usando vetores, podemos comparar matematicamente diferentes partes de dados não estruturados com base na similaridade semântica. Escolher o modelo de embedding vetorial certo é fundamental para criar um mecanismo de busca vetorial para qualquer aplicação.
Neste post, aprendemos que embeddings vetoriais são a representação interna dos dados de entrada em uma rede neural. Como resultado, eles dependem fortemente da arquitetura da rede e dos dados usados para treinar o modelo. Diferentes tipos de dados (como imagens, texto e áudio) exigem modelos específicos. Felizmente, muitos modelos open source pré-treinados estão disponíveis para uso. Neste post, abordamos modelos para os cinco tipos de dados mais comuns: imagens, texto, multimodal, áudio e vídeo. Além disso, se você quiser aproveitar ao máximo os embeddings vetoriais, bancos de dados vetoriais são a ferramenta mais popular.
Continue lendo

Milvus 2.6.x Now Generally Available on Zilliz Cloud, Making Vector Search Faster, Smarter, and More Cost-Efficient for Production AI
Milvus 2.6.x is now GA on Zilliz Cloud, delivering faster vector search, smarter hybrid queries, and lower costs for production RAG and AI applications.

1 Table = 1000 Words? Foundation Models for Tabular Data
TableGPT2 automates tabular data insights, overcoming schema variability, while Milvus accelerates vector search for efficient, scalable decision-making.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.



