Realiza una búsqueda de vectores de similitud en Bigtable encontrando los K vecinos más cercanos
La búsqueda de vectores de similitud puede ayudarte a identificar conceptos similares y significados contextuales en tus datos de Bigtable, lo que significa que puede proporcionar resultados más relevantes cuando filtras los datos almacenados dentro de un rango de claves especificado. Estos son algunos ejemplos de casos de uso:
- Es la correlación semántica de mensajes para un usuario en particular en la búsqueda de Recibidos.
- Detección de anomalías dentro de un rango de sensores
- Recupera los documentos más relevantes dentro de un conjunto de claves conocidas para la generación mejorada por recuperación (RAG).
- Personalización de los resultados de la búsqueda para mejorar la experiencia del usuario recuperando y clasificando los resultados según sus instrucciones y preferencias históricas que almacena Bigtable
- Recuperación de hilos de conversación similares para encontrar y mostrar conversaciones anteriores que sean contextualmente similares al chat actual de un usuario y, así, brindar una experiencia más personalizada
- Anulación de duplicados de instrucciones para identificar instrucciones idénticas o similares semánticamente enviadas por el mismo usuario y evitar el procesamiento redundante de la IA
En esta página, se describe cómo realizar una búsqueda de vectores de similitud en Bigtable con las funciones de vectores de distancia euclidiana y distancia del coseno en GoogleSQL para Bigtable para encontrar los K vecinos más cercanos. Antes de leer esta página, es importante que comprendas los siguientes conceptos:
- Distancia euclidiana: Mide la distancia más corta entre dos vectores.
- Distancia de coseno: Mide el coseno del ángulo entre dos vectores.
- K-vecinos más cercanos (KNN): Es un algoritmo de aprendizaje automático supervisado que se usa para resolver problemas de clasificación o regresión.
Bigtable admite las funciones COSINE_DISTANCE()
y EUCLIDEAN_DISTANCE()
, que operan en embeddings de vectores y te permiten encontrar los KNN del embedding de entrada.
Puedes usar las APIs de Vertex AI Text Embeddings para generar y almacenar tus datos de Bigtable como embeddings de vectores. Luego, puedes proporcionar estos embeddings de vector como parámetro de entrada en tu búsqueda para encontrar los vectores más cercanos en el espacio N-dimensional y buscar elementos relacionados o similares desde el punto de vista semántico.
Ambas funciones de distancia toman los argumentos vector1
y vector2
, que son del tipo array<>
y deben constar de las mismas dimensiones y tener la misma longitud. Para obtener más detalles sobre estas funciones, consulta lo siguiente:
El código de esta página muestra cómo crear incorporaciones, almacenarlas en Bigtable y, luego, realizar una búsqueda de KNN.
En el ejemplo de esta página, se usan EUCLIDEAN_DISTANCE()
y la biblioteca cliente de Bigtable para Python. Sin embargo, también puedes usar COSINE_DISTANCE()
y cualquier biblioteca cliente que admita GoogleSQL para Bigtable, como la
biblioteca cliente de Bigtable para Java.
Antes de comenzar
Completa los siguientes pasos antes de probar las muestras de código.
Roles requeridos
Para obtener los permisos que necesitas para leer y escribir en Bigtable, pídele a tu administrador que te otorgue el siguiente rol de IAM:
- Usuario de Bigtable (
roles/bigtable.user
) en la instancia de Bigtable a la que deseas enviar solicitudes
Configura tu entorno
Descarga e instala la biblioteca cliente de Bigtable para Python. Para usar las funciones de GoogleSQL para Bigtable, debes usar la versión
python-bigtable
2.26.0 o posterior. Las instrucciones, incluida la configuración de la autenticación, se encuentran en Python Hello World.Si no tienes una instancia de Bigtable, sigue los pasos que se indican en Crea una instancia.
Identifica los IDs de tus recursos. Cuando ejecutes el código, reemplaza los siguientes marcadores de posición por los IDs de tu proyecto Google Cloud , instancia de Bigtable y tabla:
PROJECT_ID
INSTANCE_ID
TABLE_ID
Crea una tabla para almacenar el texto, los embeddings y la frase de búsqueda
Crea una tabla con dos familias de columnas.
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 textos con un modelo fundamental previamente entrenado de Vertex
Genera el texto y los embeddings para almacenarlos en Bigtable junto con las claves asociadas. Para obtener documentación adicional, consulta Obtén incorporaciones de texto o Obtén incorporaciones multimodales.
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")
Define funciones que te permiten convertirte en objetos de bytes
Bigtable está optimizado para pares clave-valor y, por lo general, almacena datos como objetos de bytes. Si deseas obtener más información para diseñar tu modelo de datos para Bigtable, consulta Recomendaciones sobre el diseño del esquema.
Debes convertir las incorporaciones que provienen de Vertex, que se almacenan como una lista de números de punto flotante en Python. Convierte cada elemento al formato de punto flotante IEEE 754 big-endian y, luego, los concatena. La siguiente función logra esto.
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)
Escribe las incorporaciones en Bigtable
Convierte los embeddings en objetos de bytes, crea una mutación y, luego, escribe los datos en 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)
Realiza una búsqueda de KNN con GoogleSQL para Bigtable
Los vectores se almacenan como datos codificados de forma binaria que se pueden leer desde Bigtable con una función de conversión del tipo BYTES
a ARRAY<FLOAT32>
.
Esta es la consulta en SQL:
SELECT _key, TO_VECTOR32(data['embedding']) AS embedding
FROM table WHERE _key LIKE 'store123%';
En Python, puedes usar la función COSINE_DISTANCE
de GoogleSQL para encontrar la similitud entre tus incorporaciones de texto y las frases de búsqueda que le proporciones. Dado que este cálculo puede tardar en procesarse, usa el cliente de datos asíncrono de la biblioteca cliente de Python para ejecutar la consulta en 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 respuesta que se devuelve es una descripción de texto generada que describe Bigtable.
¿Qué sigue?
- Compila aplicaciones con tecnología de LLM a través de LangChain.
- Obtén más información para usar SQL en Bigtable.