הגדרת באצ'ינג דינמי ל-LLM: האצת GPU

הבקשות מגיעות בצורה לא אחידה: חלק מהמאיצים עומדים ללא שימוש, והתור למודל גדל. אנו מגדירים באצ'ינג דינמי מקצה לקצה — איסוף חבילות בזמן אמת מקצר את זמן התגובה ומעלה את התפוקה על אותו צי מאיצים. נדון במשימה ונחזור עם הערכה ותוכנית.

תחומי פיתוח AI

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

באצ'ינג דינמי של LLM: מדוע המאיצים עומדים בטלים

מאיץ שמשרת בקשה אחת בכל פעם כמעט תמיד עובד בחצי כוח. בזמן שמודל השפה מייצר תשובה טוקן אחר טוקן, בכל צעד מתבצעות פעולות קטנות על רצף בודד, והזיכרון תפוס במשקולות. בלוקי החישוב עומדים בטלים — וזה אינו תקלה נדירה אלא מצב שגרתי של עיבוד בקשות אחת-אחת.

בפרופיל עומס אמיתי התמונה נראית מיד: הבקשות מגיעות בצורה לא אחידה, עם שיאים והפוגות. עיבוד אחת-אחת הופך התפלגות כזו למשור — פרץ עומס קצר, ואחריו צניחה והמתנה לבקשה הבאה.

התור גדל, האחוזון ה-95 של זמן התגובה מטפס, והתפוקה נשארת נמוכה: המאיץ עומד בטל בדיוק כשםיכול היה לעבד עבודה באצווה.

באצ'ינג דינמי של LLM סוגר את הפער הזה: בקשות שהגיעו בחלון קצר מתאחדות לאצווה אחת. ההבדל המרכזי מתרשים סטטי — ההרכב נבנה מחדש בכל צעד של הגנרציה: רצפים שהסתיימו יוצאים מהאצווה, וחדשים תופסים את מקומם. היא נשארת מלאה, והעיבוד אינו ממתין לבקשה האיטית ביותר בקבוצה.

הכיול אינו מצטמצם לפרמטר אחד: לפרופיל עומס מסוים נבחרים גודל חלון ההמתנה, תקרת האצווה וכללי התור בעת גלישה. מהם תלוי האיזון בין זמן התגובה למספר הבקשות המעובדות ליחידת זמן — בהמשך נפרט כיצד ערכים אלה נבחרים לפי המדדים של השירות שלכם.

מה משתנה אחרי הכיול: מהירות התגובה והעומס על המאיצים

כל עוד הבקשות מגיעות למאיץ אחת-אחת, הוא עומד בטל בין ריצות: החישובים תופסים שברירי זמן, והשאר מתבזבז על המתנה לקריאה הבאה. באצ'ינג דינמי מקבץ בקשות שהגיעו בחלון קצר לריצה אחת — Triton Inference Server וסביבות דומות עושות זאת ברמת המתזמן, ולא בקוד המודל. התפוקה על אותו מערך מאיצים עולה פי כמה: צוואר הבקבוק עובר מהמאיץ לרשת ולהכנת הנתונים.

התוצאה השנייה — השהיית התגובה מפסיקה להיות תלויה בנהירת המשתמשים. כל עוד חלון ההמתנה והגבול העליון של האצווה מוגדרים במפורש, בקשה בודדת אינה ממתינה „עד שתתאסף חבורה”, והזרם בשיא אינו נבנה לתור הולך וגדל.

מודדים חציון ואחוזון 95 לפני ואחרי: בדרך כלל דווקא המקרה הגרוע משתפר, ולא הממוצע — ולכן הממשק מפסיק להיתקע בשיאים.

האפקט השלישי — נעלם סוג שלם של כשלים בשל עומס יתר. בעבר, בעת פרץ, בקשות הצטברו בתור הכניסה, חלקן נפלו בפסק זמן, והשירות חייב ניתוח ידני של התקרית. כעת האצווה אוספת בעצמה עבודה מהתור, ובמיצוי המכסה מופעל כשל צפוי עם קוד מובן.

הכלכלה כאן נקראת דרך ניצולת המשאבים: מאיץ שעומד בטל הוא הספק שאינו מניב תוצאה. כשהעומס על המאיצים נשאר אחיד, הרחבת המערך נדחית, ועלות השבתה מפסיקה להיות סעיף קבוע בתכנון.

אפשרויות קיבוץ הבקשות לאצוות: השוואת מצבים

אופן קיבוץ הבקשות לאצוות משפיע על עומס המאיץ יותר מבחירת המודל עצמו: בתרשים כושל הכרטיס עומד בטל בין איטרציות, וזנב התור נמתח לשניות.

צ'אט אינטראקטיבי, ניתוח מסמכים באצוות ואנליטיקה ברקע מעמיסים על השירות בדרכים שונות, ולכן אין הגדרה אוניברסלית — את המצב בוחרים לפי פרופיל התעבורה.

מצב מתי מתאים מגבלות המצב
עיבוד אצוות סטטי בקשות אחידות באורך ידוע: ייצוא לילי, תיוג ארכיון, דוחות באצוות האצווה ממתינה לתשובה הארוכה ביותר, בקשות קצרות עומדות בטלות, המאיץ עמוס בצורה לא אחידה
הרכבה רציפה של אצוות זרם מעורב עם פיזור אורכים: צ'אט, עוזרים, זרם פניות דרוש מתזמן ברמת שרת ההסקה — vLLM ודומיו; קשה יותר לשחזר מדידות
תור עם עדיפויות מחלקות משימות שונות באותו שירות: אינטראקטיבי חשוב יותר מאנליטיקה הרעבה של משימות בעדיפות נמוכה, נדרשים כללי דחיקה מפורשים
כיוונון גודל האצווה ידנית זרם יציב ללא פרצים בזיכרון מאיץ מוגבל איזון שברירי: גודל מוגזם מוביל לכשלים, גודל קטן מדי לחוסר עומס

בפועל משלבים בין המצבים: הרכבה רציפה של אצוות קובעת את הקצב הבסיסי, תור עם עדיפויות מפריד בין אינטראקטיבי למשימות רקע, וגודל האצווה מוגבל מלמעלה לפי הזיכרון הזמין. את הבחירה בודקים על פרופיל תעבורה אמיתי — אחרת מגבלות המצב צפות דווקא בשיא, כשלא נשאר זמן לשנות את התרשים.

סדר ההטמעה: מפרופיל העומס ועד להעלאה לפרודקשן

באצ'ינג דינמי אינו נדלק במפסק אחד: חלון האיסוף, גודל האצווה המקסימלי ומגבלות ההמתנה נבחרים לפי פרופיל תעבורה מסוים. להלן שלבי ההטמעה: ממדידת העומס האמיתי ועד למסירת השירות לפעילות שוטפת.

  1. מדידת פרופיל העומס — התפלגות הבקשות לפי אורך הקלט והפלט, שיעור התשובות הקצרות והארוכות, מרווחי שיא. בלי המספרים האלה גודל האצווה נבחר בערך.

  2. תרשים איסוף התור — היכן הבקשות מתאחדות: באפליקציה, בשכבה מתווכת או בשרת ההסקה עצמו, וכיצד מתואמים חלונות ההמתנה בין השכבות.

  3. כיול שרת ההסקה — גודל האצווה המרבי, חלון ההמתנה, ההתנהגות בעת גלישת התור ועדיפות הבקשות האינטראקטיביות על פני בקשות הרקע.

  4. הפרדה לפי מחלקות תעבורה — בקשות שיחה קצרות עוברות לאצוות קטנות, עיבוד באצוות לגדולות, כדי שמשימות ארוכות לא יעכבו את התשובה למשתמש.

  5. בדיקת עומס — הרצת זרם עם הפרופיל מהשלב הראשון, בקרה על השהיית הטוקן הראשון, על התפוקה ועל אורך התור בשיא.

  6. מנגנוני הגנה וחזרה לאחור — חזרה לעיבוד בודד במפסק אחד וספים שבהם הבאצ'ינג מנוטרל אוטומטית.

  7. מסירה לפעילות שוטפת — תצורה, לוחות עם המדדים המרכזיים, נהלים לשינוי מכסות וניתוח כשלים אופייניים.

מה נמסר לידיים: תצורות, תרשימים, נהלים

אנחנו מוסרים לא מצגת אלא ערכה עובדת: לפיה המהנדס שלכם יוכל לשנות את התנהגות הבאצ'ינג, לאבחן פרצים של השהיות ולהחזיר את המצב הקודם בלי להמתין לנו. להלן מה שנשאר במאגר הקוד ובבסיס הידע הפנימי עד רגע המסירה.

  • תצורת השירות: קבצי פרמטרים של חלון האיסוף — גודל מקסימלי, זמן המתנה לאיסוף, ספי עומס המאיץ — עם הערות מדוע נבחרו דווקא הערכים האלה, ופרופיל נפרד לשעות השיא.
  • תרשים זרימות הבקשות: המסלול מהקליטה ועד למסירת התשובה, נקודות הצטברות התור, הרגע שבו נוצר החלון, ההתנהגות בעת גלישה ובשקט, כשאין על מה להמתין.
  • נהלי תפעול: כיצד לשנות את גודל החלון בלי להפעיל מחדש את השירות, אילו מדדים לבדוק אחרי השינוי ובאילו ערכים להחזיר את הפרופיל הקודם.
  • מדיניות גישה: הפרדת הרשאות בין קריאת מדדים לשינוי תצורה, תפקידי תורן ותורן בכיר, סדר רוטציית מפתחות הגישה לשירות.
  • מדדים ולוח ניטור: שיעור מילוי החלון, השהיה לכל בקשה, עומס המאיץ, מספר הבקשות שנדחו בפסק זמן — עם ספים שמעבר להם מתחילה הרעה.
  • תיעוד: תיאור הארכיטקטורה, ניתוח תרחישי כשל, הוראות לפעולות אופייניות ויומן שינויים בתצורה עם ציון מבצע השינוי.
  • תרחישי בדיקה: מערכת הרצות עומס המשחזרות זרם אחיד, פרץ קצר ושיא ארוך — כדי ששינוי תצורה ייבדק לפני העלאה לסביבת העבודה.

מקרה בוחן: גידול בתפוקה על אותו מערך מאיצים

הלקוח — שירות תמיכה עם זרם פניות דרך צ'אט: מערך מאיצים אחד, בלילה העומס אחיד, ביום שיאים קצרים גבוהים פי 4-5 מהממוצע. לא רצו להרחיב את המערך: בשיאים כאלה המאיצים עמדו בטלים, והיה צריך להצדיק את ההשקעה בכרטיסים חדשים.

לפני השינויים גודל האצווה היה קבוע — לפי העומס הממוצע. בשיא הבקשות הצטברו בתור: האחוזון ה-95 של זמן התגובה הגיע ל-4.5 שניות, ו-9% מהפניות נפלו בשל חריגה מזמן ההמתנה — בזמן שהעומס על המאיצים היה לא אחיד.

העבודה נבנתה מחדש על שרת הסקת מודלים vLLM עם באצ'ינג רציף: המתזמן בונה מחדש את האצווה בכל צעד גנרציה ומשבץ בקשות חדשות למשבצות שהתפנו, בלי להמתין לסיום הקבוצה הנוכחית.

במקביל הגבילו את אורך התור, קבעו תקרה לזיכרון המטמון והפרידו עדיפויות — פניות קצרות כבר אינן ממתינות לגנרציות ארוכות.

מה קרה על אותו מערך: התפוקה עלתה בערך פי שלושה — מ-18 ל-52 בקשות בשנייה, האחוזון ה-95 של התגובה ירד ל-1.2 שניות, שיעור הכשלים בשל עומס יתר — מ-9% ל-0.4%, והעומס על המאיצים בשעות השיא הגיע ל-85-90% במקום 40-60%. את התצורה עם תקציב ההשהיה המצופה ומגבלות התור העבירו לשאר המודלים בשירות בלי לשנות את החומרה.

במה הרכבה רציפה של אצוות שונה מבאצ'ינג דינמי?

ההבדל הוא מתי נקלט הרכב האצווה. הרכבה דינמית צוברת בקשות בחלון ההמתנה, מרכיבה אצווה לפי גודל או פסק זמן ומובילה אותה ללא שינוי עד הסוף — המקומות שהתפנו עומדים בטלים עד לסיום התשובה הארוכה ביותר.

הרכבה רציפה של אצוות בונה את ההרכב מחדש בכל איטרציה של הגנרציה: רצף שהסתיים יוצא, ומקומו נתפס מיד בידי הבקשה הבאה מהתור.

מכאן ההבדל באפקט. בתעבורה מעורבת, שבה הולכים זה לצד זה תגובה קצרה והנמקה ארוכה, המאיץ מפסיק להמתין למפגרים — התפוקה עולה פי כמה על אותה חומרה, וההשהיה עד לתשובה הראשונה נעשית צפויה.

המחיר לכך — בניהול. יש להגביל את מספר הרצפים בו-זמנית, לעקוב אחר הזיכרון למצבי הביניים ולכוונן את חלון ההמתנה: ארוך מדי אוכל את הרווח, קצר מדי לא מאפשר למלא את האצווה.

בחירת המצב נקבעת לפי פרופיל העומס. בקשות קצרות ואחידות כמעט אינן חשות בהבדל בין הגישות — שם מספיקה הרכבה דינמית, והיא פשוטה יותר לתחזוקה. אורכי תשובה מעורבים — זה המקרה של ההרכבה הרציפה.

אם שרת הסקת המודלים כבר פרוס, עוברים בהדרגה: מפעילים הרכבה דינמית, מודדים מדדי בסיס, ואז מעבירים להרכבה רציפה חלק מהתעבורה מאחורי מאזן העומסים ומשווים את שיעור הזמן התפוס של המאיץ עם יציבות התשובות. מעבר מלא — כשההשוואה הראתה רווח; חזרה לאחור — החזרת המצב הקודם על צומת אחד.

התלבטויות לפני הטמעה: תורים, השהיות, עמידות

בשלב בחירת הספק הספקות הטכניים נשמעים כמעט אותו דבר: האם לא יהיה גרוע יותר מכך שהבקשות מעובדות כעת באצוות. באצ'ינג דינמי של LLM נראה הגיוני בגרפי הניצולת של המאיץ, אבל אצל המהנדס עולה מיד שאלה נגדית — באיזו תמורה. להלן חמש שאלות שנשאלות לרוב בדיון, ותשובות קצרות לעניין.

האם ההשהיה בתשובה לבקשות בודדות תגדל?

חלון ההמתנה אדפטיבי: תחת עומס נמוך הוא מתכווץ כמעט לאפס, ובקשה בודדת יוצאת לעיבוד מיד. אצווה נאספת רק כשבתור כבר יש בקשות המוכנות לעיבוד בו-זמני — אף אחד לא ימתין לשווא.

מה קורה בעומס לא אחיד — שקט או הצפה?

הדיספצ'ר מחשב מחדש את גודל האצווה ואת החלון לפי הזרם הנכנס בפועל: בלילה הוא מחזיק אצוות גדולות וסוחט את המאיץ, ובפרץ חד — מקטין אותן כדי לא לצבור השהיה. הגבולות מוגדרים בתצורה כמדיניות, ולא נבחרים לפי העין.

האם השירות יתחיל להשליך בקשות בעומס יתר?

התור מוגבל מלמעלה, אך הבקשות אינן הולכות לאיבוד — הן ממתינות בזמן צפוי מראש, וחלק מהתעבורה אפשר להפנות לצומת גיבוי. ההשלכה נשארת מצב חירום עם קוד שגיאה מפורש, ולא התנהגות שגרתית בשיא.

האם יספיק זיכרון המאיץ לאצוות גדולות?

גודל האצווה מוגבל מלמעלה לפי נפח הזיכרון הזמין, ולכן עצירת חירום של העיבוד נשללת. בשיא המדיניות מקטינה בעצמה את גודל האצווה — התפוקה יורדת בהדרגה, בלי כשל מוחלט.

כיצד בודקים עמידות ומה עם חזרה לאחור?

את העמידות בשיא מאשרים בהרצה לפי פרופיל עומס אמיתי — גידול מדורג, ניתוק חיבורים, בקשות חוזרות. החזרה למצב סטטי נעשית בפרמטר תצורה אחד, בלי בנייה מחדש של השירות ובלי שינויים בקוד האפליקציה.

נדון במשימה: מה נדרש להערכה ולתוכנית עבודה

הערכת פרויקט של באצ'ינג דינמי ל-LLM נשענת לא על שיקולים כלליים אלא על פרופיל העומס שלכם ועל תרשים שירות הבקשות הקיים. ככל שהנתונים הראשוניים קונקרטיים יותר, כך פחות סבבי הבהרה ותוכנית העבודה מדויקת יותר — עם סדר השלבים ונקודות שבהן אפשר לחזור לאחור.

  • פרופיל העומס. כמה בקשות מגיעות בממוצע ובשיא, כיצד הן מתפלגות לפי אורך הקלט והפלט, האם יש פרצים יומיים. זה קובע כמה בקשות מתאחדות לאצווה אחת והיכן הרווח יהיה מורגש.
  • התרשים הנוכחי. מופע אחד של המודל או כמה, כיצד מתפלגות הבקשות, האם יש תור ומטמון תשובות, כיצד מתעדכנות המשקולות. בלי זה לא ברור מה בדיוק לשנות.
  • מגבלות זמן תגובה. היכן ההשהיה קריטית — אינטראקטיבי, פלט בזרימה — והיכן אפשר להמתין. באצ'ינג דינמי מאזן בין תפוקה להמתנה, ואת הגבולות קובעים אתם.
  • תשתית והרשאות. אילו מאיצים ובכמה, כיצד בנויה הפריסה, האם יש סביבת בדיקה להרצת עומס בלי סיכון לסביבת הייצור.
  • מדדים. במה אתם מודדים תפוקה והשהיה כיום, אילו פרוסות נתונים אתם אוספים ולפי אילו מדדים תקבלו את העבודה.
  • צוות ותפקידים. מי בצד שלכם אחראי על התשתית, מי על המודל, מי מאשר את התוצאה — כדי לא להמתין לתשובות במעגלים.

תארו את המשימה בצורה חופשית — נחזור עם הערכה, תוכנית עבודה ושאלות הבהרה, אם משהו יחסר.