במדריך הזה נסביר איך לשתף ביעילות משאבי האצה בין עומסי עבודה (workload) של אימון והסקת מסקנות באשכול יחיד של Google Kubernetes Engine (GKE). כשמפיצים את עומסי העבודה המעורבים באשכול יחיד, משפרים את ניצול המשאבים, מפשטים את ניהול האשכולות, מצמצמים את הבעיות שנובעות ממגבלות על כמות המאיצים ומשפרים את היעילות הכוללת מבחינת עלויות.
במדריך הזה תיצרו פריסת מילוי בקשות בעדיפות גבוהה באמצעות מודל שפה גדול (LLM) Gemma 2 להסקת מסקנות, ומסגרת Hugging Face TGI (ממשק ליצירת טקסט) למילוי בקשות, יחד עם משימת כוונון עדין של LLM בעדיפות נמוכה. שתי עומסי העבודה פועלים באותו אשכול שמשתמש ב-GPU מסוג NVIDIA L4. אתם משתמשים ב-Kueue, מערכת בקוד פתוח לניהול ותזמון של עומסי עבודה (workload) ב-Kubernetes. בעזרת Kueue אפשר לתת עדיפות למשימות של הצגת מודלים ולבטל משימות אימון בעדיפות נמוכה יותר, כדי לבצע אופטימיזציה של ניצול המשאבים. כשהדרישות להצגת מודעות יורדות, אתם מקצים מחדש את המאיצים הפנויים כדי להמשיך את משימות האימון. אתם משתמשים ב-Kueue ובסיווגי עדיפות כדי לנהל את מכסות המשאבים לאורך התהליך.
המדריך הזה מיועד למהנדסי למידת מכונה (ML), לאדמינים ולמפעילים של פלטפורמות ולמומחים בתחום הנתונים וה-AI שרוצים לאמן ולארח מודל של למידת מכונה (ML) באשכול GKE, וגם רוצים לצמצם את העלויות ואת תקורה הניהול, במיוחד כשמדובר במספר מוגבל של מאיצים. מידע נוסף על תפקידים נפוצים ועל משימות לדוגמה שאנחנו מתייחסים אליהן בתוכן זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE. Google Cloud
לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את הנושאים הבאים:
מטרות
בסיום המדריך הזה, תוכלו לבצע את השלבים הבאים:
- הגדרת פריסה של הצגת מודעות בעדיפות גבוהה.
- הגדרת משימות אימון בעדיפות נמוכה יותר.
- הטמעת אסטרטגיות קדימות כדי לתת מענה לביקוש משתנה.
- ניהול הקצאת משאבים בין משימות אימון ומשימות הגשה באמצעות Kueue.
לפני שמתחילים
- נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the required APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the required APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
צריך לוודא שיש לכם בפרויקט את התפקיד או התפקידים הבאים:
roles/container.admin,roles/iam.serviceAccountAdminבדיקת התפקידים
-
נכנסים לדף IAM במסוף Google Cloud .
כניסה לדף IAM - בוחרים את הפרויקט.
-
בעמודה Principal (חשבון המשתמש), מוצאים את כל השורות שבהן מופיע השם שלכם או של קבוצה שאתם נכללים בה. כדי לברר באילו קבוצות אתם נכללים, פנו לאדמין.
- בודקים את העמודה Role בכל השורות שבהן מצוין או מופיע השם שלכם, כדי לראות אם רשימת התפקידים כוללת את התפקידים הנדרשים.
מתן התפקידים
-
נכנסים לדף IAM במסוף Google Cloud .
כניסה לדף IAM - בוחרים את הפרויקט.
- לוחצים על Grant access.
-
בשדה New principals, מזינים את מזהה המשתמש. בדרך כלל מזהה המשתמש הוא כתובת האימייל של חשבון Google.
- לוחצים על Select a role ומחפשים את התפקיד.
- כדי לתת עוד תפקידים, לוחצים על Add another role ומוסיפים אותם.
- לוחצים על Save.
-
- יוצרים חשבון ב-Hugging Face, אם עדיין אין לכם חשבון.
- מוודאים שיש בפרויקט מכסה מספקת ל-GPU L4. מידע נוסף זמין במאמרים מידע על יחידות GPU ומכסות הקצאה.
הכנת הסביבה
בקטע הזה, תספקו את המשאבים שדרושים לפריסת TGI ולמודל עבור עומסי העבודה של ההסקה והאימון.
גישה למודל
כדי לקבל גישה למודלים של Gemma לצורך פריסה ב-GKE, צריך קודם לחתום על הסכם ההסכמה לרישיון, ואז ליצור טוקן גישה של Hugging Face.
- חתימה על הסכם ההסכמה לרישיון. נכנסים אל דף ההסכמה לשימוש במודל, מאמתים את ההסכמה באמצעות חשבון Hugging Face ומאשרים את התנאים לשימוש במודל.
יצירת אסימון גישה כדי לגשת למודל דרך Hugging Face, צריך טוקן של Hugging Face. אם עדיין אין לכם אסימון, אתם יכולים ליצור אסימון חדש באמצעות השלבים הבאים:
- לוחצים על הפרופיל שלך > הגדרות > טוקנים של גישה.
- בוחרים באפשרות New Token (טוקן חדש).
- מציינים שם לבחירתכם ותפקיד ברמה של
Readלפחות. - לוחצים על יצירת אסימון.
- מעתיקים את הטוקן שנוצר ללוח.
הפעלת Cloud Shell
במדריך הזה משתמשים ב-Cloud Shell כדי לנהל משאבים שמתארחים ב-Google Cloud. ב-Cloud Shell מותקן מראש התוכנה שדרושה לכם כדי לבצע את המדריך הזה, כולל kubectl,
ה-CLI של gcloud ו-Terraform.
כדי להגדיר את הסביבה באמצעות Cloud Shell:
ב Google Cloud מסוף, מפעילים סשן של Cloud Shell על ידי לחיצה על Activate Cloud Shell בGoogle Cloud מסוף.
תופעל סשן בחלונית התחתונה של Google Cloud המסוף.
מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project)מחליפים את PROJECT_ID ב Google Cloud מזהה הפרויקט.
משכפלים את הקוד לדוגמה מ-GitHub. ב-Cloud Shell, מריצים את הפקודות הבאות:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/ cd kubernetes-engine-samples/ai-ml/mix-train-and-inference export EXAMPLE_HOME=$(pwd)
יצירת אשכול GKE
אתם יכולים להשתמש באשכול במצב Autopilot או באשכול רגיל בשביל עומסי העבודה המעורבים. כדי ליהנות מחוויית Kubernetes מנוהלת באופן מלא, מומלץ להשתמש באשכול Autopilot. כדי לבחור את מצב הפעולה של GKE שהכי מתאים לעומסי העבודה שלכם, אפשר לעיין במאמר בחירת מצב פעולה של GKE.
טייס אוטומטי
מגדירים את משתני הסביבה שמוגדרים כברירת מחדל ב-Cloud Shell:
export HF_TOKEN=HF_TOKEN export REGION=REGION export CLUSTER_NAME="llm-cluster" export PROJECT_NUMBER=$(gcloud projects list \ --filter="$(gcloud config get-value project)" \ --format="value(PROJECT_NUMBER)") export MODEL_BUCKET="model-bucket-$PROJECT_ID"מחליפים את הערכים הבאים:
- HF_TOKEN: האסימון של Hugging Face שיצרתם קודם.
- REGION: אזור שתומך בסוג המאיץ שרוצים להשתמש בו, לדוגמה,
us-central1עבור GPU מסוג L4.
אפשר לשנות את המשתנה MODEL_BUCKET, שמייצג את הקטגוריה של Cloud Storage שבה מאוחסנים משקלי המודל שאומן.
יצירת אשכול Autopilot:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --location=${REGION} \ --release-channel=rapidיוצרים את הקטגוריה של Cloud Storage לעבודת הכוונון העדין:
gcloud storage buckets create gs://${MODEL_BUCKET} \ --location ${REGION} \ --uniform-bucket-level-accessכדי להעניק גישה לקטגוריה של Cloud Storage, מריצים את הפקודה הבאה:
gcloud storage buckets add-iam-policy-binding "gs://$MODEL_BUCKET" \ --role=roles/storage.objectAdmin \ --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/llm/sa/default \ --condition=Noneכדי לקבל פרטי כניסה לאימות עבור האשכול, מריצים את הפקודה הבאה:
gcloud container clusters get-credentials llm-cluster \ --location=$REGION \ --project=$PROJECT_IDיוצרים מרחב שמות לפריסות. ב-Cloud Shell, מריצים את הפקודה הבאה:
kubectl create ns llm
רגילה
מגדירים את משתני הסביבה שמוגדרים כברירת מחדל ב-Cloud Shell:
export HF_TOKEN=HF_TOKEN export REGION=REGION export CLUSTER_NAME="llm-cluster" export GPU_POOL_MACHINE_TYPE="g2-standard-24" export GPU_POOL_ACCELERATOR_TYPE="nvidia-l4" export PROJECT_NUMBER=$(gcloud projects list \ --filter="$(gcloud config get-value project)" \ --format="value(PROJECT_NUMBER)") export MODEL_BUCKET="model-bucket-$PROJECT_ID"מחליפים את הערכים הבאים:
- HF_TOKEN: האסימון של Hugging Face שיצרתם קודם.
- REGION: האזור שתומך בסוג המאיץ שרוצים להשתמש בו. לדוגמה,
us-central1עבור GPU מסוג L4.
אפשר לשנות את המשתנים האלה:
- GPU_POOL_MACHINE_TYPE: סדרת המכונות של מאגר הצמתים שרוצים להשתמש בה באזור שנבחר. הערך הזה תלוי בסוג המאיץ שבחרתם. מידע נוסף זמין במאמר מגבלות השימוש ב-GPU ב-GKE. לדוגמה, במדריך הזה נעשה שימוש ב-
g2-standard-24עם שני GPU שמצורפים לכל צומת. רשימת מעבדי ה-GPU הזמינים העדכנית ביותר מופיעה במאמר מעבדי GPU לעומסי עבודה של מחשוב. - GPU_POOL_ACCELERATOR_TYPE: סוג המאיץ שנתמך באזור שבחרתם. לדוגמה, במדריך הזה נעשה שימוש ב-
nvidia-l4. רשימת ה-GPU הזמינים העדכנית מופיעה במאמר מעבדי GPU לעומסי עבודה של מחשוב. - MODEL_BUCKET: הקטגוריה של Cloud Storage שבה מאחסנים את משקלי המודל שאומן.
יצירת אשכול רגיל:
gcloud container clusters create ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --location=${REGION} \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --release-channel=rapid \ --machine-type=e2-standard-4 \ --addons GcsFuseCsiDriver \ --num-nodes=1יוצרים את מאגר צמתי ה-GPU לעומסי עבודה של הסקת מסקנות ושינוי פרמטרים:
gcloud container node-pools create gpupool \ --accelerator type=${GPU_POOL_ACCELERATOR_TYPE},count=2,gpu-driver-version=latest \ --project=${PROJECT_ID} \ --location=${REGION} \ --node-locations=${REGION}-a \ --cluster=${CLUSTER_NAME} \ --machine-type=${GPU_POOL_MACHINE_TYPE} \ --num-nodes=3יוצרים את הקטגוריה של Cloud Storage לעבודת הכוונון העדין:
gcloud storage buckets create gs://${MODEL_BUCKET} \ --location ${REGION} \ --uniform-bucket-level-accessכדי להעניק גישה לקטגוריה של Cloud Storage, מריצים את הפקודה הבאה:
gcloud storage buckets add-iam-policy-binding "gs://$MODEL_BUCKET" \ --role=roles/storage.objectAdmin \ --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/llm/sa/default \ --condition=Noneכדי לקבל פרטי כניסה לאימות עבור האשכול, מריצים את הפקודה הבאה:
gcloud container clusters get-credentials llm-cluster \ --location=$REGION \ --project=$PROJECT_IDיוצרים מרחב שמות לפריסות. ב-Cloud Shell, מריצים את הפקודה הבאה:
kubectl create ns llm
יצירת סוד של Kubernetes לפרטי הכניסה של Hugging Face
כדי ליצור סוד של Kubernetes שמכיל את האסימון של Hugging Face, מריצים את הפקודה הבאה:
kubectl create secret generic hf-secret \
--from-literal=hf_api_token=$HF_TOKEN \
--dry-run=client -o yaml | kubectl apply --namespace=llm --filename=-
הגדרת Kueue
במדריך הזה, Kueue הוא מנהל המשאבים המרכזי, שמאפשר שיתוף יעיל של מעבדי GPU בין עומסי העבודה של האימון וההגשה. Kueue עושה את זה על ידי הגדרת דרישות משאבים ('טעמים'), תעדוף של עומסי עבודה באמצעות תורים (עם תעדוף של משימות הגשה על פני אימון) והקצאה דינמית של משאבים על סמך הביקוש והעדיפות. במדריך הזה נעשה שימוש בסוג המשאב Workload כדי לקבץ את עומסי העבודה של ההסקה וההתאמה העדינה, בהתאמה.
תכונת העדיפות של Kueue מבטיחה שלעומסי עבודה של שירותים עם עדיפות גבוהה תמיד יהיו המשאבים הדרושים. לשם כך, המערכת משהה או מפנה משרות אימון עם עדיפות נמוכה יותר כשהמשאבים מועטים.
כדי לשלוט בפריסת שרת ההסקות באמצעות Kueue, מפעילים את השילוב של pod ומגדירים את managedJobsNamespaceSelector כך שמרחבי השמות kube-system ו-kueue-system יוחרגו.
במאגר
/kueue, רואים את הקוד בkustomization.yaml. קובץ המניפסט הזה מתקין את מנהל המשאבים Kueue עם הגדרות בהתאמה אישית.במאגר
/kueue, רואים את הקוד בpatch.yaml. ה-ConfigMap הזה מגדיר את Kueue כך שלא יכלול ניהול של Pods במרחבי השמותkube-systemו-kueue-system.ב-Cloud Shell, מריצים את הפקודה הבאה כדי להתקין את Kueue:
cd ${EXAMPLE_HOME} kubectl kustomize kueue |kubectl apply --server-side --filename=-מחכים עד שה-Pods של Kueue יהיו מוכנים:
watch kubectl --namespace=kueue-system get podsהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE kueue-controller-manager-bdc956fc4-vhcmx 1/1 Running 0 3m15sבמאגר
/workloads, צופים בקבציםflavors.yaml,cluster-queue.yamlו-local-queue.yaml. בקובצי המניפסט האלה מצוין איך Kueue מנהל את מכסות המשאבים:ResourceFlavor
קובץ המניפסט הזה מגדיר ResourceFlavor כברירת מחדל ב-Kueue לניהול משאבים.
ClusterQueue
קובץ המניפסט הזה מגדיר ClusterQueue של Kueue עם מגבלות משאבים למעבד (CPU), לזיכרון ולמעבד גרפי (GPU).
במדריך הזה נעשה שימוש בצמתים עם שני מעבדי GPU מסוג Nvidia L4 שמצורפים, עם סוג הצומת המתאים
g2-standard-24, שמציע 24 vCPU ו-96GB RAM. בדוגמת הקוד מוצג איך להגביל את השימוש במשאבים של עומס העבודה לשימוש מקסימלי של שש יחידות GPU.השדה
preemptionבהגדרת ClusterQueue מפנה אל PriorityClasses כדי לקבוע אילו פודים אפשר להפסיק לפני הזמן כשאין מספיק משאבים.LocalQueue
קובץ המניפסט הזה יוצר LocalQueue בשם
lqבמרחב השמותllm.צפייה בקבצים
default-priorityclass.yaml,low-priorityclass.yamlו-high-priorityclass.yaml. קבצי המניפסט האלה מגדירים את אובייקטי PriorityClass לתזמון ב-Kubernetes.עדיפות ברירת מחדל
עדיפות נמוכה
עדיפות גבוהה
כדי ליצור את אובייקטי Kueue ו-Kubernetes, מריצים את הפקודות הבאות כדי להחיל את המניפסטים המתאימים.
cd ${EXAMPLE_HOME}/workloads kubectl apply --filename=flavors.yaml kubectl apply --filename=default-priorityclass.yaml kubectl apply --filename=high-priorityclass.yaml kubectl apply --filename=low-priorityclass.yaml kubectl apply --filename=cluster-queue.yaml kubectl apply --filename=local-queue.yaml --namespace=llm
פריסת שרת ההיקשים TGI
בקטע הזה תפרסו את מאגר TGI כדי להפעיל את מודל Gemma 2.
במאגר
/workloads, צופים בקובץtgi-gemma-2-9b-it-hp.yaml. קובץ המניפסט הזה מגדיר פריסת Kubernetes כדי לפרוס את זמן הריצה של TGI ואת מודלgemma-2-9B-it. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול.הפריסה נותנת עדיפות למשימות של הסקת מסקנות ומשתמשת בשני מעבדי GPU עבור המודל. הוא משתמש במקביליות טנסורית על ידי הגדרת משתנה הסביבה
NUM_SHARDכדי להתאים את המודל לזיכרון ה-GPU.מריצים את הפקודה הבאה כדי להחיל את המניפסט:
kubectl apply --filename=tgi-gemma-2-9b-it-hp.yaml --namespace=llmפעולת הפריסה תימשך כמה דקות.
כדי לבדוק אם GKE יצר את הפריסה בהצלחה, מריצים את הפקודה הבאה:
kubectl --namespace=llm get deploymentהפלט אמור להיראות כך:
NAME READY UP-TO-DATE AVAILABLE AGE tgi-gemma-deployment 1/1 1 1 5m13s
אימות ניהול המכסות ב-Kueue
בקטע הזה, מאשרים שמכסת ה-GPU של הפריסה נאכפת בצורה נכונה על ידי Kueue.
כדי לבדוק אם Kueue מודע לפריסה שלכם, מריצים את הפקודה הבאה כדי לאחזר את הסטטוס של אובייקטים של עומסי עבודה:
kubectl --namespace=llm get workloadsהפלט אמור להיראות כך:
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE pod-tgi-gemma-deployment-6bf9ffdc9b-zcfrh-84f19 lq cluster-queue True 8m23sכדי לבדוק את ההחלפה של מכסות, משנים את קנה המידה של הפריסה לארבעה עותקים:
kubectl scale --replicas=4 deployment/tgi-gemma-deployment --namespace=llmמריצים את הפקודה הבאה כדי לראות את מספר הרפליקות ש-GKE פורס:
kubectl get workloads --namespace=llmהפלט אמור להיראות כך:
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE pod-tgi-gemma-deployment-6cb95cc7f5-5thgr-3f7d4 lq cluster-queue True 14s pod-tgi-gemma-deployment-6cb95cc7f5-cbxg2-d9fe7 lq cluster-queue True 5m41s pod-tgi-gemma-deployment-6cb95cc7f5-tznkl-80f6b lq 13s pod-tgi-gemma-deployment-6cb95cc7f5-wd4q9-e4302 lq cluster-queue True 13sבפלט אפשר לראות שרק שלושה פודים התקבלו בגלל מכסת המשאבים שאוכפת Kueue.
מריצים את הפקודה הבאה כדי להציג את קבוצות ה-Pod במרחב השמות
llm:kubectl get pod --namespace=llmהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE tgi-gemma-deployment-7649884d64-6j256 1/1 Running 0 4m45s tgi-gemma-deployment-7649884d64-drpvc 0/1 SchedulingGated 0 7s tgi-gemma-deployment-7649884d64-thdkq 0/1 Pending 0 7s tgi-gemma-deployment-7649884d64-znvpb 0/1 Pending 0 7sעכשיו מצמצמים את הפריסה בחזרה ל-1. חובה לבצע את השלב הזה לפני שמפעילים את משימת הכוונון העדין, אחרת המשימה לא תתקבל כי למשימת ההסקה יש עדיפות.
kubectl scale --replicas=1 deployment/tgi-gemma-deployment --namespace=llm
הסבר על ההתנהגות
במקרה של דוגמת ההרחבה, נוצרות רק שלוש רפליקות (למרות ההרחבה לארבע) בגלל מגבלת מכסת ה-GPU שהגדרתם בהגדרות של ClusterQueue. בקטע spec.resourceGroups של ClusterQueue מוגדר nominalQuota עם הערך 6 עבור nvidia.com/gpu. הפריסה מציינת שכל Pod דורש 2 יחידות GPU.
לכן, התור ClusterQueue יכול להכיל רק עד שלוש רפליקות של הפריסה בכל פעם (כי 3 רפליקות * 2 GPU לכל רפליקה = 6 GPU, שזה המכסה הכוללת).
כשמנסים להגדיל את מספר הרפליקות לארבע, Kueue מזהה שהפעולה הזו תגרום לחריגה ממכסת ה-GPU ומונעת את התזמון של הרפליקה הרביעית. הסטטוס SchedulingGated של ה-Pod הרביעי מציין זאת. ההתנהגות הזו מדגימה את האכיפה של מכסת המשאבים ב-Kueue.
פריסת משימת האימון
בקטע הזה מפרטים איך פורסים משימת כוונון עדין בעדיפות נמוכה יותר למודל Gemma 2 שדורש ארבע יחידות GPU בשני Pods. ב-Kubernetes, בקר משימות יוצר פוד אחד או יותר ועוזר לוודא שהם מבצעים משימה ספציפית בהצלחה.
למשימה הזו יידרש שאר מכסת ה-GPU ב-ClusterQueue. העבודה משתמשת בתמונה שנוצרה מראש ושומרת נקודות ביקורת כדי לאפשר הפעלה מחדש מתוצאות ביניים.
משימת הכוונון העדין משתמשת במערך הנתונים b-mc2/sql-create-context. אפשר למצוא את המקור של משימת הכוונון העדין במאגר.
צפייה בקובץ
fine-tune-l4.yaml. המניפסט הזה מגדיר את משימת הכוונון העדין.מחילים את המניפסט כדי ליצור את משימת הכוונון העדין:
cd ${EXAMPLE_HOME}/workloads sed -e "s/<MODEL_BUCKET>/$MODEL_BUCKET/g" \ -e "s/<PROJECT_ID>/$PROJECT_ID/g" \ -e "s/<REGION>/$REGION/g" \ fine-tune-l4.yaml |kubectl apply --filename=- --namespace=llmמוודאים שהפריסות פועלות. כדי לבדוק את הסטטוס של אובייקטים של עומסי עבודה, מריצים את הפקודה הבאה:
kubectl get workloads --namespace=llmהפלט אמור להיראות כך:
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE job-finetune-gemma-l4-3316f lq cluster-queue True 29m pod-tgi-gemma-deployment-6cb95cc7f5-cbxg2-d9fe7 lq cluster-queue True 68mלאחר מכן, מציגים את ה-Pods במרחב השמות
llmעל ידי הרצת הפקודה הבאה:kubectl get pod --namespace=llmהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE finetune-gemma-l4-0-vcxpz 2/2 Running 0 31m finetune-gemma-l4-1-9ppt9 2/2 Running 0 31m tgi-gemma-deployment-6cb95cc7f5-cbxg2 1/1 Running 0 70mבפלט אפשר לראות ש-Kueue מאשר את ההרצה של משימת הכוונון העדין ושל ה-Pods של שרת ההסקה, ומשריין את המשאבים הנכונים על סמך מכסות השימוש שצוינו.
מעיינים ביומני הפלט כדי לוודא שעבודת הכוונון העדין שומרת את נקודות הבדיקה בקטגוריה של Cloud Storage. תהליך הכוונון העדין נמשך כ-10 דקות לפני שהמערכת מתחילה לשמור את נקודת הבדיקה הראשונה.
kubectl logs --namespace=llm --follow --selector=app=finetune-jobהפלט של נקודת הבדיקה הראשונה שנשמרה אמור להיראות כך:
{"name": "finetune", "thread": 133763559483200, "threadName": "MainThread", "processName": "MainProcess", "process": 33, "message": "Fine tuning started", "timestamp": 1731002351.0016131, "level": "INFO", "runtime": 451579.89835739136} … {"name": "accelerate.utils.fsdp_utils", "thread": 136658669348672, "threadName": "MainThread", "processName": "MainProcess", "process": 32, "message": "Saving model to /model-data/model-gemma2/experiment/checkpoint-10/pytorch_model_fsdp_0", "timestamp": 1731002386.1763802, "level": "INFO", "runtime": 486753.8924217224}
בדיקה של הקצאה דינמית ושל דחיקה של משימות ב-Kueue בעומס עבודה מעורב
בקטע הזה, תדמו תרחיש שבו העומס על שרת ההסקה גדל, ולכן הוא צריך להתרחב. בתרחיש הזה אפשר לראות איך Kueue נותן עדיפות לשרת ההסקה עם העדיפות הגבוהה, על ידי השהיה ודחיקה של משימת הכוונון העדין עם העדיפות הנמוכה יותר, כשיש מגבלות על המשאבים.
מריצים את הפקודה הבאה כדי לשנות את קנה המידה של העותקים של שרת ההסקה לשניים:
kubectl scale --replicas=2 deployment/tgi-gemma-deployment --namespace=llmבודקים את הסטטוס של אובייקטים של עומס עבודה:
kubectl get workloads --namespace=llmהפלט אמור להיראות כך:
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE job-finetune-gemma-l4-3316f lq False 32m pod-tgi-gemma-deployment-6cb95cc7f5-cbxg2-d9fe7 lq cluster-queue True 70m pod-tgi-gemma-deployment-6cb95cc7f5-p49sh-167de lq cluster-queue True 14sהפלט מראה שעבודת הכוונון העדין כבר לא מתקבלת כי העותקים המשוכפלים של שרת ההסקה המוגדל משתמשים במכסת ה-GPU הזמינה.
בודקים את הסטטוס של משימת הכוונון העדין:
kubectl get job --namespace=llmהפלט אמור להיראות כך, ולציין שהסטטוס של משימת הדיוק העדין הוא עכשיו מושהה:
NAME STATUS COMPLETIONS DURATION AGE finetune-gemma-l4 Suspended 0/2 33mמריצים את הפקודה הבאה כדי לבדוק את ה-Pods:
kubectl get pod --namespace=llmהפלט אמור להיראות כך, ולציין ש-Kueue הפסיק את הפעולה של תרמילי ה-Job Pods של הכוונון העדין כדי לפנות משאבים לפריסת שרת ההסקה בעדיפות גבוהה יותר.
NAME READY STATUS RESTARTS AGE tgi-gemma-deployment-6cb95cc7f5-cbxg2 1/1 Running 0 72m tgi-gemma-deployment-6cb95cc7f5-p49sh 0/1 ContainerCreating 0 91sלאחר מכן, בודקים את התרחיש שבו העומס על שרת ההסקה יורד וה-Pods שלו מצטמצמים. מריצים את הפקודה הבאה:
kubectl scale --replicas=1 deployment/tgi-gemma-deployment --namespace=llmמריצים את הפקודה הבאה כדי להציג את אובייקטי העומס:
kubectl get workloads --namespace=llmהפלט אמור להיראות כך, ולציין שאחד מפריסות שרת ההסקה הופסק, והמשימה של הכוונון העדין התקבלה מחדש.
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE job-finetune-gemma-l4-3316f lq cluster-queue True 37m pod-tgi-gemma-deployment-6cb95cc7f5-cbxg2-d9fe7 lq cluster-queue True 75mמריצים את הפקודה הבאה כדי להציג את המשימות:
kubectl get job --namespace=llmהפלט אמור להיראות כך, ולציין שה-Job של הכוונון העדין פועל שוב, וממשיך מנקודת הבדיקה האחרונה שזמינה.
NAME STATUS COMPLETIONS DURATION AGE finetune-gemma-l4 Running 0/2 2m11s 38m
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.
מחיקת המשאבים שנפרסו
כדי להימנע מחיובים בחשבון Google Cloud על המשאבים שיצרתם במדריך הזה, מריצים את הפקודות הבאות:
gcloud storage rm --recursive gs://${MODEL_BUCKET}
gcloud container clusters delete ${CLUSTER_NAME} --location ${REGION}