Esplorare gli embedding multimodali con FiftyOne e Milvus
Qual è il primo passo per creare un’app retrieval augmented generation (RAG) multimodale? Ottenere vector embeddings multimodali. In un certo senso, dire che un embedding è multimodale è un termine improprio. Esistono molti modi per lavorare con più modalità all’interno dei vettori, ma per questo tutorial ci concentriamo sugli embedding vettoriali prodotti da modelli multimodali.
In questo articolo, trattiamo:
- Cosa significa “multimodale”?
- In che modo Milvus gestisce gli embedding multimodali?
- Esempi di modelli multimodali
- Uso di FiftyOne e Milvus per l’esplorazione degli embedding multimodali
- Esplorazione degli embedding multimodali per CIFAR 10 tramite FiftyOne e CLIP
- Come possiamo personalizzare ulteriormente FiftyOne per l’esplorazione dei dati con Milvus?
- Riepilogo dell’esplorazione degli embedding multimodali con FiftyOne e Milvus
Cosa significa “multimodale”?
Quando parliamo di "multimodale", ci riferiamo alle capacità dei modelli. Sia il large language model/modello fondamentale sia il modello di embedding in uno stack RAG possono essere multimodali. Per questo esempio esploriamo embedding multimodali da un modello open-source. Come otteniamo un embedding vettoriale? Gli embedding vettoriali provengono dal penultimo layer di un modello di embedding.
Questo perché ogni layer del modello apprende alcune informazioni sull’input, e l’ultimo layer effettua una previsione. Poiché non vogliamo una previsione, ma piuttosto poter lavorare con una rappresentazione numerica dei dati, eliminiamo l’ultimo layer e prendiamo l’output dal penultimo layer, che contiene tutte le informazioni apprese dal modello. Usiamo FiftyOne per facilitare l’esplorazione e Milvus per contenere i vettori.
In che modo Milvus gestisce gli embedding multimodali?
La cosa interessante degli embedding multimodali, o degli embedding vettoriali in generale, è che non richiedono un trattamento speciale. Gli embedding vettoriali sono semplicemente rappresentazioni numeriche di uno specifico tipo di dati di input. Per quanto riguarda il tipo di dato effettivo, gli embedding vettoriali sono solo vettori, una lista di numeri. Milvus gestisce tutti questi vettori nello stesso modo.
I vettori possono essere densi o sparsi. I vettori densi sono tipicamente composti da float e sono prodotti da modelli di deep learning, un esempio dei quali vedremo oggi. I vettori sparsi sono talvolta chiamati vettori binari e sono composti da 0 e 1. Una cosa importante da tenere a mente quando si lavora con i vettori è che si possono confrontare solo vettori della stessa dimensione o dimensionalità. Inoltre, anche quando hanno la stessa dimensione, gli embedding generati da modelli diversi non possono necessariamente essere confrontati in modo diretto.
Gli embedding multimodali sono particolarmente insidiosi. La maggior parte dei modelli di deep learning è progettata per gestire un solo tipo, o modalità, di dati. Potrebbero essere immagini, testo, video o qualcosa di più specifico. Tuttavia, poiché questi modelli sono ottimizzati solo per un tipo di dati, non possono elaborare o rappresentare altre modalità: un modello addestrato ad accettare input testuale in genere non sarà in grado di accettare immagini.
I modelli multimodali sono addestrati a interagire con più tipi di dati. Per i nostri scopi, siamo interessati a modelli multimodali che producono embedding vettoriali per più modalità di dati. In particolare, ci interessano modelli che incorporano dati testuali e visivi nello stesso spazio, così che le dimensioni dei vettori generati siano le stesse e possiamo ragionevolmente trattarli in modo simile.
Il modello multimodale più comune per generare embedding di testo e immagini è CLIP, di OpenAI, che utilizza tecniche contrastive per allineare gli embedding delle immagini fotografiche con gli embedding testuali delle loro didascalie.
Uso di FiftyOne e Milvus per l’esplorazione degli embedding multimodali
FiftyOne è la principale libreria open-source per la curatela e la visualizzazione di dati non strutturati. FiftyOne si integra con molteplici backend di vector store, con Milvus particolarmente adatto a lavorare in modo flessibile con dataset grandi e in crescita. In questo esempio, utilizziamo Milvus Lite, una versione embedded di Milvus che puoi avviare direttamente nel tuo notebook. Per un approfondimento, consulta questa guida end-to-end a Milvus Lite.
Prima di immergerti nel codice, assicurati che tutti i prerequisiti corretti siano installati. Devi eseguire pip install milvus pymilvus fiftyone torch torchvision. Il primo passo è avviare la nostra istanza Milvus Lite. Possiamo farlo importando default_server da Milvus e chiamando la funzione start().
from milvus import default_server
default_server.start()
Ora che abbiamo un’istanza di Milvus pronta all’uso, possiamo collegarla a FiftyOne per confronti tra vector embedding. Importiamo FiftyOne, il FiftyOne Brain, e il FiftyOne Zoo e carichiamo lo split di test del dataset CIFAR 10.
import fiftyone as fo
import fiftyone.brain as fob
import fiftyone.zoo as foz
# Step 1: Load your data into FiftyOne
dataset = foz.load_zoo_dataset("cifar10", split="test")
In questo esempio useremo il modello CLIP per incorporare le nostre immagini. Poi useremo la funzione compute_similarity dal FiftyOne Brain. Questa funzione genera prima gli embedding per i nostri campioni usando un modello specificato, quindi crea una collection Milvus da questi embedding e la collega alla sample collection di FiftyOne. Con FiftyOne e i backend di vector search, puoi generare un indice di similarità su immagini, object patch, e persino frame video!
La funzione compute_similarity accetta il dataset FiftyOne e vari parametri denominati. Il brain_key è una chiave univoca che FiftyOne usa per tenere traccia delle esecuzioni. La chiave backend indica a FiftyOne quale backend di database vettoriale usare, e model accetta il nome del modello che FiftyOne sfrutterà per creare gli embedding.
fob.compute_similarity(
dataset,
brain_key="clip_sim",
backend="milvus",
model="clip-vit-base32-torch",
)
L’ultimo passaggio che esaminiamo qui prima di esplorare consiste nell’usare FiftyOne per lanciare la FiftyOne App. Passiamo il dataset e impostiamo auto=False così la finestra non si apre nel notebook ma può essere accessibile tramite una scheda Chrome su localhost:5151.
session = fo.launch_app(dataset, auto=False)
Esplorazione di embedding multimodali per CIFAR 10 tramite FiftyOne e CLIP
È tempo di esplorare! Vediamo come usare il testo per trovare immagini semanticamente simili. Consideriamo tre parole: Ferrari, Mustang e Pony.
La nostra prima ricerca per Ferrari restituisce un’auto.
La ricerca successiva, “pony”, ci dà chiaramente immagini di cavalli.
Ma, se cerchiamo “mustang”, otteniamo un mix.
Questo passaggio mostra che è essenziale valutare il tuo dataset e comprendere il contesto dei tuoi dati!
Come possiamo personalizzare ulteriormente FiftyOne per l’esplorazione dei dati con Milvus?
Per impostare Milvus come “backend” predefinito per la ricerca vettoriale in FiftyOne, possiamo caricare la seguente variabile d’ambiente:
export FIFTYONE_BRAIN_DEFAULT_SIMILARITY_BACKEND=milvus
Per qualsiasi indice specifico, possiamo anche specificare il nome della collection, quale livello di consistenza usare e quale metrica usare per valutare la similarità. Ecco un secondo indice di similarità che usa una metrica euclidea e consistenza Bounded:
fob.compute_similarity(
dataset,
brain_key="clip_euclid",
model="clip-vit-base32-torch",
metric="euclidean",
consistency_level="Bounded"
)
Se abbiamo più indici di similarità su un dataset, possiamo selezionare quale vogliamo usare nell’app cliccando sull’icona dell’ingranaggio accanto alla barra di ricerca sotto la lente d’ingrandimento, e scegliendo l’indice tramite la sua brain key:
Possiamo anche usare un modello multimodale diverso per generare i nostri embedding di immagini e testo. Infatti, possiamo farlo con qualsiasi modello OpenCLIP (avremo un link migliore qui tra qualche giorno), o qualsiasi modello di predizione zero-shot dalla libreria Transformers di Hugging Face. Come esempio, ecco un indice costruito con AltCLIP:
!pip install transformers
fob.compute_similarity(
dataset,
brain_key="altclip",
model="zero-shot-classification-transformer-torch",
name_or_path="BAAI/AltCLIP",
)
Riepilogo dell’esplorazione degli embedding multimodali con FiftyOne e Milvus
Questo post ha esplorato come funzionano gli embedding multimodali con FiftyOne e Milvus. Abbiamo mostrato come puoi esplorare un modello multimodale popolare - CLIP - su un dataset popolare - CIFAR 10. Usi CLIP per creare gli embedding dei dati di input, Milvus per archiviare gli embedding dei dati multimodali (a volte chiamati “embedding multimodali”), e FiftyOne per esplorare gli embedding.
Usare CLIP in questo modo ti consente di cercare tra le immagini con il testo. Con ciò, abbiamo esplorato lo spazio usando il linguaggio naturale per confrontare immagini di parole che possono avere significati diversi in contesti diversi. Abbiamo visto come “pony” sia chiaramente un cavallo, “Ferrari” sia chiaramente un’auto, ma “mustang” potrebbe essere entrambi.
Continua a leggere

How to Choose the Best Embedding Model for RAG in 2026: 10 Models Benchmarked
We benchmarked 10 embedding models on cross-modal, cross-lingual, long-document, and dimension compression tasks. See which one fits your RAG pipeline.

Announcing the General Availability of Zilliz Cloud BYOC on Google Cloud Platform
Zilliz Cloud BYOC on GCP offers enterprise vector search with full data sovereignty and seamless integration.

Introducing DeepSearcher: A Local Open Source Deep Research
In contrast to OpenAI’s Deep Research, this example ran locally, using only open-source models and tools like Milvus and LangChain.



