milvus-logo
LFAI
Casa
  • Integrazioni

Ricerca video avanzata: Sfruttare Twelve Labs e Milvus per il recupero semantico

Introduzione

Benvenuti in questa guida completa sull'implementazione della ricerca semantica di video utilizzando Twelve Labs Embed API e Milvus. In questa guida esploreremo come sfruttare la potenza degli embeddings multimodali avanzati di Twelve Labs e l'efficiente database vettoriale di Milvus per creare una solida soluzione di ricerca video. Integrando queste tecnologie, gli sviluppatori possono aprire nuove possibilità nell'analisi dei contenuti video, consentendo applicazioni come il recupero di video basati sui contenuti, sistemi di raccomandazione e sofisticati motori di ricerca che comprendono le sfumature dei dati video.

Questo tutorial vi guiderà attraverso l'intero processo, dalla configurazione dell'ambiente di sviluppo all'implementazione di un'applicazione di ricerca semantica video funzionale. Verranno trattati concetti chiave come la generazione di embeddings multimodali dai video, la loro archiviazione efficiente in Milvus e l'esecuzione di ricerche di similarità per recuperare i contenuti rilevanti. Sia che stiate costruendo una piattaforma di analisi video, uno strumento di scoperta dei contenuti o che stiate migliorando le vostre applicazioni esistenti con funzionalità di ricerca video, questa guida vi fornirà le conoscenze e i passi pratici per sfruttare i punti di forza combinati di Twelve Labs e Milvus nei vostri progetti.

Prerequisiti

Prima di iniziare, assicuratevi di disporre di quanto segue:

Una chiave API di Twelve Labs (se non ce l'avete, registratevi su https://api.twelvelabs.io) Python 3.7 o successivo installato sul vostro sistema.

Impostazione dell'ambiente di sviluppo

Creare una nuova cartella per il progetto e navigare al suo interno:

mkdir video-search-tutorial
cd video-search-tutorial

Impostare un ambiente virtuale (facoltativo ma consigliato):

python -m venv venv
source venv/bin/activate  # On Windows, use `venv\Scripts\activate`

Installare le librerie Python necessarie:

pip install twelvelabs pymilvus

Creare un nuovo file Python per il progetto:

touch video_search.py

Questo file video_search.py sarà lo script principale che useremo per l'esercitazione. Quindi, impostare la chiave API di Twelve Labs come variabile d'ambiente per la sicurezza:

export TWELVE_LABS_API_KEY='your_api_key_here'

Connessione a Milvus

Per stabilire una connessione con Milvus, utilizzeremo la classe MilvusClient. Questo approccio semplifica il processo di connessione e ci permette di lavorare con un'istanza di Milvus basata su file locali, che è perfetta per il nostro tutorial.

from pymilvus import MilvusClient

# Initialize the Milvus client
milvus_client = MilvusClient("milvus_twelvelabs_demo.db")

print("Successfully connected to Milvus")

Questo codice crea una nuova istanza di Milvus client che memorizza tutti i dati in un file chiamato milvus_twelvelabs_demo.db. Questo approccio basato su file è ideale per lo sviluppo e i test.

Creare una raccolta Milvus per le incorporazioni video

Ora che siamo collegati a Milvus, creiamo una collezione per memorizzare i nostri embeddings video e i metadati associati. Definiamo lo schema della collezione e creiamo la collezione se non esiste già.

# Initialize the collection name
collection_name = "twelvelabs_demo_collection"

# Check if the collection already exists and drop it if it does
if milvus_client.has_collection(collection_name=collection_name):
    milvus_client.drop_collection(collection_name=collection_name)

# Create the collection
milvus_client.create_collection(
    collection_name=collection_name,
    dimension=1024  # The dimension of the Twelve Labs embeddings
)

print(f"Collection '{collection_name}' created successfully")

In questo codice, per prima cosa controlliamo se la collezione esiste già e, in caso affermativo, la eliminiamo. Questo ci assicura di partire da zero. Creiamo l'insieme con una dimensione di 1024, che corrisponde alla dimensione di output degli embeddings di Twelve Labs.

Generazione degli embeddings con l'API Embed di Twelve Labs

Per generare gli embeddings per i nostri video utilizzando l'API Twelve Labs Embed, useremo l'SDK Twelve Labs Python. Il processo prevede la creazione di un task di embedding, l'attesa del suo completamento e il recupero dei risultati. Ecco come implementarlo:

Innanzitutto, assicurarsi di aver installato l'SDK di Twelve Labs e importare i moduli necessari:

from twelvelabs import TwelveLabs
from twelvelabs.models.embed import EmbeddingsTask
import os

# Retrieve the API key from environment variables
TWELVE_LABS_API_KEY = os.getenv('TWELVE_LABS_API_KEY')

Inizializzare il client di Twelve Labs:

twelvelabs_client = TwelveLabs(api_key=TWELVE_LABS_API_KEY)

Creare una funzione per generare embeddings per un dato URL video:

def generate_embedding(video_url):
    """
    Generate embeddings for a given video URL using the Twelve Labs API.

    This function creates an embedding task for the specified video URL using
    the Marengo-retrieval-2.6 engine. It monitors the task progress and waits
    for completion. Once done, it retrieves the task result and extracts the
    embeddings along with their associated metadata.

    Args:
        video_url (str): The URL of the video to generate embeddings for.

    Returns:
        tuple: A tuple containing two elements:
            1. list: A list of dictionaries, where each dictionary contains:
                - 'embedding': The embedding vector as a list of floats.
                - 'start_offset_sec': The start time of the segment in seconds.
                - 'end_offset_sec': The end time of the segment in seconds.
                - 'embedding_scope': The scope of the embedding (e.g., 'shot', 'scene').
            2. EmbeddingsTaskResult: The complete task result object from Twelve Labs API.

    Raises:
        Any exceptions raised by the Twelve Labs API during task creation,
        execution, or retrieval.
    """

    # Create an embedding task
    task = twelvelabs_client.embed.task.create(
        engine_name="Marengo-retrieval-2.6",
        video_url=video_url
    )
    print(f"Created task: id={task.id} engine_name={task.engine_name} status={task.status}")

    # Define a callback function to monitor task progress
    def on_task_update(task: EmbeddingsTask):
        print(f"  Status={task.status}")

    # Wait for the task to complete
    status = task.wait_for_done(
        sleep_interval=2,
        callback=on_task_update
    )
    print(f"Embedding done: {status}")

    # Retrieve the task result
    task_result = twelvelabs_client.embed.task.retrieve(task.id)

    # Extract and return the embeddings
    embeddings = []
    for v in task_result.video_embeddings:
        embeddings.append({
            'embedding': v.embedding.float,
            'start_offset_sec': v.start_offset_sec,
            'end_offset_sec': v.end_offset_sec,
            'embedding_scope': v.embedding_scope
        })
    
    return embeddings, task_result

Utilizzare la funzione per generare embeddings per i propri video:

# Example usage
video_url = "https://example.com/your-video.mp4"

# Generate embeddings for the video
embeddings, task_result = generate_embedding(video_url)

print(f"Generated {len(embeddings)} embeddings for the video")
for i, emb in enumerate(embeddings):
    print(f"Embedding {i+1}:")
    print(f"  Scope: {emb['embedding_scope']}")
    print(f"  Time range: {emb['start_offset_sec']} - {emb['end_offset_sec']} seconds")
    print(f"  Embedding vector (first 5 values): {emb['embedding'][:5]}")
    print()

Questa implementazione consente di generare incorporazioni per qualsiasi URL video utilizzando l'API Twelve Labs Embed. La funzione generate_embedding gestisce l'intero processo, dalla creazione del task al recupero dei risultati. Restituisce un elenco di dizionari, ognuno dei quali contiene un vettore di incorporamento insieme ai suoi metadati (intervallo di tempo e ambito).Ricordarsi di gestire i potenziali errori, come i problemi di rete o i limiti delle API, in un ambiente di produzione. Si potrebbe anche voler implementare dei tentativi o una gestione degli errori più robusta, a seconda del caso d'uso specifico.

Inserire gli embeddings in Milvus

Dopo aver generato gli embeddings utilizzando l'API Twelve Labs Embed, il passo successivo è inserire questi embeddings insieme ai loro metadati nella nostra collezione Milvus. Questo processo ci permette di memorizzare e indicizzare gli embeddings dei video per una ricerca efficiente delle somiglianze in un secondo momento.

Ecco come inserire gli embeddings in Milvus:

def insert_embeddings(milvus_client, collection_name, task_result, video_url):
    """
    Insert embeddings into the Milvus collection.

    Args:
        milvus_client: The Milvus client instance.
        collection_name (str): The name of the Milvus collection to insert into.
        task_result (EmbeddingsTaskResult): The task result containing video embeddings.
        video_url (str): The URL of the video associated with the embeddings.

    Returns:
        MutationResult: The result of the insert operation.

    This function takes the video embeddings from the task result and inserts them
    into the specified Milvus collection. Each embedding is stored with additional
    metadata including its scope, start and end times, and the associated video URL.
    """
    data = []

    for i, v in enumerate(task_result.video_embeddings):
        data.append({
            "id": i,
            "vector": v.embedding.float,
            "embedding_scope": v.embedding_scope,
            "start_offset_sec": v.start_offset_sec,
            "end_offset_sec": v.end_offset_sec,
            "video_url": video_url
        })

    insert_result = milvus_client.insert(collection_name=collection_name, data=data)
    print(f"Inserted {len(data)} embeddings into Milvus")
    return insert_result

# Usage example
video_url = "https://example.com/your-video.mp4"

# Assuming this function exists from previous step
embeddings, task_result = generate_embedding(video_url)

# Insert embeddings into the Milvus collection
insert_result = insert_embeddings(milvus_client, collection_name, task_result, video_url)
print(insert_result)

Questa funzione prepara i dati per l'inserimento, includendo tutti i metadati rilevanti come il vettore di incorporamento, l'intervallo di tempo e l'URL del video di origine. Quindi utilizza il client Milvus per inserire questi dati nella raccolta specificata.

Una volta memorizzati i nostri embeddings in Milvus, possiamo eseguire ricerche di somiglianza per trovare i segmenti video più rilevanti in base a un vettore di query. Ecco come implementare questa funzionalità:

def perform_similarity_search(milvus_client, collection_name, query_vector, limit=5):
    """
    Perform a similarity search on the Milvus collection.

    Args:
        milvus_client: The Milvus client instance.
        collection_name (str): The name of the Milvus collection to search in.
        query_vector (list): The query vector to search for similar embeddings.
        limit (int, optional): The maximum number of results to return. Defaults to 5.

    Returns:
        list: A list of search results, where each result is a dictionary containing
              the matched entity's metadata and similarity score.

    This function searches the specified Milvus collection for embeddings similar to
    the given query vector. It returns the top matching results, including metadata
    such as the embedding scope, time range, and associated video URL for each match.
    """
    search_results = milvus_client.search(
        collection_name=collection_name,
        data=[query_vector],
        limit=limit,
        output_fields=["embedding_scope", "start_offset_sec", "end_offset_sec", "video_url"]
    )

    return search_results
    
# define the query vector
# We use the embedding inserted previously as an example. In practice, you can replace it with any video embedding you want to query.
query_vector = task_result.video_embeddings[0].embedding.float

# Perform a similarity search on the Milvus collection
search_results = perform_similarity_search(milvus_client, collection_name, query_vector)

print("Search Results:")
for i, result in enumerate(search_results[0]):
    print(f"Result {i+1}:")
    print(f"  Video URL: {result['entity']['video_url']}")
    print(f"  Time Range: {result['entity']['start_offset_sec']} - {result['entity']['end_offset_sec']} seconds")
    print(f"  Similarity Score: {result['distance']}")
    print()

Questa implementazione fa quanto segue:

  1. Definisce una funzione perform_similarity_search che prende un vettore di query e cerca embeddings simili nella collezione Milvus.
  2. Utilizza il metodo di ricerca del client Milvus per trovare i vettori più simili.
  3. Specifica i campi di output che vogliamo recuperare, compresi i metadati sui segmenti video corrispondenti.
  4. Fornisce un esempio di come usare questa funzione con un video di query, generando prima il suo incorporamento e poi usandolo per la ricerca.
  5. Stampa i risultati della ricerca, compresi i metadati pertinenti e i punteggi di somiglianza.

Implementando queste funzioni, si è creato un flusso di lavoro completo per memorizzare le incorporazioni dei video in Milvus ed eseguire ricerche di somiglianza. Questa configurazione consente di recuperare in modo efficiente contenuti video simili in base alle incorporazioni multimodali generate dall'API Embed di Twelve Labs.

Ottimizzazione delle prestazioni

Bene, portiamo questa applicazione al livello successivo! Quando si ha a che fare con collezioni di video su larga scala, le prestazioni sono fondamentali. Per ottimizzare, dovremmo implementare l'elaborazione in batch per la generazione e l'inserimento degli embedding in Milvus. In questo modo, possiamo gestire più video contemporaneamente, riducendo significativamente il tempo di elaborazione complessivo. Inoltre, potremmo sfruttare la funzione di partizionamento di Milvus per organizzare i nostri dati in modo più efficiente, magari per categorie di video o periodi di tempo. Questo velocizzerebbe le interrogazioni, consentendo di cercare solo le partizioni rilevanti.

Un altro trucco di ottimizzazione consiste nell'utilizzare meccanismi di caching per gli embeddings o i risultati di ricerca a cui si accede di frequente. Questo potrebbe migliorare notevolmente i tempi di risposta per le query più frequenti. Non dimenticate di mettere a punto i parametri dell'indice di Milvus in base al vostro set di dati specifico e ai modelli di query: una piccola modifica può contribuire a migliorare le prestazioni della ricerca.

Funzioni avanzate

Ora aggiungiamo alcune caratteristiche interessanti per far risaltare la nostra applicazione! Potremmo implementare una ricerca ibrida che combina query testuali e video. Infatti, Twelve Labs Embed API può anche generare incorporazioni di testo per le query testuali. Immaginiamo di consentire agli utenti di inserire sia una descrizione testuale che un video di esempio: genereremo embeddings per entrambi ed eseguiremo una ricerca ponderata in Milvus. In questo modo otterremmo risultati estremamente precisi.

Un'altra fantastica aggiunta sarebbe la ricerca temporale all'interno dei video. Potremmo suddividere i video lunghi in segmenti più piccoli, ciascuno con il proprio embedding. In questo modo, gli utenti potrebbero trovare momenti specifici all'interno dei video, non solo interi clip. E perché non aggiungere un po' di analisi video di base? Potremmo usare le incorporazioni per raggruppare segmenti di video simili, rilevare tendenze o persino identificare i valori anomali in grandi raccolte di video.

Gestione degli errori e registrazione

Ammettiamolo, le cose possono andare male e quando succedono dobbiamo essere preparati. L 'implementazione di una solida gestione degli errori è fondamentale. Dovremmo avvolgere le nostre chiamate API e le operazioni di database in blocchi try-except, fornendo messaggi di errore informativi agli utenti quando qualcosa non funziona. Per i problemi legati alla rete, l'implementazione di tentativi con un backoff esponenziale può aiutare a gestire con grazia i problemi temporanei.

Per quanto riguarda il logging, è il nostro migliore amico per il debug e il monitoraggio. Dovremmo usare il modulo di log di Python per tenere traccia degli eventi importanti, degli errori e delle metriche delle prestazioni in tutta la nostra applicazione. Impostiamo diversi livelli di log: DEBUG per lo sviluppo, INFO per il funzionamento generale ed ERROR per i problemi critici. E non dimentichiamo di implementare la rotazione dei log per gestire le dimensioni dei file. Con una corretta registrazione, saremo in grado di identificare e risolvere rapidamente i problemi, assicurando che la nostra applicazione di ricerca video funzioni senza problemi anche quando cresce.

Conclusione

Congratulazioni! Avete realizzato una potente applicazione di ricerca semantica di video utilizzando l'API Embed di Twelve Labs e Milvus. Questa integrazione consente di elaborare, archiviare e recuperare contenuti video con una precisione e un'efficienza senza precedenti. Sfruttando le incorporazioni multimodali, avete creato un sistema che comprende le sfumature dei dati video, aprendo possibilità interessanti per la scoperta di contenuti, i sistemi di raccomandazione e l'analisi video avanzata.

Mentre continuate a sviluppare e perfezionare la vostra applicazione, ricordate che la combinazione tra la generazione avanzata di embedding di Twelve Labs e la memorizzazione vettoriale scalabile di Milvus fornisce una solida base per affrontare sfide di comprensione video ancora più complesse. Vi invitiamo a sperimentare le funzioni avanzate discusse e a spingersi oltre i confini del possibile nella ricerca e nell'analisi dei video.