Melakukan penelusuran vektor kesamaan di Bigtable dengan menemukan K-nearest neighbors
Penelusuran vektor kesamaan dapat membantu Anda mengidentifikasi konsep serupa dan makna kontekstual dalam data Bigtable, yang berarti dapat menghasilkan hasil yang lebih relevan saat memfilter data yang disimpan dalam rentang kunci yang ditentukan. Contoh kasus penggunaan dapat mencakup hal berikut:
- Penelusuran kotak masuk, tempat Anda ingin melakukan pencocokan semantik pesan untuk pengguna tertentu
- Deteksi anomali dalam rentang sensor
- Mengambil dokumen yang paling relevan dalam kumpulan kunci yang diketahui untuk retrieval augmented generation (RAG)
Halaman ini menjelaskan cara melakukan penelusuran vektor kesamaan di Bigtable menggunakan fungsi vektor jarak kosinus dan jarak Euclidean di GoogleSQL untuk Bigtable untuk menemukan tetangga terdekat K. Sebelum membaca halaman ini, Anda harus memahami konsep berikut:
- Jarak Euclidean: mengukur jarak terpendek antara dua vektor.
- Jarak kosinus: mengukur kosinus sudut antara dua vektor.
- Tetangga terdekat (KNN): algoritma machine learning terpandu yang digunakan untuk memecahkan masalah klasifikasi atau regresi.
Bigtable mendukung fungsi COSINE_DISTANCE()
dan
EUCLIDEAN_DISTANCE()
, yang beroperasi pada penyematan vektor, sehingga
Anda dapat menemukan KNN penyematan input.
Anda dapat menggunakan text-embeddings API Vertex AI untuk membuat dan menyimpan data Bigtable sebagai embedding vektor. Kemudian, Anda dapat memberikan embedding vektor ini sebagai parameter input dalam kueri untuk menemukan vektor terdekat dalam ruang N dimensi untuk menelusuri item yang serupa atau terkait secara semantik.
Kedua fungsi jarak menggunakan argumen vector1
dan vector2
, yang merupakan
jenis array<>
dan harus terdiri dari dimensi yang sama dan memiliki
panjang yang sama. Untuk mengetahui detail selengkapnya tentang fungsi ini, lihat hal berikut:
Kode di halaman ini menunjukkan cara membuat penyematan, menyimpannya di Bigtable, lalu melakukan penelusuran KNN.
Contoh di halaman ini menggunakan EUCLIDEAN_DISTANCE()
dan library klien Bigtable untuk Python. Namun, Anda juga dapat menggunakan
COSINE_DISTANCE()
dan library klien apa pun yang mendukung
GoogleSQL untuk Bigtable, seperti
library klien Bigtable untuk
Java.
Sebelum memulai
Selesaikan langkah-langkah berikut sebelum Anda mencoba contoh kode.
Peran yang diperlukan
Untuk mendapatkan izin yang Anda perlukan untuk membaca dan menulis ke Bigtable, minta administrator untuk memberi Anda peran IAM berikut.
- Bigtable User (
roles/bigtable.user
) di instance Bigtable yang ingin Anda kirimi permintaan
Menyiapkan lingkungan Anda
Download dan instal library klien Bigtable untuk Python. Untuk menggunakan fungsi GoogleSQL untuk Bigtable, Anda harus menggunakan
python-bigtable
versi 2.26.0 atau yang lebih baru. Petunjuk, termasuk cara menyiapkan autentikasi, ada di Python hello world.Jika Anda tidak memiliki instance Bigtable, ikuti langkah-langkah di bagian Membuat instance.
Identifikasi ID resource Anda. Saat Anda menjalankan kode, ganti placeholder berikut dengan ID project Google Cloud, instance Bigtable, dan tabel Anda:
PROJECT_ID
INSTANCE_ID
TABLE_ID
Membuat tabel untuk menyimpan teks, penyematan, dan frasa penelusuran
Buat tabel dengan dua grup kolom.
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")
Menyematkan teks dengan model dasar yang telah dilatih sebelumnya dari Vertex
Buat teks dan penyematan untuk disimpan di Bigtable bersama dengan kunci terkait. Untuk dokumentasi tambahan, lihat Mendapatkan embedding teks atau Mendapatkan embedding multimodal.
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")
Menentukan fungsi yang memungkinkan Anda mengonversi menjadi objek byte
Bigtable dioptimalkan untuk key-value pair dan umumnya menyimpan data sebagai objek byte. Untuk mengetahui informasi selengkapnya tentang mendesain model data untuk Bigtable, lihat Praktik terbaik desain skema.
Anda perlu mengonversi penyematan yang ditampilkan dari Vertex, yang disimpan sebagai daftar bilangan floating point di Python. Anda mengonversi setiap elemen ke formasi floating point IEEE 754 big-endian, lalu menggabungkannya. Fungsi berikut akan melakukannya.
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)
Menulis penyematan ke Bigtable
Konversikan penyematan ke objek byte, buat mutasi, lalu tulis data ke 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)
Melakukan penelusuran KNN menggunakan GoogleSQL untuk Bigtable
Vektor disimpan sebagai data berenkode biner yang dapat dibaca dari Bigtable menggunakan fungsi konversi dari jenis BYTES
ke ARRAY<FLOAT32>
.
Berikut adalah kueri SQL:
SELECT _key, TO_VECTOR32(data['embedding']) AS embedding
FROM table WHERE _key LIKE 'store123%';
Di Python, Anda dapat menggunakan fungsi COSINE_DISTANCE
GoogleSQL untuk menemukan kesamaan antara penyematan teks dan frasa penelusuran yang Anda berikan. Karena komputasi ini dapat memerlukan waktu untuk diproses, gunakan klien data asinkron library klien Python untuk menjalankan kueri 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()
Respons yang ditampilkan adalah deskripsi teks yang dihasilkan yang mendeskripsikan Bigtable.
Langkah selanjutnya
- Mem-build aplikasi yang didukung LLM menggunakan LangChain.
- Pelajari lebih lanjut cara menggunakan SQL di Bigtable.