במדריך הזה נדגים איך לתזמן כמה עומסי עבודה (workload) של multislice ב-Google Kubernetes Engine (GKE) כדי לשפר את ניצול המשאבים. לדוגמה, אתם פורסים עומס עבודה של Jax, מפעילים פתרונות חכמים ב-TPU Multislice ומטמיעים תור של משימות באמצעות JobSet ו-Kueue. מערכת Kueue קובעת מתי עבודות צריכות לפעול על סמך משאבים זמינים, מכסות והיררכיה לחלוקה הוגנת בין צוותים.
המדריך הזה מיועד למהנדסי למידת מכונה (ML) ולאדמינים ולמפעילים של פלטפורמות שמתעניינים ביכולות של Kubernetes לניהול קונטיינרים לצורך אימון של מודלים גדולים של שפה (LLM). מידע נוסף על תפקידים נפוצים ודוגמאות למשימות שאנחנו מתייחסים אליהן ב Google Cloud תוכן זמין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.
לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את הנושאים הבאים:
- זמינות של גרסאות TPU עדכניות עם ארכיטקטורת מערכת Cloud TPU
- TPU Multislice ב-GKE
מטרות
- מכינים את הסביבה עם אשכול GKE עם שלושה חלקי TPU v5e. לכל פרוסת TPU יש
2x4טופולוגיה עם 8 שבבים. לכן, סך הכול 24 שבבי TPU v5e TPU. - יוצרים את משאבי Kueue כדי לוודא שהמכסות משותפות באופן הוגן בין עומסי העבודה.
- מריצים את עומס העבודה של Multislice.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
מתקינים את JobSet גרסה 0.2.3 ואילך.
מתקינים את Kueue בגרסה 0.4.1 ואילך.
הכנת הסביבה
במסוף Google Cloud , מפעילים מכונה של Cloud Shell:
פותחים את Cloud Shellמגדירים את משתני הסביבה שמוגדרים כברירת מחדל באמצעות הפקודה
gcloud config set:gcloud config set project PROJECT_IDמחליפים את PROJECT_ID ב Google Cloud מזהה הפרויקט.
באשכולות במצב Autopilot שמופעלת בהם גרסה 1.29.2-gke.1521000 ואילך, יחידות TPU מופעלות כברירת מחדל. מגדירים את ה-TPU באשכולות של Autopilot במפרט של עומס העבודה. מידע נוסף זמין בקטע הגדרת עומסי עבודה של Multislice באמצעות JobSets.
יצירת אשכול GKE
ב-Cloud Shell, יוצרים אשכול GKE:
טייס אוטומטי
gcloud container clusters create-auto multislice-cluster \
--location=CONTROL_PLANE_LOCATION \
--cluster-version 1.29.2-gke.1521000 \
--release-channel rapid
בפקודה הזו:
- הדגל
--locationמציין את האזור ב-Compute Engine של מישור הבקרה של האשכול. - הדגל
--cluster-versionמציין את גרסת Kubernetes של האשכול. - הדגל
--release-channelמציין את ערוץ ההפצה של האשכול. במקרה כזה, הערוץ המהיר תומך בגרסאות העדכניות ביותר שזמינות ב-GKE.
רגילה
gcloud container clusters create multislice-cluster \
--location=CONTROL_PLANE_LOCATION
מחליפים את CONTROL_PLANE_LOCATION במיקום שבו רוצים ליצור את האשכול. מוודאים שיש לו קיבולת לסוג המכונה ct5lp-hightpu-4t.
יצירת האשכול עשויה להימשך כמה דקות.
אם אתם משתמשים במצב GKE Autopilot, דלגו אל הקטע יצירת משאבי Kueue. באשכולות של Autopilot שמופעלת בהם גרסה 1.29.2-gke.1521000 ואילך, יחידות TPU מופעלות כברירת מחדל.
יצירת שלוש קבוצות של צמתים עם פרוסות TPU במצב רגיל
בקטע הזה יוצרים מאגרי צמתים של TPU באמצעות הפקודה gcloud beta container node-pools create.
יוצרים את מאגר הצמתים הראשון בשם
nodepool1:gcloud beta container node-pools create nodepool1 \ --location=CONTROL_PLANE_LOCATION \ --cluster=multislice-cluster \ --node-locations=NODE_LOCATION \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=2x4 \ --project=PROJECT_IDמחליפים את NODE_LOCATION בתחום אחד או יותר באזור של האשכול שבו רוצים ליצור את הצמתים.
יוצרים את מאגר הצמתים השני בשם
nodepool2:gcloud beta container node-pools create nodepool2 \ --location=CONTROL_PLANE_LOCATION \ --cluster=multislice-cluster \ --node-locations=NODE_LOCATION \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=2x4 \ --project=PROJECT_IDיוצרים את מאגר הצמתים השלישי בשם
nodepool3:gcloud beta container node-pools create nodepool3 \ --location=CONTROL_PLANE_LOCATION \ --cluster=multislice-cluster \ --node-locations=NODE_LOCATION \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=2x4 \ --project=PROJECT_ID
GKE יוצר שלושה מאגרי צמתים. כל מאגר צמתים הוא פלח TPU נפרד.
בשלבים הקודמים השתמשתם בפקודה gcloud beta container node-pools create כדי ליצור את מאגרי הצמתים. הפקודות האלה משתמשות בדגלים הבאים:
-
--node-locations: רשימה מופרדת בפסיקים של אזור אחד או יותר שבהם GKE יוצר את מאגרי הצמתים. -
--machine-type: סוג המכונה שבה רוצים להשתמש לצמתים. במקרה הזה, השתמשת ב-ct5lp-hightpu-4t. מידע נוסף על סוגי מכונות שתואמים ל-TPU זמין בטבלה שבמאמר בחירת גרסת ה-TPU. -
--tpu-topology: טופולוגיית ה-TPU לשימוש במאגר הצמתים. במקרה הזה, השתמשתם ב-2x4. מידע נוסף על טופולוגיות של TPU מופיע במאמר בחירת טופולוגיה של TPU.
יצירת משאבי Kueue
יוצרים את קובץ המניפסט
kueue.yamlהבא:apiVersion: kueue.x-k8s.io/v1beta1 kind: ResourceFlavor metadata: name: "vlp-24" spec: nodeLabels: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 --- apiVersion: kueue.x-k8s.io/v1beta1 kind: ClusterQueue metadata: name: "cluster-queue" spec: namespaceSelector: {} queueingStrategy: BestEffortFIFO resourceGroups: - coveredResources: ["google.com/tpu"] flavors: - name: "vlp-24" resources: - name: "google.com/tpu" nominalQuota: 24 --- apiVersion: kueue.x-k8s.io/v1beta1 kind: LocalQueue metadata: namespace: default name: multislice-queue spec: clusterQueue: cluster-queueהחלת מניפסט
kueue.yaml:kubectl apply -f kueue.yaml
GKE יוצר את משאבי Kueue הבאים:
- ResourceFlavor: הפשטה של המשאבים באשכול. בדוגמה הזו, GKE יוצר שלוש חלוקות של TPU עם טופולוגיה של
2x4. לכל פרוסת TPU יש טופולוגיה של2x4עם 8 שבבים (24 שבבי TPU בסך הכול). - ClusterQueue: תור גלובלי לניהול עומסי עבודה ומשאבי אשכולות.
- LocalQueue: מקבץ עומסי עבודה שקשורים זה לזה, שבדרך כלל מופעלים על ידי דייר יחיד (משתמש). כל LocalQueue מצביע על ClusterQueue שממנו מוקצים משאבים להרצת עומסי העבודה שלו. עומס עבודה ב-Kueue הוא הפשטה שמייצגת עומס עבודה של קבוצת משימות. במקרה הזה, כל עומס עבודה הוא JobSet.
הגדרת עומסי עבודה של Multislice באמצעות JobSets
בקטע הזה יוצרים שלושה JobSets. Jobset הוא API של עומסי עבודה שמאפשר לכם לנהל קבוצה של משימות Kubernetes כיחידה אחת. התרחיש הנפוץ ביותר לשימוש ב-JobSet הוא אימון מבוזר, אבל אפשר להשתמש בו גם להרצת עומסי עבודה של אצווה.
ה-JobSets הבאים מריצים עומס עבודה של Jax שמפיק את המספר הכולל של שבבי TPU בפלח, ואז נכנס למצב שינה למשך 60 שניות כדי לדמות זמן אימון של מודל, ואז יוצא.
מתקינים את JobSet API באשכול:
VERSION=v0.8.1 kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/$VERSION/manifests.yamlיוצרים את קובץ המניפסט
jobsets-multislice.yamlהבא:טייס אוטומטי
apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: multislice-1slice labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 1 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 command: - bash - -c - | pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html python -c 'import jax; print("Global device count:", jax.device_count())' resources: limits: google.com/tpu: 4 --- apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: multislice-2slice labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 2 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 command: - bash - -c - | pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html python -c 'import jax; print("Global device count:", jax.device_count())' sleep 60 resources: limits: google.com/tpu: 4 --- apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: multislice-3slice labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 3 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 command: - bash - -c - | sleep 60 resources: limits: google.com/tpu: 4רגילה
apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: multislice-1slice labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 1 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 securityContext: privileged: true command: - bash - -c - | pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html python -c 'import jax; print("Global device count:", jax.device_count())' resources: limits: google.com/tpu: 4 --- apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: multislice-2slice labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 2 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 securityContext: privileged: true command: - bash - -c - | pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html python -c 'import jax; print("Global device count:", jax.device_count())' sleep 60 resources: limits: google.com/tpu: 4 --- apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: multislice-3slice labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 3 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 securityContext: privileged: true command: - bash - -c - | sleep 60 resources: limits: google.com/tpu: 4החלת מניפסט
jobsets-multislice.yaml:kubectl apply -f jobsets-multislice.yaml
GKE יוצר את המשימות עם בקשות המשאבים הבאות:
- ה-JobSet
multislice-1sliceיוצר Job אחד שנדרש לו פרוסת TPU אחת בסך הכול. - ה-JobSet
multislice-2sliceיוצר שני Jobs שדורשים בסך הכול שני חלקי TPU. - ה-JobSet
multislice-3sliceיוצר שלוש משימות שדורשות בסך הכול שלוש פרוסות TPU.
מכיוון שיש באשכול רק 3 חלקי TPU, לא כל קבוצות המשימות יכולות לפעול בו-זמנית.
כש-Kueue מוסיף לתור את כל שלושת ה-JobSets של multislice-3slice, המשימות שלו פועלות לבד עד לסיום. האירועים multislice-1slice ו-multislice-2slice ימתינו ויפעלו יחד לאחר מכן.
אימות של עומסי העבודה שהתקבלו על ידי Kueue
בודקים את עומסי העבודה בתור ב-Kueue:
kubectl get workloadsהפלט אמור להיראות כך:
NAME QUEUE ADMITTED BY AGE jobset-multislice-1slice-2530a multislice-queue 3s jobset-multislice-2slice-ffb02 multislice-queue 4s jobset-multislice-3slice-8c695 multislice-queue cluster-queue 10s
Kueue מוסיף לתור עומסי עבודה אחד או יותר, בהתאם למשאבי ה-TPU שנדרשים להם.
מעקב אחרי עומסי העבודה
מדדים ולוחות בקרה של JobSet ושל מאגר צמתים בGoogle Cloud מסוף זמינים לכולם.
מדדים ולוחות בקרה של תפוקה טובה של אימון ותפוקה טובה של Cloud ML ב Google Cloud מסוף נמצאים ב תצוגה מקדימה. מידע נוסף על goodput זמין במאמר הצגת מדד goodput של פרודוקטיביות ML: מדד למדידת היעילות של מערכת AI.
מרכזי שליטה
כדי לראות את הסטטוס של מאגרי הצמתים של TPU מרובי-מארחים ב-GKE, עוברים אל לוח הבקרה GKE TPU Node Pool Status שמוצג על ידי Cloud Monitoring:
מעבר לסטטוס של מאגר צמתים של GKE TPU
מידע נוסף זמין במאמר מעקב אחרי מדדי תקינות של צמתי TPU ומאגרי צמתים.
כדי לראות מידע מקיף על התקינות והביצועים של JobSet, עוברים אל לוח הבקרה JobSet monitoring במסוף Google Cloud :
מעבר ללוח הבקרה של מעקב אחרי JobSet
לוח הבקרה למעקב אחר JobSet כולל שלוש כרטיסיות:
- סקירה כללית: בכרטיסייה הזו מוצגת התשתית הבסיסית של JobSet, כמו סטטוס JobSet, מוכנות של רפליקות ומצב רפליקה. הכרטיסייה כוללת גם מדדי תפוקה ומדדי תשתית מסוימים, כולל מדדי מעבד (CPU), מעבד גרפי (GPU), מעבד TPU, זיכרון ואחסון. מידע נוסף זמין במאמר מעקב אחרי תקינות של JobSet באמצעות מדדים.
- קצב נתונים יעיל של אימון (גרסת Preview): בכרטיסייה הזו מוצגת תמונה מקיפה של היעילות התפעולית מקצה לקצה של JobSet, כמו תקינות של מאגרי צמתים בסיסיים וביצוע בפועל של עומס העבודה. הוא מספק ציוני goodput כדי שתוכלו לעקוב אחרי הביצועים של JobSet, כולל goodput של תזמון ו-goodput של זמן ריצה של proxy . מידע נוסף זמין במאמר בנושא מעקב אחרי נתונים טובים של JobSet.
Cloud ML Goodput (תצוגה מקדימה): בכרטיסייה הזו מוצג תובנה מפורטת לגבי Goodput של JobSet, כולל פירוט של Badput בשכבת האפליקציה.
כדי להשתמש בלוח הבקרה הזה, צריך להגדיר שילוב עם Goodput Measurement API ולבצע אינסטרומנטציה של האפליקציה כדי לשלוח מדדי תפוקה. פרטים נוספים זמינים בהוראות שבספריית ML Goodput Measurement.
מעקב אחרי הפעלת ה-Pods
kubectl get pods
הפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE
multislice-1slice-slice-0-0-pf2ll 1/1 Running 0 1s
multislice-1slice-slice-0-1-55g62 1/1 Running 0 1s
multislice-2slice-slice-0-0-f4hf7 1/1 Running 0 3s
multislice-2slice-slice-0-1-c8kv7 1/1 Running 0 3s
multislice-2slice-slice-1-0-7h46t 1/1 Running 0 3s
multislice-2slice-slice-1-1-lj9hb 1/1 Running 0 3s
multislice-3slice-slice-0-0-wzq9t 0/1 Completed 0 2m31s
multislice-3slice-slice-0-1-zf4dp 0/1 Completed 0 2m30s
multislice-3slice-slice-1-0-hbfn5 0/1 Completed 0 2m31s
multislice-3slice-slice-1-1-45fgl 0/1 Completed 0 2m30s
multislice-3slice-slice-2-0-wjbp4 0/1 Completed 0 2m30s
multislice-3slice-slice-2-1-lwnvs 0/1 Completed 0 2m30s
אפשר לראות ש-GKE תזמן, יצר והפעיל את ה-Pods עבור multislice-3slice קודם. לאחר מכן, GKE הפעיל את ה-Pods מ-multislice-1slice ו-multislice-2slice JobSets.
מעקב אחרי תקינות של JobSet באמצעות מדדים
כדי להבין אם JobSet פועל כמצופה, או כדי להסיק אם הוא הופסק, אפשר להשתמש במדדים של Prometheus מחבילת המדדים של JobSet, כמו kube_jobset_succeeded_replicas.
שימו לב שמדדי תקינות של Jobset נתמכים רק ב-GKE מגרסה 1.32.1-gke.135700 ואילך. מדדי תקינות של JobSet מופעלים כברירת מחדל באשכולות שנוצרו לאחרונה עם גרסאות נתמכות. במקרה של אשכולות קיימים שמשודרגים לגרסאות נתמכות, הלקוחות צריכים להפעיל ידנית את חבילת המדדים JobSet. מידע נוסף מופיע במאמרי העזרה.
כדי לבדוק את השלמת JobSet במדריך הזה, מריצים את שאילתת PromQL הבאה:
kube_jobset_succeeded_replicas{
cluster="multislice-cluster",
jobset_name=~"mulitslice-.*"}
מעקב אחרי תזמון של JobSet
כדי לעקוב אחרי התזמון של JobSet, משתמשים במדדים הבאים:
-
kubernetes.io/jobset/assigned_node_pools: מאגרי צמתים של GKE שבהם תרמילי Pods מתוזמנים על ידי JobSet של Kubernetes. -
kubernetes.io/node_pool/assigned_jobsets: Kubernetes JobSets שקבעו תזמון של Pods במאגר צמתים של GKE. -
kubernetes.io/jobset/assigned_nodes: צומתי GKE שבהם מתוזמנים Pods על ידי Kubernetes JobSet. -
kubernetes.io/node/assigned_jobsets: Kubernetes JobSets שכוללים Pods מתוזמנים בצומת GKE.
כדי לראות את מאגרי הצמתים שבהם מתוזמנים פודים לכל JobSet באשכול ספציפי, מריצים את שאילתת PromQL הבאה:
avg_over_time(
kubernetes_io:jobset_assigned_node_pools{
monitored_resource="k8s_entity",
cluster_name="multislice-cluster"}[${__interval}])
כדי לזהות את מאגרי הצמתים שבהם נקבעה תזמון של Jobset ספציפי, מריצים את שאילתת PromQL הבאה:
avg_over_time(
kubernetes_io:jobset_assigned_node_pools{
monitored_resource="k8s_entity",
cluster_name="multislice-cluster",
entity_name=~"multislice-.*"}[${__interval}])
כדי לזהות את קבוצות המשימות שתוזמנו במאגר צמתים ספציפי, מריצים את שאילתת PromQL הבאה:
avg_over_time(
kubernetes_io:node_pool_assigned_jobsets{
monitored_resource="k8s_node_pool",
cluster_name="multislice-cluster",
node_pool_name="multislice-np"}[${__interval}])
מעקב אחרי זמן הפעולה (uptime) של JobSet, הזמן עד להתאוששות (TTR) והזמן בין הפרעות (TBI)
המדדים הבאים שימושיים למעקב אחר הזמינות של JobSet:
-
kubernetes.io/jobset/uptime: הזמן הכולל שבו JobSet היה זמין. -
kubernetes.io/jobset/times_to_recover: חלוקת תקופת ההתאוששות של JobSet. כל דוגמה מציינת אירוע שחזור יחיד מתוך תקופת השבתה של JobSet. -
kubernetes.io/jobset/times_between_interruptions: התפלגות המרווח בין סוף ההפרעה הקודמת לתחילת ההפרעה הנוכחית עבור JobSet. כל דגימה מציינת משך זמן יחיד בין ההפרעה הקודמת להפרעה הנוכחית.
המדדים האלה רלוונטיים ל-JobSets שיש בהם בדיוק עבודה אחת של שכפול GPU או TPU. החישוב של המדדים מבוסס רק על הזמינות של העבודה המשוכפלת היחידה הזו. המדדים נתמכים בכל הגרסאות של GKE.
כדי לראות את זמן הפעולה של JobSets שהשתמשתם בהם במדריך הזה, מריצים את שאילתת PromQL הבאה:
avg_over_time(
kubernetes_io:jobset_uptime{
monitored_resource="k8s_entity", entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}])
כדי לראות את התפלגויות ה-TBI של JobSets מהמדריך הזה, מריצים את שאילתת PromQL הבאה:
histogram_quantile(0.50,
sum_over_time(
kubernetes_io:jobset_times_between_interruptions_bucket{
monitored_resource="k8s_entity",entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}]))
אפשר להאריך את פרק הזמן של השאילתה, למשל ל-7 ימים, ולחשב את הזמן הממוצע בין הפרעות (MTBI) במהלך התקופה הזו:
sum(sum_over_time(
kubernetes_io:jobset_times_between_interruptions_sum{
monitored_resource="k8s_entity",entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}]))
/
sum(sum_over_time(
kubernetes_io:jobset_times_between_interruptions_count{
monitored_resource="k8s_entity",entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}]))
כדי לראות את התפלגויות ה-TTR, אפשר להריץ את שאילתות PromQL הבאות:
histogram_quantile(0.50,
sum_over_time(
kubernetes_io:jobset_times_to_recover_bucket{
monitored_resource="k8s_entity",entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}]))
אחרי שמגדילים את מרווח השאילתות לטווח זמן ארוך יותר, כמו 7 ימים, אפשר לחשב את הזמן הממוצע לשחזור (MTTR) במהלך התקופה הזו:
sum(sum_over_time(
kubernetes_io:jobset_times_to_recover_sum{
monitored_resource="k8s_entity",entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}]))
/
sum(sum_over_time(
kubernetes_io:jobset_times_to_recover_count{
monitored_resource="k8s_entity",entity_type="jobset",
entity_name=~"multislice-.*",cluster_name="multislice-cluster"}[${__interval}]))
מעקב אחרי תפוקה טובה של JobSet
המדדים הבאים שימושיים למעקב אחרי הביצועים של JobSet:
-
kubernetes.io/jobset/scheduling_goodput: חלקיק הזמן שבו כל המשאבים שנדרשים להרצת JobSet של אימון זמינים.
kubernetes.io/jobset/proxy_runtime_goodput: חלקיק הזמן שבו כל המאיצים הנדרשים פעילים. המדד הזה מספק אומדן של קצב העברת הנתונים בפועל בזמן הריצה.אם אתם צריכים מדד מדויק יותר של קצב העברת נתונים נטו בזמן ריצה, אתם יכולים להטמיע את האפליקציה שלכם ולבצע אינטגרציה עם API למדידת Goodput. פרטים נוספים זמינים בהוראות שבספריית המדידה של ML Goodput.
כדי לראות את קצב העברת הנתונים המתוזמן של JobSet שבו השתמשתם במדריך הזה, מריצים את שאילתת PromQL הבאה:
avg_over_time(
kubernetes_io:jobset_scheduling_goodput{
monitored_resource="k8s_entity", entity_type="jobset",
entity_name=~"multislice-.*",
cluster_name="multislice-cluster"}[${__interval}])
כדי לראות את קצב העברת הנתונים של ה-proxy בזמן הריצה עבור JobSets מהמדריך הזה, מריצים את שאילתת PromQL הבאה:
avg_over_time(
kubernetes_io:jobset_proxy_runtime_goodput{
monitored_resource="k8s_entity", entity_type="jobset",
entity_name=~"multislice-.*",
cluster_name="multislice-cluster"}[${__interval}])
הפעלה של סדרי עדיפויות ודחיקה של עומסי עבודה ב-Kueue
אפשר גם להקצות לעומסי עבודה ב-Kueue עדיפויות שקובעות את הסדר שבו Kueue מאשר את עומסי העבודה שהוכנסו לתור.
מעדכנים את
ClusterQueueכך שתהיה לו מדיניות קדימות:apiVersion: kueue.x-k8s.io/v1beta1 kind: ResourceFlavor metadata: name: "vlp-24" spec: nodeLabels: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 --- apiVersion: kueue.x-k8s.io/v1beta1 kind: ClusterQueue metadata: name: "cluster-queue" spec: namespaceSelector: {} resourceGroups: - coveredResources: ["google.com/tpu"] flavors: - name: "vlp-24" resources: - name: "google.com/tpu" nominalQuota: 24 preemption: reclaimWithinCohort: Any withinClusterQueue: LowerPriority --- apiVersion: kueue.x-k8s.io/v1beta1 kind: LocalQueue metadata: namespace: default name: multislice-queue spec: clusterQueue: cluster-queueיוצרים
PriorityClassלכל רמת עדיפות שרוצים להקצות לעומסי עבודה:apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 100 globalDefault: false description: "This low priority class should be used for some Pods only."מקצים את
priorityClassNameל-JobSet:טייס אוטומטי
apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: low-priority labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 1 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 priorityClassName: low-priority containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 command: - bash - -c - | sleep 60 resources: limits: google.com/tpu: 4 # Number of TPU chips per workerרגילה
apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: low-priority labels: kueue.x-k8s.io/queue-name: multislice-queue annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool spec: failurePolicy: maxRestarts: 4 replicatedJobs: - name: slice replicas: 1 template: spec: parallelism: 2 completions: 2 backoffLimit: 0 template: spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice cloud.google.com/gke-tpu-topology: 2x4 priorityClassName: low-priority containers: - name: jax-tpu image: python:3.8 ports: - containerPort: 8471 - containerPort: 8080 securityContext: privileged: true command: - bash - -c - | sleep 60 resources: limits: google.com/tpu: 4 # Number of TPU chips per worker
GKE כולל מדיניות קדימות שקובעת איך Kueue מקצה את המשאבים הזמינים. המדיניות קובעת שאפשר לבצע הפסקה זמנית של עומס עבודה אם עומס עבודה בעדיפות גבוהה יותר צריך את המשאבים. יש סיכוי גבוה יותר שעומסי עבודה עם ערך עדיפות נמוך יותר יידחקו על ידי עומסי עבודה עם עדיפות גבוהה יותר.
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.
מחיקת הפרויקט
- במסוף Google Cloud , נכנסים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
מחיקת המשאב הספציפי
מוחקים את משאבי Kueue:
kubectl delete -f jobsets-multislice.yaml kubectl delete -f kueue.yamlמחיקת האשכול:
gcloud container clusters delete multislice-cluster --location=CONTROL_PLANE_LOCATION