Come ottenere i giusti embedding vettoriali
Questo articolo è stato originariamente pubblicato su The New Stack ed è ripubblicato qui con autorizzazione.
Un’introduzione completa ai vector embeddings e a come generarli con popolari modelli open source.
Immagine di Денис Марчук da Pixabay
I vector embeddings sono fondamentali quando si lavora con la somiglianza semantica. Tuttavia, un vettore è semplicemente una serie di numeri; un vector embedding è una serie di numeri che rappresenta dati di input. Utilizzando i vector embeddings, possiamo strutturare dati non strutturati o lavorare con qualsiasi tipo di dato convertendolo in una serie di numeri. Questo approccio ci consente di eseguire operazioni matematiche sui dati di input, invece di affidarci a confronti qualitativi.
I vector embeddings sono importanti per molte attività, in particolare per la ricerca semantica. Tuttavia, è fondamentale ottenere i vector embeddings appropriati prima di utilizzarli. Per esempio, se utilizzi un modello per immagini per vettorializzare del testo, o viceversa, probabilmente otterrai risultati scadenti.
In questo post, impareremo che cosa significano i vector embeddings, come generare i vector embeddings giusti per le tue applicazioni usando modelli diversi e come sfruttare al meglio i vector embeddings con database vettoriali come Milvus e Zilliz Cloud.
Come vengono creati i vector embeddings?
Ora che comprendiamo l’importanza dei vector embeddings, impariamo come funzionano. Un vector embedding è la rappresentazione interna dei dati di input in un modello di deep learning, noto anche come modello di embedding o rete neurale profonda. Quindi, come estraiamo queste informazioni?
Otteniamo i vettori rimuovendo l’ultimo livello e prendendo l’output dal penultimo livello. L’ultimo livello di una rete neurale di solito restituisce la previsione del modello, quindi prendiamo l’output del penultimo livello. Il vector embedding è il dato fornito al livello predittivo di una rete neurale.
La dimensionalità di un vector embedding equivale alla dimensione del penultimo livello nel modello e, quindi, è intercambiabile con la dimensione o lunghezza del vettore. Le dimensionalità vettoriali comuni includono 384 (generata da Sentence Transformers Mini-LM), 768 (da Sentence Transformers MPNet), 1.536 (da OpenAI) e 2.048 (da ResNet-50).
Che cosa significa un vector embedding?
Una volta qualcuno mi ha chiesto il significato di ciascuna dimensione in un vector embedding. La risposta breve è: nulla. Una singola dimensione in un vector embedding non significa nulla, poiché è troppo astratta per determinarne il significato. Tuttavia, quando consideriamo tutte le dimensioni insieme, esse forniscono il significato semantico dei dati di input.
Le dimensioni del vettore sono rappresentazioni astratte e di alto livello di diversi attributi. Gli attributi rappresentati dipendono dai dati di addestramento e dal modello stesso. I modelli di testo e di immagini generano embeddings diversi perché sono addestrati per tipi di dati fondamentalmente diversi. Anche modelli di testo diversi generano embeddings diversi. A volte differiscono per dimensione; altre volte, differiscono negli attributi che rappresentano. Per esempio, un modello addestrato su dati legali apprenderà cose diverse rispetto a uno addestrato su dati sanitari. Ho esplorato questo argomento nel mio post sul confronto tra diversi vector embeddings.
Generare i vector embeddings giusti
Come si ottengono i vettori di embedding corretti? Tutto inizia con l'identificazione del tipo di dati che si desidera incorporare. Questa sezione tratta l'embedding di cinque diversi tipi di dati: immagini, testo, audio, video e dati multimodali. Tutti i modelli che presentiamo qui sono open source e provengono da Hugging Face o PyTorch.
Embedding di immagini
Il riconoscimento delle immagini ha preso il via nel 2012 dopo l'arrivo di AlexNet. Da allora, il campo della computer vision ha assistito a numerosi progressi. Il più recente modello notevole di riconoscimento delle immagini è ResNet-50, una rete residuale profonda a 50 livelli basata sulla precedente architettura ResNet-34.
Le reti neurali residuali (ResNet) risolvono il problema del gradiente evanescente nelle reti neurali convoluzionali profonde utilizzando connessioni shortcut. Queste connessioni consentono all'output dei livelli precedenti di passare direttamente ai livelli successivi senza attraversare tutti i livelli intermedi, evitando così il problema del gradiente evanescente. Questo design rende ResNet meno complessa di VGGNet (Visual Geometry Group), una rete neurale convoluzionale precedentemente tra le più performanti.
Consiglio due implementazioni di ResNet-50 come esempi: ResNet 50 su Hugging Face e ResNet 50 su PyTorch Hub. Sebbene le reti siano le stesse, il processo per ottenere gli embedding differisce.
L'esempio di codice seguente dimostra come usare PyTorch per ottenere vettori di embedding. Per prima cosa, carichiamo il modello da PyTorch Hub. Successivamente, rimuoviamo l'ultimo livello e chiamiamo .eval() per istruire il modello a comportarsi come se fosse in esecuzione per l'inferenza. Quindi, la funzione embed genera il vettore di embedding.
# 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
HuggingFace utilizza una configurazione leggermente diversa. Il codice seguente dimostra come ottenere un vettore di embedding da Hugging Face. Per prima cosa, abbiamo bisogno di un feature extractor e di un modello dalla libreria transformers . Useremo il feature extractor per ottenere gli input per il modello e useremo il modello per ottenere gli output ed estrarre l'ultimo stato nascosto.
# 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()
Embedding di testo
Ingegneri e ricercatori sperimentano con il linguaggio naturale e l'IA fin dall'invenzione dell'IA. Alcuni dei primi esperimenti includono:
- ELIZA, il primo chatbot terapeuta basato su IA.
- La Stanza cinese di John Searle, un esperimento mentale che esamina se la capacità di tradurre tra cinese e inglese richieda una comprensione della lingua.
- Traduzioni basate su regole tra inglese e russo.
Il funzionamento dell'IA sul linguaggio naturale si è evoluto in modo significativo rispetto ai suoi embedding basati su regole. Partendo dalle reti neurali primarie, abbiamo aggiunto relazioni di ricorrenza tramite RNN per tenere traccia dei passaggi nel tempo. Da lì, abbiamo usato i transformer per risolvere il problema della trasduzione di sequenze.
I transformer consistono in un encoder, che codifica un input in una matrice che rappresenta lo stato, una matrice di attenzione e un decoder. Il decoder decodifica lo stato e la matrice di attenzione per prevedere il token successivo corretto per completare la sequenza di output. GPT-3, il modello linguistico più popolare finora, comprende decoder rigorosi. Codificano l'input e prevedono il/i token successivo/i corretto/i.
Ecco due modelli della libreria sentence-transformers di Hugging Face che puoi usare in aggiunta agli embedding di OpenAI:
- MiniLM-L6-v2: un modello a 384 dimensioni
- MPNet-Base-V2: un modello a 768 dimensioni
Puoi accedere agli embedding di entrambi i modelli nello stesso modo.
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("<model-name>")
vector_embeddings = model.encode(“<input>”)
Embedding multimodali
I modelli multimodali sono meno sviluppati rispetto ai modelli per immagini o testo. Spesso mettono in relazione le immagini con il testo.
L’esempio open source più utile è CLIP VIT, un modello da immagine a testo. Puoi accedere agli embedding di CLIP VIT nello stesso modo in cui lo faresti con un modello di immagini, come mostrato nel codice qui sotto.
# 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()
Embedding audio
L’IA per l’audio ha ricevuto meno attenzione rispetto all’IA per il testo o le immagini. Il caso d’uso più comune per l’audio è la conversione da voce a testo per settori come call center, tecnologia medica e accessibilità. Un popolare modello open source per la conversione da voce a testo è Whisper di OpenAI. Il codice qui sotto mostra come ottenere embedding vettoriali dal modello di conversione da voce a testo.
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
Embedding video
Gli embedding video sono più complessi degli embedding audio o di immagini. È necessario un approccio multimodale quando si lavora con i video, poiché includono audio e immagini sincronizzati. Un modello video popolare è il multimodal perceiver di DeepMind. Questo tutorial in notebook mostra come usare il modello per classificare un video.
Per ottenere gli embedding dell’input, usa outputs[1][-1].squeeze() dal codice mostrato nel notebook invece di eliminare gli output. Evidenzio questo frammento di codice nella funzione 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
Archiviazione, indicizzazione e ricerca di embedding vettoriali con database vettoriali
Ora che comprendiamo cosa sono gli embedding vettoriali e come generarli utilizzando vari potenti modelli di embedding, la domanda successiva è come archiviarli e sfruttarli. I database vettoriali sono la risposta.
I database vettoriali come Milvus e Zilliz Cloud sono progettati appositamente per archiviare, indicizzare e cercare in enormi dataset di dati non strutturati tramite embedding vettoriali. Sono anche una delle infrastrutture più critiche per vari stack di IA.
I database vettoriali di solito utilizzano l'algoritmo Approximate Nearest Neighbor (ANN) per calcolare la distanza spaziale tra il vettore di query e i vettori archiviati nel database. Più vicini si trovano i due vettori, più sono rilevanti. Quindi l'algoritmo trova i primi k vicini più prossimi e li fornisce all'utente.
I database vettoriali sono popolari in casi d'uso come LLM retrieval augmented generation (RAG), sistemi di domande e risposte, sistemi di raccomandazione, ricerche semantiche e ricerche di similarità di immagini, video e audio.
Per saperne di più sugli embedding vettoriali, sui dati non strutturati e sui database vettoriali, considera di iniziare con la serie Vector Database 101 .
Riepilogo
I vettori sono uno strumento potente per lavorare con dati non strutturati. Utilizzando i vettori, possiamo confrontare matematicamente diversi elementi di dati non strutturati in base alla similarità semantica. Scegliere il giusto modello di embedding vettoriale è fondamentale per creare un motore di ricerca vettoriale per qualsiasi applicazione.
In questo post abbiamo appreso che gli embedding vettoriali sono la rappresentazione interna dei dati di input in una rete neurale. Di conseguenza, dipendono fortemente dall'architettura della rete e dai dati utilizzati per addestrare il modello. Tipi di dati diversi (come immagini, testo e audio) richiedono modelli specifici. Fortunatamente, sono disponibili molti modelli open source preaddestrati da utilizzare. In questo post abbiamo trattato i modelli per i cinque tipi di dati più comuni: immagini, testo, multimodali, audio e video. Inoltre, se vuoi sfruttare al meglio gli embedding vettoriali, i database vettoriali sono lo strumento più popolare.
Continua a leggere

We spent 8 years making vector databases faster. Then we stopped.
Rarely queried embeddings still need to stay searchable. See how Vector Lakebase enables on-demand vector search without always-on compute costs.

Zilliz Cloud Update: Tiered Storage, Business Critical Plan, Cross-Region Backup, and Pricing Changes
This release offers a rebuilt tiered storage with lower costs, a new Business Critical plan for enhanced security, and pricing updates, among other features.

Vector Databases vs. Graph Databases
Use a vector database for AI-powered similarity search; use a graph database for complex relationship-based queries and network analysis.



