הצגת LLM באמצעות TPU Trillium ב-GKE עם vLLM

במדריך הזה נסביר איך להכניס לשימוש בסביבת הייצור מודלים גדולים של שפה (LLM) באמצעות Tensor Processing Units (TPU) ב-Google Kubernetes Engine ‏ (GKE) עם ה-vLLM, פלטפורמה להצגת מודלים. במדריך הזה נלמד איך להכניס לשימוש בסביבת הייצור את Llama 3.1 70b, להשתמש ב-TPU Trillium ולהגדיר התאמה אופקית של קבוצות Pod לעומס באמצעות מדדי שרת vLLM.

המסמך הזה הוא נקודת התחלה טובה אם אתם צריכים שליטה מפורטת, מדרגיות, חוסן (resilience), ניידות ויעילות כלכלית של Kubernetes מנוהל כשאתם פורסים ומכניסים לשימוש בסביבת הייצור את עומסי העבודה של AI/ML.

רקע

באמצעות TPU Trillium ב-GKE, אתם יכולים להטמיע פתרון חזק ומוכן לייצור עם כל היתרונות של Kubernetes מנוהל, כולל יכולת הרחבה יעילה וזמינות גבוהה יותר. בקטע הזה מתוארות הטכנולוגיות העיקריות שמופיעות במדריך הזה.

TPU Trillium

יחידות TPU הן מעגלים משולבים לאפליקציות ספציפיות (ASIC) שפותחו על ידי Google. יחידות TPU משמשות להאצת מודלים של למידת מכונה ו-AI שנבנו באמצעות מסגרות כמו TensorFlow,‏ PyTorch ו-JAX. במדריך הזה נעשה שימוש ב-TPU Trillium, שהוא ה-TPU מהדור השישי של Google.

לפני שמשתמשים ב-TPU ב-GKE, מומלץ להשלים את תוכנית הלימודים הבאה:

  1. מידע על ארכיטקטורת המערכת של TPU Trillium
  2. מידע נוסף על TPUs ב-GKE

vLLM

‫vLLM הוא פריימוורק בקוד פתוח שעבר אופטימיזציה גבוהה להצגת מודלים גדולים של שפה (LLM). בעזרת vLLM אפשר להגדיל את קצב העברת הנתונים (throughput) של הצגת המודלים ב-TPU, עם תכונות כמו:

  • הטמעה של טרנספורמר שעבר אופטימיזציה באמצעות PagedAttention.
  • הוספת תכונה של אצווה מתמשכת כדי לשפר את התפוקה הכוללת של הצגת המודעות.
  • מקביליות טנסורית והצגה מבוזרת בכמה יחידות TPU.

מידע נוסף מופיע במאמרי העזרה בנושא vLLM.

מודלים ותכונות נתמכים

לפני שמפעילים מודלים של LLM עם vLLM ב-TPU, מומלץ לוודא שהמודל תואם ושהתכונות הנתמכות פועלות, כדי למנוע בעיות בהפעלה. הספרייה vllm-project/tpu-inference מספקת את הקצה העורפי הדרוש כדי להפעיל את vLLM ב-TPU.

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

Cloud Storage FUSE

‫Cloud Storage FUSE מספק גישה מאשכול GKE ל-Cloud Storage למשקלי מודלים שנמצאים בקטגוריות של אחסון אובייקטים. במדריך הזה, הקטגוריה של Cloud Storage שתיצורו תהיה ריקה בהתחלה. כש-vLLM מופעל, GKE מוריד את המודל מ-Hugging Face ומאחסן במטמון את המשקלים בקטגוריה של Cloud Storage. בהפעלה מחדש של Pod או בהרחבת הפריסה, טעינות המודלים הבאות יורידו נתונים שנשמרו במטמון מהקטגוריה של Cloud Storage, וישתמשו בהורדות מקבילות לביצועים אופטימליים.

מידע נוסף זמין במאמר בנושא מנהל התקן ה-CSI של Cloud Storage FUSE.

מטרות

המדריך הזה מיועד למהנדסי MLOps או DevOps או לאדמינים של פלטפורמות שרוצים להשתמש ביכולות התזמור של GKE כדי להפעיל מודלים גדולים של שפה (LLM).

במדריך הזה מוסבר איך:

  1. יוצרים אשכול GKE עם טופולוגיית TPU Trillium המומלצת על סמך מאפייני המודל.
  2. פורסים את מסגרת vLLM במאגר צמתים באשכול.
  3. שימוש ב-framework של vLLM כדי להציג את Llama 3.1 70b באמצעות מאזן עומסים.
  4. הגדרה של התאמה אופקית של קבוצות Pod לעומס באמצעות מדדי שרת vLLM.
  5. הצגת המודל.

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

  • נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

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

    בדיקת התפקידים

    1. נכנסים לדף IAM במסוף Google Cloud .

      כניסה לדף IAM
    2. בוחרים את הפרויקט.
    3. בעמודה Principal (חשבון המשתמש), מוצאים את כל השורות שבהן מופיע השם שלכם או של קבוצה שאתם נכללים בה. כדי לברר באילו קבוצות אתם נכללים, פנו לאדמין.

    4. בודקים את העמודה Role בכל השורות שבהן מצוין או מופיע השם שלכם, כדי לראות אם רשימת התפקידים כוללת את התפקידים הנדרשים.

    מתן התפקידים

    1. נכנסים לדף IAM במסוף Google Cloud .

      כניסה לדף IAM
    2. בוחרים את הפרויקט.
    3. לוחצים על Grant access.
    4. בשדה New principals, מזינים את מזהה המשתמש. ‫ בדרך כלל מזהה המשתמש הוא כתובת האימייל של חשבון Google.

    5. לוחצים על Select a role ומחפשים את התפקיד.
    6. כדי לתת עוד תפקידים, לוחצים על Add another role ומוסיפים אותם.
    7. לוחצים על Save.

הכנת הסביבה

בקטע הזה, תכינו את המשאבים שדרושים לפריסת vLLM והמודל.

גישה למודל

כדי להשתמש ב-Llama 3.1 70b במאגר Hugging Face, צריך לחתום על הסכם ההסכמה.

יצירת אסימון גישה

אם עדיין אין לכם טוקן, יוצרים טוקן חדש של Hugging Face:

  1. לוחצים על הפרופיל שלך > הגדרות > טוקנים של גישה.
  2. בוחרים באפשרות New Token (טוקן חדש).
  3. מציינים שם לבחירתכם ותפקיד ברמה של Read לפחות.
  4. לוחצים על יצירת אסימון.

הפעלת Cloud Shell

במדריך הזה משתמשים ב-Cloud Shell כדי לנהל משאבים שמתארחים ב-Google Cloud. ב-Cloud Shell מותקנת מראש התוכנה שדרושה לכם כדי לבצע את ההדרכה הזו, כולל kubectl ו-CLI של gcloud.

כדי להגדיר את הסביבה באמצעות Cloud Shell:

  1. ב Google Cloud מסוף, מפעילים סשן של Cloud Shell על ידי לחיצה על Activate Cloud Shell בGoogle Cloud מסוף.סמל ההפעלה של Cloud Shell סשן יופעל בחלונית התחתונה של מסוף Google Cloud .

  2. מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:

    gcloud config set project PROJECT_ID && \
    gcloud config set billing/quota_project PROJECT_ID && \
    export PROJECT_ID=$(gcloud config get project) && \
    export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") && \
    export CLUSTER_NAME=CLUSTER_NAME && \
    export CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATION && \
    export ZONE=ZONE && \
    export HF_TOKEN=HUGGING_FACE_TOKEN && \
    export CLUSTER_VERSION=CLUSTER_VERSION && \
    export GSBUCKET=GSBUCKET && \
    export KSA_NAME=KSA_NAME && \
    export NAMESPACE=NAMESPACE
    

    מחליפים את הערכים הבאים:

    • PROJECT_ID : Google Cloud מזהה הפרויקט.
    • CLUSTER_NAME : השם של אשכול GKE.
    • CONTROL_PLANE_LOCATION: האזור של Compute Engine במישור הבקרה של האשכול. צריך לציין אזור שתומך ב-TPU Trillium‏ (v6e).
    • ZONE : אזור שתומך ב-TPU Trillium‏ (v6e).
    • CLUSTER_VERSION : גרסת GKE שתומכת ב-TPU Trillium‏ (v6e). מידע נוסף זמין במאמר אימות הזמינות של TPU ב-GKE.
    • GSBUCKET : השם של קטגוריית Cloud Storage שבה רוצים להשתמש ב-Cloud Storage FUSE.
    • KSA_NAME : השם של Kubernetes ServiceAccount שמשמש לגישה לקטגוריות של Cloud Storage. כדי ש-Cloud Storage FUSE יפעל, צריך גישה לקטגוריה.
    • NAMESPACE : מרחב השמות של Kubernetes שבו רוצים לפרוס את נכסי vLLM.

יצירת אשכול GKE

אפשר להפעיל מודלים של שפה גדולה (LLM) ב-TPU באשכול GKE Autopilot או באשכול רגיל. מומלץ להשתמש באשכול Autopilot כדי ליהנות מחוויית Kubernetes מנוהלת באופן מלא. כדי לבחור את מצב הפעולה של GKE שהכי מתאים לעומסי העבודה שלכם, אפשר לעיין במאמר בחירת מצב פעולה של GKE.

טייס אוטומטי

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

    gcloud container clusters create-auto ${CLUSTER_NAME} \
        --cluster-version=${CLUSTER_VERSION} \
        --location=${CONTROL_PLANE_LOCATION}
    

רגילה

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

    gcloud container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID} \
        --location=${CONTROL_PLANE_LOCATION} \
        --node-locations=${ZONE} \
        --cluster-version=${CLUSTER_VERSION} \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --addons GcsFuseCsiDriver
    

הפקודה הזו יוצרת אשכול GKE Standard, ומפעילה את איחוד שירותי אימות הזהות של עומסי עבודה ואת Cloud Storage FUSE CSI driver. אם אתם משתמשים באשכול קיים, ודאו שמנהל התקן ה-CSI של Cloud Storage FUSE מופעל.

  1. יוצרים מאגר צמתים של פרוסת TPU:

    gcloud container node-pools create tpunodepool \
        --location=${CONTROL_PLANE_LOCATION} \
        --node-locations=${ZONE} \
        --num-nodes=1 \
        --machine-type=ct6e-standard-8t \
        --cluster=${CLUSTER_NAME} \
        --enable-autoscaling --total-min-nodes=1 --total-max-nodes=2
    

    ‫GKE יוצר את המשאבים הבאים עבור ה-LLM:

הגדרת kubectl לתקשורת עם האשכול

כדי להגדיר את kubectl לתקשורת עם האשכול, מריצים את הפקודה הבאה:

  gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${CONTROL_PLANE_LOCATION}

יצירת סוד של Kubernetes לפרטי הכניסה של Hugging Face

  1. יוצרים מרחב שמות. אפשר לדלג על השלב הזה אם משתמשים במרחב השמות default:

    kubectl create namespace ${NAMESPACE}
    
  2. כדי ליצור סוד של Kubernetes שמכיל את האסימון של Hugging Face, מריצים את הפקודה הבאה:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token=${HF_TOKEN} \
        --namespace ${NAMESPACE}
    

יצירת קטגוריה של Cloud Storage

ב-Cloud Shell, מריצים את הפקודה הבאה:

gcloud storage buckets create gs://${GSBUCKET} \
    --uniform-bucket-level-access

פעולה זו יוצרת קטגוריה של Cloud Storage לאחסון קובצי המודל שהורדתם מ-Hugging Face.

הגדרת ServiceAccount ב-Kubernetes כדי לגשת לקטגוריה

  1. יוצרים את חשבון השירות של Kubernetes:

    kubectl create serviceaccount ${KSA_NAME} --namespace ${NAMESPACE}
    
  2. מעניקים לחשבון השירות של Kubernetes הרשאת קריאה וכתיבה כדי לגשת לקטגוריה של Cloud Storage:

    gcloud storage buckets add-iam-policy-binding gs://${GSBUCKET} \
      --member "principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/${KSA_NAME}" \
      --role "roles/storage.objectUser"
    
  3. לחלופין, אפשר לתת הרשאות קריאה וכתיבה לכל הקטגוריות של Cloud Storage בפרויקט:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member "principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/${KSA_NAME}" \
    --role "roles/storage.objectUser"
    

    ‫GKE יוצר את המשאבים הבאים עבור ה-LLM:

    1. קטגוריה של Cloud Storage לאחסון המודל שהורד ומטמון הקומפילציה. מנהל התקן ה-CSI של Cloud Storage FUSE קורא את התוכן של הקטגוריה.
    2. כרכים שמופעל בהם מטמון קבצים והתכונה הורדה מקבילית של Cloud Storage FUSE.
    שיטה מומלצת:

    כדאי להשתמש במטמון קבצים שמגובה על ידי tmpfs או Hyperdisk / Persistent Disk, בהתאם לגודל הצפוי של תוכן המודל, למשל קבצי משקל. במדריך הזה משתמשים במטמון קבצים של Cloud Storage FUSE שמגובה על ידי RAM.

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

כדי לפרוס את שרת המודלים של vLLM, במדריך הזה נעשה שימוש בפריסת Kubernetes. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול.

  1. בודקים את מניפסט הפריסה הבא שנשמר כ-vllm-llama3-70b.yaml, שמשתמש בעותק יחיד:

    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-tpu
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: vllm-tpu
      template:
        metadata:
          labels:
            app: vllm-tpu
          annotations:
            gke-gcsfuse/volumes: "true"
            gke-gcsfuse/cpu-limit: "0"
            gke-gcsfuse/memory-limit: "0"
            gke-gcsfuse/ephemeral-storage-limit: "0"
        spec:
          serviceAccountName: KSA_NAME
          nodeSelector:
            cloud.google.com/gke-tpu-topology: 2x4
            cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
          containers:
          - name: vllm-tpu
            image: vllm/vllm-tpu:latest
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --host=0.0.0.0
            - --port=8000
            - --tensor-parallel-size=8
            - --max-model-len=4096
            - --model=meta-llama/Llama-3.1-70B
            - --download-dir=/data
            - --max-num-batched-tokens=512
            - --max-num-seqs=128
            env: 
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            - name: VLLM_XLA_CACHE_PATH
              value: "/data"
            - name: VLLM_USE_V1
              value: "1"
            ports:
            - containerPort: 8000
            resources:
              limits:
                google.com/tpu: 8
            readinessProbe:
              tcpSocket:
                port: 8000
              initialDelaySeconds: 15
              periodSeconds: 10
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
            - name: dshm
              mountPath: /dev/shm
          volumes:
          - name: gke-gcsfuse-cache
            emptyDir:
              medium: Memory
          - name: dshm
            emptyDir:
              medium: Memory
          - name: gcs-fuse-csi-ephemeral
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: GSBUCKET
                mountOptions: "implicit-dirs,file-cache:enable-parallel-downloads:true,file-cache:parallel-downloads-per-file:100,file-cache:max-parallel-downloads:-1,file-cache:download-chunk-size-mb:10,file-cache:max-size-mb:-1"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: vllm-service
    spec:
      selector:
        app: vllm-tpu
      type: LoadBalancer	
      ports:
        - name: http
          protocol: TCP
          port: 8000  
          targetPort: 8000
    

    אם תגדילו את הפריסה לכמה רפליקות, הכתיבות המקבילות ל-VLLM_XLA_CACHE_PATH יגרמו לשגיאה: RuntimeError: filesystem error: cannot create directories. כדי למנוע את השגיאה הזו, יש שתי אפשרויות:

    1. כדי להסיר את מיקום המטמון של XLA, מסירים את הבלוק הבא מקובץ ה-YAML של הפריסה. כלומר, כל העותקים המשוכפלים יקמפלו מחדש את המטמון.

      - name: VLLM_XLA_CACHE_PATH
        value: "/data"
      
    2. משנים את קנה המידה של הפריסה ל-1 ומחכים שהרפליקה הראשונה תהיה מוכנה ותיכתב למטמון XLA. לאחר מכן, מגדילים את מספר הרפליקות. כך שאר העותקים יוכלו לקרוא את המטמון בלי לנסות לכתוב בו.

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

    kubectl apply -f vllm-llama3-70b.yaml -n ${NAMESPACE}
    
  3. צפייה ביומנים משרת המודלים הפועל:

    kubectl logs -f -l app=vllm-tpu -n ${NAMESPACE}
    

    הפלט אמור להיראות כך:

    INFO:     Started server process [1]
    INFO:     Waiting for application startup.
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
    

פרסום המודל

  1. כדי לקבל את כתובת ה-IP החיצונית של שירות ה-VLLM, מריצים את הפקודה הבאה:

    export vllm_service=$(kubectl get service vllm-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}' -n ${NAMESPACE})
    
  2. מנהלים אינטראקציה עם המודל באמצעות curl:

    curl http://$vllm_service:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "meta-llama/Llama-3.1-70B",
        "prompt": "San Francisco is a",
        "max_tokens": 7,
        "temperature": 0
    }'
    

    הפלט אמור להיראות כך:

    {"id":"cmpl-6b4bb29482494ab88408d537da1e608f","object":"text_completion","created":1727822657,"model":"meta-llama/Llama-3-8B","choices":[{"index":0,"text":" top holiday destination featuring scenic beauty and","logprobs":null,"finish_reason":"length","stop_reason":null,"prompt_logprobs":null}],"usage":{"prompt_tokens":5,"total_tokens":12,"completion_tokens":7}}
    

הגדרת קנה מידה אוטומטי בהתאמה אישית

בקטע הזה מגדירים התאמה אופקית של קבוצות Pod לעומס באמצעות מדדים מותאמים אישית של Prometheus. אתם משתמשים במדדים של השירות המנוהל של Google Cloud ל-Prometheus משרת vLLM.

מידע נוסף זמין במאמר בנושא השירות המנוהל של Google Cloud ל-Prometheus. ההגדרה הזו אמורה להיות מופעלת כברירת מחדל באשכול GKE.

  1. מגדירים את Custom Metrics Stackdriver Adapter באשכול:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    
  2. מוסיפים את התפקיד Monitoring Viewer לחשבון השירות שבו משתמש מתאם Stackdriver של מדדים מותאמים אישית:

    gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
        --role roles/monitoring.viewer \
        --member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
    
  3. שומרים את קובץ המניפסט הבא בשם vllm_pod_monitor.yaml:

    
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
     name: vllm-pod-monitoring
    spec:
     selector:
       matchLabels:
         app: vllm-tpu
     endpoints:
     - path: /metrics
       port: 8000
       interval: 15s
    
  4. מחילים אותו על האשכול:

    kubectl apply -f vllm_pod_monitor.yaml -n ${NAMESPACE}
    

יצירת עומס בנקודת הקצה של vLLM

יוצרים עומס על שרת vLLM כדי לבדוק איך GKE מבצע התאמה אוטומטית לעומס (autoscaling) באמצעות מדד vLLM מותאם אישית.

  1. מריצים סקריפט bash ‏ (load.sh) כדי לשלוח N מספר בקשות מקבילות לנקודת הקצה של vLLM:

    #!/bin/bash
    N=PARALLEL_PROCESSES
    export vllm_service=$(kubectl get service vllm-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}' -n ${NAMESPACE})
    for i in $(seq 1 $N); do
      while true; do
        curl http://$vllm_service:8000/v1/completions -H "Content-Type: application/json" -d '{"model": "meta-llama/Llama-3.1-70B", "prompt": "Write a story about san francisco", "max_tokens": 1000, "temperature": 0}'
      done &  # Run in the background
    done
    wait
    

    מחליפים את PARALLEL_PROCESSES במספר התהליכים המקבילים שרוצים להריץ.

  2. מריצים את סקריפט ה-Bash:

    chmod +x load.sh
    nohup ./load.sh &
    

אימות ההטמעה של המדדים בשירות המנוהל של Google Cloud ל-Prometheus

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

  1. נכנסים לדף Metrics explorer במסוף Google Cloud .

    כניסה לדף Metrics Explorer

  2. לוחצים על < > PromQL.

  3. מזינים את השאילתה הבאה כדי לראות את מדדי התנועה:

    vllm:num_requests_waiting{cluster='CLUSTER_NAME'}
    

תרשים קו שמציג את מדד ה-vLLM (num_requests_waiting) שנמדד לאורך זמן. המדד vLLM עולה מ-0 (טרום טעינה) לערך (אחרי טעינה). הגרף הזה מאשר שהמדדים של vLLM מוזנים לשירות המנוהל של Google Cloud ל-Prometheus. בדוגמה הבאה מוצג גרף עם ערך התחלתי של 0 לפני הטעינה, שמגיע לערך מקסימלי של כמעט 400 אחרי הטעינה, תוך דקה אחת.

vllm:num_requests_waiting

פריסת ההגדרה של Horizontal Pod Autoscaler

כשמחליטים על איזה מדד להגדיר שינוי גודל אוטומטי, מומלץ להשתמש במדדים הבאים עבור vLLM TPU:

  • num_requests_waiting: המדד הזה מתייחס למספר הבקשות שממתינות בתור של שרת המודל. המספר הזה מתחיל לגדול באופן משמעותי כשהמטמון של kv מלא.

  • gpu_cache_usage_perc: המדד הזה מתייחס לניצול של מטמון kv, שקשור ישירות למספר הבקשות שעוברות עיבוד עבור מחזור הסקה נתון בשרת המודל. הערה: המדד הזה פועל באופן זהה ב-GPU וב-TPU, אבל הוא קשור לסכימת השמות של ה-GPU.

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

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

הסבר נוסף זמין במאמר שיטות מומלצות להתאמה אוטומטית לעומס של עומסי עבודה של היקש במודלים גדולים של שפה (LLM) באמצעות TPU.

כשבוחרים averageValue יעד להגדרת HPA, צריך לקבוע אותו באופן ניסיוני. בפוסט בבלוג Save on GPUs: Smarter autoscaling for your GKE inferencing workloads (חיסכון בעלויות של מעבדי GPU: התאמה אוטומטית חכמה יותר לעומס העבודה של מסקנות ב-GKE) מפורטים רעיונות נוספים לאופטימיזציה של החלק הזה. profile-generator שבו נעשה שימוש בפוסט הזה בבלוג פועל גם עם vLLM TPU.

בהוראות הבאות, אתם פורסים את הגדרות ה-HPA באמצעות המדד num_requests_waiting. לצורך הדוגמה, הגדרתם את המדד לערך נמוך כדי שההגדרה של HPA תגדיל את מספר העותקים של vLLM לשניים. כדי לפרוס את ההגדרה של Horizontal Pod Autoscaler (HPA) באמצעות num_requests_waiting, פועלים לפי השלבים הבאים:

  1. שומרים את קובץ המניפסט הבא בשם vllm-hpa.yaml:

    
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
     name: vllm-hpa
    spec:
     scaleTargetRef:
       apiVersion: apps/v1
       kind: Deployment
       name: vllm-tpu
     minReplicas: 1
     maxReplicas: 2
     metrics:
       - type: Pods
         pods:
           metric:
             name: prometheus.googleapis.com|vllm:num_requests_waiting|gauge
           target:
             type: AverageValue
             averageValue: 10
    

    המדדים של vLLM בשירות המנוהל של Google Cloud ל-Prometheus הם בפורמט vllm:metric_name.

    שיטה מומלצת:

    משתמשים ב-num_requests_waiting כדי לשנות את קצב העברת הנתונים. מומלץ להשתמש ב-gpu_cache_usage_perc בתרחישי שימוש ב-TPU שרגישים לזמן האחזור.

  2. פורסים את ההגדרה של Horizontal Pod Autoscaler:

    kubectl apply -f vllm-hpa.yaml -n ${NAMESPACE}
    

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

  3. צופים בהתקדמות של התאמת קבוצות ה-Pod לעומס:

    kubectl get hpa --watch -n ${NAMESPACE}
    

    הפלט אמור להיראות כך:

    NAME       REFERENCE             TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
    vllm-hpa   Deployment/vllm-tpu   <unknown>/10   1         2         0          6s
    vllm-hpa   Deployment/vllm-tpu   34972m/10      1         2         1          16s
    vllm-hpa   Deployment/vllm-tpu   25112m/10      1         2         2          31s
    vllm-hpa   Deployment/vllm-tpu   35301m/10      1         2         2          46s
    vllm-hpa   Deployment/vllm-tpu   25098m/10      1         2         2          62s
    vllm-hpa   Deployment/vllm-tpu   35348m/10      1         2         2          77s
    
  4. מחכים 10 דקות וחוזרים על השלבים בקטע אימות ההטמעה של המדדים בשירות המנוהל של Google Cloud ל-Prometheus. השירות המנוהל של Google Cloud ל-Prometheus קולט עכשיו את המדדים משני נקודות הקצה של vLLM.

הסרת המשאבים

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

מחיקת המשאבים שנפרסו

כדי להימנע מחיובים בחשבון Google Cloud על המשאבים שיצרתם במדריך הזה, מריצים את הפקודות הבאות:

ps -ef | grep load.sh | awk '{print $2}' | xargs -n1 kill -9
gcloud container clusters delete ${CLUSTER_NAME} \
  --location=${CONTROL_PLANE_LOCATION}

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