כשמריצים עומסי עבודה של אימון או הסקה בקנה מידה גדול ב-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 slice שצורכת הזמנת 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.
כדי לבדוק את המגבלה ואת השימוש הנוכחי במכסת Compute Engine API עבור TPU:
נכנסים לדף 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 יוצר את המשאבים שלכם.
- מכסת SSD של Persistent Disk (GB): דיסק האתחול של כל צומת Kubernetes דורש 100GB כברירת מחדל. לכן, צריך להגדיר את המכסה הזה לפחות בגובה של מכפלת מספר הצמתים המקסימליים של GKE שאתם צופים ליצור ב-100GB (צמתים * 100GB).
- מכסת כתובות IP בשימוש: כל צומת Kubernetes צורך כתובת IP אחת. לכן, צריך להגדיר את המכסה הזו לפחות כמספר המקסימלי של צמתי GKE שאתם צפויים ליצור.
- מוודאים ש-
max-pods-per-nodeתואם לטווח של רשת המשנה: כל צומת Kubernetes משתמש בטווחים משניים של כתובות IP עבור קבוצות Pod. לדוגמה,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 slice בגלל חוסר קיבולת. GKE יוצר את הצמתים כשהקיבולת הופכת לזמינה.
אם יוצרים מאגר צמתי TPU slice עם מארח יחיד, הודעת השגיאה תיראה בערך כך:
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 יוצר את הצמתים שלא נוצרו.
אם אתם צריכים קיבולת מוקדם יותר, כדאי לנסות מכונות וירטואליות מסוג Spot. שימו לב שמכונות וירטואליות מסוג Spot צורכות מכסה שונה ממכסות של מכונות וירטואליות על פי דרישה.
כדי למחוק את בקשת ה-TPU שהוכנסה לתור, צריך למחוק את מאגר הצמתים של פרוסת ה-TPU.
אין מספיק משאבי TPU כדי למלא את בקשת ה-TPU
שגיאה שמכילה את GCE_STOCKOUT מציינת שמשאבי TPU לא זמינים באופן זמני כדי למלא את הבקשה. מערכת GKE תמלא את בקשת ההקצאה כשהמשאבים של TPU יהיו זמינים.
כדי לפתור את הבעיה, אפשר להשתמש באחת מאפשרויות הצריכה הבאות:
- Flex-start: כדי להקצות מכונות וירטואליות מסוג Flex-start למשך עד שבעה ימים, כאשר GKE מקצה את החומרה באופן אוטומטי על בסיס הזמינות. מידע נוסף זמין במאמר מידע על הקצאת GPU, TPU ו-H4D במצב הקצאה עם הפעלה גמישה.
- מכונות וירטואליות (VM) זמניות מסוג Spot: כדי להקצות מכונות וירטואליות זמניות מסוג Spot, אפשר לקבל הנחות משמעותיות, אבל המכונות האלה יכולות להיפסק בכל שלב, עם אזהרה של 30 שניות מראש. מידע נוסף זמין במאמר בנושא מכונות וירטואליות מסוג Spot.
- מקום שמור לעתיד ל-90 יום (במצב יומן): כדי להקצות משאבי TPU לתקופה של עד 90 יום, לתקופה מוגדרת. מידע נוסף זמין במאמר בנושא שליחת בקשה ל-TPU עם מקום שמור לעתיד במצב יומן.
- הזמנות של TPU: כדי לבקש מקום שמור לעתיד למשך שנה או יותר.
- על פי דרישה: כדי לצרוך TPU בלי לתכנן מראש את הקיבולת. לפני שמבקשים משאבים, צריך לוודא שיש מספיק מכסת שימוש לפי דרישה לסוג ולכמות הספציפיים של מכונות וירטואליות של TPU. האפשרות 'על פי דרישה' היא האפשרות הכי גמישה לשימוש במשאבים, אבל אין ערובה לכך שיהיו מספיק משאבים על פי דרישה כדי לספק את הבקשה שלכם.
אם לא מציינים אפשרות אחרת, מודל הצריכה שמוגדר כברירת מחדל ל-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 שחורג ממגבלות המשאבים, ביומני הנראות של Cluster Autoscaler מוצגת הודעת השגיאה הבאה:
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, ליבות CPU וזיכרון באשכול.
כדי לבצע את השלבים האלה:
- חישוב דרישות המשאבים לסוג מכונה ולמספר מסוים של 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 שאינם 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 עם מארח יחיד או עם כמה מארחים. כדי לצמצם את הבעיות שקשורות לקיבולת, אפשר להשתמש בהזמנות או במכונות וירטואליות מסוג 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 הזמינים במאגר צמתים של חלקי TPU מוסבר איך פורסים עומסי עבודה של TPU ב-GKE.
שגיאות בתזמון כשפורסים Pods שצורכים TPU ב-GKE
הבעיה הבאה מתרחשת כש-GKE לא מצליח לתזמן בקשות של Pods ל-TPU בצמתים של חלקי TPU. לדוגמה, זה יכול לקרות אם חלק מאשכולות TPU Pods כבר תוכננו בצמתי 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 בתוך מאגר התגים.
קיפאון בתזמון
יכול להיות שתזמון של שתי משימות או יותר ייכשל בגלל קיפאון (deadlock). לדוגמה, בתרחיש שבו מתרחשים כל הדברים הבאים:
- יש לכם שני ג'ובים (Job A ו-Job B) עם כללי זיקה של Pod.
GKE מתזמן את חלקי ה-TPU לשתי המשימות עם טופולוגיית TPU של
v4-32. - יש לכם שני חלקי TPU
v4-32באשכול. - ל-TPU שלכם יש מספיק קיבולת לתזמון של שני סוגי העבודות, ותיאורטית, אפשר לתזמן כל עבודה במהירות בכל פרוסת TPU.
- מתזמן Kubernetes מתזמן Pod אחד ממשימה א' בפרוסת זמן אחת, ואז מתזמן Pod אחד ממשימה ב' באותה פרוסת זמן.
במקרה הזה, בהתאם לכללי הזיקה של ה-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 בהודעת השגיאה.
הוספת כתם למאגר הצמתים או לאחד הצמתים שמופיעים בהודעת השגיאה. מידע נוסף זמין במאמר בנושא הוספת מאפיינים ותווית למאגר צמתים לעומסי העבודה
מריצים מחדש את העבודה במאגר צמתים אחר.
אם הבעיה נמשכת, אפשר לפתוח בקשת תמיכה או לפנות לצוות ניהול החשבון.
צפייה ביומני GKE TPU
כדי לראות את כל היומנים שקשורים ל-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, אפשר לסנן את היומנים לפי שמות ה-Pod. לדוגמה:
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 הוא אופציונלי בין השוואות ואפשר להשמיט אותו. מידע נוסף על שפת השאילתות זמין במאמר מפרט שפת השאילתות של רישום ביומן.
אפשר גם לקרוא שאילתות יומן שקשורות ל-Kubernetes כדי לראות עוד דוגמאות לשאילתות.
אם אתם מעדיפים להשתמש ב-SQL באמצעות Log Analytics, תוכלו למצוא דוגמאות לשאילתות במאמר שאילתת SQL באמצעות Log Analytics. אפשר גם להריץ את השאילתות באמצעות Google Cloud CLI במקום באמצעות הכלי Logs Explorer. לדוגמה:
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כדי לקבל תמיכה נוספת מהקהילה. - פתיחת באגים או בקשות להוספת תכונות באמצעות הכלי הציבורי למעקב אחר בעיות.