۱. مقدمه
پیشرفتهای اخیر در یادگیری عمیق، نمایش متن و سایر دادهها را به گونهای که معنای معنایی را در بر بگیرد، امکانپذیر کرده است. این امر منجر به رویکرد جدیدی به جستجو، به نام جستجوی برداری، شده است که از نمایشهای برداری متن (که به عنوان جاسازیها شناخته میشوند) برای یافتن اسنادی که بیشترین ارتباط را با جستجوی کاربر دارند، استفاده میکند. جستجوی برداری نسبت به جستجوی سنتی برای برنامههایی مانند جستجوی پوشاک، که در آن کاربران اغلب اقلام را بر اساس توضیحات، سبک یا زمینه آنها جستجو میکنند، نه بر اساس نام دقیق محصول یا برند، ترجیح داده میشود. ما میتوانیم پایگاه داده Cloud Spanner را با Vector Search ادغام کنیم تا تطبیق شباهت برداری را انجام دهیم. با استفاده همزمان از Spanner و Vector Search ، مشتریان میتوانند یک ادغام قدرتمند ایجاد کنند که قابلیت دسترسی، قابلیت اطمینان و مقیاس Spanner و قابلیتهای جستجوی شباهت پیشرفته Vertex AI Vector Search را با هم ترکیب میکند. این جستجو با مقایسه جاسازیهای اقلام در فهرست Vector Search و بازگرداندن مشابهترین تطابقها انجام میشود.
مورد استفاده
تصور کنید که شما یک دانشمند داده در یک خردهفروشی مد هستید که سعی میکنید با روندهای به سرعت در حال تغییر، جستجوهای محصول و توصیهها همگام باشید. چالش این است که شما منابع و انبارهای داده محدودی دارید. این پست وبلاگ نحوه پیادهسازی یک مورد استفاده از توصیه پوشاک با استفاده از رویکرد جستجوی شباهت روی دادههای پوشاک را نشان میدهد. مراحل زیر پوشش داده شده است:
- دادهها از Spanner تهیه شدهاند
- بردارهایی که برای دادههای پوشاک با استفاده از ML.PREDICT تولید شده و در Spanner ذخیره شدهاند
- دادههای برداری Spanner با جستجوی برداری با استفاده از کارهای جریان داده و گردش کار یکپارچه شدهاند.
- جستجوی برداری برای یافتن تطابق شباهت برای ورودی وارد شده توسط کاربر انجام شد.
ما یک برنامه وب آزمایشی خواهیم ساخت که جستجوی پوشاک را بر اساس متن ورودی کاربر انجام میدهد. این برنامه به کاربران اجازه میدهد تا با وارد کردن توضیحات متنی، پوشاک را جستجو کنند.
فهرست جستجوی آچار به بردار:
دادههای مربوط به جستجوی پوشاک در Spanner ذخیره میشوند. ما API مربوط به Vertex AI Embeddings را در ساختار ML.PREDICT مستقیماً از دادههای Spanner فراخوانی خواهیم کرد. سپس از کارهای Dataflow و Workflow که این دادهها (موجودی و جاسازیها) را به صورت انبوه در Vector Search مربوط به Vertex AI بارگذاری کرده و شاخص را بهروزرسانی میکنند، استفاده خواهیم کرد.
اجرای کوئریهای کاربر روی ایندکس:
وقتی کاربر توضیحات لباس را وارد میکند، برنامه با استفاده از API Text Embeddings، جاسازیها را به صورت بلادرنگ تولید میکند. سپس این ورودی به API Vector Search ارسال میشود تا 10 توضیح محصول مرتبط را از فهرست پیدا کند و تصویر مربوطه را نمایش دهد.
نمای کلی معماری
معماری برنامهی Spanner-Vector Search در نمودار دو قسمتی زیر نشان داده شده است:
فهرست جستجوی آچار به بردار: 
برنامه کلاینت برای اجرای کوئریهای کاربر روی ایندکس:
آنچه خواهید ساخت
شاخص آچار به بردار:
- پایگاه داده Spanner برای ذخیره و مدیریت دادههای منبع و جاسازیهای مربوطه
- یک کار گردش کار که دادهها (شناسه و جاسازیها) را به صورت انبوه در پایگاه داده جستجوی برداری Vertex AI بارگذاری میکند.
- یک API جستجوی برداری که برای یافتن توضیحات مربوط به محصول از فهرست استفاده میشود.
اجرای کوئریهای کاربر روی ایندکس:
- یک برنامه وب که به کاربران اجازه میدهد توضیحات متنی از پوشاک را وارد کنند، جستجوی شباهت را با استفاده از نقطه پایانی شاخص مستقر انجام میدهد و نزدیکترین پوشاک را به ورودی برمیگرداند.
چگونه کار میکند؟
وقتی کاربر توضیح متنی پوشاک را وارد میکند، برنامه وب آن توضیح را به Vector Search API ارسال میکند. سپس Vector Search API از جاسازیهای توضیحات پوشاک برای یافتن مرتبطترین توضیحات محصول از فهرست استفاده میکند. سپس توضیحات محصول و تصاویر مربوطه به کاربر نمایش داده میشوند. گردش کار کلی به شرح زیر است:
- ایجاد جاسازی برای دادههای ذخیره شده در Spanner.
- خروجی گرفتن و آپلود جاسازیها در یک فهرست جستجوی برداری (Vector Search).
- با انجام جستجوی نزدیکترین همسایه، فهرست جستجوی برداری (Vector Search) را برای موارد مشابه جستجو کنید.
۲. الزامات
قبل از اینکه شروع کنی
- در کنسول گوگل کلود ، در صفحه انتخاب پروژه، یک پروژه گوگل کلود را انتخاب یا ایجاد کنید
- مطمئن شوید که صورتحساب برای پروژه ابری شما فعال است. یاد بگیرید که چگونه بررسی کنید که آیا صورتحساب در یک پروژه فعال است یا خیر.
- مطمئن شوید که تمام APIهای لازم (Cloud Spanner، Vertex AI، Google Cloud Storage) فعال هستند.
- شما از Cloud Shell ، یک محیط خط فرمان که در Google Cloud اجرا میشود و از قبل با gcloud بارگذاری شده است، استفاده خواهید کرد. برای دستورات و نحوه استفاده از gcloud به مستندات مراجعه کنید. اگر پروژه شما تنظیم نشده است، از دستور زیر برای تنظیم آن استفاده کنید:
gcloud config set project <YOUR_PROJECT_ID>
- برای شروع، به صفحه Cloud Spanner با پروژه فعال Google Cloud خود بروید.
۳. بکاند: منبع داده و جاسازیهای Spanner خود را ایجاد کنید
در این مورد استفاده، پایگاه داده Spanner موجودی پوشاک را به همراه تصاویر و توضیحات مربوطه در خود جای میدهد. مطمئن شوید که برای توضیحات متنی، جاسازیهایی ایجاد کرده و آنها را در پایگاه داده Spanner خود به صورت ARRAY<float64> ذخیره میکنید.
- ایجاد دادههای Spanner
یک نمونه با نام "spanner-vertex" و یک پایگاه داده با نام "spanner-vertex-embeddings" ایجاد کنید. با استفاده از DDL یک جدول ایجاد کنید:
CREATE TABLE
apparels ( id NUMERIC,
category STRING(100),
sub_category STRING(50),
uri STRING(200),
content STRING(2000),
embedding ARRAY<FLOAT64>
)
PRIMARY KEY
(id);
- درج دادهها در جدول با استفاده از دستور INSERT SQL
اسکریپتهای درج برای دادههای نمونه اینجا موجود است.
- ایجاد مدل جاسازی متن
این مورد لازم است تا بتوانیم جاسازیهایی برای محتوای ورودی ایجاد کنیم. در زیر DDL مربوط به آن آمده است:
CREATE MODEL text_embeddings INPUT(content STRING(MAX))
OUTPUT(
embeddings
STRUCT<
statistics STRUCT<truncated BOOL, token_count FLOAT64>,
values ARRAY<FLOAT64>>
)
REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/abis-345004/locations/us-central1/publishers/google/models/textembedding-gecko');
- ایجاد جاسازیهای متنی برای دادههای منبع
یک جدول برای ذخیره جاسازیها ایجاد کنید و جاسازیهای تولید شده را وارد کنید. در یک برنامه پایگاه داده واقعی، بارگذاری دادهها در Spanner تا مرحله 2 تراکنشی خواهد بود. برای حفظ بهترین شیوههای طراحی، ترجیح میدهم جداول تراکنشی را نرمال نگه دارم، بنابراین یک جدول جداگانه برای جاسازیها ایجاد میکنم.
CREATE TABLE apparels_embeddings (id string(100), embedding ARRAY<FLOAT64>)
PRIMARY KEY (id);
INSERT INTO apparels_embeddings(id, embeddings)
SELECT CAST(id as string), embeddings.values
FROM ML.PREDICT(
MODEL text_embeddings,
(SELECT id, content from apparels)
) ;
اکنون که محتوای حجیم و جاسازیها آماده هستند، بیایید یک فهرست جستجوی برداری و نقطه پایانی برای ذخیره جاسازیهایی که به انجام جستجوی برداری کمک میکنند، ایجاد کنیم.
۴. کار گردش کار: اکسپورت دادهها با آچار به جستجوی برداری
- یک سطل ذخیرهسازی ابری ایجاد کنید
این برای ذخیره جاسازیها از Spanner در یک سطل GCS با فرمت json که Vector Search آن را به عنوان ورودی انتظار دارد، لازم است. یک سطل در همان ناحیهای که دادههای شما در Spanner قرار دارند، ایجاد کنید . در صورت لزوم، یک پوشه درون آن ایجاد کنید، اما عمدتاً یک فایل خالی به نام empty.json در آن ایجاد کنید.
- تنظیم گردش کار ابری
برای تنظیم خروجی دستهای از Spanner به یک شاخص جستجوی برداری Vertex AI:
یک اندیس خالی ایجاد کنید :
مطمئن شوید که فهرست جستجوی برداری (Vector Search Index) در همان ناحیهای است که سطل ذخیرهسازی ابری (Cloud Storage Bucket) و دادهها در آن قرار دارند. 11 مرحله از دستورالعمل زیر تب کنسول در بخش «ایجاد یک فهرست برای بهروزرسانی دستهای » در صفحه مدیریت فهرستها را دنبال کنید. در پوشهای که به contentsDeltaUri منتقل میشود، یک فایل خالی به نام empty.json ایجاد کنید زیرا بدون این فایل نمیتوانید فهرستی ایجاد کنید. این کار یک فهرست خالی ایجاد میکند.
اگر از قبل یک فهرست دارید، میتوانید از این مرحله صرف نظر کنید. گردش کار، فهرست شما را بازنویسی میکند.
توجه : شما نمیتوانید یک اندیس خالی را در یک نقطه پایانی مستقر کنید. بنابراین، مرحله استقرار آن در یک نقطه پایانی را به مرحله بعدی، پس از خروجی گرفتن دادههای برداری به فضای ذخیرهسازی ابری، موکول میکنیم.
کلون کردن این مخزن گیت : روشهای مختلفی برای کلون کردن یک مخزن گیت وجود دارد، یکی از این روشها اجرای دستور زیر با استفاده از GitHub CLI است. دو دستور زیر را از ترمینال Cloud Shell اجرا کنید:
gh repo clone cloudspannerecosystem/spanner-ai
cd spanner-ai/vertex-vector-search/workflows
این پوشه شامل دو فایل است
-
batch-export.yaml: این تعریف گردش کار است. -
sample-batch-input.json: این نمونهای از پارامترهای ورودی گردش کار است.
تنظیم input.json از فایل نمونه: ابتدا، فایل json نمونه را کپی کنید.
ورودی.json با cp sample-batch-input.json
سپس input.json با جزئیات پروژه خود ویرایش کنید. در این حالت، json شما باید به شکل زیر باشد:
{
"project_id": "<<YOUR_PROJECT>>",
"location": "<<us-central1>>",
"dataflow": {
"temp_location": "gs://<<YOUR_BUCKET>>/<<FOLDER_IF_ANY>>/workflow_temp"
},
"gcs": {
"output_folder": "gs://<<YOUR_BUCKET>>/<<FOLDER_IF_ANY>>/workflow_output"
},
"spanner": {
"instance_id": "spanner-vertex",
"database_id": "spanner-vertex-embeddings",
"table_name": "apparels_embeddings",
"columns_to_export": "embedding,id"
},
"vertex": {
"vector_search_index_id": "<<YOUR_INDEX_ID>>"
}
}
مجوزهای راهاندازی
برای محیطهای عملیاتی، اکیداً توصیه میکنیم یک حساب کاربری سرویس جدید ایجاد کنید و یک یا چند نقش IAM که شامل حداقل مجوزهای مورد نیاز برای مدیریت سرویس هستند را به آن اعطا کنید. نقشهای زیر برای تنظیم گردش کار جهت خروجی گرفتن دادهها از Spanner (جاسازیها) به شاخص Vector Search مورد نیاز هستند:
حساب کاربری سرویس گردش کار ابری :
به طور پیشفرض از حساب سرویس پیشفرض Compute Engine استفاده میکند.
اگر از یک حساب کاربری سرویس پیکربندیشده دستی استفاده میکنید، باید نقشهای زیر را نیز در آن بگنجانید:
برای اجرای یک کار جریان داده: مدیر جریان داده، کارگر جریان داده.
برای جعل هویت یک حساب سرویس دهنده جریان داده: کاربر حساب سرویس.
برای نوشتن گزارشها: نویسنده گزارشها.
برای فعال کردن بازسازی جستجوی برداری هوش مصنوعی Vertex: کاربر هوش مصنوعی Vertex.
حساب کاربری سرویس Dataflow Worker :
اگر از یک حساب کاربری سرویس پیکربندیشده دستی استفاده میکنید، باید نقشهای زیر را نیز در آن بگنجانید:
برای مدیریت جریان داده: Dataflow Admin و Dataflow Worker. برای خواندن دادهها از Spanner: Cloud Spanner Database Reader. دسترسی نوشتن روی رجیستری کانتینر GCS انتخاب شده: GCS Storage Bucket Owner.
- گردش کار ابری را مستقر کنید
فایل yaml گردش کار را در پروژه Google Cloud خود مستقر کنید. میتوانید منطقه یا مکانی را که گردش کار هنگام اجرا در آن اجرا خواهد شد، پیکربندی کنید.
gcloud workflows deploy vector-export-workflow --source=batch-export.yaml --location="us-central1" [--service account=<service_account>]
or
gcloud workflows deploy vector-export-workflow --source=batch-export.yaml --location="us-central1"
اکنون گردش کار باید در صفحه گردشهای کاری در کنسول Google Cloud قابل مشاهده باشد.
توجه : همچنین میتوانید گردش کار را از کنسول Google Cloud ایجاد و مستقر کنید. دستورالعملهای موجود در کنسول Cloud را دنبال کنید. برای تعریف گردش کار، محتویات batch-export.yaml را کپی و جایگذاری کنید.
پس از تکمیل این مرحله، گردش کار را اجرا کنید تا صادرات دادهها آغاز شود.
- اجرای گردش کار ابری
برای اجرای گردش کار، دستور زیر را اجرا کنید:
gcloud workflows execute vector-export-workflow --data="$(cat input.json)"
اجرا باید در تب Executions در Workflows نمایش داده شود. این باید دادههای شما را در پایگاه داده Vector Search بارگذاری و آن را فهرستبندی کند.
توجه : همچنین میتوانید با استفاده از دکمهی Execute از کنسول اجرا کنید. دستورالعملها را دنبال کنید و برای ورودی، محتویات input.json سفارشی خود را کپی و جایگذاری کنید.
۵. استقرار شاخص جستجوی برداری
استقرار شاخص در یک نقطه پایانی
برای استقرار ایندکس میتوانید مراحل زیر را دنبال کنید:
- در صفحه فهرستهای جستجوی برداری ، باید دکمه DEPLOY را در کنار فهرستی که در مرحله 2 بخش قبلی ایجاد کردهاید، ببینید. همچنین میتوانید به صفحه اطلاعات فهرست بروید و روی دکمه DEPLOY TO ENDPOINT کلیک کنید.
- اطلاعات لازم را ارائه دهید و ایندکس را در یک نقطه پایانی مستقر کنید.
به عنوان یک روش جایگزین، میتوانید برای استقرار آن در یک نقطه پایانی به این دفترچه یادداشت مراجعه کنید (به بخش استقرار دفترچه یادداشت بروید). پس از استقرار، شناسه شاخص مستقر شده و آدرس اینترنتی نقطه پایانی را یادداشت کنید.
۶. فرانتاند: دادههای کاربر برای جستجوی برداری
بیایید یک برنامه ساده پایتون با یک UX مبتنی بر گرادیو بسازیم تا پیادهسازی خود را به سرعت آزمایش کنیم: میتوانید برای پیادهسازی این برنامه آزمایشی در دفترچه یادداشت همکاری خود، به اینجا مراجعه کنید.
- ما از sdk پایتون aiplatform برای فراخوانی API Embeddings و همچنین برای فراخوانی نقطه پایانی شاخص Vector Search استفاده خواهیم کرد.
# [START aiplatform_sdk_embedding]
!pip install google-cloud-aiplatform==1.35.0 --upgrade --quiet --user
import vertexai
vertexai.init(project=PROJECT_ID, location="us-central1")
from vertexai.language_models import TextEmbeddingModel
import sys
if "google.colab" in sys.modules:
# Define project information
PROJECT_ID = " " # Your project id
LOCATION = " " # Your location
# Authenticate user to Google Cloud
from google.colab import auth
auth.authenticate_user()
- ما از گرادیو برای نمایش سریع و آسان اپلیکیشن هوش مصنوعی که با رابط کاربری میسازیم استفاده خواهیم کرد. قبل از اجرای این مرحله، زمان اجرا را مجدداً راهاندازی کنید.
!pip install gradio
import gradio as gr
- از برنامه وب، پس از ورودی کاربر، API Embeddings را فراخوانی کنید، ما از مدل جاسازی متن استفاده خواهیم کرد: textembedding-gecko@latest
متد زیر مدل جاسازی متن را فراخوانی میکند و جاسازیهای برداری را برای متن وارد شده توسط کاربر برمیگرداند:
def text_embedding(content) -> list:
"""Text embedding with a Large Language Model."""
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@latest")
embeddings = model.get_embeddings(content)
for embedding in embeddings:
vector = embedding.values
#print(f"Length of Embedding Vector: {len(vector)}")
return vector
آن را آزمایش کنید
text_embedding("red shorts for girls")
شما باید خروجی مشابه زیر را ببینید (لطفاً توجه داشته باشید که تصویر از نظر ارتفاع برش خورده است، بنابراین نمیتوانید کل پاسخ برداری را ببینید):

- شناسه شاخص مستقر شده و شناسه نقطه پایانی را اعلام کنید
from google.cloud import aiplatform
DEPLOYED_INDEX_ID = "spanner_vector1_1702366982123"
#Vector Search Endpoint
index_endpoint = aiplatform.MatchingEngineIndexEndpoint('projects/273845608377/locations/us-central1/indexEndpoints/2021628049526620160')
- متد Vector Search را برای فراخوانی نقطه پایانی اندیس و نمایش نتیجه با 10 مورد از نزدیکترین تطابقها برای پاسخ جاسازی مربوط به متن ورودی کاربر تعریف کنید.
در تعریف روش زیر برای جستجوی برداری، توجه داشته باشید که روش find_neighbors برای شناسایی 10 بردار نزدیک فراخوانی شده است.
def vector_search(content) -> list:
result = text_embedding(content)
#call_vector_search_api(content)
index_endpoint = aiplatform.MatchingEngineIndexEndpoint('projects/273845608377/locations/us-central1/indexEndpoints/2021628049526620160')
# run query
response = index_endpoint.find_neighbors(
deployed_index_id = DEPLOYED_INDEX_ID,
queries = [result],
num_neighbors = 10
)
out = []
# show the results
for idx, neighbor in enumerate(response[0]):
print(f"{neighbor.distance:.2f} {spanner_read_data(neighbor.id)}")
out.append(f"{spanner_read_data(neighbor.id)}")
return out
همچنین متوجه فراخوانی متد spanner_read_data خواهید شد. بیایید در مرحله بعدی به آن نگاهی بیندازیم.
- پیادهسازی متد خواندن دادهی Spanner را تعریف کنید که متد execute_sql را برای استخراج تصاویر مربوط به شناسههای بردارهای نزدیکترین همسایهی بازگردانده شده از مرحلهی قبل فراخوانی میکند.
!pip install google-cloud-spanner==3.36.0
from google.cloud import spanner
instance_id = "spanner-vertex"
database_id = "spanner-vertex-embeddings"
projectId = PROJECT_ID
client = spanner.Client()
client.project = projectId
instance = client.instance(instance_id)
database = instance.database(database_id)
def spanner_read_data(id):
query = "SELECT uri FROM apparels where id = " + id
outputs = []
with database.snapshot() as snapshot:
results = snapshot.execute_sql(query)
for row in results:
#print(row)
#output = "ID: {}, CONTENT: {}, URI: {}".format(*row)
output = "{}".format(*row)
outputs.append(output)
return "\n".join(outputs)
باید URL های تصاویر مربوط به بردارهای انتخاب شده را برگرداند.
- در نهایت، بیایید قطعات را در یک رابط کاربری کنار هم قرار دهیم و فرآیند جستجوی برداری را آغاز کنیم.
from PIL import Image
def call_search(query):
response = vector_search(query)
return response
input_text = gr.Textbox(label="Enter your query. Examples: Girls Tops White Casual, Green t-shirt girls, jeans shorts, denim skirt etc.")
output_texts = [gr.Image(label="") for i in range(10)]
demo = gr.Interface(fn=call_search, inputs=input_text, outputs=output_texts, live=True)
resp = demo.launch(share = True)
شما باید نتیجه را مانند تصویر زیر ببینید:

تصویر: لینک
ویدیوی نتیجه را ببینید: اینجا .
۷. تمیز کردن
برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این پست، این مراحل را دنبال کنید:
- در کنسول گوگل کلود، به صفحه مدیریت منابع بروید.
- در لیست پروژهها، پروژهای را که میخواهید حذف کنید انتخاب کنید و سپس روی حذف کلیک کنید.
- در کادر محاورهای، شناسه پروژه را تایپ کنید و سپس برای حذف پروژه، روی خاموش کردن کلیک کنید.
- اگر نمیخواهید پروژه را حذف کنید، نمونه Spanner را با رفتن به نمونهای که برای این پروژه ایجاد کردهاید و کلیک بر روی دکمه DELETE INSTANCE در گوشه سمت راست بالای صفحه نمای کلی نمونه، حذف کنید.
- همچنین میتوانید به فهرست Vector Search بروید، نقطه پایانی و فهرست را از حالت استقرار خارج کنید و فهرست را حذف کنید.
۸. نتیجهگیری
تبریک! شما با موفقیت پیادهسازی جستجوی برداری Spanner - Vertex را تکمیل کردید.
- ایجاد منبع داده Spanner و تعبیهها برای برنامههایی که از پایگاه داده Spanner منبعگیری شدهاند.
- ایجاد فهرست پایگاه داده جستجوی برداری
- ادغام دادههای برداری از Spanner به Vector Search با استفاده از Dataflow و Workflow Jobs.
- استقرار شاخص در یک نقطه پایانی.
- در نهایت، جستجوی برداری (Vector Search) با ورودی کاربر در یک پیادهسازی پایتون از Vertex AI sdk فراخوانی میشود.
میتوانید پیادهسازی را به مورد استفاده خودتان گسترش دهید یا مورد استفاده فعلی را با ویژگیهای جدید بداههسازی کنید. برای کسب اطلاعات بیشتر در مورد قابلیتهای یادگیری ماشینی Spanner به اینجا مراجعه کنید.