هوش مصنوعی بدون سرور: EmbeddingGemma با Cloud Run

۱. مقدمه

در این آزمایشگاه کد، شما یاد خواهید گرفت که چگونه EmbeddingGemma ، یک مدل جاسازی متن چندزبانه قدرتمند، را با استفاده از GPUها روی Cloud Run مستقر کنید. سپس از این سرویس مستقر برای تولید جاسازی‌ها برای یک برنامه جستجوی معنایی استفاده خواهید کرد.

برخلاف مدل‌های زبان بزرگ سنتی (LLM) که متن تولید می‌کنند، مدل‌های جاسازی، متن را به بردارهای عددی تبدیل می‌کنند. این بردارها برای ساخت سیستم‌های بازیابی-تقویت‌شده (RAG) بسیار مهم هستند، که به شما امکان می‌دهند مرتبط‌ترین اسناد را برای جستجوی کاربر پیدا کنید.

کاری که انجام خواهید داد

  • مدل EmbeddingGemma را با استفاده از Ollama کانتینرایز کنید.
  • کانتینر را با شتاب‌دهنده‌ی GPU روی Cloud Run مستقر کنید.
  • مدل پیاده‌سازی شده را با ایجاد جاسازی‌هایی برای متن نمونه آزمایش کنید.
  • با استفاده از سرویس مستقر شده خود، یک سیستم جستجوی معنایی سبک بسازید.

آنچه نیاز دارید

  • یک پروژه گوگل کلود با قابلیت پرداخت.
  • آشنایی اولیه با داکر و خط فرمان.

۲. قبل از شروع

راه‌اندازی پروژه

  1. اگر از قبل حساب گوگل ندارید، باید یک حساب گوگل ایجاد کنید .
    • به جای حساب کاری یا تحصیلی از یک حساب شخصی استفاده کنید. حساب‌های کاری و تحصیلی ممکن است محدودیت‌هایی داشته باشند که مانع از فعال کردن APIهای مورد نیاز برای این آزمایشگاه توسط شما شود.
  2. وارد کنسول ابری گوگل شوید.
  3. فعال کردن پرداخت در کنسول ابری
    • تکمیل این آزمایشگاه باید کمتر از ۱ دلار آمریکا از طریق منابع ابری هزینه داشته باشد.
    • شما می‌توانید مراحل انتهای این آزمایش را برای حذف منابع دنبال کنید تا از هزینه‌های بیشتر جلوگیری شود.
    • کاربران جدید واجد شرایط استفاده از دوره آزمایشی رایگان ۳۰۰ دلاری هستند.
  4. یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید.
    • اگر در مورد سهمیه پروژه خطایی مشاهده کردید، از یک پروژه موجود دوباره استفاده کنید یا یک پروژه موجود را حذف کنید تا یک پروژه جدید ایجاد شود.

شروع پوسته ابری

Cloud Shell یک محیط خط فرمان است که در Google Cloud اجرا می‌شود و ابزارهای لازم از قبل روی آن بارگذاری شده‌اند.

  1. روی فعال کردن Cloud Shell در بالای کنسول Google Cloud کلیک کنید.
  2. پس از اتصال به Cloud Shell، احراز هویت خود را تأیید کنید:
    gcloud auth list
    
  3. تأیید کنید که پروژه شما انتخاب شده است:
    gcloud config get project
    
  4. در صورت نیاز آن را تنظیم کنید:
    gcloud config set project <YOUR_PROJECT_ID>
    

فعال کردن APIها

برای فعال کردن تمام API های مورد نیاز، این دستور را اجرا کنید:

gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com

۳. مدل را کانتینریزه کنید

برای اجرای EmbeddingGemma به صورت بدون سرور، باید آن را در یک کانتینر بسته‌بندی کنیم. ما از Ollama ، یک چارچوب سبک برای اجرای LLMها، و Docker استفاده خواهیم کرد.

ایجاد فایل داکر

در Cloud Shell، یک دایرکتوری جدید برای پروژه خود ایجاد کنید و به آن بروید:

mkdir embedding-gemma-codelab
cd embedding-gemma-codelab

یک فایل با نام Dockerfile با محتوای زیر ایجاد کنید:

FROM ollama/ollama:latest

# Listen on all interfaces, port 8080
ENV OLLAMA_HOST=0.0.0.0:8080

# Store model weight files in /models
ENV OLLAMA_MODELS=/models

# Reduce logging verbosity
ENV OLLAMA_DEBUG=false

# Never unload model weights from the GPU
ENV OLLAMA_KEEP_ALIVE=-1

# Store the model weights in the container image
ENV MODEL=embeddinggemma:latest
RUN ollama serve & sleep 5 && ollama pull $MODEL

# Start Ollama
ENTRYPOINT ["ollama", "serve"]

این Dockerfile کارهای زیر را انجام می‌دهد:

  1. از تصویر پایه رسمی Ollama شروع می‌شود.
  2. Ollama را طوری پیکربندی می‌کند که روی پورت ۸۰۸۰ (پورت پیش‌فرض Cloud Run) گوش دهد.
  3. دستور RUN سرور ollama را اجرا می‌کند و مدل embeddinggemma را در طول فرآیند ساخت دانلود می‌کند تا در تصویر ادغام شود.
  4. مقدار OLLAMA_KEEP_ALIVE=-1 را تنظیم می‌کند تا از بارگذاری مدل در حافظه GPU برای درخواست‌های بعدی سریع‌تر، اطمینان حاصل شود.

۴. ساخت و استقرار

ما از Cloud Run source deployment برای ساخت و استقرار کانتینر خود در یک مرحله استفاده خواهیم کرد. این دستور، image را با استفاده از Cloud Build می‌سازد، آن را در Artifact Registry ذخیره می‌کند و در Cloud Run مستقر می‌کند.

برای استقرار، دستور زیر را اجرا کنید:

gcloud run deploy embedding-gemma \
  --source . \
  --region europe-west1 \
  --concurrency 4 \
  --cpu 8 \
  --set-env-vars OLLAMA_NUM_PARALLEL=4 \
  --gpu 1 \
  --gpu-type nvidia-l4 \
  --max-instances 1 \
  --memory 32Gi \
  --no-allow-unauthenticated \
  --no-cpu-throttling \
  --no-gpu-zonal-redundancy \
  --timeout=600 \
  --labels dev-tutorial=codelab-embedding-gemma

درک پیکربندی

  • --source . دایرکتوری فعلی را به عنوان منبع ساخت مشخص می‌کند.
  • --region europe-west1 ما از منطقه‌ای استفاده می‌کنیم که از پردازنده‌های گرافیکی (GPU) در Cloud Run پشتیبانی می‌کند.
  • --concurrency 4 طوری تنظیم شده است که با مقدار متغیر محیطی OLLAMA_NUM_PARALLEL مطابقت داشته باشد.
  • --gpu 1 با --gpu-type nvidia-l4 به هر نمونه Cloud Run در سرویس، یک پردازنده گرافیکی NVIDIA L4 اختصاص می‌دهد.
  • --max-instances 1 حداکثر تعداد نمونه‌هایی را که باید مقیاس‌بندی شوند مشخص می‌کند. این تعداد باید برابر یا کمتر از سهمیه پردازنده گرافیکی سطح ۴ انویدیا پروژه شما باشد.
  • --no-allow-unauthenticated دسترسی غیرمجاز به سرویس را محدود می‌کند. با خصوصی نگه داشتن سرویس، می‌توانید برای ارتباطات سرویس به سرویس، به احراز هویت داخلی مدیریت هویت و دسترسی (IAM) Cloud Run تکیه کنید.
  • --برای فعال کردن GPU، --no-cpu-throttling لازم است.
  • --no-gpu-zonal-redundancy گزینه‌های افزونگی منطقه‌ای را بسته به الزامات failover منطقه‌ای و سهمیه موجود خود تنظیم کنید.

ملاحظات منطقه

پردازنده‌های گرافیکی (GPU) در Cloud Run در مناطق خاصی موجود هستند. می‌توانید مناطق پشتیبانی‌شده را در مستندات بررسی کنید.

خروجی استقرار

پس از چند دقیقه، عملیات نصب به پایان می‌رسد و پیامی مانند زیر مشاهده خواهید کرد:

Service [embedding-gemma] revision [embedding-gemma-12345-abc] has been deployed and is serving 100 percent of traffic.
Service URL: https://embedding-gemma-123456789012.europe-west1.run.app

۵. آزمایش استقرار

از آنجایی که سرویس را با --no-allow-unauthenticated مستقر کرده‌ایم، نمی‌توانیم به سادگی URL عمومی را curl . ابتدا باید به خودمان اجازه دسترسی به سرویس را بدهیم و از توکن auth در درخواست استفاده کنیم.

  1. به حساب کاربری خود اجازه دهید تا سرویس را فراخوانی کند:
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=user:$(gcloud config get-value account) \
        --role='roles/run.invoker'
    
  2. اطلاعات کاربری گوگل کلود و شماره پروژه خود را در متغیرهای محیطی برای استفاده در درخواست ذخیره کنید:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  3. دستور زیر را برای ایجاد جاسازی برای "متن نمونه" اجرا کنید:
    curl -X POST "https://embedding-gemma-$PROJECT_NUMBER.europe-west1.run.app/api/embed" \
        -H "Authorization: Bearer $ID_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{
            "model": "embeddinggemma",
            "input": "Sample text"
        }'
    

شما باید یک پاسخ JSON حاوی یک بردار (لیست طولانی از اعداد) را در زیر فیلد embedding مشاهده کنید. این تأیید می‌کند که مدل جاسازی بدون سرور و پشتیبانی‌شده با GPU شما کار می‌کند!

پاسخ مشابه این خواهد بود: خروجی حلقه گذاری Gemma با جاسازی

کلاینت پایتون

همچنین می‌توانید از پایتون برای تعامل با سرویس استفاده کنید. فایلی با نام test_client.py ایجاد کنید:

import urllib.request
import urllib.parse
import json
import os

# 1. Setup the URL and Payload
url = f"https://embedding-gemma-{os.environ['PROJECT_NUMBER']}.europe-west1.run.app/api/embed"
payload = {
    "model": "embeddinggemma",
    "input": "Sample text"
}

# 2. Create the Request object
# Note: Providing 'data' automatically makes this a POST request
req = urllib.request.Request(
    url,
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {os.environ['ID_TOKEN']}",
        "Content-Type": "application/json"
    }
)

# 3. Execute and print the response
response = urllib.request.urlopen(req)
result = json.loads(response.read().decode("utf-8"))
print(result)

اجراش کن:

python test_client.py

۶. یک برنامه جستجوی معنایی بسازید

حالا که یک سرویس جاسازی کارآمد داریم، بیایید یک برنامه جستجوی معنایی ساده بسازیم. ما از جاسازی‌های تولید شده برای یافتن مرتبط‌ترین سند برای یک پرس‌وجوی داده شده استفاده خواهیم کرد.

وابستگی‌ها

ما chromadb به عنوان پایگاه داده برداری و از کتابخانه کلاینت ollama استفاده خواهیم کرد.

uv init semantic-search --description "Semantic Search Application"
cd semantic-search
uv add chromadb ollama

ایجاد برنامه جستجو

یک فایل با نام semantic_search.py ​​با کد زیر ایجاد کنید:

import ollama
import chromadb
import os

# 1. Define our knowledge base
documents = [
    "Poland is a country located in Central Europe.",
    "The capital and largest city of Poland is Warsaw.",
    "Poland's official language is Polish, which is a West Slavic language.",
    "Marie Curie, the pioneering scientist who conducted groundbreaking research on radioactivity, was born in Warsaw, Poland.",
    "Poland is famous for its traditional dish called pierogi, which are filled dumplings.",
    "The Białowieża Forest in Poland is one of the last and largest remaining parts of the immense primeval forest that once stretched across the European Plain.",
]

print("Initializing Vector Database...")
client = chromadb.Client()
collection = client.create_collection(name="docs")

# Configure the client to point to our Cloud Run proxy
ollama_client = ollama.Client(
    host=f"https://embedding-gemma-{os.environ['PROJECT_NUMBER']}.europe-west1.run.app",
    headers={'Authorization': 'Bearer ' + os.environ['ID_TOKEN']}
)

print("Generating embeddings and indexing documents...")
# 2. Store each document in the vector database
for i, d in enumerate(documents):
    # This calls our Cloud Run service to get the embedding
    response = ollama_client.embed(model="embeddinggemma", input=d)
    embeddings = response["embeddings"]
    collection.add(ids=[str(i)], embeddings=embeddings, documents=[d])

print("Indexing complete.\n")

# 3. Perform a Semantic Search
question = "What is Poland's official language?"
print(f"Query: {question}")

# Generate an embedding for the question
response = ollama_client.embed(model="embeddinggemma", input=question)

# Query the database for the most similar document
results = collection.query(
    query_embeddings=[response["embeddings"][0]],
    n_results=1
)

best_match = results["documents"][0][0]
print(f"Best Match Document: {best_match}")

برنامه را اجرا کنید

اسکریپت را اجرا کنید:

uv run semantic_search.py

شما باید خروجی مشابه این را ببینید:

Initializing Vector Database...
Generating embeddings and indexing documents...
Indexing complete.

Query: What is Poland's official language?
Best Match Document: Poland's official language is Polish, which is a West Slavic language.

این اسکریپت هسته اصلی یک سیستم RAG را نشان می‌دهد: استفاده از سرویس EmbeddingGemma بدون سرور شما برای تبدیل اسناد و پرس‌وجوها به بردارها، که شما را قادر می‌سازد اطلاعات دقیق مورد نیاز برای پاسخ به سوال کاربر را پیدا کنید.

۷. تمیز کردن

برای جلوگیری از هزینه‌های مداوم برای حساب Google Cloud خود، منابع ایجاد شده در طول این codelab را حذف کنید.

سرویس Cloud Run را حذف کنید

gcloud run services delete embedding-gemma --region europe-west1 --quiet

تصویر کانتینر را حذف کنید

gcloud artifacts docker images delete \
    europe-west1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/cloud-run-source-deploy/embedding-gemma \
    --quiet

۸. تبریک

تبریک! شما با موفقیت EmbeddingGemma را روی Cloud Run با GPU مستقر کردید و از آن برای راه‌اندازی یک برنامه جستجوی معنایی استفاده کردید.

اکنون شما یک پایه مقیاس‌پذیر و بدون سرور برای ساخت برنامه‌های هوش مصنوعی دارید که نیاز به درک معنای متن دارند.

آنچه آموخته‌اید

  • نحوه کانتینرایز کردن یک مدل اولاما با داکر.
  • نحوه استقرار یک سرویس مبتنی بر GPU در Cloud Run.
  • نحوه استفاده از مدل مستقر برای جستجوی معنایی (RAG).

مراحل بعدی

اسناد مرجع