Esegui la ricerca vettoriale di similarità in Bigtable trovando i K-nearest neighbor
La ricerca vettoriale per similarità può aiutarti a identificare concetti simili e il significato contestuale nei tuoi dati Bigtable, il che significa che può fornire risultati più pertinenti quando filtri i dati archiviati in un intervallo di chiavi specificato. Ecco alcuni esempi di casi d'uso:
- Corrispondenza semantica dei messaggi per un determinato utente nella ricerca nella Posta in arrivo.
- Rilevamento di anomalie in una gamma di sensori.
- Recupero dei documenti più pertinenti all'interno di un insieme di chiavi note per la generazione aumentata dal recupero (RAG).
- Personalizzazione dei risultati di ricerca per migliorare l'esperienza di ricerca di un utente recuperando e classificando i risultati in base ai prompt e alle preferenze storici memorizzati da Bigtable.
- Recupero di thread di conversazione simili per trovare e visualizzare conversazioni passate che sono contestualmente simili alla chat attuale di un utente per un'esperienza più personalizzata.
- Richiedi la deduplicazione per identificare prompt identici o semanticamente simili inviati dallo stesso utente ed evitare l'elaborazione ridondante dell'AI.
Questa pagina descrive come eseguire la ricerca vettoriale di similarità in Bigtable utilizzando le funzioni vettoriali di distanza del coseno e distanza euclidea in GoogleSQL per Bigtable per trovare i K-nearest neighbors. Prima di leggere questa pagina, è importante che tu comprenda i seguenti concetti:
- Distanza euclidea: misura la distanza più breve tra due vettori.
- Distanza del coseno: misura il coseno dell'angolo tra due vettori.
- K-Nearest Neighbors (KNN): un algoritmo di machine learning supervisionato utilizzato per risolvere problemi di classificazione o regressione.
Bigtable supporta le funzioni COSINE_DISTANCE()
e
EUCLIDEAN_DISTANCE()
, che operano su incorporamenti vettoriali, consentendoti
di trovare il KNN dell'incorporamento di input.
Puoi utilizzare le API Vertex AI per gli incorporamenti di testo per generare e archiviare i tuoi dati Bigtable come incorporamenti vettoriali. Puoi quindi fornire questi incorporamenti vettoriali come parametro di input nella query per trovare i vettori più vicini nello spazio N-dimensionale per cercare elementi semanticamente simili o correlati.
Entrambe le funzioni di distanza accettano gli argomenti vector1
e vector2
, che sono di tipo array<>
e devono essere costituiti dalle stesse dimensioni e avere la stessa lunghezza. Per maggiori dettagli su queste funzioni, consulta quanto segue:
Il codice in questa pagina mostra come creare incorporamenti, archiviarli in Bigtable ed eseguire una ricerca KNN.
L'esempio in questa pagina utilizza EUCLIDEAN_DISTANCE()
e la
libreria client Bigtable per Python. Tuttavia, puoi anche utilizzare
COSINE_DISTANCE()
e qualsiasi libreria client che supporti
GoogleSQL per Bigtable, ad esempio la
libreria client Bigtable per
Java.
Prima di iniziare
Completa le seguenti operazioni prima di provare gli esempi di codice.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per leggere e scrivere in Bigtable, chiedi all'amministratore di concederti il seguente ruolo IAM:
- Utente Bigtable
(
roles/bigtable.user
) sull'istanza Bigtable a cui vuoi inviare le richieste
Configura l'ambiente
Scarica e installa la libreria client Bigtable per Python. Per utilizzare GoogleSQL per le funzioni Bigtable, devi utilizzare
python-bigtable
versione 2.26.0 o successive. Le istruzioni, inclusa la configurazione dell'autenticazione, sono disponibili in Python hello world.Se non hai un'istanza Bigtable, segui i passaggi descritti in Creare un'istanza.
Identifica gli ID risorsa. Quando esegui il codice, sostituisci i seguenti segnaposto con gli ID del tuo progetto Google Cloud , dell'istanza Bigtable e della tabella:
PROJECT_ID
INSTANCE_ID
TABLE_ID
Crea una tabella per archiviare il testo, gli incorporamenti e la frase di ricerca
Crea una tabella con due famiglie di colonne.
Python
from google.cloud import bigtable
from google.cloud.bigtable import column_family
client = bigtable.Client(project=PROJECT_ID, admin=True)
instance = client.instance(INSTANCE_ID)
table = instance.table(TABLE_ID)
column_families = {"docs":column_family.MaxVersionsGCRule(2), "search_phrase":column_family.MaxVersionsGCRule(2)}
if not table.exists():
table.create(column_families=column_families)
else:
print("Table already exists")
Incorpora testi con un modello di base preaddestrato di Vertex
Genera il testo e gli incorporamenti da archiviare in Bigtable insieme alle chiavi associate. Per ulteriore documentazione, consulta Recuperare incorporamenti di testo o Recuperare incorporamenti multimodali.
Python
from typing import List, Optional
from vertexai.language_models import TextEmbeddingInput, TextEmbeddingModel
from vertexai.generative_models import GenerativeModel
#defines which LLM that we should use to generate the text
model = GenerativeModel("gemini-1.5-pro-001")
#First, use generative AI to create a list of 10 chunks for phrases
#This can be replaced with a static list of text items or your own data
chunks = []
for i in range(10):
response = model.generate_content(
"Generate a paragraph between 10 and 20 words that is about about either
Bigtable or Generative AI"
)
chunks.append(response.text)
print(response.text)
#create embeddings for the chunks of text
def embed_text(
texts: List[str] = chunks,
task: str = "RETRIEVAL_DOCUMENT",
model_name: str = "text-embedding-004",
dimensionality: Optional[int] = 128,
) -> List[List[float]]:
"""Embeds texts with a pre-trained, foundational model."""
model = TextEmbeddingModel.from_pretrained(model_name)
inputs = [TextEmbeddingInput(text, task) for text in texts]
kwargs = dict(output_dimensionality=dimensionality) if dimensionality else {}
embeddings = model.get_embeddings(inputs, **kwargs)
return [embedding.values for embedding in embeddings]
embeddings = embed_text()
print("embeddings created for text phrases")
Definisci funzioni che consentono di eseguire la conversione in oggetti byte
Bigtable è ottimizzato per le coppie chiave-valore e in genere archivia i dati come oggetti byte. Per saperne di più sulla progettazione del modello dei dati per Bigtable, consulta Best practice per la progettazione dello schema.
Devi convertire gli incorporamenti restituiti da Vertex, che vengono memorizzati come elenco di numeri in virgola mobile in Python. Converti ogni elemento in formato a virgola mobile IEEE 754 big-endian e poi concatenali. La seguente funzione consente di ottenere questo risultato.
Python
import struct
def floats_to_bytes(float_list):
"""
Convert a list of floats to a bytes object, where each float is represented
by 4 big-endian bytes.
Parameters:
float_list (list of float): The list of floats to be converted.
Returns:
bytes: The resulting bytes object with concatenated 4-byte big-endian
representations of the floats.
"""
byte_array = bytearray()
for value in float_list:
packed_value = struct.pack('>f', value)
byte_array.extend(packed_value)
# Convert bytearray to bytes
return bytes(byte_array)
Scrivi gli incorporamenti in Bigtable
Converti gli incorporamenti in oggetti byte, crea una mutazione e poi scrivi i dati in Bigtable.
Python
from google.cloud.bigtable.data import RowMutationEntry
from google.cloud.bigtable.data import SetCell
mutations = []
embeddings = embed_text()
for i, embedding in enumerate(embeddings):
print(embedding)
#convert each embedding into a byte object
vector = floats_to_bytes(embedding)
#set the row key which will be used to pull the range of documents (ex. doc type or user id)
row_key = f"doc_{i}"
row = table.direct_row(row_key)
#set the column for the embedding based on the byte object format of the embedding
row.set_cell("docs","embedding",vector)
#store the text associated with vector in the same key
row.set_cell("docs","text",chunks[i])
mutations.append(row)
#write the rows to Bigtable
table.mutate_rows(mutations)
Esegui una ricerca KNN utilizzando GoogleSQL per Bigtable
I vettori vengono archiviati come dati codificati in formato binario che possono essere letti da
Bigtable utilizzando una funzione di conversione dal tipo BYTES
a
ARRAY<FLOAT32>
.
Ecco la query SQL:
SELECT _key, TO_VECTOR32(data['embedding']) AS embedding
FROM table WHERE _key LIKE 'store123%';
In Python, puoi utilizzare la funzione GoogleSQL COSINE_DISTANCE
per trovare la somiglianza tra gli incorporamenti di testo e le frasi di ricerca che fornisci. Poiché l'elaborazione di questo calcolo può richiedere tempo, utilizza il client di dati asincroni della libreria client Python per eseguire la query SQL.
Python
from google.cloud.bigtable.data import BigtableDataClientAsync
#first embed the search phrase
search_embedding = embed_text(texts=["Apache HBase"])
query = """
select _key, docs['text'] as description
FROM knn_intro
ORDER BY COSINE_DISTANCE(TO_VECTOR32(docs['embedding']), {search_embedding})
LIMIT 1;
"""
async def execute_query():
async with BigtableDataClientAsync(project=PROJECT_ID) as client:
local_query = query
async for row in await client.execute_query(query.format(search_embedding=search_embedding[0]), INSTANCE_ID):
return(row["_key"],row["description"])
await execute_query()
La risposta restituita è una descrizione di testo generata che descrive Bigtable.
Passaggi successivi
- Crea applicazioni basate su LLM utilizzando LangChain.
- Scopri di più sull'utilizzo di SQL in Bigtable.