כשמריצים עומסי עבודה של אימון או הסקה בקנה מידה גדול ב-Google Kubernetes Engine (GKE), יכול להיות שתיתקלו בבעיות בהקצאה או בשימוש ביחידות לעיבוד טנסורים (TPU). יכול להיות שה-Pods שלכם ייתקעו במצב Pending כי GKE לא מצליח להקצות צמתים חדשים של חלקי TPU, או שעומס העבודה שלכם ייכשל בגלל מכסת שימוש לא מספיקה, הגדרות טופולוגיה שגויות או הגדרות שגויות של עומס העבודה.
במאמר הזה מוסבר איך לבדוק אם יש בעיות במכסות, לוודא שהבקשות של עומס העבודה ל-nodeSelector ולמשאבים נכונות, ולמצוא יומנים כדי לזהות את שורש הבעיה בכשלים בתזמון או באתחול.
המידע הזה מיועד לאדמינים ולמפעילים של פלטפורמות שמקצים ומנהלים מאגרי צמתים עם טופולוגיות ספציפיות של פרוסות TPU, ולמפתחי אפליקציות שפותרים בעיות בעומסי עבודה של אימון או הסקה של TPU בקנה מידה גדול. למידע נוסף על התפקידים הנפוצים ודוגמאות למשימות שאנחנו מתייחסים אליהן בתוכן של Google Cloud , קראו את המאמר תפקידים ומשימות נפוצים של משתמשי GKE.
אין מספיק מכסה כדי לבצע את הבקשה ל-TPU
שגיאה דומה ל-Insufficient quota to satisfy the request מציינת שבפרויקטGoogle Cloud אין מכסה מספקת כדי לבצע את הבקשה.
כדי לפתור את הבעיה, צריך לבדוק את מגבלת המכסה של הפרויקט ואת השימוש הנוכחי. במקרה הצורך, אפשר לבקש להגדיל את מכסת ה-TPU.
בדיקת מגבלת המכסה והשימוש הנוכחי
בקטעים הבאים מוסבר איך לוודא שיש לכם מספיק מכסה כשאתם משתמשים ב-TPU ב-GKE.מכסה למכונות וירטואליות לפי דרישה או במודל Spot
אם אתם יוצרים מאגר צמתים של פרוסת TPU עם מכונות וירטואליות לפי דרישה או מכונות וירטואליות מסוג Spot, אתם צריכים לוודא שיש לכם מכסת TPU מספקת באזור שבו אתם רוצים להשתמש.
כדי ליצור מאגר צמתים של חלקי TPU שצורכים הזמנת TPU, לא נדרשת מכסת TPU.1 אפשר לדלג על הקטע הזה אם משתמשים ב-TPU מוזמן.
כדי ליצור מאגר צמתים של פרוסות TPU על פי דרישה או במחיר מוזל ב-GKE, צריך מכסת Compute Engine API. המכסה של Compute Engine API (compute.googleapis.com) שונה מהמכסה של Cloud TPU API (tpu.googleapis.com), שנדרשת כשיוצרים יחידות TPU באמצעות Cloud TPU API.
כדי לבדוק את המגבלה ואת השימוש הנוכחי במכסת ה-TPU של Compute Engine API:
נכנסים לדף Quotas במסוף Google Cloud :
בתיבה Filter, מבצעים את הפעולות הבאות:
משתמשים בטבלה הבאה כדי לבחור ולהעתיק את מאפיין המכסה בהתאם לגרסת ה-TPU ולסוג המכונה. לדוגמה, אם אתם מתכננים ליצור צומתי TPU v5e על פי דרישה שסוג המכונה שלהם מתחיל ב-
ct5lp-, הזינוName: TPU v5 Lite PodSlice chips.גרסת TPU, סוג המכונה מתחיל ב- המאפיין והשם של המכסה עבור מופעים על פי דרישה המאפיין והשם של המכסה למכונות Spot2 TPU v3,
ct3-Dimensions (e.g. location):
tpu_family:CT3לא רלוונטי TPU v3,
ct3p-Dimensions (e.g. location):
tpu_family:CT3Pלא רלוונטי TPU v4,
ct4p-Name:
TPU v4 PodSlice chipsName:
Preemptible TPU v4 PodSlice chipsTPU v5e,
ct5lp-Name:
TPU v5 Lite PodSlice chipsName:
Preemptible TPU v5 Lite Podslice
chipsTPU v5p,
ct5p-Name:
TPU v5p chipsName:
Preemptible TPU v5p chipsTPU Trillium,
ct6e-Dimensions (e.g. location):
tpu_family:CT6EName:
Preemptible TPU slices v6eIronwood (TPU7x),
tpu7x-standard-4tDimensions (e.g. location):
tpu_family:tpu7xName:
Preemptible TPU slices tpu7xבוחרים במאפיין Dimensions (e.g. locations) (מאפיינים (למשל מיקומים)) ומזינים
region:ואחריו את שם האזור שבו מתכננים ליצור יחידות TPU ב-GKE. לדוגמה, מזיניםregion:us-west4אם מתכננים ליצור צמתים של חלקי TPU באזורus-west4-a. מכסת ה-TPU היא אזורית, ולכן כל האזורים באותו אזור צורכים את אותה מכסת TPU.
אם אין מכסות שתואמות למסנן שהזנתם, סימן שהפרויקט לא קיבל אף אחת מהמכסות שצוינו לאזור שאתם צריכים, ואתם צריכים לבקש שינוי במכסת ה-TPU.
כשיוצרים הזמנת TPU, גם המגבלה וגם ערכי השימוש הנוכחיים של המכסה המתאימה גדלים לפי מספר הצ'יפים בהזמנת ה-TPU. לדוגמה, כשיוצרים הזמנה ל-16 שבבי TPU v5e
שסוג המכונה שלהם מתחיל ב-ct5lp-
,
הערכים של Limit ושל Current usage במכסת TPU v5 Lite PodSlice chips באזור הרלוונטי גדלים ב-16.
-
כשיוצרים מאגר צמתים של פרוסות TPU, משתמשים בדגלים
--reservationו---reservation-affinity=specificכדי ליצור מכונה שמורה. אפשר להזמין TPU כשרוכשים התחייבות. ↩ -
כשיוצרים מאגר צמתים של פרוסות TPU, משתמשים בדגל
--spotכדי ליצור מכונה של Spot. ↩
מכסות למשאבי GKE נוספים
יכול להיות שתצטרכו להגדיל את המכסות הבאות שקשורות ל-GKE באזורים שבהם GKE יוצר את המשאבים שלכם.
- מכסת Persistent Disk SSD (GB): דיסק האתחול של כל צומת Kubernetes דורש 100GB כברירת מחדל. לכן, המכסה הזו צריכה להיות לפחות בגודל של מכפלת המספר המקסימלי של צומתי GKE שאתם צופים שתיצרו ב-100GB (צמתים * 100GB).
- מכסת כתובות ה-IP שבשימוש: כל צומת Kubernetes צורך כתובת IP אחת. לכן, צריך להגדיר את המכסה הזו לפחות כמספר המקסימלי של צמתי GKE שאתם צפויים ליצור.
- מוודאים ש-
max-pods-per-nodeתואם לטווח של רשת המשנה: כל צומת של Kubernetes משתמש בטווחי כתובות IP משניים ל-Pods. לדוגמה,max-pods-per-nodeמתוך 32 דורש 64 כתובות IP, שמתורגמות לרשת משנה /26 לכל צומת. חשוב לזכור שאסור לשתף את הטווח הזה עם אשכול אחר. כדי להימנע ממיצוי טווח כתובות ה-IP, משתמשים בדגל--max-pods-per-nodeכדי להגביל את מספר הפודים שאפשר לתזמן בצומת. המכסה שלmax-pods-per-nodeצריכה להיות לפחות בגודל של מספר הצמתים המקסימלי ב-GKE שאתם צופים שתיצרו.
כדי לבקש להגדיל את המכסות, אפשר לעיין במאמר בנושא איך שולחים בקשה לשינוי המכסות.
איך GKE מטפל בבעיות קיבולת
אם GKE לא יכול ליצור את מאגר הצמתים של פרוסת ה-TPU בגלל קיבולת TPU לא מספקת, יכול להיות שהבקשה תיכשל עם שגיאה לגבי זמינות משאבים, או ש-GKE יוסיף את בקשת ההקצאה לתור עד שתהיה קיבולת זמינה.
אם משאבי TPU לא זמינים באופן זמני, יכול להיות שתקבלו שגיאה עם השדות GCE_STOCKOUT או ZONE_RESOURCE_POOL_EXHAUSTED. מידע נוסף זמין במאמר בנושא אין מספיק משאבי TPU כדי למלא את בקשת ה-TPU.
במקרים אחרים, GKE מוסיף את הבקשה לתור ומוצגת הודעת שגיאה שמציינת שלא ניתן ליצור צומתי פרוסות TPU בגלל מחסור בקיבולת. GKE יוצר את הצמתים כשהקיבולת הופכת לזמינה.
אם יוצרים מאגר צמתים של פרוסת TPU עם מארח יחיד, הודעת השגיאה תיראה בערך כך:
1 node cannot be created due to lack of capacity. The missing nodes will be
created asynchronously once capacity is available. You can either wait for the
nodes to be up, or delete the node pool and try re-creating it again later.
אם אתם יוצרים מאגר צמתים של פרוסות TPU עם כמה מארחים, הודעת השגיאה תיראה בערך כך:
The nodes (managed by ...) cannot be created now due to lack of capacity. They
will be created asynchronously once capacity is available. You can either wait
for the nodes to be up, or delete the node pool and try re-creating it again
later.
הבקשה להקצאת TPU יכולה להישאר בתור למשך זמן רב, ובזמן הזה היא נשארת במצב Provisioning.
כשהקיבולת זמינה, GKE יוצר את הצמתים שלא נוצרו.
אם אתם צריכים קיבולת מוקדם יותר, כדאי לנסות VM במודל Spot. חשוב לזכור שVM במודל Spot צורכות מכסה שונה ממכסות של מכונות לפי דרישה.
כדי למחוק את בקשת ה-TPU שהוכנסה לתור, צריך למחוק את מאגר הצמתים של פרוסת ה-TPU.
אין מספיק משאבי TPU כדי למלא את בקשת ה-TPU
שגיאה שמכילה את GCE_STOCKOUT מציינת שמשאבי TPU לא זמינים באופן זמני כדי למלא את הבקשה. GKE ממלא את בקשת ההקצאה כשמשאבי ה-TPU זמינים.
כדי לפתור את הבעיה, אתם יכולים להשתמש בכל אחת מאפשרויות הצריכה הבאות:
- Flex-start: כדי להקצות מכונות וירטואליות מסוג Flex-start למשך עד שבעה ימים, כאשר GKE מקצה את החומרה באופן אוטומטי על בסיס הזמינות. מידע נוסף מופיע במאמר מידע על הקצאת GPU, TPU ו-H4D במצב הקצאה "התחלה גמישה".
- מכונות וירטואליות (VM) במודל Spot: כדי להקצות מכונות וירטואליות במודל Spot, אפשר לקבל הנחות משמעותיות, אבל המכונות הווירטואליות האלה יכולות להיפסק בכל שלב, עם אזהרה של 30 שניות. מידע נוסף זמין במאמר בנושא VM במודל Spot.
- מקום שמור לעתיד לתקופה של עד 90 יום (במצב לוח שנה): כדי להקצות משאבי TPU לתקופה של עד 90 יום, לפרק זמן מסוים. מידע נוסף זמין במאמר בנושא שליחת בקשה ל-TPU עם מקום שמור לעתיד במצב יומן.
- שרייני TPU: כדי לבקש מקום שמור לעתיד לשנה אחת או יותר.
- על פי דרישה: כדי לצרוך TPU בלי לתכנן מראש את הקיבולת. לפני שמבקשים משאבים, צריך לוודא שיש לכם מספיק מכסה על פי דרישה לסוג ולכמות הספציפיים של TPU VM. האפשרות 'על פי דרישה' היא האפשרות הכי גמישה לשימוש במשאבים, אבל אין ערובה לכך שיהיו מספיק משאבים על פי דרישה כדי לספק את הבקשה שלכם.
אם לא מציינים אפשרות אחרת, מודל הצריכה שמוגדר כברירת מחדל ל-TPU ב-GKE הוא על פי דרישה. כדי לבחור את אפשרות הצריכה שמתאימה לדרישות של עומס העבודה, אפשר לעיין במאמר מידע על אפשרויות צריכת מאיצים לעומסי עבודה של AI/ML ב-GKE.
שגיאה בהפעלת הקצאת צמתים אוטומטית (NAP) במאגר צמתים של פרוסת TPU
השגיאה הבאה מתרחשת כשמפעילים הקצאת צמתים אוטומטית (NAP) באשכול GKE שלא תומך ב-TPU.
הודעת השגיאה דומה לזו:
ERROR: (gcloud.container.clusters.create) ResponseError: code=400,
message=Invalid resource: tpu-v4-podslice.
כדי לפתור את הבעיה, צריך לשדרג את אשכול GKE לגרסה 1.27.6 ואילך.
GKE לא מקצה באופן אוטומטי צמתים של חלקי TPU
בקטעים הבאים מתוארים המקרים שבהם GKE לא מקצה אוטומטית צמתים של פרוסות TPU ואיך לפתור את הבעיות האלה.
הגדרת מכסה שגויה
אם מגבלות הקצאת המשאבים האוטומטית של האשכול חסרות או נמוכות מדי, מערכת GKE לא תקצה אוטומטית צמתים של פרוסות TPU. במקרים כאלה, יכול להיות שתראו את השגיאות הבאות:
כש-GKE מנסה להקצות משאבים אוטומטית למאגר צמתים של פרוסות TPU שלא הוגדרו לו מגבלות, הודעת השגיאה הבאה מופיעה ביומני החשיפה של הכלי להתאמה אוטומטית של גודל האשכול:
messageId: "no.scale.up.nap.pod.tpu.no.limit.defined"אם קיים מאגר צמתים של פרוסת TPU, אבל GKE לא יכול להגדיל את מספר הצמתים בגלל חריגה ממגבלות המשאבים, הודעת השגיאה הבאה תוצג כשמריצים את הפקודה
kubectl get events:11s Normal NotTriggerScaleUp pod/tpu-workload-65b69f6c95-ccxwz pod didn't trigger scale-up: 1 node(s) didn't match Pod's node affinity/selector, 1 max cluster cpu, memory limit reachedבנוסף, בתרחיש הזה, יכול להיות שתראו הודעות אזהרה דומות לאלה שמופיעות Google Cloud במסוף:
"Your cluster has one or more unschedulable Pods"כש-GKE מנסה להקצות משאבים אוטומטית למאגר של צומתי פרוסות TPU שחורג ממגבלות המשאבים, הודעת השגיאה הבאה תופיע ביומני החשיפה של המידרוג האוטומטי של האשכול:
messageId: "no.scale.up.nap.pod.zonal.resources.exceeded"בנוסף, בתרחיש הזה, יכול להיות שתראו הודעות אזהרה דומות לאלה שמופיעות Google Cloud במסוף:
"Can't scale up because node auto-provisioning can't provision a node pool for the Pod if it would exceed resource limits"
כדי לפתור את הבעיות האלה, צריך להגדיל את המספר המקסימלי של שבבי TPU, ליבות מעבד וזיכרון באשכול.
כדי לבצע את השלבים האלה:
- חישוב דרישות המשאבים לסוג ולמספר מסוימים של מכונות TPU. שימו לב: צריך להוסיף משאבים למאגרי צמתים של פרוסות שאינן TPU, כמו עומסי עבודה של המערכת.
קבלת תיאור של ה-TPU, המעבד והזיכרון שזמינים לסוג מכונה ולאזור ספציפיים. משתמשים ב-CLI של gcloud:
gcloud compute machine-types describe MACHINE_TYPE \ --zone COMPUTE_ZONEמחליפים את מה שכתוב בשדות הבאים:
-
MACHINE_TYPE: סוג המכונה שרוצים לחפש. -
COMPUTE_ZONE: השם של אזור החישוב.
הפלט כולל שורת תיאור שדומה לזו:
description: 240 vCPUs, 407 GB RAM, 4 Google TPUs ```-
כדי לחשב את המספר הכולל של מעבדים וזיכרון, מכפילים את הכמויות האלה במספר הצמתים הנדרש. לדוגמה, סוג המכונה
ct4p-hightpu-4tמשתמש ב-240 ליבות של מעבד (CPU) וב-407GB RAM עם 4 שבבי TPU. אם אתם צריכים 20 שבבי TPU, שמתאימים לחמישה צמתים, אתם צריכים להגדיר את הערכים הבאים:--max-accelerator=type=tpu-v4-podslice,count=20.CPU = 1200(240 פעמים 5 )memory = 2035(407 כפול 5)
מומלץ להגדיר את המגבלות עם מרווח מסוים כדי להתאים אותן לצמתים של חלקי TPU שאינם מיועדים לעומסי עבודה של המערכת.
עדכון המגבלות של האשכול:
gcloud container clusters update CLUSTER_NAME \ --max-accelerator type=TPU_ACCELERATOR \ count=MAXIMUM_ACCELERATOR \ --max-cpu=MAXIMUM_CPU \ --max-memory=MAXIMUM_MEMORYמחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_NAME: שם האשכול. -
TPU_ACCELERATOR: השם של מאיץ ה-TPU. -
MAXIMUM_ACCELERATOR: המספר המקסימלי של שבבי TPU באשכול. -
MAXIMUM_CPU: המספר המקסימלי של ליבות באשכול. -
MAXIMUM_MEMORY: מספר הגיגה-בייט המקסימלי של הזיכרון באשכול.
-
לא כל המופעים פועלים
ERROR: nodes cannot be created due to lack of capacity. The missing nodes
will be created asynchronously once capacity is available. You can either
wait for the nodes to be up, or delete the node pool and try re-creating it
again later.
השגיאה הזו עשויה להופיע כשפג הזמן הקצוב לתפוגה של פעולת GKE או כשאי אפשר למלא את הבקשה ולהוסיף אותה לתור להקצאת מאגרי צמתים של TPU עם מארח יחיד או עם כמה מארחים. כדי לצמצם את בעיות הקיבולת, אתם יכולים להשתמש במקומות שמורים או ב-VM במודל Spot.
הגדרה שגויה של עומס עבודה
השגיאה הזו מתרחשת בגלל הגדרה שגויה של עומס העבודה. פירטנו כאן כמה מהסיבות הנפוצות ביותר לשגיאה הזו:
- התוויות
cloud.google.com/gke-tpu-acceleratorו-cloud.google.com/gke-tpu-topologyשגויות או חסרות ב-Pod spec. מערכת GKE לא תקצה מאגרי צמתים של פרוסות TPU, והקצאת הצמתים באופן אוטומטי לא תוכל להגדיל את האשכול. - במפרט של ה-Pod לא מצוין
google.com/tpuבדרישות המשאבים.
כדי לפתור את הבעיה, אפשר לנסות את הפתרונות הבאים:
- מוודאים שאין תוויות לא נתמכות בבורר הצמתים של עומס העבודה.
לדוגמה, בורר צמתים לתווית
cloud.google.com/gke-nodepoolימנע מ-GKE ליצור מאגרי צמתים נוספים ל-Pods. - מוודאים שמפרטי תבנית ה-Pod, שבהם פועלת עומס העבודה של ה-TPU, כוללים את הערכים הבאים:
- תוויות
cloud.google.com/gke-tpu-acceleratorו-cloud.google.com/gke-tpu-topologyבnodeSelector. google.com/tpuבבקשה שלו.
- תוויות
כדי ללמוד איך לפרוס עומסי עבודה של TPU ב-GKE, אפשר לעיין במאמר בנושא הרצת עומס עבודה שמציג את מספר שבבי ה-TPU הזמינים במאגר צמתים של חלקי TPU.
שגיאות בתזמון כשפורסים Pods שצורכים TPU ב-GKE
הבעיה הבאה מתרחשת כש-GKE לא יכול לתזמן Pods שמבקשים יחידות TPU בצומתי פרוסות TPU. לדוגמה, זה יכול לקרות אם חלק מאשכולות TPU Pods שלא מבוססים על TPU כבר תוכננו בצמתי TPU.
הודעת השגיאה, שמופיעה כאירוע FailedScheduling ב-Pod, דומה לזו שבהמשך:
Cannot schedule pods: Preemption is not helpful for scheduling.
Error message: 0/2 nodes are available: 2 node(s) had untolerated taint
{google.com/tpu: present}. preemption: 0/2 nodes are available: 2 Preemption is
not helpful for scheduling
כדי לפתור את הבעיה:
מוודאים שיש לפחות מאגר צמתים אחד של מעבדים (CPU) באשכול, כדי שהמערכת תוכל להריץ את ה-Pods הקריטיים בצמתי שאינם TPU. מידע נוסף על פריסת Pod למאגר צמתים ספציפי
פתרון בעיות נפוצות ב-JobSets ב-GKE
בדף פתרון הבעיות של JobSet אפשר למצוא מידע על בעיות נפוצות ב-JobSet והצעות לפתרון בעיות. בדף הזה מוסבר על בעיות נפוצות כמו השגיאה 'Webhook not available', עבודות צאצא או Pods שלא נוצרו, ובעיות בהמשכת עומסי עבודה שנפסקו באמצעות JobSet ו-Kueue.
האתחול של ה-TPU נכשל
הבעיה הבאה מתרחשת כש-GKE לא מצליח להקצות עומסי עבודה חדשים של TPU בגלל שאין לו הרשאה לגשת למכשירי TPU.
הודעת השגיאה דומה לזו:
TPU platform initialization failed: FAILED_PRECONDITION: Couldn't mmap: Resource
temporarily unavailable.; Unable to create Node RegisterInterface for node 0,
config: device_path: "/dev/accel0" mode: KERNEL debug_data_directory: ""
dump_anomalies_only: true crash_in_debug_dump: false allow_core_dump: true;
could not create driver instance
כדי לפתור את הבעיה, צריך לוודא שמריצים את מאגר ה-TPU במצב הרשאות או להגדיל את ulimit בתוך מאגר התגים.
תזמון של חסימה הדדית
יכול להיות שתזמון של שתי משימות או יותר ייכשל בגלל מצב של קיפאון. לדוגמה, בתרחיש שבו כל התנאים הבאים מתקיימים:
- יש לכם שתי משימות (משימה א' ומשימה ב') עם כללי זיקה של Pod.
GKE מתזמן את חלקי ה-TPU לשתי המשימות עם טופולוגיית TPU של
v4-32. - יש שני חלקי TPU (
v4-32) באשכול. - לאשכול יש מספיק קיבולת כדי לתזמן את שתי המשימות, ובאופן תיאורטי אפשר לתזמן כל משימה במהירות בכל פרוסת TPU.
- מתזמן המשימות של Kubernetes מתזמן פוד אחד ממשימה א' בפרוסה אחת, ואז מתזמן פוד אחד ממשימה ב' באותה פרוסה.
במקרה כזה, בהתחשב בכללי הזיקה של ה-Pod למשימה A, מתזמן המשימות מנסה לתזמן את כל ה-Pods שנותרו למשימה A ולמשימה B, כל אחד בפלח TPU יחיד. כתוצאה מכך, מערכת GKE לא תוכל לתזמן באופן מלא את Job A או את Job B. לכן, הסטטוס של שתי המשימות יישאר 'בהמתנה'.
כדי לפתור את הבעיה, צריך להשתמש בPod anti-affinity עם cloud.google.com/gke-nodepool בתור topologyKey, כמו בדוגמה הבאה:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
parallelism: 2
template:
metadata:
labels:
job: pi
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: job
operator: In
values:
- pi
topologyKey: cloud.google.com/gke-nodepool
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: job
operator: NotIn
values:
- pi
topologyKey: cloud.google.com/gke-nodepool
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- kube-system
containers:
- name: pi
image: perl:5.34.0
command: ["sleep", "60"]
restartPolicy: Never
backoffLimit: 4
ההרשאה נדחתה במהלך יצירת האשכול ב-us-central2
אם אתם מנסים ליצור אשכול ב-us-central2 (האזור היחיד שבו זמין TPU v4), יכול להיות שתיתקלו בהודעת שגיאה דומה לזו שמופיעה בהמשך:
ERROR: (gcloud.container.clusters.create) ResponseError: code=403,
message=Permission denied on 'locations/us-central2' (or it may not exist).
השגיאה הזו מוצגת כי האזור us-central2 הוא אזור פרטי.
כדי לפתור את הבעיה, אפשר לפתוח בקשת תמיכה או לפנות לצוות ניהול החשבון כדי לבקש להציג את us-central2 בפרויקטGoogle Cloud .
מכסה לא מספיקה במהלך יצירת מאגר צומתי TPU ב-us-central2
אם אתם מנסים ליצור מאגר צמתים של פרוסת TPU ב-us-central2 (האזור היחיד שבו TPU v4 זמין), יכול להיות שתצטרכו להגדיל את המכסות הבאות שקשורות ל-GKE כשאתם יוצרים מאגרי צמתים של TPU v4 בפעם הראשונה:
- מכסת דיסק מתמיד (persistent disk) מסוג SSD (ב-GB) באזור us-central2: דיסק האתחול של כל צומת Kubernetes דורש 100GB כברירת מחדל. לכן, צריך להגדיר את המכסה הזו לפחות בגובה של מכפלת המספר המקסימלי של צמתי GKE שאתם צפויים ליצור ב-
us-central2ב-100GB (maximum_nodesX100 GB). - מכסת כתובות IP בשימוש באזור us-central2: כל צומת Kubernetes צורך כתובת IP אחת. לכן, המכסה הזה צריך להיות לפחות גבוה כמו המספר המקסימלי של צמתי GKE שאתם צופים ליצור ב-
us-central2.
חסרה רשת משנה במהלך יצירת אשכול GKE
אם אתם מנסים ליצור אשכול ב-us-central2 (האזור היחיד שבו זמין TPU v4), יכול להיות שתיתקלו בהודעת שגיאה דומה לזו שמופיעה בהמשך:
ERROR: (gcloud.container.clusters.create) ResponseError: code=404,
message=Not found: project <PROJECT> does not have an auto-mode subnetwork
for network "default" in region <REGION>.
כדי לספק קישוריות לצומתי GKE, נדרשת רשת משנה ברשת ה-VPC. עם זאת, באזורים מסוימים כמו us-central2, יכול להיות שלא תיווצר רשת משנה שמוגדרת כברירת מחדל, גם אם משתמשים ברשת ה-VPC שמוגדרת כברירת מחדל במצב אוטומטי (ליצירת רשתות משנה).
כדי לפתור את הבעיה, צריך לוודא שיצרתם רשת משנה מותאמת אישית באזור לפני שיצרתם את אשכול GKE. רשת המשנה הזו לא יכולה לחפוף לרשתות משנה אחרות שנוצרו באזורים אחרים באותה רשת VPC.
הפעלת יציאת kubelet לקריאה בלבד
אם אתם משתמשים בגרסה של אשכול GKE שמוקדמת לגרסה 1.32, הקפידו לבדוק שהשדה insecureKubeletReadonlyPortEnabled מוגדר לערך true.
כדי לבדוק את הערך של השדה insecureKubeletReadonlyPortEnabled, אפשר לתאר את מאגר הצמתים:
gcloud container node-pools describe NODEPOOL_NAME --cluster=CLUSTER_NAME
אם הפלט כולל את insecureKubeletReadonlyPortEnabled: false, מפעילים את היציאה על ידי הרצת הפקודה הבאה:
gcloud container node-pools update NODEPOOL_NAME --cluster CLUSTER_NAME --enable-insecure-kubelet-readonly-port
בדוגמאות הבאות לשגיאות מוזכרת שגיאה בחיבור TCP ליציאה 10255, מה שמצביע על כך שייתכן שצריך להפעיל את היציאה.
error sending request: Get "http://gke-tpu-d32e5ca6-f4gp:10255/pods": GET http://gke-tpu-d32e5ca6-f4gp:10255/pods giving up after 5 attempt(s): Get "http://gke-tpu-d32e5ca6-f4gp:10255/pods": dial tcp [2600:1901:8130:662:0:19c::]:10255: connect: connection refused
failed to get TPU container Info: failed to call kubelet: Get "http://gke-tpu-d32e5ca6-f4gp:10255/pods": GET http://gke-tpu-d32e5ca6-f4gp:10255/pods giving up after 5 attempt(s): Get "http://gke-tpu-d32e5ca6-f4gp:10255/pods": dial tcp [2600:1901:8130:662:0:19c::]:10255: connect: connection refused
שגיאת חיבור בהרצת עומס עבודה של אימון עם JAX
אם אתם מנסים להפעיל את מסגרת JAX כדי להריץ עומס עבודה של אימון במכונות TPU, יכול להיות שתופיע הודעת שגיאה דומה לזו:
E0115 19:06:10.727412 340 master.cc:246] Initialization of slice failed with
error status: INVALID_ARGUMENT: When linking node TPU_ID:pe0:0
to TPU_ID:pe0:3</code> with link TPU_ID:pe0:0:p5:x couldn't find opposite link in destination node.; Failed to create the mesh (xW, xW, xW); Please make sure the topology is correct.;
Failed to discover ICI network topology
השגיאה הזו מתרחשת כש-GKE לא מצליח ליצור את הטופולוגיה של הרשת של חיבורים מהירים בין שבבים (ICI) על פני פרוסות גדולות של TPU.
כדי לפתור את הבעיה:
מזהים את חלקי ה-TPU שבהם מתרחשת שגיאת הקישוריות. כדי לראות את יומני האירועים, משתמשים בשאילתה הבאה:
resource.type="k8s_container" resource.labels.project_id=PROJECT_ID severity>=DEFAULT SEARCH("`[/dev/vfio/0` `TPU_ID` Driver `opened.`")מחליפים את מה שכתוב בשדות הבאים:
PROJECT_ID: מזהה הפרויקט.-
TPU_ID: המזהה של ה-TPU שבו מתרחשות שגיאות. מזהה ה-TPU מופיע בהודעת השגיאה.
הוספת כתם למאגר הצמתים או לאחד מהצמתים שמופיעים בהודעת השגיאה. מידע נוסף זמין במאמר בנושא הוספת תג ו-taint למאגר צמתים בשביל עומסי העבודה
מריצים מחדש את העבודה במאגר צמתים אחר.
אם הבעיה נמשכת, שלחו בקשת תמיכה או פנו לצוות ניהול החשבון.
צפייה ביומני TPU ב-GKE
כדי לראות את כל היומנים שקשורים ל-TPU עבור עומס עבודה ספציפי, אפשר להשתמש ב-Cloud Logging. זהו מיקום מרכזי לשליחת שאילתות ליומנים האלה כשהרישום ביומן של מערכת GKE ועומס העבודה מופעלים. ב-Cloud Logging, היומנים מאורגנים כרשומות ביומן, ולכל רשומה ביומן יש פורמט מובנה. הדוגמה הבאה היא רשומה ביומן של משימת אימון ב-TPU.
{
insertId: "gvqk7r5qc5hvogif"
labels: {
compute.googleapis.com/resource_name: "gke-tpu-9243ec28-wwf5"
k8s-pod/batch_kubernetes_io/controller-uid: "443a3128-64f3-4f48-a4d3-69199f82b090"
k8s-pod/batch_kubernetes_io/job-name: "mnist-training-job"
k8s-pod/controller-uid: "443a3128-64f3-4f48-a4d3-69199f82b090"
k8s-pod/job-name: "mnist-training-job"
}
logName: "projects/gke-tpu-demo-project/logs/stdout"
receiveTimestamp: "2024-06-26T05:52:39.652122589Z"
resource: {
labels: {
cluster_name: "tpu-test"
container_name: "tensorflow"
location: "us-central2-b"
namespace_name: "default"
pod_name: "mnist-training-job-l74l8"
project_id: "gke-tpu-demo-project"
}
type: "k8s_container"
}
severity: "INFO"
textPayload: "
1/938 [..............................] - ETA: 13:36 - loss: 2.3238 - accuracy: 0.0469
6/938 [..............................] - ETA: 9s - loss: 2.1227 - accuracy: 0.2995
13/938 [..............................] - ETA: 8s - loss: 1.7952 - accuracy: 0.4760
20/938 [..............................] - ETA: 7s - loss: 1.5536 - accuracy: 0.5539
27/938 [..............................] - ETA: 7s - loss: 1.3590 - accuracy: 0.6071
36/938 [>.............................] - ETA: 6s - loss: 1.1622 - accuracy: 0.6606
44/938 [>.............................] - ETA: 6s - loss: 1.0395 - accuracy: 0.6935
51/938 [>.............................] - ETA: 6s - loss: 0.9590 - accuracy: 0.7160
……
937/938 [============================>.] - ETA: 0s - loss: 0.2184 - accuracy: 0.9349"
timestamp: "2024-06-26T05:52:38.962950115Z"
}
לכל רשומת יומן מהצמתים של פרוסת ה-TPU יש את התווית compute.googleapis.com/resource_name, והערך שלה מוגדר כשם הצומת.
אם אתם רוצים לראות את היומנים של צומת מסוים ואתם יודעים את שם הצומת, אתם יכולים לסנן את היומנים לפי הצומת הזה בשאילתה. לדוגמה, השאילתה הבאה מציגה את היומנים מצומת ה-TPU gke-tpu-9243ec28-wwf5:
resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" = "gke-tpu-9243ec28-wwf5"
GKE מצרף את התוויות cloud.google.com/gke-tpu-accelerator ו-cloud.google.com/gke-tpu-topology לכל הצמתים שמכילים יחידות TPU. לכן, אם אתם לא בטוחים לגבי שם הצומת או שאתם רוצים לראות רשימה של כל הצמתים של חלקי ה-TPU, אתם יכולים להריץ את הפקודה הבאה:
kubectl get nodes -l cloud.google.com/gke-tpu-accelerator
פלט לדוגמה:
NAME STATUS ROLES AGE VERSION
gke-tpu-9243ec28-f2f1 Ready <none> 25m v1.30.1-gke.1156000
gke-tpu-9243ec28-wwf5 Ready <none> 7d22h v1.30.1-gke.1156000
אפשר לבצע סינון נוסף על סמך תוויות הצמתים והערכים שלהן. לדוגמה, הפקודה הבאה מציגה ברשימה צומת TPU עם סוג וטופולוגיה ספציפיים:
kubectl get nodes -l cloud.google.com/gke-tpu-accelerator=tpu-v5-lite-podslice,cloud.google.com/gke-tpu-topology=1x1
כדי לראות את כל היומנים בצמתים של חלקי ה-TPU, אפשר להשתמש בשאילתה שתואמת לתווית של הסיומת של צומת חלקי ה-TPU. לדוגמה, אפשר להשתמש בשאילתה הבאה:
resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*"
log_id("stdout")
כדי לראות את היומנים שמשויכים לעומס עבודה מסוים של TPU באמצעות Kubernetes Job, אפשר לסנן את היומנים באמצעות התווית batch.kubernetes.io/job-name. לדוגמה, כדי לראות את יומני STDOUT של המשימה mnist-training-job, מריצים את השאילתה הבאה:
resource.type="k8s_container"
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job"
log_id("stdout")
כדי לראות את היומנים של עומס עבודה ב-TPU באמצעות Kubernetes JobSet, אתם יכולים לסנן את היומנים באמצעות התווית k8s-pod/jobset_sigs_k8s_io/jobset-name.
לדוגמה:
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
כדי לבצע חיתוך עמוק יותר, אפשר לסנן לפי תוויות אחרות של עומסי עבודה.
לדוגמה, כדי להציג את היומנים של עומס עבודה עם כמה פרוסות מתוך worker 0 ופרוסה 1, אפשר לסנן לפי התוויות: job-complete-index ו-job-index:
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
labels."k8s-pod/batch_kubernetes_io/job-completion-index"="0"
labels."k8s-pod/jobset_sigs_k8s_io/job-index"="1"
אפשר גם לסנן באמצעות תבנית של שם ה-Pod:
resource.labels.pod_name:<jobSetName>-<replicateJobName>-<job-index>-<worker-index>
לדוגמה, בשאילתה הבאה, הערך של jobSetName הוא multislice-job והערך של replicateJobName הוא slice. הערכים של job-index וגם של worker-index הם 0:
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
resource.labels.pod_name:"multislice-job-slice-0-0"
בעומסי עבודה אחרים של TPU, כמו עומס עבודה של Pod יחיד ב-GKE, אפשר לסנן את היומנים לפי שמות Pods. לדוגמה:
resource.type="k8s_container"
resource.labels.pod_name="tpu-job-jax-demo"
כדי לבדוק אם הפלאגין של מכשיר ה-TPU פועל בצורה תקינה, אפשר להשתמש בשאילתה הבאה כדי לבדוק את יומני ה-container שלו:
resource.type="k8s_container"
labels.k8s-pod/k8s-app="tpu-device-plugin"
resource.labels.namespace_name="kube-system"
מריצים את השאילתה הבאה כדי לבדוק את האירועים שקשורים לבעיה:
jsonPayload.involvedObject.name=~"tpu-device-plugin.*"
log_id("events")
לכל השאילתות, אפשר להוסיף מסננים נוספים, כמו שם האשכול, מיקום ומזהה הפרויקט. אפשר גם לשלב תנאים כדי לצמצם את התוצאות. לדוגמה:
resource.type="k8s_container" AND
resource.labels.project_id="gke-tpu-demo-project" AND
resource.labels.location="us-west1" AND
resource.labels.cluster_name="tpu-demo" AND
resource.labels.namespace_name="default" AND
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" AND
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job" AND
log_id("stdout")
האופרטור AND הוא אופציונלי בין השוואות ואפשר להשמיט אותו. מידע נוסף על שפת השאילתות זמין במאמר מפרט שפת השאילתות של Logging.
אפשר גם לקרוא דוגמאות נוספות לשאילתות של יומנים שקשורות ל-Kubernetes.
אם אתם מעדיפים להשתמש ב-SQL באמצעות Observability Analytics, תוכלו למצוא דוגמאות לשאילתות במאמר שאילתת SQL באמצעות Observability Analytics. אפשר גם להריץ את השאילתות באמצעות Google Cloud CLI במקום באמצעות הכלי 'סייר היומנים'. לדוגמה:
gcloud logging read 'resource.type="k8s_container" labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" log_id("stdout")' --limit 10 --format json
המאמרים הבאים
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו להיעזר בקבלת תמיכה, כולל עצות בנושאים הבאים:
- פתיחת בקשת תמיכה באמצעות פנייה אל Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אתם יכולים גם להצטרף לערוץ Slack#kubernetes-engineכדי לקבל תמיכה מהקהילה. - דיווח על בעיות או שליחת בקשות להוספת תכונות באמצעות הכלי הציבורי Issue Tracker.