במדריך הזה נדגים איך לתזמן כמה עומסי עבודה (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.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את gcloud CLI. אם התקנתם בעבר את ה-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
בקטע הזה יוצרים שלושה JobSet. Jobset הוא API של עומס עבודה שמאפשר לכם לנהל קבוצה של משימות Kubernetes כיחידה אחת. התרחיש הנפוץ ביותר לשימוש ב-JobSet הוא אימון מבוזר, אבל אפשר להשתמש בו גם להרצת עומסי עבודה של אצווה.
ה-JobSets הבאים מריצים עומס עבודה של Jax שמפיק את המספר הכולל של שבבי TPU בפרוסת ה-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, לא ניתן להריץ את כל JobSet בו-זמנית.
כש-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 .
מדדי ניראות (observability) ולוחות בקרה של תפוקה טובה (goodput) של אימון ושל Cloud ML בGoogle Cloud מסוף זמינים בתצוגה מקדימה. מידע נוסף על goodput זמין במאמר Introducing ML Productivity Goodput: a metric to measure AI system efficiency.
מרכזי שליטה
כדי לראות את הסטטוס של מאגרי הצמתים של 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, כמו תקינות המאגרים הבסיסיים של הצמתים וביצוע עומס העבודה בפועל. הוא מספק ציוני תפוקה כדי לעקוב אחרי הביצועים של JobSet, כולל תפוקת תזמון ותפוקת זמן ריצה של שרת 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}])
מעקב אחרי זמן הפעולה של 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: חלקיק הזמן שבו כל המאיצים הנדרשים פעילים. המדד הזה מספק אומדן של קצב העברת הנתונים האפקטיבי בזמן הריצה.אם אתם צריכים מדד מדויק יותר של קצב העברת נתונים נטו בזמן ריצה, אתם יכולים להטמיע את האפליקציה שלכם ולבצע אינטגרציה עם Goodput Measurement API. לפרטים נוספים, אפשר לעיין בהוראות שבספריית ML Goodput Measurement.
כדי לראות את קצב העברת הנתונים המתוזמן של 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