שימוש בניתוב מבוסס-חביון חזוי באמצעות GKE Inference Gateway

במאמר הזה מוסבר איך להפעיל את הניתוב מבוסס-החביון החזוי שמוצע על ידי llm-d ב-GKE Inference Gateway ואיך להשתמש בו. כברירת מחדל, GKE Inference Gateway מעביר בקשות באמצעות שילוב של אותות עומס ושיטות היוריסטיות של זיקה למטמון עם קידומת. ניתוב מבוסס-חביון חזוי מחליף את המשקלים ההיוריסטיים הסטטיים במודל XGBoost שאומן באופן רציף על תנועה פעילה, וכך מאפשר לקבל החלטות ניתוב מדויקות יותר ככל שדפוסי עומס העבודה משתנים.

מתי כדאי להשתמש בניתוב מבוסס-חביון חזוי

התכונה הזו הכי יעילה כשהתנאים הבאים מתקיימים בעומס העבודה:

  • שונות גבוהה באורך ההנחיה וההשלמה: עומק התור לבדו הוא מדד לא טוב לעומס השרתים כשגדלי הבקשות משתנים באופן משמעותי. הכלי לחיזוי זמן האחזור מתחשב בעלות בפועל של מילוי מראש ופענוח לכל בקשה.
  • הסכמי רמת שירות (SLO) של זמן אחזור לכל בקשה: כשמציינים באפליקציות יעדים של זמן עד לקבלת הטוקן הראשון (TTFT) או זמן לכל טוקן פלט (TPOT) בבקשות ספציפיות, המתזמן אוכף את היעדים האלה במהלך הניתוב. הוא עושה את זה על ידי חישוב הפוטנציאל (השהייה החזויה פחות יעד ה-SLO) לכל Pod מועמד.
  • כוונון סטטי שברירי של משקלים: אם אתם מכווננים מחדש לעיתים קרובות את האיזון בין קרבה למטמון לבין אותות עומס, ככל שדפוסי התנועה משתנים, המודל שאומן אונליין יסתגל אוטומטית.

איך פועל ניתוב מבוסס-חביון חזוי

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

ארכיטקטורה

תזמון מבוסס-חביון (latency) חזוי פורס שני קונטיינרים נוספים מסוג sidecar בתוך ה-Pod של EPP, לצד ה-EPP עצמו:

רכיב תיאור
שרת אימון מבצע אימון מחדש באופן רציף של מודלי XGBoost TTFT ו-TPOT על דוגמאות של בקשות שהושלמו שהתקבלו מה-EPP. השיטה משתמשת בחלוקה לשכבות על פני חלון נע, כדי שלא יישכחו מצבי תנועה נדירים. כותב מודלים מעודכנים לנפח אחסון משותף.
שרתי חיזוי הצגת תחזיות של TTFT ו-TPOT ל-EPP בנתיב המהיר של הבקשה. קריאה של המודל המאומן האחרון מהאחסון המשותף. ניתן להרחבה אופקית – כל מופע של שרת יכול לתמוך בכ-300 שאילתות לשנייה של עבודת חיזוי. מספר מופעים מאוזנים על ידי פרוקסי לאיחוד ב-Go ב-EPP, שמקבץ בקשות מקבילות לתחזיות בחלון של אלפית השנייה.

llm-d EPP scheduling pipeline

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

  1. ‫predicted-latency-producer: קוראת לשרת החיזוי כדי לקבל הערכות של TTFT ו-TPOT לכל Pod מועמד ב-InferencePool, בהתאם לשימוש הנוכחי במטמון KV של כל Pod, לעומק התור, לציון ההתאמה של מטמון הקידומת ולתכונות של הבקשה הנכנסת. אחרי שהתגובה מוחזרת ללקוח, המפיק שולח את ה-TTFT שנצפה ואת זמן האחזור בין הטוקנים בחזרה לשרת האימון כדוגמה חדשה לאימון.

    • התנהגות חזרה: אם אי אפשר להגיע לשרת החיזוי או שהוא מחזיר שגיאה, ה-EPP חוזר אוטומטית לציון מורכב שמבוסס על השימוש במטמון של זוגות מפתח/ערך, על עומק התור ועל התאמה למטמון של הקידומת.
  2. ‫prefix-cache-affinity-filter: המסנן הזה מצמצם את קבוצת המועמדים ל-Pods שחמים במטמון, אם ציון ההתאמה של מטמון הקידומת של Pod כלשהו חורג מסף הזיקה (ברירת מחדל של 0.80). הסף הזה מפריד בין שתי אוכלוסיות שנצפו בסביבת הייצור: Pods שכבר יש להם היסטוריית שיחות במטמון מפניות קודמות, ו-Pods שאין להם היסטוריית שיחות במטמון. המסנן הזה מיישם אסטרטגיה של ניצול וחיפוש עם פרמטר אפסילון:

    • ‫Exploit (נתיב ברירת המחדל): הנתיב הזה מוביל ל-Pods של מטמון חם, כך שהניקוד מתמקד בשימוש חוזר במטמון.

    • Explore (small probability): הנתיב הזה עוקף את המסנן לחלוטין בחלק קטן של הבקשות שניתן להגדרה, כדי לאכלס רשומות במטמון ב-Pods חדשים ולמנוע פיצול של המטמון.

    • TTFT load gate: גם בנתיב הניצול, אם ה-TTFT החזוי של ה-Pod הטוב ביותר לטעינת מטמון חם חורג מה-TTFT הכולל הטוב ביותר של ה-Pod ביותר מסף שניתן להגדרה (ברירת מחדל של 5,000 אלפיות השנייה), הקשר נשבר ונעשה שימוש במערך המועמדים המלא.

  3. ‫slo-headroom-tier-filter (בקשות SLO בלבד): כשהבקשה כוללת כותרות SLO, המערכת מפצלת את ה-Pods המועמדים לשתי רמות: רמה חיובית (צפוי שהם יעמדו ב-SLO) ורמה שלילית (צפוי שהם יפרו את ה-SLO).

  4. ‫latency-scorer: ניקוד של רצפי מודעות פוטנציאליים. אם לא מצורפים כותרות SLO, נבחר הפוד עם זמן האחזור הנמוך ביותר. כשמשתמשים בכותרות SLO, הציון מבוסס על מרווח הביטחון (SLO פחות זמן האחזור הצפוי) באמצעות headroomSelectionStrategy:

    • ‫least (ברירת מחדל): Bin-pack. הניתוב אל ה-Pod עם המרווח החיובי הקטן ביותר, כדי למקסם את הניצול ולשמור על Pods עם עומס נמוך יותר פנויים לפרצי תנועה עתידיים.
    • ‫most: המרחק. מסלולים אל ה-Pod עם המרווח החיובי הגדול ביותר, כדי להשאיר יותר מרווח לשיאים לא צפויים בעומס.
  5. ‫latency-slo-admitter (בקשות SLO בלבד): דחיית בקשות שניתנות להסרה (העדיפות נמוכה מ-0) כשאין חיזוי של אף Pod מועמד שיעמוד ביעד ה-SLO, במקום לנצל את הקיבולת בבקשה שצפוי שלא תעמוד ביעד שלה. למסנן הזה אין השפעה כשאין כותרות SLO או כשקיים Pod שעומד בדרישות ה-SLO.

  6. ‫weighted-random-picker: בוחר את הפוד הסופי באמצעות בחירה אקראית משוקללת על סמך הניקוד. כך העומס מתחלק בין הפודים, אבל עדיין יש עדיפות לפודים עם ניקוד טוב יותר.

מצב סטרימינג

הפלאגין predicted-latency-producer תומך בשני מצבי אימון, שמוגדרים באמצעות הפרמטר streamingMode:

  • ‫streamingMode: false (ברירת מחדל): אימון על זמן טעינה של בקשה מקצה לקצה (E2E). כדאי להשתמש במצב הזה אם בעומס העבודה יש שילוב של תגובות בסטרימינג ותגובות שלא בסטרימינג, או אם אתם צריכים ניתוב עם מודעות לזמן האחזור בלי אכיפה של SLO לכל בקשה.
  • ‫streamingMode: true: מאמן מודלים נפרדים של TTFT ו-TPOT. הערך של TTFT נרשם בחלק הראשון של הסטרימינג, והערך של TPOT נדגם בטוקנים הבאים. כדאי להשתמש במצב הזה אם עומס העבודה שלכם מבוסס על סטרימינג מלא ואתם צריכים אכיפה משמעותית של x-slo-ttft-ms / x-slo-tpot-ms.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • אם צריך, מפעילים את Compute Engine API, את Network Services API ואת Model Armor API.

    עוברים אל הפעלת גישה לממשקי API ופועלים לפי ההוראות.

  • מוודאים שיש פריסה תקינה של GKE Inference Gateway. איך פורסים את GKE Inference Gateway

  • חשוב לוודא ש-InferencePool משתמש במערך הומוגני של Pods – סוג GPU זהה, משקלי מודל ותצורת הגשה.

  • מוודאים שאשכול GKE הוא מגרסה 1.32.3 ואילך.

  • מתקינים את Helm. אפשר לעיין במדריך ההתקנה של Helm.

הפעלת תזמון מבוסס-חביון צפוי

השלבים הבאים מנחים אתכם בהפעלת תזמון מבוסס-חביון חזוי לפריסת GKE Inference Gateway.

שלב 1: התקנה או שדרוג של InferencePool עם הפעלת חיזוי של זמן האחזור

הדגל latencyPredictor.enabled=true פורס את ה-sidecar של שרת האימון ושל שרת החיזוי בתוך ה-Pod של EPP ומקשר את צינור הנתונים המלא של תוסף התזמון:

helm upgrade --install INFERENCE_POOL_NAME \
  --set inferencePool.modelServers.matchLabels.app=MODEL_SERVER_LABEL \
  --set provider.name=gke \
  --set inferenceExtension.monitoring.gke.enabled=true \
  --set inferenceExtension.latencyPredictor.enabled=true \
  --version LLM_D_VERSION \
  oci://LLM_D_REGISTRY_PATH

מחליפים את מה שכתוב בשדות הבאים:

  • ‫INFERENCE_POOL_NAME: השם של InferencePool, לדוגמה vllm-llama3-8b-instruct.
  • ‫MODEL_SERVER_LABEL: מפתח התווית שמשמש לבחירת ה-Pods של שרת המודל.
  • ‫LLM_D_VERSION: גרסת תרשים ה-Helm של llm-d שבה רוצים להשתמש.
  • ‫LLM_D_REGISTRY_PATH: הנתיב למאגר OCI של llm-d.

שלב 2: בדיקת הפריסה

מוודאים ש-EPP Pod פועל וכל קונטיינרים של sidecar מוכנים:

kubectl get pods -l app=INFERENCE_POOL_NAME-epp

ב-EPP Pod אמורים להופיע כל מאגרי התגים במצב Running או Ready: ה-EPP עצמו, שרת ההדרכה ושרת חיזוי אחד או יותר.

שלב 3: שליחת בקשה ראשונית

לפני שמפעילים כותרות SLO, שולחים בקשת הסקה רגילה כדי לוודא שהניתוב פועל:

curl -i -X POST GATEWAY_IP:PORT/v1/completions \
 -H 'Content-Type: application/json' \
 -H 'Authorization: Bearer $(gcloud auth print-access-token)' \
 -H 'x-prediction-based-scheduling: true' \
 -d '{
    "model": "MODEL_NAME",
    "prompt": "PROMPT_TEXT",
    "max_tokens": MAX_TOKENS,
    "temperature": "0"
 }'

מחליפים את מה שכתוב בשדות הבאים:

  • ‫GATEWAY_IP: כתובת ה-IP של שירות השער.
  • ‫PORT: מספר היציאה של שירות השער.
  • ‫MODEL_NAME: השם של המודל שבו רוצים להשתמש להסקת מסקנות.
  • ‫PROMPT_TEXT: הפרומפט לקלט.
  • ‫MAX_TOKENS: המספר המקסימלי של האסימונים שייווצרו.

הכותרת x-prediction-based-scheduling: true מאפשרת להוסיף את הבקשה הזו לצינור של תזמון חזוי של זמן האחזור. במהלך תקופת החימום של כלי החיזוי, ה-EPP חוזר לניתוב היוריסטי.

שלב 4: שליחת בקשות עם מודעות להסכם רמת שירות (אופציונלי)

כדי להפעיל אכיפה של SLO לכל בקשה, מוסיפים כותרות של יעדי חביון TTFT ו-TPOT:

curl -i -X POST GATEWAY_IP:PORT/v1/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer $(gcloud auth print-access-token)' \
  -H 'x-prediction-based-scheduling: true' \
  -H 'x-slo-ttft-ms: 500' \
  -H 'x-slo-tpot-ms: 50' \
  -d '{
    "model": "MODEL_NAME",
    "prompt": "PROMPT_TEXT",
    "max_tokens": MAX_TOKENS,
    "temperature": "0",
    "stream": true
  }'

מחליפים את מה שכתוב בשדות הבאים:

  • ‫GATEWAY_IP: כתובת ה-IP של שירות השער.
  • ‫PORT: מספר היציאה של שירות השער.
  • ‫MODEL_NAME: השם של המודל שבו רוצים להשתמש להסקת מסקנות.
  • ‫PROMPT_TEXT: הפרומפט לקלט.
  • ‫MAX_TOKENS: המספר המקסימלי של האסימונים שייווצרו.

כותרות הבקשות:

  • ‫x-prediction-based-scheduling: true: צינור התזמון של זמן האחזור החזוי.
  • ‫x-slo-ttft-ms: משך הזמן המקסימלי שנסבל עד לקבלת האסימון הראשון, באלפיות השנייה.
  • ‫x-slo-tpot-ms: הזמן המקסימלי המקובל לכל אסימון פלט באלפיות השנייה.

מעקב אחרי תזמון של זמן אחזור צפוי

כשהתכונה 'חיזוי זמן האחזור' מופעלת, ה-EPP חושף מדדים נוספים דרך Cloud Monitoring.

מדד תיאור
inference_objective_request_ttft_seconds התפלגות בפועל של TTFT (או חביון מקצה לקצה אם streamingMode=false).
inference_objective_request_predicted_ttft_seconds התפלגות צפויה של TTFT (או חביון מקצה לקצה אם streamingMode=false).
inference_objective_request_tpot_seconds התפלגות ה-TPOT בפועל.
inference_objective_request_predicted_tpot_seconds התפלגות ה-TPOT הצפויה.
inference_objective_request_ttft_slo_violation_total מונה של הפרות של SLO של TTFT.

הגדלת הקיבולת של שרת החיזוי

ה-EPP מבצע קריאת חיזוי אחת לכל Pod מועמד לכל בקשה נכנסת. כל מופע של שרת חיזוי יכול לתמוך בערך ב-300 שאילתות לשנייה של עבודת חיזוי.

הנחיות משוערות לגבי מספר המופעים של שרת החיזוי:

מספר QPS באשכול (100 פודים) נדרשים שרתי חיזוי
עד 1,000 שאילתות לשנייה (QPS) שרת אחד
עד 5,000 שאילתות לשנייה (QPS) ‫2 שרתים
עד 10,000 שאילתות לשנייה ‫4 שרתים

כדי להוסיף מופעים של Prediction Server, צריך לעדכן את הערך latencyPredictor.predictionServerCount Helm.

מגבלות

  • הומוגני InferencePool נדרש: לא ניתן להשתמש בסוגים מעורבים של GPU, בגרסאות שונות של מודלים או בהגדרות שונות של הגשה במאגר אחד.
  • תקופת הרצה: כדי שהתחזיות יהיו מדויקות, מודל XGBoost צריך לקבל מספיק דגימות של תנועה בזמן אמת.
  • אכיפת SLO: האכיפה מתבצעת רק בשכבת הניתוב. שרת המודל לא מפסיק בקשות שחורגות מיעד ה-SLO אחרי הבחירה.
  • סטטוס: התכונה הזו היא בגרסת טרום-השקה (Preview). לא מומלץ להשתמש בו לעומסי עבודה בסביבת ייצור עם דרישות הסכם רמת שירות מחמירות, בלי לבצע בדיקות יסודיות.

המאמרים הבאים