מדוע GPU ב-Kubernetes עומדת ללא שימוש ומכשילה שחרורים
האשכול מדווח על עומס מלא של מאיצים, וחצי ממשימות האימון ממתינות בתור כבר יומיים. הסיבה היא שהמתזמן רואה צומת שלם, ולא מאיץ בודד: משימה תופסת כרטיס באופן בלעדי ומחזיקה בו גם במקום שבו היה מספיק חלק יחסי.
ואז נכנסת אי-האחידות. משימה אחת מבקשת הרבה זיכרון מאיץ ומעט ליבות חישוב, אחרת להפך, ואי אפשר לסדר אותן יחד על צומת אחד: פורמלית יש משאבים פנויים, בפועל הצומת לא עומד באחד הממדים. חלק מהצמתים עומדים ללא שימוש, חלקם עמוסים מדי, זמן הבטלה של המאיצים גדל, ותפוקת האשכול יורדת.
מעל זה, אימון ואינפרנס מתחרים על אותם כרטיסים. אינפרנס עובד עם שיאים ושאילתות קצרות, אימון — עם משימות ארוכות שיקר להפסיק: אובדן נקודת ביקורת פירושו הפעלה מחדש מהשמורה האחרונה ושעות אבודות. בלי עדיפויות ומכסות מנצח מי שהגיע ראשון, ולא מי שקרוב לדדליין.
מדדי עומס לפי צמתים לא מציגים תמונה כזו — צריך פירוט לפי כל מאיץ ולפי תור המשימות, אחרת מחפשים את צוואר הבקבוק במקום הלא נכון. תוצאת הטעות נראית בלוח הזמנים: אימון המודל נכשל בעמידה בלוחות זמנים, מהנדסים ממתינים שבועות לשחרור כרטיס, והתור מפסיק להיות ניתן לניהול. נבחן כיצד זה נסגר.
מה נותן תזמון מאיצים מנוהל
המתזמן כברירת מחדל מסתכל על המשאבים הפנויים של הצומת ומציב משימה על הראשון שמתאים. בעומס מעורב — אימון, הסקת מודל, הכנת נתונים — זה יוצר עיוות: חלק מהמאיצים עמוסים עד הקצה, אחרים עומדים ללא שימוש, והמשימה תלויה בתור ומחכה לשחרור של הצומת ה"לא נכון".
תזמון מנוהל מתחיל בכך שהצמתים מקבלים תוויות ברורות: דגם המאיץ, נפח הזיכרון, זמינות לצוותים מסוימים. לאחר מכן מוגדרות דרישות משאבים ועדיפויות תורים — בקשה קצרה להסקת מודל לא עומדת אחרי אימון של שעות רבות ולא חוסמת את האחרים.
האפקט מדיד: שיעור התפוסה של המאיצים מתאזן בין הצמתים, זמן ההמתנה הממוצע למשימה יורד, ותפוקת האשכול עולה באותה תצורת חומרה — בלי רכישה נוספת. בנפרד נעלם סוג הכשלים "הצומת תפוס על ידי תהליך זר": משימה כבר לא נוחתת במקום שבו הזיכרון כבר נתפס על ידי שכן, ולא נופלת בהתחלה.
הבסיס של סכמה כזו — NVIDIA GPU Operator: הוא מביא דרייברים, תוויות התקנים וחשבונאות משאבים לצורה אחידה, ולכן המתזמן רואה תמונה אמיתית של המאיצים, והעדיפויות פועלות בפועל, ולא לפי הערכה מקורבת.
מצבי הקצאת GPU ב-Kubernetes: מה לבחור
מצב הגישה למאיצים נקבע לא במניפסט של הפוד, אלא ברמת תוסף ההתקנים והמתזמן. המתזמן רואה את המאיץ כמשאב מורחב: כמה יחידות הכריז הצומת, כל כך הרבה פודים הוא ישבץ. מכאן נובעים ישירות צפיפות האריזה, פיזור השהיות, והאופן שבו השירותים יתנהגו כשתהליך אחד ייקח את כל הזיכרון.
להלן ארבעה וריאנטים שבאמת בוחרים ביניהם. NVIDIA GPU Operator פורש דרייברים ותוסף התקנים, אבל את מצב הגישה עצמו אתם מגדירים בתצורה.
| מצב | כיצד בנוי | מתי מתאים | מגבלות |
|---|---|---|---|
| גישה בלעדית למאיץ | הצומת מכריז על התקנים שלמים, המתזמן מוסר אותם לפוד אחד בכל פעם | אימון וכיוונון עדין: נדרשים כל הזיכרון ורוחב הפס | המאיצים עומדים ללא שימוש בין משימות, התור גדל, הצפיפות נמוכה |
| שיתוף GPU לפי זמן | כמה פודים מחלקים בתורם התקן אחד באמצעות הגדרת התוסף | אינפרנס קל, סביבות אינטראקטיביות, דיבאג | אין בידוד לפי זיכרון ובלוקים חישוביים — שכן משנה את ההשהיה, כשל של תהליך פוגע באחרים |
| פיצול המאיץ לאינסטנסים מבודדים | לכל פוד — חלק משלו מהזיכרון ומהבלוקים החישוביים עם בידוד חומרה | אינפרנס צפוף שבו חשובה יכולת חיזוי תחת שיא | לא כל דגמי המאיצים תומכים, מערך הפרופילים קבוע, משימות גדולות זקוקות לכרטיס שלם |
| בידוד לפי צמתים | מאגרים נפרדים עם תוויות וכללי שיבוץ: אימון והגשה לא מצטלבים | אשכולות מעורבים שבהם אימון לא צריך להפריע להגשה | המאגר עומד ללא שימוש בין הרצות, הניצולת יורדת, נדרש בקרת לוחות זמנים |
המצבים משולבים: אימון — בלעדית במאגר שלו, אינפרנס — בשיתוף או לפי אינסטנסים. את הבחירה בודקים על פרופיל עומס אמיתי, אחרת אריזה צפופה תתהפך לעלייה בהשהיות דווקא תחת שיא.
כיצד אנו מיישמים תזמון מאיצים: שלבים
סדר העבודות בנוי כך שלא נצטרך לבטל שינויים אחרי העומס הרציני הראשון. מתחילים במיפוי, ומסיימים בנהלים לצוות שיישאר לעבוד עם האשכול. כל שלב נסגר בארטיפקט שניתן לבדוק — תרשים, תצורה או דוח הרצה.
- ביקורת אשכול ומיפוי עומסים. אוספים אילו משימות מבקשות מאיצים, כמה זמן הן חיות, כמה התקנים הן מחזיקות וכמה עומדים ללא שימוש. מתעדים חלונות שיא ומקומות שבהם התור כבר גדל.
- תרשים שיבוץ משימות. מחלקים את האשכול לקבוצות צמתים לאימון, הסקה ועיבוד אצווה, מגדירים פרופילי התקנים ומכסות כדי שצוות אחד לא יתפוס את כל המאיצים.
- הגדרת המתזמן. מתקינים NVIDIA GPU Operator — דרייבר, תוסף התקנים ומדדים מתעדכנים כיחידה אחת. לאחר מכן עדיפויות, תוויות וכללי שיבוץ שלפיהם משימה מגיעה רק לצומת מתאים.
- בדיקת עמידות בתקלות. בתורם מוציאים צומת מכלל פעולה, מפילים דרייבר, נתקלים במגבלת זיכרון המאיץ — בודקים אם המשימה מתוזמנת מחדש ואם היא גוררת איתה שכנים.
- הרצה על עומס אמיתי. מריצים תרחישים של הלקוח על נפחים מבצעיים, משווים זמן משוער לזמן בפועל ומתקנים מגבלות במקומות שבהם המתזמן מחזיק משימה בתור בלי סיבה.
- מסירה לתפעול. מוסרים תרשים אשכול, תצורות, כללי מכסות, מערך התראות והוראות לתורנים — ומנתחים עם הצוות כשלים אופייניים.
תיעוד, מניפסטים ונהלים בפלט
אנו מוסרים לא רק אשכול עובד, אלא גם ערכה מלאה של חומרים שלפיהם הצוות שלכם יוכל לתפעל, להרחיב ולעדכן אותו בלעדינו. הכול נמצא במאגר שלכם לצד המניפסטים — באותם ענפים ובאותה היסטוריית שינויים כמו תצורות העבודה.
- תצורות מתזמן — מניפסטים עם מדיניות שיבוץ משימות, שריון מאיצים לעומסים מסוימים ועדיפויות לתורי אימון והסקת מודלים.
- תרשים אשכול — טופולוגיית צמתים עם מאיצים, חלוקה למאגרים, אזורי תקלה וקשרים בין שירות התזמון, האחסון ומערכת הניטור.
- מדיניות גישת צוותים — הפרדת מרחבי שמות, מכסות למאיצים ותפקידים: מי יכול להריץ אימון, מי לשנות הגדרות כלליות, מי רק לצפות במדדים.
- הוראות למהנדס תורן — מה לבדוק בעת דגרדציה, כיצד למצוא משימה שמחזיקה מאיץ, כיצד להוציא צומת לתחזוקה ולהחזירו לעבודה.
- נוהל עדכון — סדר החלפת דרייברים וגרסאות NVIDIA GPU Operator: תחילה מאגר בדיקות, אחר כך מוגבל, ואז כל האשכול, עם קריטריוני ביטול מוגדרים מראש.
- קטלוג מדדים וכללי התראות — אילו מדדי מאיצים, תורים וצמתים נחשבים לנורמה ובאיזה רגע התורן מקבל אות, ולא רעש.
- יומן החלטות — מדוע נבחר פרופיל תזמון כזה, אילו מגבלות הוא מטיל ומה לשנות עם גידול בעומס או החלפת ציוד.
כל מסמך מקושר לגרסת התצורה: כשמשתנה המניפסט מתעדכן גם התיאור. בעוד חודש הצוות שלכם קורא לא התכתבות, אלא מקור עדכני — ומבצע תיקונים בעצמו.
מקרה בוחן: תור המשימות הפסיק לחכות לשחרור המאיץ
הלקוח החזיק אימון מודלים והסקה באשכול Kubernetes אחד, שבו המאיץ ניתן כצומת שלם תחת משימה אחת. המתזמן לא ראה כמה זיכרון פנוי בהתקן, ולכן התור נבנה גם כשחלק מהמאיצים עמדו ללא שימוש. משימות נפלו בהתחלה עם שגיאה על משאב תפוס, והיה צריך להפעיל אותן מחדש ידנית.
הפרדנו פרופילי התקנים לאימון ולהסקה, הפעלנו עדיפויות תורים ובדיקת זמינות המאיץ לפני הפעלת הקונטיינר. משימות קטנות הועברו לפרופילים משותפים — הן כבר לא תופסות התקן שלם במקום שבו מספיק חלק ממנו. משימות בעדיפות גבוהה מפנות נמוכות-עדיפות, ולא מחכות עד שהצומת יתפנה כולו.
מדדים לפני ואחרי
| מדד | לפני | אחרי |
|---|---|---|
| עומס מאיצים | 40–50% | 82–88% |
| המתנה של משימה בתור | עד 6 שעות | 15–20 דקות |
| משימות שנפלו בגלל צומת תפוס | כל חמישית | בודדות |
בנפרד הגדרנו נראות: לפי כל צומת רואים עומס, מצב משימות וסיבות כשלים, ולכן הדגרדציה מורגשת לפני שהתור נעצר. החזרה לפרופיל הקודם אורכת דקות ואינה דורשת בנייה מחדש של האשכול.
במה שונה גישה משותפת למאיץ מגישה אישית?
מודל הגישה עונה על שאלה אחת: האם המשימה מקבלת את כל המאיץ או חולקת אותו עם שכנים. בבעלות בלעדית הזיכרון והבלוקים החישוביים אינם מנוצלים מחדש על ידי משימות אחרות — זמן התגובה תלוי רק בעומס עצמו. גישה משותפת, להפך, מעלה את הניצולת: מאיץ שעומד ללא שימוש בין שלבי העיבוד נמסר לאחרים.
הקנס על שיתוף מתבטא לא בביצועים ממוצעים, אלא ביכולת לחזות את זמן התגובה. כשכמה משימות חולקות זיכרון ותור חישוב, נוצרת תחרות: משימה כבדה אחת מעלה את זמן התגובה אצל כל השכנים, ואחוזוני הזנב גדלים מהר יותר מהממוצע. בידוד משימות מסיר את האפקט הזה — אבל במחיר בטלה של המשאב בין שלבים.
הבחירה נקבעת לפי פרופיל העומס, ולא לפי הרצון לחסוך: לאימון והסקה עמוסה — בידוד, לצי שירותים קטנים — חלוקה עם הגבלת חלק הזיכרון. ב-NVIDIA GPU Operator מצב הגישה נקבע במדיניות ברמת מאגר הצמתים, ולכן אפשר להעביר את אותה פלטפורמה בין מצבים בלי לבנות מחדש את היישומים.
ספקות טכניים לפני תחילת העבודה
חלק מהשאלות עולות עוד לפני ההתחלה: האשכול כבר עובד, חלק מהצמתים מוגדרים ידנית, ואף אחד לא מוכן לשנות הכול "ביום אחד". להלן מה שבדרך כלל דנים בו בשלב ההערכה.
האשכול כבר מוגדר חלקית — לבנות מחדש מאפס?
לא. תחילה מיפוי: אילו צמתים נושאים GPU, אילו דרייברים ותוויות מותקנים עליהם, מי ואיך מציב משימות. לאחר מכן מביאים את הצמתים למצב אחיד בזה אחר זה — מוציאים מתזמון, מעבירים עומס ומחזירים כבר תחת ניהול האופרטור. האשכול מחשב משימות כל הזמן הזה.
האם נצטרך לשנות קוד של מודלים?
ככלל, לא. משתנה תיאור ההרצה: בקשת משאב, מגבלות, עדיפות, שיוך לסוג צומת. סקריפטים לאימון ושירותי הסקה נשארים כשהיו — די לארוז אותם מחדש ולהעביר לכללי הרצה חדשים.
כיצד להגביל גישה למשאבים יקרים?
באמצעות מכסות ועדיפויות: מרחבי שמות עם מגבלות על מספר GPU, מדיניות ברירת מחדל, מחלקות עדיפות נפרדות לפרודקשן ולניסויים. משימה בלי בקשת משאב מפורשת לא תגיע לצומת GPU, וניסוי כבד לא יפנה שירות.
מה יקרה בכשל של צומת עם GPU?
הצומת מסומן כלא זמין, הפודים שלו מתוזמנים מחדש לצמתי GPU פנויים עם תוויות מתאימות, אימונים שלא הושלמו מופעלים מחדש מנקודת הביקורת האחרונה. השחזור אורך דקות במקום ניתוח ידני, והקיבולת נשמרת כך שהפרודקשן לא יישאר בלי משאב.
נדון במשימה: מה להבהיר לפני ההתחלה
הערכה של פרויקט כזה מתגבשת מהר כשמלפני ההתחלה ברורים הנתונים: פרופיל עומסים, אופן עבודת הצוותים, דרישות לזמן תגובה ומצב האשכול הנוכחי. להלן רשימה של מה שכדאי להבהיר מראש: איתה אנו חוזרים עם תוכנית עבודה, ולא עם שרשרת שאלות הבהרה.
- פרופיל עומסים. מה בדיוק מבוצע — אימון, אימון מחדש או הסקת מודלים; יחס בין המצבים, עומס ממוצע ושיא של מאיצים, דרישות זיכרון לתהליך אחד.
- צורת הרצת משימות. מי ואיך מציב אותן: חוקרים ידנית, שירות לפי לוח זמנים או מערכת חיצונית. מזה תלוי אם נדרשות מכסות לפי צוותים ומרחבי שמות נפרדים.
- דרישות לזמן תגובה. זמן המתנה מותר בתור, מהירות יציאת משימה למאיץ, עדיפויות, נכונות לפנות משימות בעדיפות נמוכה למען דחופות.
- מצב נוכחי. Kubernetes והטופולוגיה שלו, הרכב הצמתים, רכיבים פרוסים לעבודה עם מאיצים, אופן התקנת דרייברים ומידת החזרתיות של התצורה.
- נתונים ורשת. היכן נמצאים מערכי נתונים, נקודות ביקורת וארטיפקטים של מודלים, כמה מהר קוראים אותם, והאם רוחב הפס בין הצמתים מספיק.
- הרשאות ובקרה. מי הבעלים של שינויים, כיצד מופרדות זכויות, מה נדרש לתעד ביומן ואילו בדיקות חובה לפני פריסה.
- מסירה לצוות. למי עוברת התפעול — לצוות פלטפורמה או לחוקרים, האם נדרשים נהלים, תרשימים והדרכת תורנים.
לאחר מכן סדר העבודות הוא בדרך כלל: ניתוח הנתונים והתצורה הנוכחית, פיילוט עם צוות אחד, ואז הרחבה לשאר. תארו את המשימה בגבולות האלה — נחזור עם הערכה, לוחות זמנים ותוכנית מסירה.







