Ähnlichkeitssuche in Bigtable durchführen, indem die K-nächsten Nachbarn ermittelt werden
Mit der Suche nach Ähnlichkeitsvektoren können Sie ähnliche Konzepte und den Kontext in Ihren Bigtable-Daten ermitteln. Das bedeutet, dass Sie relevantere Ergebnisse erhalten, wenn Sie nach Daten filtern, die in einem bestimmten Schlüsselbereich gespeichert sind. Beispiele für Anwendungsfälle:
- Semantischer Abgleich von Nachrichten für einen bestimmten Nutzer bei der Suche im Posteingang.
- Anomalieerkennung für eine Reihe von Sensoren.
- Abrufen der relevantesten Dokumente innerhalb einer Reihe bekannter Schlüssel für Retrieval-Augmented Generation (RAG).
- Personalisierung von Suchergebnissen, um die Sucherfahrung eines Nutzers zu verbessern, indem Ergebnisse basierend auf seinen bisherigen Prompts und Einstellungen, die in Bigtable gespeichert sind, abgerufen und gerankt werden.
- Abrufen ähnlicher Unterhaltungsstränge, um frühere Unterhaltungen zu finden und anzuzeigen, die inhaltlich dem aktuellen Chat eines Nutzers ähneln, um die Nutzung zu personalisieren.
- Deduplizierung von Prompts, um identische oder semantisch ähnliche Prompts zu erkennen, die vom selben Nutzer eingereicht wurden, und um redundante KI-Verarbeitung zu vermeiden.
Auf dieser Seite wird beschrieben, wie Sie in Bigtable mit den Vektorfunktionen für Kosinus- und euklidische Distanz in GoogleSQL für Bigtable eine Ähnlichkeitsvektorsuche durchführen, um die K nächsten Nachbarn zu finden. Bevor Sie diese Seite lesen, sollten Sie sich mit den folgenden Konzepten vertraut machen:
- Euklidische Distanz: Misst die kürzeste Distanz zwischen zwei Vektoren.
- Kosinus-Distanz: Hier wird der Kosinus des Winkels zwischen zwei Vektoren gemessen.
- K-Nearest Neighbors (KNN): Ein Algorithmus für überwachtes maschinelles Lernen, der zur Lösung von Klassifizierungs- oder Regressionsproblemen verwendet wird.
Bigtable unterstützt die Funktionen COSINE_DISTANCE()
und EUCLIDEAN_DISTANCE()
, die für Vektoreinbettungen verwendet werden. Damit können Sie die KNN der Eingabeeinbettung ermitteln.
Mit den Vertex AI Text Embeddings 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ächstgelegenen Vektoren im N-dimensionalen Raum zu finden und nach semantisch ähnlichen oder verwandten Elementen zu suchen.
Beide Distanzfunktionen verwenden die Argumente vector1
und vector2
, die vom Typ array<>
sind und aus denselben Dimensionen bestehen und dieselbe Länge haben müssen. 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 zu erhalten, die Sie zum Lesen und Schreiben in Bigtable benötigen:
- Bigtable-Nutzer (
roles/bigtable.user
) für die 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, auch zum Einrichten der Authentifizierung, finden Sie unter Python Hello World.Wenn Sie keine Bigtable-Instanz haben, folgen Sie der Anleitung unter Instanz erstellen.
Ressourcen-IDs ermitteln 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 Suchbegriffen 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 zusammen mit den zugehörigen Schlüsseln in Bigtable gespeichert werden sollen. 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 das Schemadesign.
Sie müssen die Einbettungen, die von Vertex zurückgegeben werden und in Python als Liste von Gleitkommazahlen gespeichert sind, konvertieren. Sie konvertieren jedes Element in das Big-Endian-IEEE 754-Gleitkommaformat und verketten sie dann. Die folgende Funktion ermöglicht dies.
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 durchführen
Die Vektoren werden als binär codierte Daten gespeichert, die aus Bigtable gelesen werden können. Dazu ist eine Konvertierungsfunktion vom Typ BYTES
in ARRAY<FLOAT32>
erforderlich.
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 Texteinbettungen und den Suchbegriffen zu ermitteln, die Sie angeben. Da die Verarbeitung dieser Berechnung einige Zeit in Anspruch nehmen kann, sollten Sie die SQL-Abfrage mit dem asynchronen Datenclient der Python-Clientbibliothek ausfü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 von Bigtable.
Nächste Schritte
- LLM-gestützte Anwendungen mit LangChain erstellen
- Weitere Informationen zur Verwendung von SQL in Bigtable