Triton Inference Server: איפה נשבר האינפרנס של LLM
תמונה אופיינית אצל צוות שהעלה מודל שפה למוצר: בקשה בודדת מקבלת מענה מהר, אבל תחת עומס זמן התגובה גדל באופן לא ליניארי. הסיבה אינה במשקלים ולא בחומרה — יחידות החישוב עומדות בחוסר מעש בהמתנה.
בקשות מגיעות אחת אחת, אין במה לאחד אותן למנה משותפת, והמאיץ רוב הזמן עוסק בסנכרון ולא בחישוב. תפוקת המודלים נתקעת במתזמן, ולא בעוצמת המאיץ.
בשעת שיא התמונה מחריפה: התור מתארך, זנב ההשהיות מתארך, ואפילו שאלות קצרות וקלות נקלעות אליו. לקוחות מתחילים לחזור על בקשות, כל חזרה מוסיפה עומס, התור מתארך — והדעיכה מזינה את עצמה. שיעור חריגות הזמן עולה בקפיצה, וזו כבר לא מדד הנדסי אלא כשלים אצל המשתמשים.
צוואר הבקבוק העיקרי של האינפרנס הוא ה"קדרה המשותפת". שאלה קצרה ויצירה ארוכה עומדות באותו תור, אף שהן מחזיקות במשאב פרקי זמן שונים. פרמטרי איחוד הבקשות קבועים מראש ואינם מותאמים לפרופיל התעבורה. מטמון המפתחות והערכים (KV) מתכלה בצורה לא אחידה, חלק ממופעי המודל עומדים בטלים בעוד שאחרים נחנקים.
כאן נכנס לפעולה Triton Inference Server: איחוד דינמי של בקשות, מספר מופעי מודל על מאיץ אחד, תורים נפרדים עם עדיפויות וניהול צריכת זיכרון עבור המטמון. המאיצים נטענים באופן אחיד יותר, זמן התגובה מפסיק להתפרק בשעת שיא, ושיעור חריגות הזמן יורד — בלי לכתוב מחדש את המודל עצמו.
בהמשך נפרט איך זה נסגר ברמת הקונפיגורציה: מתזמן, פרופיל מנות, זיכרון ומדדים שמראים היכן בדיוק צוואר הבקבוק.
מה נותנת אופטימיזציית אינפרנס: אפקט ומדדים מדידים
מדדי האופטימיזציה נמדדים לא לפי ממוצע יומי, אלא לפי ההתנהגות תחת עומס: כמה בקשות בשנייה מחזיקה הקונפיגורציה, עד כמה מאוזנים המאיצים, ומה קורה כשהתעבורה מגיעה בשיא. בהמשך — מה בדיוק משתנה במספרים לאחר העברת המודל אל Triton Inference Server והגדרת איחוד דינמי של בקשות למנות.
תפוקה ומהירות תגובת המודל
איחוד בקשות למנות בצד השרת מעלה את התפוקה פי כמה על אותה חומרה, וזמן התגובה של בקשה בודדת גדל באופן לא ליניארי רק בגבול התור. אנו מתאימים את גודל המנה המרבי ואת חלון ההמתנה כך שנשמור על איזון: תחת עומס המאיץ עובד בקבוצות, ובחוסר עומס — עונה בנפרד.
עומס המאיצים ויציבות בשעת שיא
זרמי ביצוע מקבילים נכונים מסלקים את חוסר המעש: עומס המאיצים מתאזן, ובמקום קפיצות של "תור — הפוגה — תור" נוצרת זרימה אחידה. בשעת שיא המערכת עונה באופן צפוי, כי התור מוגבל ובקשות שעברו את סף ההמתנה נחתכות בשגיאה מפורשת, במקום להיתקע עד לחריגת הזמן של השירות שמעל.
אילו סוגי כשלים נעלמים
שלוש קטגוריות אופייניות נעלמות: נפילה בגלל חוסר בזיכרון בזינוק חד של פניות במקביל, חריגות זמן מדורגות בגלל תור בלתי מוגבל, ודעיכה אחרי הפעלה מחדש כשהמודל מתחמם על תעבורה חיה. נשאר תרחיש צפוי אחד — כשל מפורש בעומס יתר, והוא נראה במדדים לפני שהמשתמש מדווח עליו.
פורמטי הטמעה של Triton: מתי כל מצב מתאים
אופן הפריסה קובע לא רק את עלות החומרה, אלא גם איך המערכת תתנהג בשעת שיא. כמעט תמיד כדאי להתחיל משרת אינפרנס משותף: Triton Inference Server מחזיק מספר מודלים בתהליך אחד, מנהל בעצמו תורים וטעינת משקלים, ולכן מוצר חדש מתחבר בלי מערכת נפרדת.
למצב הזה יש מגבלה הוגנת — המודלים חולקים את זיכרון המאיץ, וזינוק בבקשות לאחד מהם מאריך את זמן התגובה של האחרים.
שני מצבים אחרים פותרים משימות מנוגדות: קו ייעודי נותן בידוד והשהיה צפויה, ועיבוד בקשות במנות — תפוקה מרבית בהרצות המוניות. בהמשך — השוואה עם המגבלות שמתגלות כבר בעבודה.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| שרת אינפרנס משותף | מספר מודלים ומוצרים, זרם בקשות משותף, חשוב לחסוך במשאבים | המודלים מתחרים על זיכרון המאיץ; שכן כבד משפיע על זמן התגובה |
| קו ייעודי | מודל קריטי אחד, דרישות לבידוד ולהשהיה יציבה | חלק מהציוד עומד בטל בין שיאים, יקר יותר לתחזוקה |
| עיבוד בקשות במנות | הרצות לא מקוונות: תיוג, ניקוד, אינדוקס מחדש של הקורפוס | ההשהיה של תגובה בודדת עולה; לא מתאים לתרחישים אינטראקטיביים |
בפועל משלבים בין המצבים: שרת משותף מכסה את האינטראקטיב, והרצות כבדות עוברות לקו המנות לפי לוח זמנים. נפרט איך פורסים פריסה כזו לפי כוחות חישוב בלי חוסר מעש.
שלבי העבודה ההנדסית: מביקורת עומס ועד מסירה
סדר השלבים אינו מקרי: כל שלב הבא נשען על המספרים שהתקבלו בקודם. בלי ביקורת עומס בוחרים קונפיגורציה בניסוי וטעייה — ההטמעה מתארכת, והגבול לבקשות במקביל נשאר לא ידוע עד השיא הראשון. לכן קודם מודדים, אחר כך מתכננים.
- ביקורת עומס. אוספים מדדים מהקו הנוכחי: התפלגות אורכי בקשות ותגובות, שיעור השיחות הארוכות, שעות שיא, דרישות להשהיה של הטוקן הראשון. התוצאה — פרופיל שלפיו מחשבים את הצורך במאיצים ובזיכרון.
- תרשים פריסה. קובעים טופולוגיה: צומת אחד או מאגר עם איזון עומסים, כמה עותקי מודל חיים על המאיץ, ואיך מתחלק הזיכרון בין המשקלים למטמון המצבים. את התרשים מקבעים לפני ההגדרה, אחרת לאחר הבדיקות יהיה צורך לשנותו.
- הכנת מודלים ושרת. ממירים את המשקלים לפורמט ש-Triton Inference Server מריץ ישירות, מתארים את המודלים באופן הצהרתי, ומפעילים איחוד דינמי של בקשות למנות עם מגבלות תור וחריגות זמן.
- הגדרת קונפיגורציה. מגדירים מקביליות, עדיפויות ומדיניות פריקה של עותקים שאינם בשימוש, כדי שהזיכרון לא ייתפס בידי מודלים בטלים.
- בדיקה תחת עומס. מריצים את הפרופיל מהשלב הראשון, מודדים זמן תגובה ברמות מקביליות שונות, ומוצאים את הנקודה שבה ההשהיה גדלה מהר יותר מהתפוקה. את הגבולות וההתנהגות בעומס יתר מתעדים בדוח.
- מסירה לתפעול. מוסרים קונפיגורציות, תרשים פריסה, נוהל עדכון מודלים וסט מדדים לניטור, ומכשירים את הצוות על תרחישים אמיתיים.
ארטיפקטים של הטמעה: קונפיגורציות, תרשימים, נהלים
לאחר המסירה נשאר אצל צוות הלקוח לא "שירות מוכן לגמרי", אלא סט מלא של ארטיפקטים שלפיהם אפשר לפרוס, להרחיב ולתחזק את הפתרון בלי אותנו. כל זה נמצא במאגרי הלקוח, מנוהל בגרסאות יחד עם הקוד ועובר סקירה כמוהו.
- קונפיגורציות פריסה — מניפסטים הצהרתיים של שירות האינפרנס על Triton Inference Server והתורים, פרמטרי מנות, מגבלות זיכרון, הפעלה אוטומטית. הסביבה מתרוממת מאפס בפקודה אחת, בלי הגדרה ידנית לפי הזיכרון של המהנדס הקודם.
- תרשימי ארכיטקטורה — נתיב הבקשה מהלקוח עד המודל, נקודות סקיילינג, מיקום הרפליקות, התנהגות המערכת בעת כשל צומת ובעומס יתר.
- נהלי תפעול — סדר העלאה של גרסת מודל חדשה, חזרה לגרסה קודמת, הוצאת צומת מפעילות, חלונות עבודות תחזוקה.
- ניטור מודלים — לוחות בקרה להשהיה, שיעור שגיאות ומשאבים, ובנוסף בקרת איכות: סחיפת נתוני קלט, עלייה בכשלים, שינוי בפרופיל הבקשות.
- מדיניות גישה — תפקידים לפרסום מודל ולצפייה במדדים, רוטציית מפתחות, יומן שינויי קונפיגורציות.
- Runbook תורן — אירועים טיפוסיים ופעולות שלב אחר שלב: מה לבדוק קודם, מתי להסלים, היכן לראות היסטוריה.
- תיעוד — תיאור המודלים והגרסאות, דרישות לנתוני קלט, מגבלות ידועות וצ'קליסט קבלה לפני שחרור.
מהנדס חדש נכנס לפרויקט לפי התיעוד, ולא לפי הסברים בעל פה. כבר בחודש הראשון הצוות בעצמו מעדכן מודל או מחזיר גרסה — בלי לפנות אלינו.
מקרה בוחן: הקלנו על המאיצים וסילקנו את תור הבקשות
אלינו הגיע שירות עם כשלושים מודלים: המלצות, דירוג תוצאות, זיהוי שפת השאילתה. כל מודל הורם בתהליך נפרד, המאיצים חולקו ביניהם ידנית, ובשעת השיא בערב תור הפניות מתח את זמן התגובה עד 2–3 שניות, וחלק מהבקשות נפלו בגלל חריגת זמן ההמתנה.
הוצאנו את כל המודלים אל שרת אינפרנס אחד — Triton Inference Server. הוא מחזיק מספר מודלים על מאיץ אחד, אוסף פניות נכנסות למנה משותפת ומחלק בעצמו את הזיכרון ביניהם, ולכן אין יותר צורך בתהליך נפרד לכל מודל.
מדדים לפני ואחרי
| מדד | לפני | אחרי |
|---|---|---|
| זמן תגובה בשעת שיא (אחוזון 95) | 2–3 ש' | 0.6–0.9 ש' |
| שיעור כשלים | 4–6 % | 0.3 % |
| מודלים על מאיץ אחד | 3 | 11 |
| העלאת גרסת מודל חדשה | הפעלה מחדש של השירות עם חוסר זמינות | החלפה בלי חוסר זמינות |
השתנתה גם ההתנהגות תחת עומס. קודם גידול בתעבורה הוביל לקטיעות ולכשלים, עכשיו — לעלייה חלקה בהשהיה: השרת מספיק לאסוף מנה, לעבד אותה ולהחזיר תגובה, והתור מתפזר מעצמו בלי התערבות ידנית. מרווח העומס גדל עד כדי כך ששעות שיא הפסיקו להיות נושא נפרד למשמרת התורנית.
שירותי הצריכה הועברו לכתובת אחידה, הסרנו את הלוגיקה של בחירת מודל בצד האפליקציה והשארנו עדיפויות לבקשות קריטיות. פריקת גרסאות ישנות מוגדרת לפי לוח זמנים, ולכן זיכרון המאיצים לא מתמלא וחזרה לגרסה קודמת נשארת זמינה.
מה לעשות אם האינפרנס של המודלים כבר פרוס ויציב
אם שרת האינפרנס כבר מחזיק עומס עבודה, לא כדאי להחליף אותו "ליתר ביטחון" — קודם מודדים. שירות יציב נתקע לרוב לא במודל, אלא בפרופיל התעבורה: שיאים לפי שעות, אורך התגובה, שיעור הבקשות החוזרות. כל עוד המספרים האלה לא נאספו, כל ארגון מחדש הוא סיכון בלי השערה ובלי קריטריון הצלחה.
מה בודקים קודם: תפוסת המאיצים בשעת שיא, עומק התור, השהיה בתגובות איטיות נדירות ושיעור הבקשות שלא עמדו בזמן היעד.
שכבה שנייה — הגדרת איחוד בקשות למנה ושימוש חוזר בתוצאות שכבר חושבו: ב-Triton Inference Server אלה מדיניות ניתנות להגדרה, והמרווח הלא מנוצל נמצא לרוב דווקא שם, ולא במשקלי המודל.
הלאה, בחירה בין שני נתיבים. שרת אינפרנס משלכם נותן שליטה על הפריסה, על מדיניות המנות ועל כך שהנתונים לא יוצאים מהמערכת — אבל דורש תורנות ועדכונים משלכם. אינפרנס ענן מוכן עולה מהר יותר ומתרחב לפי השיא, אבל מגביל את הגישה להגדרות ותולה אתכם במגבלות של אחרים ובתורים של שכנים. מעבר לענן הגיוני כשהשיאים נדירים ומכפילים, ולא כש"נראה שזה זול יותר".
מיגרציה בלי חוסר זמינות נבנית משלושה שלבים: עותק צל של התעבורה לקונפיגורציה החדשה עם השוואת תגובות שורה מול שורה, שחרור קנרית לחלק קטן מהבקשות, וחזרה אוטומטית לפי סף השהיה ושיעור שגיאות. כל עוד המדדים של הענף החדש לא השוו לישנים, לא מבצעים מיתוג.
תארו את העומס הנוכחי ואת צוואר הבקבוק — נחזור עם הערכה ותוכנית בדיקה, בלי לעצור את השירות הפעיל.
שאלות נפוצות: תאימות, תמיכה, אבטחה
לפני ההתחלה צוותים הנדסיים בודקים את אותם דברים: האם המודלים שלהם יעלו, מה יקרה אחרי ההרצה, לאן הולכים הנתונים והאם המודלים מפריעים זה לזה. בהמשך — תשובות קצרות ולעניין.
המודלים שלנו יעלו בלי אימון מחדש?
משקלים בפורמטים פתוחים מועברים כפי שהם, ובמידת הצורך ממירים לייצוג ביניים ש-Triton Inference Server מריץ ישירות. עיבוד מקדים לא סטנדרטי ושכבות מותאמות אישית נארזים כמודול נפרד. התאמה לערך הייחוס נבדקת לפי מדדים על מערך הנתונים שלכם.
מה קורה אחרי ההרצה?
מוסרים נוהל: עדכון משקלים, בקרת השהיות ושיעור שגיאות, טיפול באירועים עם זמן תגובה קצוב. המהנדסים שלכם מקבלים תיאורי קונפיגורציות ואת סדר הפעולות הטיפוסיות, כדי להחליף מודלים בעצמם.
הנתונים יוצאים אל מחוץ למערכת שלנו?
העיבוד מתבצע בתוך התשתית שלכם, החוצה יוצאים רק מדדים בלי תוכן הבקשות. מפתחות מאוחסנים בכספת סודות ואינם נכנסים ללוגים ולקונפיגורציות. בתרחישים רגישים אנחנו מכבים לחלוטין את רישום הבקשות והתגובות.
המודלים מפריעים זה לזה תחת עומס?
כל מודל מורץ במופע נפרד עם תור משלו ומגבלת זיכרון משלו — יצירה כבדה לא דוחקת מסווג מהיר. עדיפויות נקבעות לפי קריטיות התרחיש, ונפילה של מופע אחד לא מפילה את האחרים.
נדון במשימה: ננתח את פרופיל העומס של הצוות שלכם
כדי שההערכה תהיה עניינית ולא "פחות או יותר סדר גודל", אנחנו צריכים פרופיל עומס של הצוות שלכם: לא מילים כלליות על כמות מבקרים גבוהה, אלא התפלגות הבקשות לפי אורך הקלט והפלט, מרווחי שיא ושיעור הסשנים במקביל. לפי הנתונים האלה רואים מה יהיה צוואר הבקבוק — המתנה ליצירה, זיכרון המאיץ או תור הצבת המשימות.
מה עוזר להרכיב את התמונה לפני תחילת העבודה:
- סטטיסטיקת פניות — בקשות בשנייה, ערכי שיא ופרופיל יומי לתקופה טיפוסית, ייצוא בלי נתונים אישיים.
- רשימת מודלים — משפחה, גודל, רוחב סיביות של המשקלים, האם נדרש איחוד דינמי של בקשות למנות והרצה מקבילה של מספר עותקים.
- מדדים נוכחיים — זמן עד הטוקן הראשון, מהירות יצירה לטוקן, תפוסת המאיצים, שיעור הבקשות שנקטעות בגלל חריגת זמן ההמתנה.
- תרשים פריסה — שרתים משלכם או ענן, מספר המאיצים, רוחב פס הרשת, דרישות לבידוד מערכות.
- מגבלות — פרטיות נתונים, חוסר זמינות מותר בעת עדכון מודל, זמן זמינות יעד, דרישות ענפיות.
- לוגים וטרייסים — ייצוא אנונימי של כמה יממות: מהם רואים את ההתפלגות האמיתית, ולא השערות.
- אחראים מצדכם — מי מאשר ארכיטקטורה, מנפיק גישות ומקבל את התוצאה לפי קריטריוני קבלה.
נאסוף את זה לדיון במשימה ונחזור עם הערכה ותוכנית עבודה: אילו קונפיגורציות של Triton Inference Server יידרשו, שלבים, נקודות בקרה ומדדים שלפיהם נקבל את התוצאה. אם חלק מהנתונים חסוי — תארו במילים, ואת הפערים נסגור במדידות בשלב הראשון.







