הגדרה של שינוי אוטומטי של קנה המידה של פרסום מודלים ב-vLLM באמצעות מדדי GPU

במדריך הזה נסביר איך להגדיר שינוי גודל אוטומטי של שירותי Cloud Run שמפרסמים מודלים של LLM באמצעות vLLM על סמך מדדי GPU מותאמים אישית באמצעות שינוי גודל אוטומטי של מדדים חיצוניים ב-Cloud Run‏ (CREMA).

למרות ש-Cloud Run מבצע התאמה אוטומטית לעומס באמצעות ניצול CPU ובו-זמניות כברירת מחדל, עומסי עבודה של הסקת מסקנות שדורשים שימוש אינטנסיבי ב-GPU לרוב דורשים התאמה אוטומטית לעומס על סמך מדדי תור, כמו מספר הבקשות הפעילות או ניצול מטמון KV. ‫CREMA משלב את KEDA (שינוי גודל אוטומטי מבוסס-אירועים) מבוסס-Kubernetes עם Cloud Run כדי לאפשר שינוי גודל דינמי שמבוסס על מדדים של Prometheus. ‏vLLM חושף את המדדים של Prometheus ושולח אותם אל Cloud Monitoring.

מטרות

במדריך הזה תלמדו:

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

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

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

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

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. 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

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

  4. 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

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

  6. מפעילים את ממשקי ה-API של Cloud Run,‏ Parameter Manager,‏ Artifact Registry,‏ Cloud Build,‏ Secret Manager ו-Cloud Monitoring.

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    הפעלת ממשקי ה-API

  7. מתקינים ומפעילים את ה-CLI של gcloud.
  8. מגדירים משתני סביבה שמשמשים לאורך המדריך הזה:
    export PROJECT_ID=PROJECT_ID
    export REGION=us-central1
    export VLLM_SERVICE_NAME=vllm-service
    export MODEL_NAME=gemma-2-2b-it
    export REPO_NAME=vllm-repo
    export BUCKET_NAME=my-vllm-models-${PROJECT_ID}
    export CREMA_SERVICE_NAME=crema-service
    מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud .
  9. מגדירים את הפרויקט:
    gcloud config set project $PROJECT_ID
  10. אם עדיין אין לכם חשבון, אתם צריכים ליצור חשבון ב-Hugging Face. לאחר מכן, יוצרים טוקן קריאה באתר Hugging Face. ב-Hugging Face האסימון מוצג רק פעם אחת. כדאי לשמור אותו במיקום מאובטח, כי לא תהיה אפשרות לראות אותו שוב.
  11. עוברים לדף המודל gemma-2-2b-it ב-Hugging Face ומאשרים את תנאי ההסכם של המודל.

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות להשלמת המדריך, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

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

יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.

הורדה והעלאה של משקלי מודלים ל-Cloud Storage

מורידים משקלים של מודלים מ-Hugging Face ומעבירים אותם לקטגוריה של Cloud Storage כדי להפוך אותם לזמינים להצגת מודלים:

  1. מתקינים את Hugging Face CLI:

    pip install -U "huggingface_hub[cli]"
    
  2. מורידים את משקלי המודל באופן מקומי באמצעות Hugging Face CLI:

    export HF_TOKEN="HF_TOKEN"
    export LOCAL_DIR="/tmp/$MODEL_NAME"
    HF_HOME=/tmp/huggingface python -m huggingface_hub.cli.hf download google/$MODEL_NAME --token $HF_TOKEN --local-dir=$LOCAL_DIR
    

    מחליפים את HF_TOKEN באסימון הגישה של המשתמש ב-Hugging Face. האסימון צריך להתחיל ב-hf_ ואחריו 35 תווים אלפאנומריים אקראיים (לדוגמה, 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).

  3. יוצרים קטגוריה של Cloud Storage ומעתיקים אליה את המשקלים שהורדתם:

    gcloud storage buckets create gs://$BUCKET_NAME \
        --project=$PROJECT_ID \
        --location=$REGION \
        --uniform-bucket-level-access
    
    gcloud storage cp -r $LOCAL_DIR gs://$BUCKET_NAME/
    

דחיפת קובץ האימג' של קונטיינר vLLM ל-Artifact Registry

מושכים את קובצי האימג' של הקונטיינרים של מודל ההגשה ומעבירים אותם למאגר ב-Artifact Registry:

  1. יוצרים מאגר Docker ב-Artifact Registry:

    gcloud artifacts repositories create $REPO_NAME \
        --repository-format=docker \
        --location=$REGION \
        --description="vLLM Docker Images"
    
  2. מאמתים את שד Docker המקומי מול המאגר:

    gcloud auth configure-docker ${REGION}-docker.pkg.dev
    
  3. מושכים את תמונת vLLM, מתייגים אותה ומעבירים אותה בדחיפה ל-Artifact Registry:

    docker pull docker.io/vllm/vllm-openai:latest
    docker tag docker.io/vllm/vllm-openai:latest ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/vllm-openai:latest
    docker push ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/vllm-openai:latest
    

פריסת שירות ההתאמה האוטומטית לעומס (autoscaler) של CREMA

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

יצירת חשבון שירות בהתאמה אישית

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

export CREMA_SA="crema-autoscaler@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts create crema-autoscaler \
    --description="Service account for Cloud Run CREMA to read metrics and scale workloads" \
    --display-name="CREMA Autoscaler System"

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

כדי להרחיב את השירות, צריך לתת את ההרשאות הבאות בחשבון השירות המותאם אישית:

  1. נותנים לחשבון השירות של CREMA הרשאה לקרוא מ-Parameter Manager:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$CREMA_SA" \
        --role="roles/parametermanager.parameterViewer"
    
  2. נותנים לחשבון השירות של CREMA הרשאה לשנות את קנה המידה של השירות:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$CREMA_SA" \
        --role="roles/run.developer"
    
  3. נותנים לחשבון השירות של CREMA את התפקיד Service Account User:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$CREMA_SA" \
        --role="roles/iam.serviceAccountUser"
    
  4. נותנים לחשבון השירות של CREMA הרשאה לצפייה במדדים:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$CREMA_SA" \
        --role="roles/monitoring.viewer"
    

יצירה ורישום של הגדרת CREMA

מגדירים ספי צמצום וכללים במניפסט של הגדרות CREMA ורושמים אותו ב-Parameter Manager:

  1. שומרים את ההגדרה הבאה בתור my-crema-config.yaml. ההגדרה הזו מפעילה שינוי גודל כשמספר הבקשות הפעילות (vllm:num_requests_running) גדול מ-2:

    apiVersion: crema/v1
    kind: CremaConfig
    spec:
      pollingInterval: 15
      triggerAuthentications:
        - metadata:
            name: adc-trigger-auth
          spec:
            podIdentity:
              provider: gcp
      scaledObjects:
        - spec:
            scaleTargetRef:
              name: projects/PROJECT_ID/locations/us-central1/services/vllm-service
            minReplicaCount: 1
            maxReplicaCount: 5
            triggers:
              - type: prometheus
                authenticationRef:
                  name: adc-trigger-auth
                metadata:
                  serverAddress: https://monitoring.googleapis.com/v1/projects/PROJECT_ID/location/global/prometheus
                  metric: vllm:num_requests_running
                  query: sum(vllm:num_requests_running)
                  threshold: '2'
    
  2. רושמים את קובץ התצורה ב-Parameter Manager:

    gcloud parametermanager parameters create crema-config \
        --location=global \
        --parameter-format=YAML
    
    gcloud parametermanager parameters versions create 1 \
        --location=global \
        --parameter=crema-config \
        --payload-data-from-file=my-crema-config.yaml
    

פריסת שירות CREMA

פורסים את תמונת ה-CREMA כשירות הפועל ברקע פנימי ב-Cloud Run:

gcloud run deploy $CREMA_SERVICE_NAME \
    --image=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0 \
    --region=$REGION \
    --service-account="$CREMA_SA" \
    --no-allow-unauthenticated \
    --no-cpu-throttling \
    --cpu=1 \
    --memory=1Gi \
    --min-instances=1 \
    --max-instances=1 \
    --ingress=internal \
    --base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
    --set-env-vars="CREMA_CONFIG=projects/$PROJECT_ID/locations/global/parameters/crema-config/versions/1,OUTPUT_SCALER_METRICS=True"

הגדרת הרשאות לשירות vLLM

נותנים לחשבון השירות של Compute Engine הרשאות לייצא מדדים ולקרוא משקלים של מודלים מ-Cloud Storage:

  1. מאחזרים את מספר הפרויקט:

    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
  2. נותנים לחשבון השירות הרשאה לכתוב מדדים:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
        --role="roles/monitoring.metricWriter"
    
  3. נותנים לחשבון השירות הרשאה לקרוא משקלים של מודלים מ-Cloud Storage:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
        --role="roles/storage.objectViewer"
    

פריסת שירות vLLM עם קובץ עזר של OpenTelemetry

פורסים את קונטיינר ההגשה הראשי של vLLM ב-Cloud Run עם משקלי מודלים שמוצמדים מ-Cloud Storage. מכיוון שפריסת שירותים מרובי-מאגדים עם קובצי עזר ב-Cloud Run מחייבת הגדרת שירות YAML הצהרתי, אתם מגדירים את מנוע vLLM הראשי לצד קובץ עזר של OpenTelemetry לאיסוף ולייצוא מדדי vLLM:

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

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: vllm-service
      labels:
        cloud.googleapis.com/location: us-central1
      annotations:
        run.googleapis.com/scalingMode: manual
        run.googleapis.com/manualInstanceCount: "1"
    spec:
      template:
        metadata:
          annotations:
            run.googleapis.com/execution-environment: gen2
            run.googleapis.com/cpu-throttling: "false"
            run.googleapis.com/gpu-zonal-redundancy-disabled: "true"
            autoscaling.knative.dev/minScale: "1"
        spec:
          containerConcurrency: 80
          nodeSelector:
            run.googleapis.com/accelerator: nvidia-l4
          volumes:
            - name: gcs-volume
              csi:
                driver: gcsfuse.run.googleapis.com
                volumeAttributes:
                  bucketName: my-vllm-models-PROJECT_ID
          containers:
            # Primary container: vLLM serving engine
            - name: vllm-container
              image: us-central1-docker.pkg.dev/PROJECT_ID/vllm-repo/vllm-openai:latest
              ports:
                - containerPort: 8080
              resources:
                limits:
                  cpu: "4"
                  memory: 16Gi
                  nvidia.com/gpu: "1"
              args:
                - "--model"
                - "/gcs/gemma-2-2b-it"
                - "--port"
                - "8080"
                - "--max-model-len"
                - "2048"
                - "--chat-template"
                - "{% for msg in messages %}{{ msg['content'] }}{% endfor %}"
              volumeMounts:
                - name: gcs-volume
                  mountPath: /gcs
              startupProbe:
                httpGet:
                  path: /health
                  port: 8080
                periodSeconds: 10
                failureThreshold: 24
    
            # Sidecar container: OpenTelemetry Collector
            - name: otel-collector
              image: otel/opentelemetry-collector-contrib:latest
              resources:
                limits:
                  cpu: "1"
                  memory: 1Gi
              args:
                - |
                  --config=yaml:
                  receivers:
                    prometheus:
                      config:
                        scrape_configs:
                          - job_name: 'vllm'
                            scrape_interval: 10s
                            metrics_path: '/metrics'
                            static_configs:
                              - targets: ['localhost:8080']
                  processors:
                    resourcedetection:
                      detectors: [gcp]
                      timeout: 2s
                    transform:
                      metric_statements:
                        - context: datapoint
                          statements:
                            - set(attributes["exported_location"], attributes["location"])
                            - delete_key(attributes, "location")
                            - set(attributes["exported_cluster"], attributes["cluster"])
                            - delete_key(attributes, "cluster")
                            - set(attributes["exported_namespace"], attributes["namespace"])
                            - delete_key(attributes, "namespace")
                            - set(attributes["exported_job"], attributes["job"])
                            - delete_key(attributes, "job")
                            - set(attributes["exported_instance"], attributes["instance"])
                            - delete_key(attributes, "instance")
                  exporters:
                    googlemanagedprometheus:
                  service:
                    pipelines:
                      metrics:
                        receivers: [prometheus]
                        processors: [resourcedetection, transform]
                        exporters: [googlemanagedprometheus]
    
  2. מחליפים את הגדרת השירות הקיימת במניפסט של כמה קונטיינרים:

    gcloud run services replace vllm-service.yaml
    

בדיקת יומני השירות של CREMA

  1. במסוף Google Cloud , עוברים לדף Cloud Run.
  2. בוחרים את crema-service.
  3. לוחצים על הכרטיסייה Logs ומוודאים שמחזורי הסקר של המדדים פעילים:

    [INFO] [METRIC-PROVIDER] Starting metric collection cycle
    [INFO] [METRIC-PROVIDER] Successfully fetched scaled object metrics ...
    [INFO] [METRIC-PROVIDER] Sending scale request ...
    [INFO] [SCALER] Received ScaleRequest ...
    [INFO] [SCALER] Current instances ...
    [INFO] [SCALER] Recommended instances ...
    

הרצת בדיקת עומס

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

  1. בספריית העבודה, יוצרים קובץ בשם load-test.sh ומוסיפים את הקוד הבא:

    #!/bin/bash
    
    export SERVICE_URL=$(gcloud run services describe $VLLM_SERVICE_NAME --region $REGION --format='value(status.url)')
    
    echo "Launching 5 parallel heavy requests to trigger autoscaling..."
    
    for i in {1..5}; do
        curl -s -X POST "${SERVICE_URL}/v1/chat/completions" \
            -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
            -H "Content-Type: application/json" \
            -d "{
                \"model\": \"/gcs/${MODEL_NAME}\",
                \"messages\": [{\"role\": \"user\", \"content\": \"Write an exceptionally long, detailed, and exhaustive essay about the entire history of the universe from the Big Bang to the modern day.\"}]
            }" > /dev/null &
    done
    
    echo "All 5 requests dispatched. Waiting for requests to complete..."
    wait
    echo "Done."
    
  2. הופכים את הסקריפט לסקריפט שאפשר להריץ ומריצים את בדיקת העומס:

    chmod +x load-test.sh
    ./load-test.sh
    
  3. בודקים שוב את היומנים של crema-service ואת לוח המדדים של Cloud Run כדי לוודא שמספר המופעים המומלץ גדל בתגובה לבקשות שנוספו לתור.

עיון במדדי vLLM ב-Cloud Monitoring

אחרי שמריצים את בדיקת העומס, אפשר לבדוק איך תעבורת הנתונים משפיעה על מדדי פרסום המודל ב-Cloud Monitoring:

  1. במסוף Google Cloud , עוברים לדף Metrics Explorer ב-Cloud Monitoring.

    לדף Metrics Explorer

  2. לוחצים על בחירת מדד.

  3. מרחיבים את Prometheus Target (יעד Prometheus) > Vllm ובוחרים באחד מהמדדים הזמינים שמסתיימים ב-/gauge. לדוגמה, בוחרים באפשרות prometheus/vllm:num_requests_running/gauge כדי לראות את מספר הבקשות הפעילות במהלך בדיקת העומס.

כפי שמתואר במסמכי התיעוד בנושא מדדי ייצור של vLLM, מדדים נוספים של vLLM שמיוצאים אל Cloud Monitoring כוללים:

  • prometheus/vllm:num_requests_waiting/gauge: מספר הבקשות שממתינות בתור לעיבוד על ידי מנוע vLLM.
  • prometheus/vllm:num_requests_running/gauge: מספר הבקשות שמופעלות באצוות של מודלים.
  • prometheus/vllm:gpu_cache_usage_perc/gauge: אחוז הזיכרון של מטמון ה-KV ב-GPU שנמצא בשימוש.
  • prometheus/vllm:num_requests_swapped/gauge: מספר הבקשות שהמטמון שלהן מסוג KV הועבר לזיכרון המעבד המארח בגלל עומס על הזיכרון.

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

בניגוד למדדים סטנדרטיים של מקביליות בקשות HTTP שמתייחסים לכל הבקשות באופן שווה, המדדים הפנימיים של vLLM לוקחים בחשבון את טביעת הרגל הדינמית של זיכרון ה-GPU של אורכים שונים של הנחיות. התכונה 'שינוי קנה מידה ב-vllm:num_requests_running' עוזרת לכם לשנות את קנה המידה באופן יזום על סמך עומס GPU אמיתי. כך נשמר מאגר פעיל של קיבולת לפני שהשרת נאלץ להכניס בקשות לתור ב-vllm:num_requests_waiting, והמשתמשים מוגנים מפני קפיצות חדות בזמן האחזור של TTFT.

הסרת המשאבים

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

מחיקת הפרויקט

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

הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.

כדי למחוק את הפרויקט:

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת משאבי הדרכה

  1. מוחקים את שירות Cloud Run שפרסתם במדריך הזה. שירותי Cloud Run לא צוברים עלויות עד שהם מקבלים בקשות.

    כדי למחוק את שירות Cloud Run, מריצים את הפקודה הבאה:

    gcloud run services delete SERVICE-NAME

    מחליפים את SERVICE-NAME בשם השירות.

    אפשר גם למחוק שירותים של Cloud Run מGoogle Cloud המסוף.

  2. מסירים את הגדרת ברירת המחדל של האזור gcloud שהוספתם במהלך ההגדרה של המדריך:

     gcloud config unset run/region
    
  3. מסירים את הגדרות הפרויקט:

     gcloud config unset project
    
  4. מחיקת הגדרת ה-CREMA שהוקצתה ל-Parameter Manager:

    gcloud parametermanager parameters delete crema-config \
        --location=global \
        --quiet
    
  5. מוחקים את חשבון השירות המותאם אישית שנוצר עבור CREMA:

    gcloud iam service-accounts delete $CREMA_SA \
        --quiet
    
  6. מחיקת הקטגוריה של Cloud Storage שמכילה את המודל:

    gcloud storage rm --recursive gs://$BUCKET_NAME
    
  7. מחיקה של משאבים אחרים Google Cloud שנוצרו במדריך הזה:

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