Archiviazione, indicizzazione e ricerca vettoriale con MariaDB

Quando sviluppi applicazioni di intelligenza artificiale generativa, di solito introduci tre componenti aggiuntive nella tua infrastruttura: un embedder, un LLM e un database vettoriale.

Tuttavia, se stai utilizzando MariaDB, non è necessario introdurre un database aggiuntivo con il proprio dialetto SQL — o, ancora peggio — la propria API proprietaria. Dalla versione 11.7 di MariaDB (e MariaDB Enterprise Server 11.4), puoi semplicemente memorizzare i tuoi embedding (o vettori) in qualsiasi colonna di qualsiasi tabella—non è necessario rendere le tue applicazioni poliglotti del database.

“Dopo aver annunciato la preview della ricerca vettoriale nel MariaDB Server, la capacità di ricerca vettoriale è stata ora aggiunta al rilascio di MariaDB Community Server 11.7,” scrive Ralf Gebhardt, Product Manager per MariaDB Server presso MariaDB. Questo include un nuovo tipo di dato (VECTOR), un indice vettoriale e un insieme di funzioni per la manipolazione dei vettori.

Perché sono necessari i vettori nelle applicazioni di intelligenza artificiale generativa?

I vettori sono necessari nelle applicazioni di intelligenza artificiale generativa perché incorporano significati complessi in un array di numeri a lunghezza fissa e compatta (un vettore). Questo è più chiaro nel contesto di generazione aumentata da recupero (o RAG). Questa tecnica consente di recuperare dati pertinenti dalle proprie fonti (API, file, database) per arricchire l’input di un modello AI con i dati recuperati, spesso riservati all’azienda.

Poiché le tue fonti di dati possono essere vaste, hai bisogno di un modo per trovare i pezzi pertinenti, dato che i modelli AI attuali hanno una finestra di contesto finita — non puoi semplicemente aggiungere tutti i tuoi dati a un prompt. Creando chunk di dati e passando questi chunk di dati attraverso un modello AI speciale chiamato embedder, puoi generare vettori e utilizzare tecniche di ricerca per prossimità per trovare informazioni pertinenti da aggiungere a un prompt.

Ad esempio, prendi il seguente input da un utente in un chatbot di raccomandazioni:

Plain Text

 

Poiché il tuo modello AI non è stato addestrato con i dati esatti contenenti le informazioni sui prodotti nel tuo negozio online, hai bisogno di recuperare i prodotti più pertinenti e le loro informazioni prima di inviare il prompt al modello.

Per questo, invii l’input originale dell’utente a un embedder e ottieni un vettore che puoi successivamente utilizzare per ottenere i 10 prodotti più vicini all’input dell’utente. Una volta che ottieni queste informazioni (e vedremo come fare questo con MariaDB più avanti), puoi inviare il prompt arricchito al tuo modello AI:

Plain Text

 

Questo si traduce in previsioni AI che utilizzano i tuoi dati.

Creazione di Tabelle per il Magazzino dei Vettori

Per memorizzare vettori in MariaDB, utilizzare il nuovo tipo di dati VECTOR. Ad esempio:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048)
);

In questo esempio, la colonna embedding può contenere un vettore di 2048 dimensioni. È necessario corrispondere al numero di dimensioni che il vostro incorporatore genera.

Creazione di Indici Vettoriali

Per le prestazioni di lettura, è importante aggiungere un indice alla colonna vettoriale. Questo velocizza le ricerche di similarità. È possibile definire l’indice al momento della creazione della tabella nel seguente modo:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048) NOT NULL,
    VECTOR INDEX (embedding)
);

Per un maggiore controllo, è possibile specificare la funzione di distanza che il server del database utilizzerà per creare l’indice, così come il valore della  funzione di Hierarchical Navigable Small Worlds (HNSW) utilizzata da MariaDB. Ad esempio:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048) NOT NULL,
    VECTOR INDEX (embedding) M=8 DISTANCE=cosine
);

Consultare la documentazione per ulteriori informazioni su queste configurazioni.

Inserimento di Vettori

Quando si passano dati (testo, immagini, audio) attraverso un incorporatore, si ottiene un vettore. Tipicamente, si tratta di una serie di numeri in un array in formato JSON. Per inserire questo vettore in una tabella MariaDB, è possibile utilizzare la funzione VEC_FromText. Ad esempio:

MariaDB SQL

 

INSERT INTO products (name, embedding)
VALUES
  ("Alarm clock", VEC_FromText("[0.001, 0, ...]")),
  ("Cow figure", VEC_FromText("[1.0, 0.05, ...]")),
  ("Bicycle", VEC_FromText("[0.2, 0.156, ...]"));

Ricordare che i vettori inseriti devono avere il numero corretto di dimensioni come definito nella dichiarazione di CREATE TABLE.

Ricerca di Similarità (Confronto di Vettori)

Nelle applicazioni RAG, invii l’input dell’utente a un embedder per ottenere un vettore. Puoi quindi interrogare i record nel tuo database che sono più vicini a quel vettore. I vettori più vicini rappresentano dati semanticamente simili. Al momento della scrittura, MariaDB ha due funzioni di distanza che puoi utilizzare per la ricerca di similarità o prossimità:

  • VEC_DISTANCE_EUCLIDEAN: calcola la distanza in linea retta tra due vettori. È più adatto per vettori derivati da dati grezzi, non normalizzati o scenari in cui la separazione spaziale si correla direttamente con la similarità, come nel confronto di caratteristiche posizionali o numeriche. Tuttavia, è meno efficace per embedding ad alta dimensione o normalizzati poiché è sensibile alle differenze nella magnitudine del vettore.
  • VEC_DISTANCE_COSINE: misura la differenza angolare tra i vettori. Buono per confrontare embedding normalizzati, specialmente in applicazioni semantiche come il recupero di testi o documenti. Eccelle nel catturare la similarità nel significato o nel contesto.

Ricorda che la ricerca di similarità utilizzando le funzioni precedenti è solo approssimativa e dipende fortemente dalla qualità dei vettori calcolati e, quindi, dalla qualità dell’embedder utilizzato.

L’esempio seguente trova i 10 prodotti più simili a un dato vettore ($user_input_vector dovrebbe essere sostituito con il vettore effettivo restituito dall’embedder sull’input dell’utente):

MariaDB SQL

 

SELECT id, name, description
FROM products
ORDER BY VEC_DISTANCE_COSINE(
  VEC_FromText($user_input_vector),
  embedding
)
LIMIT 10;

Le funzioni VEC_DISTANCE_COSINE e VEC_DISTANCE_EUCLIDEAN prendono due vettori. Nell’esempio precedente, uno dei vettori è il vettore calcolato sull’input dell’utente, e l’altro è il vettore corrispondente per ciascun record nella tabella prodotti.

Un Esempio Pratico

Ho preparato un esempio pratico utilizzando Java e nessun framework di intelligenza artificiale in modo che tu possa comprendere veramente il processo di creazione di applicazioni di intelligenza artificiale generativa sfruttando le capacità di ricerca vettoriale di MariaDB. Puoi trovare il codice su GitHub.

Source:
https://dzone.com/articles/vector-storage-indexing-and-search-with-mariadb