Ähnlichkeitsvektorsuche in Bigtable durchführen, indem die K-nächsten Nachbarn ermittelt werden
Mit der Suche nach Ähnlichkeitsvektoren können Sie ähnliche Konzepte und kontextbezogene Bedeutungen in Ihren Bigtable-Daten ermitteln. Das bedeutet, dass Sie beim Filtern nach Daten, die in einem bestimmten Schlüsselbereich gespeichert sind, relevantere Ergebnisse erhalten. Beispiele für Anwendungsfälle:
- Posteingangssuche, bei der Sie Nachrichten für einen bestimmten Nutzer semantisch abgleichen möchten
- Anomalieerkennung innerhalb eines Bereichs von Sensoren
- Abrufen der relevantesten Dokumente innerhalb einer Reihe bekannter Schlüssel für die Retrieval-Augmented Generation (RAG)
Auf dieser Seite wird beschrieben, wie Sie mit den Vektorfunktionen „Kosinus-Distanz“ und „Euklidische Distanz“ in GoogleSQL für Bigtable eine Ähnlichkeitsvektorsuche in Bigtable ausführen, um die K-nächsten Nachbarn zu finden. Bevor Sie diese Seite lesen, sollten Sie sich mit den folgenden Konzepten vertraut machen:
- Euklidischer Abstand: Misst die kürzeste Entfernung zwischen zwei Vektoren.
- Kosinus-Distanz: Der Kosinus des Winkels zwischen zwei Vektoren.
- K-Nearest-Neighbor (KNN): Ein überwachter Algorithmus für maschinelles Lernen, der zur Lösung von Klassifizierungs- oder Regressionsproblemen verwendet wird.
Bigtable unterstützt die Funktionen COSINE_DISTANCE()
und EUCLIDEAN_DISTANCE()
, die auf Vektoreinbettungen angewendet werden und mit denen Sie den KNN der Eingabeeinbettung ermitteln können.
Mit den Vertex AI Text Embedding APIs können Sie Ihre Bigtable-Daten als Vektoreinbettungen generieren und speichern. Sie können diese Vektoreinbettungen dann als Eingabeparameter in Ihrer Abfrage angeben, um die nächsten Vektoren im n-dimensionalen Raum zu finden und nach semantisch ähnlichen oder ähnlichen Elementen zu suchen.
Beide Distanzfunktionen nehmen die Argumente vector1
und vector2
vom Typ array<>
an. Sie müssen dieselben Dimensionen haben und dieselbe Länge. Weitere Informationen zu diesen Funktionen finden Sie hier:
Der Code auf dieser Seite zeigt, wie Sie Einbettungen erstellen, in Bigtable speichern und dann eine KNN-Suche durchführen.
Im Beispiel auf dieser Seite werden EUCLIDEAN_DISTANCE()
und die Bigtable-Clientbibliothek für Python verwendet. Sie können jedoch auch COSINE_DISTANCE()
und jede Clientbibliothek verwenden, die GoogleSQL für Bigtable unterstützt, z. B. die
Bigtable-Clientbibliothek für Java.
Hinweise
Führen Sie die folgenden Schritte aus, bevor Sie die Codebeispiele ausprobieren.
Erforderliche Rollen
Bitten Sie Ihren Administrator, Ihnen die folgende IAM-Rolle zuzuweisen, um die Berechtigungen zum Lesen und Schreiben in Bigtable zu erhalten.
- Bigtable-Nutzer (
roles/bigtable.user
) der Bigtable-Instanz, an die Sie Anfragen senden möchten
Umgebung einrichten
Laden Sie die Bigtable-Clientbibliothek für Python herunter und installieren Sie sie. Wenn Sie GoogleSQL für Bigtable-Funktionen verwenden möchten, müssen Sie
python-bigtable
Version 2.26.0 oder höher verwenden. Eine Anleitung, einschließlich der Einrichtung der Authentifizierung, finden Sie unter Python-Hallo-Welt-Programm.Wenn Sie noch keine Bigtable-Instanz haben, folgen Sie der Anleitung unter Instanz erstellen.
Geben Sie Ihre Ressourcen-IDs an. Ersetzen Sie beim Ausführen des Codes die folgenden Platzhalter durch die IDs Ihres Google Cloud-Projekts, Ihrer Bigtable-Instanz und Ihrer Tabelle:
PROJECT_ID
INSTANCE_ID
TABLE_ID
Tabelle zum Speichern von Text, Einbettungen und Suchbegriff erstellen
Erstellen Sie eine Tabelle mit zwei Spaltenfamilien.
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")
Texte mit einem vortrainierten Basismodell von Vertex einbetten
Generieren Sie den Text und die Einbettungen, die in Bigtable gespeichert werden sollen, zusammen mit den zugehörigen Schlüsseln. Weitere Informationen finden Sie unter Texteinbettungen abrufen oder Multimodale Einbettungen abrufen.
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")
Funktionen definieren, mit denen Sie in Byte-Objekte konvertieren können
Bigtable ist für Schlüssel/Wert-Paare optimiert und speichert Daten in der Regel als Byte-Objekte. Weitere Informationen zum Entwerfen Ihres Datenmodells für Bigtable finden Sie unter Best Practices für Schemadesign.
Sie müssen die von Vertex zurückgegebenen Einbettungen konvertieren, die in Python als Liste von Gleitkommazahlen gespeichert sind. Sie konvertieren jedes Element in die Big-Endian-IEEE-754-Gleitkommadarstellung und verketten sie dann miteinander. Das wird mit der folgenden Funktion erreicht.
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)
Einbettungen in Bigtable schreiben
Konvertieren Sie die Einbettungen in Byte-Objekte, erstellen Sie eine Mutation und schreiben Sie die Daten dann 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)
KNN-Suche mit GoogleSQL für Bigtable ausführen
Die Vektoren werden als binärcodierte Daten gespeichert, die mithilfe einer Konvertierungsfunktion vom Typ BYTES
in ARRAY<FLOAT32>
aus Bigtable gelesen werden können.
Hier ist die SQL-Abfrage:
SELECT _key, TO_VECTOR32(data['embedding']) AS embedding
FROM table WHERE _key LIKE 'store123%';
In Python können Sie die GoogleSQL-Funktion COSINE_DISTANCE
verwenden, um die Ähnlichkeit zwischen Ihren Text-Embeddings und den von Ihnen angegebenen Suchbegriffen zu ermitteln. Da diese Berechnung einige Zeit in Anspruch nehmen kann, verwenden Sie den asynchronen Datenclient der Python-Clientbibliothek, um die SQL-Abfrage auszuführen.
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()
Die zurückgegebene Antwort ist eine generierte Textbeschreibung, die Bigtable beschreibt.
Nächste Schritte
- LLM-gestützte Anwendungen mit LangChain erstellen
- Weitere Informationen zur Verwendung von SQL in Bigtable