הגדרת JupyterHub: היכן נשברות מכסות GPU
הגדרת JupyterHub כברירת מחדל נראית תמימה: אימג' אחד, צומת עם מאיצים, כל מהנדס מרים שרת משלו ועובד. כל עוד יש צוות אחד, הסכימה מחזיקה מעמד.
ברגע שקבוצה שנייה-שלישית מתחברת לסביבה, סביבת פיתוח ML משותפת הופכת לאזור תחרות: אימון מודל תופס את כל המאיצים הזמינים ומחזיק בהם עד ה-epoch האחרון, והחוקר הבא רואה שהמשאב תפוס.
מכאן מתחילה הידרדרות מוכרת. מגבלות משאבים לצוותים לא הוגדרו, ולכן הפעלת notebook עם חיפוש היפר-פרמטרים שנשכח אוכלת את זיכרון המאיץ כולו. חלוקת GPU בין צוותים נשענת על הסכמות בעל פה בצ'אט, תור המשימות על המאיצים לא נבנה — הרצות או נופלות מחוסר זיכרון, או ממתינות ימים לשחרור. מהנדסים שוהים בחוסר מעש, ותוכנית הניסויים נדחית לא בשעות אלא בימים.
אובדן נפרד — העברה ידנית של תוצאות בין כלים. ארטיפקטים, מטריקות ופרמטרי הרצה נשארים בספריות מקומיות של notebook, מעבירים אותם ידנית, וחלק נעלם עם הפעלה מחדש של השרת. אי אפשר עוד להשוות בין שתי הרצות בין צוותים, ולשחזר תוצאה של אחר — על אחת כמה וכמה. בסופו של דבר אותה השערה נבדקת שוב, כי הדוח הקודם לא נמצא.
אנחנו מפרקים איך זה נסגר: מכסות על מאיצים לפי צוות ולפי משתמש, תור עם עדיפויות במקום תפיסת «מי ראשון», ומערכת מעקב ניסויים אחידה שאליה תוצאת ההרצה נשלחת אוטומטית.
מה נותן מתחם מנוהל: אפקטים מדידים
סביבת פיתוח מנוהלת נבדלת בכך שכל תכונה שלה נבדקת בלי פעולות ידניות של מנהל. להלן חמישה סעיפים שאנחנו סוגרים בהגדרת JupyterHub, ואיך נמדד האפקט.
סביבה מוכנה תוך דקות
סביבת העבודה עולה מפרופיל שנבנה מראש עם ענף הספריות הנדרש, ולא נבנית במקום מתלויות גולמיות. זמן הפעלת הסביבה יורד משעות לדקות, ומהנדס חדש נכנס לעבודה ביום הראשון.
בידוד משאבים בין צוותים
מכסות על מאיצים נספרות לפי קבוצות: צוות אחד לא תופס כרטיסים של אחרים ולא מפיל אימונים של אחרים. נעלם סוג התקלות בגלל עומס יתר על הצומת.
צריכת משאבים שקופה
רואים מי וכמה מחזיק מאיצים ואיפה יש חוסר מעש. עלות חוסר המעש של הקלאסטר מפסיקה להיות לא ידועה — מכסות לא מנוצלות נראות וניתן לחלקן מחדש.
ניסויים בלי העברה ידנית
פרמטרים, מטריקות וארטיפקטים נשלחים למערכת המעקב ישירות מה-notebook יחד עם גרסת הקוד. רישום הניסויים לא תלוי בכך אם החוקר זכר להעביר את התוצאות ידנית.
שחזור צפוי
הגדרות הסביבות והמכסות מתוארות באופן דקלרטיבי ונמצאות במאגר. אחרי תקלה הצומת חוזר לאותו מצב באופן משוחזר.
אפשרויות פריסה: השוואת גישות
בחירת האפשרות נקבעת לפי פרופיל העומס: כמה אנשים עובדים בו-זמנית, באיזו תדירות מופעלות משימות אימון כבדות והאם נדרש בידוד נתונים בין צוותים. אותו JupyterHub על צומת משותף ועל משאבים מופרדים מתנהג אחרת — על צומת משותף אימון אחד דוחק את כל האחרים, ואיתו נעלמות גם המטריקות ב-MLflow.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| צומת משותף | צוות קטן, שיאים נדירים, כולם עובדים עם אותם נתונים | משאב משותף: אימון כבד דוחק עמיתים, מכסות נקבעות ידנית, אין בידוד לפי נתונים |
| מתחם ייעודי לצוותים | כמה צוותים עם הרשאות גישה שונות ומערכי נתונים משלהם | יקר יותר לתחזוקה: מתחמים מתעדכנים בנפרד, סביבות נפרדות עם הזמן |
| מתזמן עם חלוקת עומס | עומס לא אחיד, יש תור משימות אימון והפעלות אינטראקטיביות | דורש עדיפויות ומגבלות מוגדרות, אחרת התור חוסם עבודה אינטראקטיבית |
| סכימת משאבים היברידית | אינטראקטיב נשמר על מתחם קבוע, אימון עובר למשאבים זמניים | נראות מורכבת יותר: יש לאסוף יומנים ומטריקות משני מקומות |
בפועל מתחילים מצומת משותף ומכסות קשיחות: זה מהיר וצפוי כל עוד הצוות קטן. ברגע שמופיע צוות שני או תור משימות, עוברים להפרדה — לפי מתחמים או דרך מתזמן. ניתוח פרופיל העומס הוא הצעד המרכזי: הוא קובע איפה תהיו בעוד חצי שנה, ולא היום.
הגדרת JupyterHub: שלבים מביקורת עד מסירה
סדר העבודה כמעט לא תלוי בגודל הצוות — שונה רק היקף המשאבים שצריך להקצות. להלן הרצף שבו אנחנו מובילים את ההטמעה: כל שלב נשען על הנתונים של הקודם, ולכן ביקורת שדולגה חוזרת כעבודה מחדש על סכימת המכסות.
- ביקורת עומס של צוותי ML. בודקים כמה אנשים עובדים בו-זמנית, אילו משימות דורשות מאיצים וכמה זמן חיים מפגשי החישוב. בפלט — פרופיל צריכה עם שעות שיא, ולא ממוצעים חודשיים.
- סכימת מכסות ותפקידים. מחלקים משאבים לפי קבוצות ותפקידים: חוקר, מהנדס, מנהל פלטפורמה. מכסות נקשר לפרופיל המשימה, ולא לאדם, — צוות חדש מקבל סביבה בלי עריכה ידנית של הגדרות.
- פריסת הסביבה. פורסים JupyterHub, מכינים אימג'ים לסטאקים טיפוסיים ובנפרד למשימות עם מאיצים, מפעילים עצירה אוטומטית של מפגשים לא פעילים. notebooks שנשכחו מפסיקים להחזיק משאבים בתור.
- חיבור מערכת רישום ניסויים. מקשרים את הסביבה למאגר ההרצות: פרמטרים, גרסאות נתונים וארטיפקטים נכנסים ליומן המשותף אוטומטית. התוצאה משוחזרת לפי רשומה, ולא לפי הזיכרון של המחבר.
- בדיקה תחת עומס שיא. משחזרים הפעלה בו-זמנית של מספר מקסימלי של מפגשים, בודקים את התנהגות המתזמן והמאגר, מודדים זמן תגובה. מתקנים מגבלות לפני המסירה, ולא אחרי התקלה הראשונה.
- מסירה והדרכת צוותים. מוסרים תיעוד, תבניות הרצה, ניתוח תקלות טיפוסיות ונוהל: איך לבקש משאבים, מי משנה מכסות, מה לעשות כשצומת נופל.
מה מוסרים לידיים: קונפיגורציות ונהלים
הגדרת JupyterHub לא מסתיימת בהפעלת השירות, אלא במסירת כל מה שדרוש לצוות הלקוח לתפעול עצמאי. ארטיפקטים שמים במאגר ומעצבים כך שמהנדס חדש יבין תוך יום, והשינויים יעברו דרך רוויו, ולא עריכות ישירות על השרת.
- קונפיגורציות סביבה — מניפסטים של פריסה, הגדרות פרוקסי ומאגר, קישור דומיין ותעודות; הפריסה חוזרת בפקודה אחת.
- סכימות חלוקת משאבים — פרופילים עם מכסות GPU וזיכרון, עדיפויות בין צוותים, מגבלות לפי משתמש ושחרור משאבים לא פעילים.
- מדיניות גישה ותפקידים — מנהל, חוקר, צופה, חיבור לספרייה הארגונית, מתן גישה לסודות ולנתונים חיצוניים.
- תבניות סביבה — אימג'ים עם גרסאות ספריות קבועות לאימון ולהרצת מודלים, הוראות להוספת חבילה משלך.
- חיבור ל-MLflow — כתובת שרת המעקב, מאגר ארטיפקטים, קישור ניסויים למחבר, כללים להעברת מודל למתחם העבודה.
- תיעוד הסביבה — מפת רכיבים, היכן לראות לוגים ומטריקות, תקלות טיפוסיות, מרווח במספר המשתמשים.
- נוהל הסלמת תקלות — רמות קריטיות, זמן תגובה, בעל ההחלטה, סדר חזרה לקונפיגורציה קודמת.
את המסירה סוגרים בהרצת תרחישים: משחזרים צומת מגיבוי, מבטלים גישה לעובד שעזב, מרימים אימון אחרי תקלה. הם עוברים בלי שאנחנו שם — המתחם התקבל.
מקרה בוחן: איך קיצרנו חוסר מעש בסביבה לצוותי AI
הלקוח — צוות מוצר בארבעה תחומים: מחקר מודלים, הכנת נתונים, הטמעה ותמיכה בשירותים פעילים. כולם חלקו מאגר אחד של מכונות עם מאיצים, והגישה ניתנה ידנית: בקשה בצ'אט, המתנה למשבצת, הגדרת סביבה למשימה מסוימת.
המחיר של סכימה כזו — חוסר מעש. מהנדס חדש חיכה לסביבת עבודה ימים, ומפגש תקוע יכול היה להחזיק מאיץ ימים שלמים, בעוד האחרים עומדים בתור. עוד סוג תקלות — אי-שחזוריות: סביבות נבנו ידנית, ותוצאת הניסוי לא חזרה על עצמה במכונה אחרת.
מה שינו
פרסנו JupyterHub כנקודת כניסה יחידה: כתובת אחת, כניסה דרך חשבון ארגוני, פרופילי סביבה מוכנים למשימות טיפוסיות. הצגנו תפקידים — חוקר, מהנדס, מנהל — עם הרשאות שונות ומערכי אימג'ים שונים, ומכסות על מאיצים לכל תחום. מפגשים לא פעילים משחררים משאבים אוטומטית, והרצות ומטריקות נכתבות למערכת מעקב ניסויים משותפת.
מטריקות לפני ואחרי
הזמן מהבקשה עד סביבת עבודה התקצר משני-שלושה ימים לדקות. חוסר מעש בגלל המתנה למשאבים ירד בערך פי חמישה, חלק ההרצות עם מטריקות שמורות עלה משליש לכמעט כולן. סוג התקלות «המאיץ תפוס במפגש של מישהו אחר» נעלם: מכסות ושחרור אוטומטי הסירו גם את התור וגם את המשא ומתן הידני על מכונות.
עבור המנהל זה שינוי תפקיד: במקום מוקדן שמחלק מכונות ידנית, הוא מגדיר מדיניות ואימג'ים. צוותים מקבלים התחלה צפויה, ומנהל התחום — תמונה גלויה של העומס לפי כל פרופיל.
MLflow כבר פרוס: איך לחבר את הסביבה?
שרת רישום ניסויים פרוס הוא מקור אמת מוכן: בו נמצאים הרצות, מטריקות וארטיפקטים שעליהם נשענות מסקנות הצוות. לכן את סביבת הפיתוח לא בונים מחדש ולא מעבירים, אלא מחברים למתחם פעיל כמשתתף נוסף. בסכימה הנוכחית שום דבר לא משתנה: השרת נשאר במקומו, המאגר — אותו מאגר, ההרשאות — כשהיו.
החיבור נעשה ברמת אימג' הסביבה: כתובת השרת וטוקן הגישה נקבעים במשתני סביבה ומוזרקים בעת ההפעלה. ה-notebook כותב הרצות לאותו מקום שאליו מוביל אותם שאר הצוות, ולא לקובץ מקומי שאף אחד לא ימצא אחר כך. אם השרת נמצא במתחם פנימי, מוסיפים נתיב פרטי — הסביבה רואה את השירות בלי לחשוף אותו החוצה.
ההיסטוריה לא הולכת לאיבוד: החיבור לא נוגע במאגר, הרצות חדשות נכתבות בנוסף לקיימות, והרשומות הקודמות נשארות זמינות להשוואה. שמות הפרויקטים ותיוג הניסויים נשמרים, ולכן אפשר לפתוח הרצה קודמת ולהמשיך אותה ישירות ב-notebook. תאימות בודקים לפני פריסה — בהרצת בדיקה ב-notebook אחד, תוך השוואת מטריקות וארטיפקטים בפאנל המשותף.
תאימות הכלים נסגרת בגרסאות ספריות: באימג' מקבעים את אותם ענפים שכבר משתמשים בהם המהנדסים, והכניסה נעשית דרך חשבון אחיד. סדר העבודה הרגיל נשאר — notebooks מופעלים כמו קודם, רק שכעת הם מקושרים לרישום ניסויים משותף. התוצאה — סביבת הפיתוח ומערכת הרישום עובדות כמתחם אחד, בלי העברת נתונים ובלי צבירה חוזרת של תוצאות.
ספקות טכניים: ניתוח שאלות נפוצות
ספקות בשלב ההטמעה נוגעים בדרך כלל לא להפעלה, אלא לתפעול: מה יקרה כשכמה צוותים עם עומס שונה יגיעו לאותו קלאסטר, מי יקבל מאיצים ראשון ומה יקרה לאימון שנמשך יומיים. להלן ניתוח לפי כל סעיף; כל זה נפתר במדיניות בקונפיגורציה, ולא בהתערבות ידנית של המנהל.
בודקים בפיילוט עם פרופיל עומס אמיתי: שניים-שלושה צוותים, צמתים מסוגים שונים והיסטוריית ניסויים מהמתחם הקודם. אם ההתנהגות שונה מהצפוי — מתקנים מדיניות לפני פריסה לכל הצי.
איך מחלקים מאיצים כשהמכונות פחות מהמעוניינים?
מכסה לקבוצה בתוספת עדיפות תור: מפגשים קצרים עוברים קודם, ארוכים נכנסים להמתנה ומקבלים התראה. המתזמן לא מוסר לצוות אחד את כל הצי, גם אם המפגשים שלו התחילו ראשונים.
צמתים מסוגים שונים מתוארים בפרופילי הפעלה נפרדים, ולכן הצוות בוחר בעצמו את המתאים, ולא תופס את החזק ביותר כברירת מחדל.
Notebook תקוע מחזיק מאיץ?
זמן החיים קשור לפעילות הליבה, ולא לרגע ההתחלה: שעות של חוסר פעילות סוגרות את המפגש, ותיקיית העבודה נשארת בדיסק. בנוסף — מגבלה על מספר מפגשים בו-זמנית למשתמש והתראה עם דחייה לפני עצירה, כדי שאף אחד לא יאבד תוצאת חישוב.
איך בנויה גישה לפי תפקידים?
קבוצות מהספרייה הארגונית נמשכות אוטומטית: מנהל מנהל אימג'ים ומכסות, חוקר מפעיל את המפגשים שלו, צופה רואה מטריקות בלי גישה לנתונים. סודות ניתנים ברמת הפרופיל ולא נכנסים למחברת; הפעולות נרשמות ביומן.
האם היסטוריית הניסויים מועברת?
הרצות מ-MLflow עוברות יחד עם פרמטרים, מטריקות וארטיפקטים. כתובת השרת מוזרקת לסביבה, ולכן הרצות קודמות נפתחות מ-notebooks חדשים בלי עריכות קוד — השוואת תוצאות לפני ואחרי המעבר נשארת תקינה.
בואו נדון במשימה: נבנה תוכנית לעומס שלכם
כדי לדון במשימה באופן ענייני ולחזור עם הערכת לוחות זמנים להטמעה, ולא עם מילים כלליות, אנחנו צריכים נתוני פתח להתחלה. חלק מהסעיפים נעבור יחד בשיחה, וחלק תכינו מראש — מזה תלויה דיוק תוכנית העבודה על הסביבה.
- פרופיל עומס. כמה מהנדסים עובדים בו-זמנית ואילו משימות דומיננטיות: אימון מודלים, כיוונון עדין או ניסויים קצרים. מכאן — קונפיגורציית הצמתים ומדיניות המכסות.
- מאיצים והרשאות. אילו מכונות הוקצו לחישוב, האם יש כוח פנוי ומי נותן גישה לקלאסטר. צריך איש קשר של מהנדס שיאשר מגבלות רשת.
- רישום ניסויים. האם אתם מנהלים יומן הרצות, גרסאות מודלים וארטיפקטים, והאם נדרש חיבור למאגר שכבר בשימוש. אם ההיסטוריה נצברה — נחליט אם להעביר אותה או להתחיל מחדש.
- הרשאות ותפקידים. למי מותרים אילו משאבים, האם נדרשות מכסות לפי פרויקטים, מי מנהל משתמשים ואיך מבטלים גישה כשעובד עוזב.
- נתונים. היכן נמצאים מערכי הנתונים, מה הנפח שלהם והאם אפשר להעביר אותם בין מתחמים. זה קובע את סכימת הרכבת המאגרים לסביבות העבודה של JupyterHub.
- גבולות הפרויקט. מי מקבל החלטות מצד הלקוח, חלון ההפעלה הרצוי ומה נחשב לתוצאת האיטרציה הראשונה.
לסיום השיחה נחזור עם הערכת לוחות זמנים ותוכנית עבודה על הסביבה: שלבים, תחומי אחריות, סדר בדיקה. אישור היקף העבודה מקבעים בכתב לפני ההתחלה — כך ההפעלה הראשונה עוברת בלי עבודה מחדש.







