פריסת GKE Inference Gateway

בדף הזה מוסבר איך לפרוס את GKE Inference Gateway.

הדף הזה מיועד למומחי רשתות שאחראים על ניהול התשתית של GKE ולאדמינים של פלטפורמות שמנהלים עומסי עבודה של AI.

לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את הנושאים הבאים:

‫GKE Inference Gateway משפר את Google Kubernetes Engine (GKE) Gateway כדי לייעל את ההצגה של אפליקציות ועומסי עבודה של AI גנרטיבי ב-GKE. הוא מאפשר ניהול יעיל של עומסי עבודה של AI והתאמה שלהם, מאפשר להגדיר יעדי ביצועים ספציפיים לעומס העבודה, כמו זמן אחזור, ומשפר את ניצול המשאבים, את יכולת הצפייה ואת הבטיחות של ה-AI.

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

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

  • מפעילים את ממשק ה-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 ואת הגנה מוגברת על המודל API.

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

  • צריך לוודא שיש לכם בפרויקט את התפקידים הבאים: roles/container.admin, ‏ roles/iam.serviceAccountAdmin.

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

  • אם עדיין אין לכם חשבון ב-Hugging Face, אתם צריכים ליצור חשבון. תצטרכו את זה כדי לגשת למשאבי המודל של המדריך הזה.

  • שולחים בקשה לגישה למודל Llama 3.1 ויוצרים אסימון גישה. כדי לגשת למודל הזה, צריך לשלוח בקשה מאושרת ב-Hugging Face. אם הגישה לא אושרה, הפריסה תיכשל.

    • חתימה על הסכם ההסכמה לרישיון: כדי להשתמש במודל Llama 3.1, צריך לחתום על הסכם ההסכמה. עוברים לדף של המודל ב-Hugging Face, מאמתים את החשבון ומאשרים את התנאים.
    • יצירת אסימון גישה: כדי לגשת למודל, צריך אסימון של Hugging Face. בחשבון Hugging Face, עוברים אל Your Profile > Settings > Access Tokens (הפרופיל שלך > הגדרות > טוקנים לגישה), יוצרים טוקן חדש עם הרשאות קריאה לפחות ומעתיקים אותו ללוח.

דרישות של GKE Gateway controller

  • ‫GKE בגרסה 1.32.3 ואילך.
  • ‫Google Cloud CLI בגרסה 407.0.0 ואילך.
  • ‫Gateway API נתמך רק באשכולות שמותאמים ל-VPC.
  • חובה להפעיל רשת משנה (subnet) של פרוקסי בלבד.
  • צריך להפעיל את התוסף HttpLoadBalancing באשכול.
  • אם אתם משתמשים ב-Istio, אתם צריכים לשדרג את Istio לאחת מהגרסאות הבאות:
    • גרסה 1.15.2 ואילך
    • ‫1.14.5 ואילך
    • ‫1.13.9 ואילך
  • אם משתמשים ב-VPC משותף, צריך להקצות את התפקיד Compute Network User לחשבון השירות של GKE בפרויקט השירות.

הגבלות ומגבלות

ההגבלות והמגבלות הבאות חלות:

  • אין תמיכה בשערי כניסה מרובי-אשכולות.
  • GKE Inference Gateway נתמך רק במשאבי gke-l7-regional-external-managed ו-gke-l7-rilb GatewayClass.
  • אין תמיכה במאזני עומסים פנימיים של אפליקציות שפועלים בכמה אזורים.

הגדרת GKE Inference Gateway

כדי להגדיר את GKE Inference Gateway, אפשר להיעזר בדוגמה הבאה. צוות מריץ מודלים של vLLM ושל Llama3 ומבצע ניסויים פעילים עם שני מתאמים שונים של LoRA שעברו כוונון עדין: food-review ו-cad-fabricator.

תהליך העבודה הכללי להגדרת GKE Inference Gateway הוא כדלקמן:

  1. הכנת הסביבה: הגדרת התשתית והרכיבים הנדרשים.
  2. יצירת מאגר הסקה: הגדרה של מאגר שרתי מודלים באמצעות InferencePool Custom Resource.
  3. מציינים יעדי הסקה: מציינים יעדי הסקה באמצעות InferenceObjective Custom Resource
  4. יוצרים את השער: חושפים את שירות ההסקה באמצעות Gateway API.
  5. יוצרים את HTTPRoute: מגדירים איך תעבורת HTTP מנותבת לשירות ההסקה.
  6. שליחת בקשות הסקה: שליחת בקשות למודל שנפרס.

הכנת הסביבה

  1. מתקינים את Helm.

  2. יוצרים אשכול GKE:

    • יוצרים אשכול GKE Autopilot או Standard בגרסה 1.32.3 ואילך. cluster-toolkit gke-a3-highgpuדוגמה להגדרה של פריסה בלחיצה אחת
    • מגדירים את הצמתים עם משפחת המחשוב והמאיץ המועדפים.
    • אפשר להשתמש במדריך למתחילים עם GKE Inference כדי לקבל מניפסטים של פריסות שהוגדרו מראש ונבדקו, על סמך המאיץ, המודל ודרישות הביצועים שבחרתם.
  3. מתקינים את ההגדרות הנדרשות של משאבים מותאמים אישית (CRD) באשכול GKE:

    • בגרסאות GKE 1.34.0-gke.1626000 ואילך, מתקינים רק את CRD של אלפא InferenceObjective:

      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/v1.0.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml
      
    • בגרסאות GKE מוקדמות יותר מ-1.34.0-gke.1626000, צריך להתקין גם את v1 InferencePool וגם את אלפא InferenceObjective CRD:

      kubectl apply -f  https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v1.0.0/manifests.yaml
      

      מידע נוסף זמין בטבלת התאימות.

  4. אם אתם משתמשים בגרסה של GKE שמוקדמת לגרסה v1.32.2-gke.1182001 ואתם רוצים להשתמש בהגנה מוגברת על המודל עם GKE Inference Gateway, אתם צריכים להתקין את ה-CRD של תוסף התנועה והניתוב:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficextensions.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcproutingextensions.yaml
    

יצירת שרת מודלים ופריסת מודלים

בקטע הזה מוסבר איך פורסים שרת מודלים ומודל. בדוגמה הזו נעשה שימוש בשרת מודלים vLLM עם מודל Llama3. הפריסה מסומנת בתווית app:vllm-llama3-8b-instruct. בפריסה הזו נעשה שימוש גם בשני מתאמי LoRA בשם food-review ו-cad-fabricator מ-Hugging Face.

אפשר להתאים את הדוגמה הזו לקונטיינר של שרת המודל ולמודל שלכם, ליציאת ההגשה ולשם הפריסה. אפשר גם להגדיר מתאמי LoRA בפריסה, או לפרוס את מודל הבסיס. בשלבים הבאים מוסבר איך ליצור את משאבי Kubernetes הנדרשים.

  1. יוצרים סוד של Kubernetes לאחסון הטוקן של Hugging Face. הטוקן הזה משמש לגישה למודל הבסיסי ולמתאמי LoRA:

    kubectl create secret generic hf-token --from-literal=token=HF_TOKEN
    

    מחליפים את HF_TOKEN באסימון Hugging Face.

  2. פורסים את שרת המודל ואת המודל. הפקודה הבאה מחילה מניפסט שמגדיר פריסת Kubernetes לשרת מודלים של vLLM עם מודל vLLM:Llama3

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/release-1.0/config/manifests/vllm/gpu-deployment.yaml
    

יצירת מאגר הסקה

InferencePool משאב מותאם אישית של Kubernetes מגדיר קבוצה של Pod עם מודל שפה גדול (LLM) בסיסי משותף והגדרת מחשוב. השדה selector מציין אילו תרמילים שייכים למאגר הזה. התוויות בכלי הבחירה הזה צריכות להיות זהות לתוויות שמוחלות על ה-Pods של שרת המודל. השדה targetPort מגדיר את היציאות שבהן שרת המודל משתמש בתוך קבוצות ה-Pod. השדה extensionRef מפנה לשירות הרחבה שמספק יכולת נוספת למאגר ההסקה. ה-InferencePool מאפשר ל-GKE Inference Gateway לנתב תנועה ל-Pods של שרת המודל.

לפני שיוצרים את InferencePool, צריך לוודא שה-Pods שנבחרו על ידי InferencePool כבר פועלים.

כדי ליצור InferencePool באמצעות Helm, מבצעים את השלבים הבאים:

helm install vllm-llama3-8b-instruct \
  --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
  --set provider.name=gke \
  --set inferenceExtension.monitoring.gke.enabled=true \
  --version v1.0.1 \
  oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool

משנים את השדה הבא בהתאם לפריסה:

  • inferencePool.modelServers.matchLabels.app: המפתח של התווית שמשמשת לבחירת ה-Pods של שרת המודל.

לצורך מעקב, גירוד מדדים עבור השירות המנוהל של Google Cloud ל-Prometheus מופעל כברירת מחדל.

  • כדי להשבית את התכונה הזו, מוסיפים את הדגל --set inferenceExtension.monitoring.gke.enabled=false לפקודה.
  • אם משתמשים בניטור ברירת המחדל באשכול GKE Autopilot, צריך להוסיף גם את הדגל --set provider.gke.autopilot=true.

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

הפעולה הזו יוצרת אובייקט InferencePool: vllm-llama3-8b-instruct עם הפניה לשירותי נקודות הקצה של המודל בתוך קבוצות ה-Pod. נוצר גם פריט לפריסה של הכלי לבחירת נקודות קצה בשם app:vllm-llama3-8b-instruct-epp עבור InferencePool שנוצר.

ציון יעדי הסקה

באמצעות המשאב המותאם אישית InferenceObjective אפשר לציין את העדיפות של הבקשות.

השדה metadata.name של משאב InferenceObjective מציין את השם של יעד ההסקות, השדה Priority מציין את רמת הקריטיות של ההצגה שלו, והשדה poolRef מציין את InferencePool שבו המודל מוצג.

apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceObjective
metadata:
  name: NAME
spec:
  priority: VALUE
  poolRef:
    name: INFERENCE_POOL_NAME
    group: "inference.networking.k8s.io"

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

  • NAME: השם של יעד ההסקה. לדוגמה, food-review.
  • VALUE: העדיפות של יעד ההסקה. זהו מספר שלם, וככל שהערך גבוה יותר הבקשה קריטית יותר. לדוגמה, 10.
  • INFERENCE_POOL_NAME: השם של InferencePool שיצרתם בשלב הקודם. לדוגמה: vllm-llama3-8b-instruct.

כדי ליצור InferenceObjective, פועלים לפי השלבים הבאים:

  1. שומרים את קובץ המניפסט הבא בשם inference-objectives.yaml. במניפסט הזה נוצרים שני משאבי InferenceObjective. ההגדרה הראשונה קובעת את food-reviewיעד ההסקה ב-vllm-llama3-8b-instruct InferencePool עם עדיפות של 10. ההגדרה השנייה קובעת שהיעד llama3-base-model Inference יציג מודעות בעדיפות גבוהה יותר של 20.

    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceObjective
    metadata:
      name: food-review
    spec:
      priority: 10
      poolRef:
        name: vllm-llama3-8b-instruct
        group: "inference.networking.k8s.io"
    ---
    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceObjective
    metadata:
      name: llama3-base-model
    spec:
      priority: 20 # Higher priority
      poolRef:
        name: vllm-llama3-8b-instruct
    
  2. מחילים את קובץ המניפסט לדוגמה על האשכול:

    kubectl apply -f inference-objectives.yaml
    

יצירת השער

משאב השער הוא נקודת הכניסה לתעבורה חיצונית לאשכול Kubernetes. היא מגדירה את המאזינים שמקבלים חיבורים נכנסים.

ה-GKE Inference Gateway פועל עם Gateway Classes הבאים:

  • gke-l7-rilb: למאזני עומסים פנימיים אזוריים של אפליקציות.
  • gke-l7-regional-external-managed: למאזני עומסים אזוריים חיצוניים של אפליקציות (ALB).

מידע נוסף זמין במאמר בנושא Gateway Classes.

כדי ליצור שער:

  1. שומרים את קובץ המניפסט לדוגמה הבא בשם gateway.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
    spec:
      gatewayClassName: GATEWAY_CLASS
      listeners:
        - protocol: HTTP
          port: 80
          name: http
    

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

    • GATEWAY_NAME: שם ייחודי למשאב Gateway. לדוגמה, inference-gateway.
    • GATEWAY_CLASS: Gateway Class שרוצים להשתמש בו. לדוגמה, gke-l7-regional-external-managed.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f gateway.yaml
    

הערה: מידע נוסף על הגדרת TLS כדי לאבטח את השער באמצעות HTTPS זמין במסמכי התיעוד של GKE בנושא הגדרת TLS.

יצירת HTTPRoute

משאב HTTPRoute מגדיר איך שער GKE מנתב בקשות HTTP נכנסות לשירותי קצה עורפיים, כמו InferencePool. המשאב HTTPRoute מציין כללי התאמה (לדוגמה, כותרות או נתיבים) ואת השרת העורפי שאליו התנועה צריכה להיות מועברת.

  1. כדי ליצור HTTPRoute, שומרים את קובץ המניפסט לדוגמה הבא בשם httproute.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: HTTPROUTE_NAME
    spec:
      parentRefs:
      - name: GATEWAY_NAME
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: PATH_PREFIX
        backendRefs:
        - name: INFERENCE_POOL_NAME
          group: "inference.networking.k8s.io"
          kind: InferencePool
    

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

    • HTTPROUTE_NAME: שם ייחודי של משאב HTTPRoute. לדוגמה, my-route.
    • GATEWAY_NAME: השם של משאב Gateway שיצרתם. לדוגמה, inference-gateway.
    • PATH_PREFIX: קידומת הנתיב שבה משתמשים כדי להתאים לבקשות נכנסות. לדוגמה, / כדי להתאים לכולם.
    • INFERENCE_POOL_NAME: השם של משאב InferencePool שאליו רוצים לנתב את התנועה. לדוגמה, vllm-llama3-8b-instruct.
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f httproute.yaml
    

שליחת בקשת הסקה

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

כדי לשלוח בקשות להסקת מסקנות:

  1. מגדירים את משתני הסביבה הבאים:

    export GATEWAY_NAME=GATEWAY_NAME
    export PORT_NUMBER=PORT_NUMBER # Use 80 for HTTP
    

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

    • GATEWAY_NAME: השם של משאב ה-Gateway.
    • PORT_NUMBER: מספר היציאה שהגדרתם ב-Gateway.
  2. כדי לקבל את נקודת הקצה של שער, מריצים את הפקודה הבאה:

    echo "Waiting for the Gateway IP address..."
    IP=""
    while [ -z "$IP" ]; do
      IP=$(kubectl get gateway/${GATEWAY_NAME} -o jsonpath='{.status.addresses[0].value}' 2>/dev/null)
      if [ -z "$IP" ]; then
        echo "Gateway IP not found, waiting 5 seconds..."
        sleep 5
      fi
    done
    
    echo "Gateway IP address is: $IP"
    PORT=${PORT_NUMBER}
    
  3. כדי לשלוח בקשה לנקודת הקצה /v1/completions באמצעות curl, מריצים את הפקודה הבאה:

    curl -i -X POST ${IP}:${PORT}/v1/completions \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer $(gcloud auth application-default print-access-token)' \
    -d '{
        "model": "MODEL_NAME",
        "prompt": "PROMPT_TEXT",
        "max_tokens": MAX_TOKENS,
        "temperature": "TEMPERATURE"
    }'
    

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

    • MODEL_NAME: השם של המודל או של מתאם LoRA שרוצים להשתמש בהם.
    • PROMPT_TEXT: הנחיית הקלט למודל.
    • MAX_TOKENS: המספר המקסימלי של הטוקנים שיופיעו בתגובה.
    • TEMPERATURE: שולט באקראיות של הפלט. כדי לקבל פלט דטרמיניסטי, צריך להשתמש בערך 0, או במספר גבוה יותר כדי לקבל פלט יצירתי יותר.

בדוגמה הבאה אפשר לראות איך לשלוח בקשת דוגמה ל-GKE Inference Gateway:

curl -i -X POST ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -H 'Authorization: Bearer $(gcloud auth print-access-token)' -d '{
    "model": "food-review-1",
    "prompt": "What is the best pizza in the world?",
    "max_tokens": 2048,
    "temperature": "0"
}'

חשוב לשים לב להתנהגויות הבאות:

  • גוף הבקשה: גוף הבקשה יכול לכלול פרמטרים נוספים כמו stop ו-top_p. רשימה מלאה של האפשרויות מופיעה במפרט של OpenAI API.
  • טיפול בשגיאות: צריך להטמיע טיפול מתאים בשגיאות בקוד הלקוח כדי לטפל בשגיאות אפשריות בתגובה. לדוגמה, בודקים את קוד הסטטוס של HTTP בתגובה curl. קוד סטטוס שאינו 200 בדרך כלל מציין שגיאה.
  • אימות והרשאה: עבור פריסות בסביבת ייצור, אבטחו את נקודת הקצה ל-API באמצעות מנגנוני אימות והרשאה. הבקשות צריכות לכלול את הכותרות המתאימות (לדוגמה, Authorization).

מטריצת תאימות

בטבלה מפורטים התאימות והתמיכה במטריצה של Gateway API Inference Extension Custom Resource Definitions (CRDs). במאמר מפורטות גרסאות ה-CRD שנתמכות על ידי GKE בהשוואה לפרויקט התוסף היקש של Gateway API בקוד פתוח (OSS), כולל דרישות ספציפיות לגבי הגרסאות והערות לגבי ההתקנה.

שם CRD גרסת CRD API תמיכה מנוהלת ב-GKE תמיכה ב-OSS (Gateway API Inference Extension)
V1 InferencePool inference.networking.k8s.io/v1 נתמך ב-GKE 1.32.3 ואילך, ו-CRD מותקן כברירת מחדל ב-GKE 1.34.0-gke.1626000 ואילך נתמך החל מ-Gateway API Inference Extension v1.0.0
‫Alpha InferencePool (מומלץ למשתמשים להתחיל עם InferencePool v1 כי גרסת האלפא של InferencePool הוצאה משימוש) inference.networking.x-k8s.io/v1alpha2 נתמך ב-GKE 1.32.3 ואילך. עם זאת, CRD לא מותקן כברירת מחדל ב-GKE. המשתמשים צריכים להתקין את CRD באופן ידני מתוך Gateway API Inference Extension. נתמך החל מ-Gateway API Inference Extension v0.2.0
Alpha InferenceObjective inference.networking.x-k8s.io/v1alpha2 ‫GKE לא מנהל את InferenceObjective נתמך החל מ-Gateway API Inference Extension v1.0.0
‫Alpha InferenceModel (מומלץ למשתמשים להתחיל עם InferenceObjective כי InferenceModel הוצא משימוש) inference.networking.x-k8s.io/v1alpha2 ‫GKE לא מנהל את InferenceModel התמיכה מתחילה בגרסה 0.2.0 של Gateway API Inference Extension.

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