פריסת LLM על Kubernetes: היכן הפרודקשן נשבר תחת עומס
האשכול מחזיק בשלווה עומס הדגמה, אך מתפרק כבר בהתפרצות הראשונה: הקריאות מצטברות בתור הבקשות למודל, זמן התגובה גדל באופן לא ליניארי, וחלק מהפניות נושרות בגלל חריגת זמן המתנה.
הסיבה בדרך כלל אינה המודל עצמו — בעת פריסת LLM על Kubernetes נחשף מחסור במשאבים, שאין אותם בסביבה, או שהם כבר תפוסים על ידי משימות אחרות.
מאיצים הם משאב נדיר ובלתי ניתן לחלוקה. אם ההתקנים מרוכזים בצומת אחד, אימון, כיוונון עדין והסקה מתחרים עליהם: המתזמן מחזיק את רפליקות השירות בהמתנה, התור גדל, והידרדרות בזמן התגובה מופיעה כבר בתעבורה מתונה. סקיילינג כאן לא עוזר — אי אפשר להוסיף רפליקות בלי מאיצים פנויים.
נקודת כשל נפרדת היא התנגשות עדכונים בסביבה. פריסת גרסה חדשה של המודל והשירותים הנלווים מתבצעת לאותו אשכול שאליו מגיעה תעבורת העבודה, ובמהלך החימום תפוקת המערכת יורדת.
ללא בידוד בין סביבות, עומסי בדיקה ועומסי פרודקשן חולקים את אותם התקנים, ולכן ניסוי של מהנדס אחד הופך לתקרית אצל הלקוח.
כל התקלות האלה צפויות מראש, וכל אחת מהן נפתרת באמצעות קונפיגורציה, ולא באמצעות גבורה של תורן: מאגרי צמתים נפרדים, סדרי עדיפויות בתורים, אסטרטגיית פריסה עם חימום ונסיגה מהירה. בהמשך נסביר כיצד זה נסגר בפועל — מתכנון קיבולת ועד נוהל עדכונים.
מה נותן הסקה מנוהלת תחת עומס שיא
הסקה מנוהלת היא מצב שבו רפליקות המודל פועלות על צמתי GPU בניהול אורקסטרטור, והתעבורה מגיעה דרך נקודת כניסה אחודה. המתזמן מאתר בעצמו מאיצים פנויים, מרים רפליקה חדשה לצד זו שכבר מחזירה תשובות, ומסיר אותה כשהתור מתרוקן. הפריסה מפסיקה להיות פעולה ידנית על מכונה מסוימת והופכת לתיאור הצהרתי של המצב הרצוי.
זמן תגובה יציב נשען לא על הממוצע, אלא על הזנב של ההתפלגות. הסקיילינג מבוצע לפי עומק התור ותפוסת המאיץ, ולא לפי עומס המעבד: רפליקה מתווספת לפני שהבקשות מתחילות להמתין בבאפר. לכן אחוזון 95 נשאר בטווח שהוגדר גם בהתפרצות וגם בשעות שקטות.
שיעור הבקשות המוצלחות עולה משום שכשל מפסיק להיות טוטאלי. בדיקות מוכנות אינן מכניסות תעבורה לרפליקה שעדיין לא חוממה, מופעים לא תקינים מוצאים מאיזון, וזמני המתנה וניסיונות חוזרים מכוונים כך שהלקוח יקבל תשובה ולא שגיאה.
פריסה אוטומטית של גרסת מודל מתבצעת בתרחיש קנרי: הבנייה החדשה מקבלת חלק קטן מהתעבורה, מדדי האיכות והשהיה מושווים לנוכחיים, ורק אז חלק זה גדל. נסיגה היא חזרה לתמונה הקודמת, בלי לבנות מחדש את הסביבה ובלי תיקונים ידניים.
הצד השני של אותו מנגנון הוא צמצום פעולות תפעול ידניות. אתחולים בלילה, הוספה ידנית של צמתים לפי עומס ותיקון קונפיגים עוברים למדיניות הצהרתית, והמהנדס עוסק במודל ולא בתורנות.
אפשרויות פריסה של מודלים: השוואת מצבים
מצב הפריסה קובע כיצד האשכול מחלק מאיצים בין מודלים וכיצד המערכת מתנהגת בשיא. הבחירה תלויה במספר המודלים, בדרישות לבידוד עומסים ובחיזוי התעבורה: מעבר בין אפשרויות לאחר ההפעלה כואב יותר מאשר לבחור מלכתחילה את המתאימה.
השוואת מצבים
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| צומת בודד עם מאיצים | מודל אחד או שניים, סביבה פנימית, הרצת הוכחה ראשונית | אין בידוד עומסים: בקשה כבדה למודל אחד מחלישה את זה שלצדו; סקיילינג רק כלפי מעלה, והתקרה היא משאב הצומת |
| מאגר מאיצים משותף | מספר מודלים עם פרופיל עומס שונה ושיא משותף בזמן | נדרשים מכסות, סדרי עדיפויות לפינוי ומגבלות למודל; שכן רועש נשאר סיכון, וכשל של צומת אחד פוגע בכולם |
| קבוצה ייעודית למודל | מודלים בפרודקשן עם דרישות נוקשות לתגובה ונתונים רגישים | בעומס נמוך המאיצים עומדים ללא שימוש; יקר יותר לתחזוקה, אך כשל מוגבל למודל אחד |
| מודל המתפרס על פני כמה צמתים | משקל המודל אינו נכנס לצומת אחד, או שנדרש מרווח לבקשות מקבילות | תקשורת בין הצמתים מוסיפה השהיה; קשה יותר לתכנן עמידות בכשלים ועדכונים |
בפועל מתחילים במאגר משותף: הוא מעניק גמישות ומאפשר למדוד את פרופיל הבקשות האמיתי. קבוצה ייעודית מקימים עבור מודל אחד או שניים, שבהם מחיר הנפילה גבוה מעלות המאיצים שעומדים ללא שימוש, ואת בידוד העומסים מחזקים באמצעות מרחבי שמות נפרדים, מכסות וסדרי עדיפויות.
כדאי לקבוע מראש את מגבלות הסקיילינג — לפי איזה סימן עומס עובר לקבוצה נפרדת ומה קורה בעת כשל של צומת.
שלבי יישום: מביקורת הסביבה ועד למסירה
פריסת מודל באשכול אינה התקנה של שירות בודד, אלא רצף שבו כל שלב נשען על זה שלפניו. אם מדלגים על הביקורת ועוברים מיד לכיול, הסכימה תתפרק בשינוי הראשון של פרופיל העומס: התורים גדלים, המאיצים עומדים ללא שימוש, והנסיגה נבנית תחת לחץ. להלן סדר העבודות שאנו חוזרים עליו בכל פרויקט.
- ביקורת סביבת ההסקה של המודלים — מלאי: אילו מודלים ומשקלים בשימוש, היכן הם פועלים כעת, פרופיל הבקשות, מגבלות זיכרון של המאיצים, רשימת הצרכנים. התוצר — מפת מצב נוכחי ורשימת צווארי בקבוק.
- תכנון סכימת הפריסה — טופולוגיה של מאגרי צמתים, פיזור רפליקות, מכסות, סקיילינג אוטומטי, בידוד סביבות. התוצאה — קונפיגורציה שמשוחזרת מהמאגר, ולא כזו שנבנתה ביד.
- כיול ובדיקה בסיסית — מניפסטים, מטמון משקלים, מגבלות משאבים, מדיניות רשת, איסוף מדדים ולוגים. מוודאים שהשירות מגיב ועובר הפעלה מחדש בצורה תקינה.
- בדיקה תחת עומס — פרופיל קרוב לזה של הפרודקשן: בקשות מקבילות, הקשרים ארוכים, התפרצויות שיא, כשל של צומת בודד. בוחנים השהיה של האסימון הראשון ותפוקה, ומקבעים את סף ההידרדרות.
- תוכנית נסיגת גרסה — כיצד להחזיר את תמונת המודל והקונפיגורציה הקודמת בפעולה אחת, לאחר בדיקה בסביבת ניסוי. בלי נסיגה מתורגלת אנחנו לא מוציאים גרסה.
- מסירה לתפעול — הרשאות, נהלים, התראות, תיעוד, הדרכת משמרת תורנים. בהמשך המערכת מנוהלת בידי צוות התמיכה.
השלבים מתבצעים לפי הסדר בקפדנות: ביקורת שהוחמצה חוזרת כשיפוץ הסכימה, ונסיגה שלא נבדקה חוזרת כהשבתה ברגע הכי לא נוח.
מה נשאר אצלכם: קונפיגורציות, סכימות, נהלים
כל מה שאנחנו מגדירים בעת הפריסה נשאר במאגר ובאשכול שלכם — בלי תלות בצוות שלנו. אנחנו מעבירים לא "תיקייה עם קבצים", אלא סביבת עבודה: המהנדס שלכם מקים סביבה מאפס לפי התיעוד, בלי לשאול אותנו שאלות.
- מניפסטים לפריסה. פריסות, שירותים, נקודות כניסה, מכסות לצמתי GPU, סקיילינג אוטומטי לפי אורך תור הבקשות. החלה על אשכול נקי משחזרת את הסביבה אחד לאחד.
- סכימת עמידות בכשלים. פיזור רפליקות בין אזורים, מגבלות משאבים, ספי בדיקות מוכנות, התנהגות בעת נפילת צומת. רואים איזו הידרדרות מותרת ומה קורה לתור.
- נוהל עדכון מודל. חלק קנרי מהתעבורה, מדדי השוואת איכות תשובות, קריטריוני נסיגה, נקודת אל-חזור. עדכון מפסיק להיות עצירה של השירות.
- מדיניות גישה לצוותים. תפקידים באשכול, הפרדת מרחבי שמות, גישה לסודות עם מפתחות, מגבלות משאבים לכל צוות.
- תיעוד תפעולי. סכימת ארכיטקטורה, נקודות כשל, תקלות אופייניות וסדרי פעולה, מדדים ולוגים, נקודות ציון בעת הידרדרות.
- סקריפטים לבניית תמונות. בנייה משוחזרת, תיוג, בדיקות לפני פריסה.
בהמשך אתם מנהלים את השירות בעצמכם: מחליפים מודל, מוסיפים צוותים, מסקיילים את מאגר הצמתים. אנחנו נשארים זמינים למשימות חדשות, אך לא כיחידים שיודעים לגעת בקונפיגורציה.
מקרה בוחן: הסקה יציבה תחת עומס שיא
הלקוח — שירות ליצירת טקסטים בזרם פניות.
העומס הממוצע נשמר יציב, אך בשעות הבוקר מספר הבקשות בדקה גדל פי שלושה, והתמונה הזו בדיוק נשברה: רפליקות ההסקה לא הספיקו להתחמם לפני הכנסתן לאיזון, חלק מהפניות נסגרו בשגיאה, ופריסת גרסה חדשה של המודל עצרה את קליטת התעבורה לכל משך בניית הסביבה מחדש.
המדדים נלקחו לפני ההתערבות וחודש לאחריה:
| מדד | לפני | אחרי |
|---|---|---|
| שיעור כשלי בקשות בחלונות שיא | 11% | 0.4% |
| זמן תגובה באחוזון 95 | 4.8 ש' | 1.3 ש' |
| זמן פריסת גרסת מודל חדשה | 40 דק' עם עצירת קליטה | 5 דק' בלי עצירה |
| מוכנות רפליקה לאחר עלייה | 6–9 דק' | 25–40 שנ' |
השינויים נגעו בשלושה דברים: חימום, פיזור ופריסה. משקל המודל המחומם נמצא כעת בתמונה, רפליקה חדשה אינה נכנסת לאיזון עד שהיא מוכנה לקבל בקשות, והגרסה עולה על חלק מהתעבורה עם הרחבה הדרגתית של הנתח.
כשהתור גדל, המתזמן מרים רפליקות נוספות, וכשהוא מתכווץ — מסיר אותן, ולכן לא מוחזק מלאי קבוע לשיא, ומאגר המאיצים NVIDIA לא גדל. נסיגה לגרסה הקודמת היא פקודה אחת, התעבורה חוזרת תוך דקות, וזה נבדק בנפרד בתרגול נסיגה.
במה שונה פריסת הסקה מכיוונון עדין של מודל?
אלה שתי סביבות שונות עם פרופיל עומס הפוך, וערבובן בסביבה אחת הוא מקור לתקלות מתמשכות. פריסת הסקה משרתת בקשות: התעבורה מגיעה באופן לא אחיד, התשובה נדרשת באופן מיידי, והשבתה נראית למשתמש מיד.
סביבת הכיוונון העדין של המודל עובדת בקבוצות: ריצות ארוכות, תפוסה מלאה של המאיצים, ועצירה באמצע עולה ביום חישוב אבוד.
הפרדת המשאבים מכתיבה את הטופולוגיה. להסקה נדרש מלאי מאיצים מובטח ומרווח זיכרון לתור הבקשות — אחרת בשיא יתחילו כשלים. לכיוונון עדין משתלם לקחת את החומרה הפנויה כולה ולשחרר אותה בסיום.
לכן אנו מפרידים את הסביבות למאגרי צמתים נפרדים ולפי לוח זמנים: האימון מתחיל בחלון של עומס נמוך ואינו גוזל ביצועים מהשירות.
גם תדירות העדכונים שונה. המשקלים משתנים אחת לכמה שבועות, ואילו התשתית סביבם — ניתוב, מגבלות, מטמון, מדדים — מתעדכנת כל הזמן; בסביבת הכיוונון העדין המחזור שונה: ניסוי, בדיקת איכות, העלאת גרסה חדשה.
הדרישות לכשלים הן תמונת מראה. להסקה נדרשים הידרדרות חלקה ונסיגה מהירה לגרסה הקודמת: כמה עותקים, בדיקות חיים, הסרת תעבורה מצומת לא תקין. לכיוונון עדין חשוב יותר שימור ההתקדמות — נקודות ביקורת קבועות, כך שנפילת צומת תעלה בהפעלה מחדש של הקטע האחרון בלבד, ולא של כל הריצה.
את שתי הסביבות אנו מרימים על Kubernetes כפלטפורמה משותפת, אך עם מדיניות שונה: מאגרים נפרדים, כללי סקיילינג משלהם, סדרי עדיפויות שונים של המתזמן. הפרדה כזו מסירה את מחלקת הכשלים המרכזית — כאשר האימון דוחק את השירות והמוצר נופל כולו.
ספקות טכניים לפני הפעלת הסקה
לפני הפעלת מודל באשכול, צוותים שואלים כמעט את אותן שאלות — וטוב שכך: התשובות להן קובעות כיצד השירות יתנהג בעת עדכון ובתקלה. להלן תשובות קצרות לעניין, בלי מילים כלליות.
איך להבין שצוואר הבקבוק אינו המאיץ?
בוחנים את כל השרשרת: תור הבקשות, גודל המנה, הכנת נתוני הקלט, העברה בין שירותים. לעיתים קרובות המאיץ עומד ללא שימוש, והזמן מתבזבז על עיבוד מקדים והמתנה בתור. אם שיעור אי-הניצול גבוה באופן עקבי, יש לייעל לא את החישוב.
איך לעדכן מודל בלי השבתה?
גרסה חדשה עולה לצד הישנה ומקבלת תחילה חלק קטן מהתעבורה — משווים את איכות התשובות והשהיה על בקשות חיות. המשקלים נשמרים כארטיפקט נפרד עם גרסה, ולכן נסיגה היא החזרת התעבורה לאחור, ולא בנייה מחדש. הלוגים והתשובות תמיד משויכים לגרסת המודל.
איך לתת לצוותים גישה לסביבה?
דרך מרחבי שמות ותפקידים: מפתח רואה לוגים ומדדים של השירות שלו, אך אינו מנהל את האשכול או עומסים של אחרים. פרטי התחברות נשמרים רק במאגר סודות תקני, לא בקונפיגורציות ולא בהתכתבות. גישה ניתנת לתפקיד, ולא לאדם — בעת שינוי הרכב הצוות אין צורך לשלול אותה ידנית.
מה קורה בעת כשל של מאיץ?
הצומת מוצא מהאיזון, והעומס שלו עובר לצמתים פנויים. אם אין מלאי, הבקשות נכנסות לתור עם הגבלת זמן — השירות מאט, אך אינו מחזיר שגיאה. במקביל מופעל תוכנית הידרדרות: מצמצמים את המקביליות ואת אורך נתוני הקלט, ותרחישים קריטיים מטופלים במודל קומפקטי.
רמות ההידרדרות, הספים שלהן וסדר המעבר מתוארים מראש ונבדקים בתרגילים — ואז בתקלה ההחלטה מתקבלת על ידי האוטומציה, ולא על ידי התורן.
נדון במשימה: מה לשלוח להערכת הסביבה
כדי לחזור עם הערכה ותוכנית עבודה, ולא עם שיקולים כלליים, אנחנו צריכים תקציר קצר על הסביבה שלכם: ממנו רואים היכן צווארי הבקבוק, כמה מאיצים באמת יידרשו ואילו החלטות יהיה צריך לקבל לפני הפריסה הראשונה. שלחו את מה שיש — לפעמים חלק מנתוני הפתיחה חסר, וזה בסדר, נשלים יחד בשיחה.
- מודל ופורמט משקלים: פתוח או מכוונן עדין, גודל, דיוק מותר (מלא או מכומת), האם נדרשת גישה למשקלים פרטיים ומאין לקחת אותם.
- פרופיל עומס: בקשות בשנייה בשיא ובממוצע, אורך ההקשר, שיעור החזרת תשובה בזרימה, האם יש משימות באטצ'ים ארוכות בנפרד מהאינטראקטיבי.
- סביבת הפריסה הנוכחית: אשכול והרשת שלו, זמינות צמתים עם מאיצים, במה אתם מנהלים משאבים, היכן נשמרים המשקלים וכיצד נבנות התמונות.
- דרישות לזמינות: שיעור היעד של בקשות מוצלחות, זמן השבתה מותר בעת עדכון, האם נדרש חימום לפני הכנסת מופע חדש לעבודה.
- הרשאות וגבולות: מי הבעלים של האשכול, אילו שירותים חיצוניים צריכים להיות זמינים, האם יש דרישות לבידוד בקשות בין צוותים.
- נראות: מה כבר נאסף — תפוסת מאיצים, תור בקשות, השהיות, לוגים — ולאן זה נשמר.
- תוכנית התפתחות: גידול העומס באופק, הופעת מודלים חדשים, הצורך בכיוונון עדין לנתונים שלכם.
זה מספיק כדי להציע סכימת פריסה, מדיניות עדכונים ונסיגות, וכן תוכנית עבודה עם שלבים וקריטריוני קבלה. תארו את המשימה בצורה הנוחה לכם — נחזור עם הערכה ותוכנית.







