1. מבוא
ב-Codelab הזה תלמדו איך לפרוס את EmbeddingGemma, מודל רב-לשוני רב עוצמה להטמעת טקסט, ב-Cloud Run באמצעות GPU. לאחר מכן תשתמשו בשירות הפרוס הזה כדי ליצור הטמעות לאפליקציית חיפוש סמנטי.
בניגוד למודלים גדולים של שפה (LLM) מסורתיים שמייצרים טקסט, מודלים של הטמעה ממירים טקסט לווקטורים מספריים. הווקטורים האלה חיוניים לבניית מערכות Retrieval-Augmented Generation (RAG), שמאפשרות למצוא את המסמכים הרלוונטיים ביותר לשאילתה של משתמש.
הפעולות שתבצעו:
- העברת המודל EmbeddingGemma לקונטיינר באמצעות Ollama.
- פורסים את הקונטיינר ב-Cloud Run עם האצת GPU.
- בודקים את המודל שנפרס על ידי יצירת הטמעות של טקסט לדוגמה.
- ליצור מערכת קלה לחיפוש סמנטי באמצעות השירות שפרסתם.
הדרישות
- פרויקט ב-Google Cloud שהחיוב בו מופעל.
- היכרות בסיסית עם Docker ועם שורת הפקודה.
2. לפני שמתחילים
הגדרת הפרויקט
- אם עדיין אין לכם חשבון Google, אתם צריכים ליצור חשבון Google.
- משתמשים בחשבון לשימוש אישי במקום בחשבון לצורכי עבודה או בחשבון בית ספרי. יכול להיות שבחשבונות לצורכי עבודה או בחשבונות בית ספריים יש הגבלות שימנעו מכם להפעיל את ממשקי ה-API שנדרשים למעבדה הזו.
- נכנסים למסוף Google Cloud.
- מפעילים את החיוב במסוף Cloud.
- העלות של השלמת ה-Lab הזה במשאבי Cloud צריכה להיות פחות מ-1$.
- כדי למחוק משאבים ולמנוע חיובים נוספים, אפשר לבצע את השלבים בסוף ה-Lab הזה.
- משתמשים חדשים זכאים לתקופת ניסיון בחינם בשווי 300$.
- יוצרים פרויקט חדש או בוחרים להשתמש מחדש בפרויקט קיים.
- אם מופיעה שגיאה לגבי מכסת הפרויקט, צריך לעשות שימוש חוזר בפרויקט קיים או למחוק פרויקט קיים כדי ליצור פרויקט חדש.
הפעלת Cloud Shell
Cloud Shell היא סביבת שורת פקודה שפועלת ב-Google Cloud וכוללת מראש את הכלים הנדרשים.
- לוחצים על Activate Cloud Shell בחלק העליון של מסוף Google Cloud.
- אחרי שמתחברים ל-Cloud Shell, מאמתים את האימות:
gcloud auth list - מוודאים שהפרויקט נבחר:
gcloud config get project - מגדירים אותו לפי הצורך:
gcloud config set project <YOUR_PROJECT_ID>
הפעלת ממשקי ה-API
מריצים את הפקודה הבאה כדי להפעיל את כל ממשקי ה-API הנדרשים:
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
3. העברת המודל למאגר
כדי להריץ את EmbeddingGemma ללא שרת, צריך לארוז אותו בקונטיינר. נשתמש ב-Ollama, מסגרת קלת משקל להפעלת מודלים גדולים של שפה, וב-Docker.
יצירת קובץ Dockerfile
ב-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 הזה מבצע את הפעולות הבאות:
- התהליך מתחיל מקובץ הבסיס הרשמי של Ollama.
- הגדרת Ollama להאזנה ביציאה 8080 (ברירת המחדל של Cloud Run).
- הפקודה
RUNמפעילה את השרתollamaומורידה את המודלembeddinggemmaבמהלך תהליך ה-build, כך שהוא מוטמע בתמונה. - ההגדרה
OLLAMA_KEEP_ALIVE=-1מבטיחה שהמודל יישאר טעון בזיכרון ה-GPU כדי שבקשות עתידיות יעובדו מהר יותר.
4. בנייה ופריסה
נשתמש ב-Cloud Run source deployment כדי ליצור ולפרוס את הקונטיינר שלנו בשלב אחד. הפקודה הזו יוצרת את קובץ האימג' באמצעות 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 .מציין את הספרייה הנוכחית כמקור ל-build. -
--region europe-west1אנחנו משתמשים באזור שתומך ב-GPU ב-Cloud Run. - הערך של
--concurrency 4מוגדר בהתאם לערך של משתנה הסביבה OLLAMA_NUM_PARALLEL. -
--gpu 1עם--gpu-type nvidia-l4מקצה יחידת GPU אחת של NVIDIA L4 לכל מופע של Cloud Run בשירות. -
--max-instances 1מציין את המספר המקסימלי של מופעים שאליהם יתבצע שינוי גודל. הוא צריך להיות שווה למכסת ה-GPU של NVIDIA L4 בפרויקט או נמוך ממנה. --no-allow-unauthenticatedמגביל את הגישה לשירות ללא אימות. אם השירות פרטי, אפשר להסתמך על אימות מובנה של ניהול זהויות והרשאות גישה (IAM) ב-Cloud Run לתקשורת בין שירותים.- נדרשת
--no-cpu-throttlingכדי להפעיל את ה-GPU. --no-gpu-zonal-redundancyלהגדיר אפשרויות של יתירות אזורית בהתאם לדרישות שלכם למעבר לשירות חלופי באזור ולמכסת הזמינות.
שיקולים לגבי האזור
מעבדי 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
5. בדיקת הפריסה
מכיוון שפרסנו את השירות באמצעות --no-allow-unauthenticated, אי אפשר פשוט curl את כתובת ה-URL הגלויה לכולם. קודם צריך לתת לעצמנו הרשאה לגשת לשירות ולהשתמש באסימון האימות בבקשה.
- נותנים לחשבון המשתמש הרשאה להתקשר לשירות:
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \ --member=user:$(gcloud config get-value account) \ --role='roles/run.invoker' - שומרים את פרטי הכניסה ל-Google Cloud ואת מספר הפרויקט במשתני סביבה לשימוש בבקשה:
export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)") export ID_TOKEN=$(gcloud auth print-identity-token) - מריצים את הפקודה הבאה כדי ליצור הטמעה של 'טקסט לדוגמה':
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 ללא שרת עובד!
התגובה תיראה כך: 
לקוח Python
אפשר גם להשתמש ב-Python כדי ליצור אינטראקציה עם השירות. יוצרים קובץ בשם 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
6. פיתוח אפליקציית חיפוש סמנטי
עכשיו שיש לנו שירות הטמעה שעובד, נבנה אפליקציית חיפוש סמנטי פשוטה. אנחנו נשתמש בהטמעות שנוצרו כדי למצוא את המסמך הרלוונטי ביותר לשאילתה מסוימת.
תלויות
נשתמש ב-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 בלי שרת (serverless) כדי להמיר מסמכים ושאילתות לווקטורים, וכך למצוא את המידע המדויק שנדרש כדי לענות על שאלה של משתמש.
7. הסרת המשאבים
כדי להימנע מחיובים שוטפים בחשבון 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
8. מזל טוב
מעולה! הצלחתם לפרוס את EmbeddingGemma ב-Cloud Run עם מעבדי GPU ולהשתמש בו כדי להפעיל אפליקציית חיפוש סמנטי.
עכשיו יש לכם בסיס מדרגי ללא שרת לבניית אפליקציות AI שנדרשת בהן הבנה של משמעות הטקסט.
מה למדתם
- איך להכניס מודל Ollama לקונטיינר באמצעות Docker.
- איך פורסים שירות עם תמיכה ב-GPU ב-Cloud Run.
- איך משתמשים במודל הפרוס לחיפוש סמנטי (RAG).
השלבים הבאים
- אפשר לעיין בדגמים נוספים במשפחת Gemma.
- מידע נוסף על מעבדים גרפיים ל-Cloud Run
- הדרכות נוספות של Codelab בנושא Cloud Run
- כדי ליצור צינור RAG מלא, מקשרים את שלב האחזור הזה למודל גנרטיבי.