שימוש ב-vLLM ב-GKE להרצת היקש עם gpt-oss-120b

במדריך הזה נסביר איך לפרוס מודל שפה של gpt-oss-120b ולהשתמש בו באמצעות vLLM framework. אתם פורסים את המודל הזה באשכול Autopilot של Google Kubernetes Engine ‏ (GKE) ומשתמשים במכונה וירטואלית (VM) אחת מסוג A4 עם 8 יחידות GPU מסוג B200.

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

מטרות

  1. גישה אל gpt-oss-120b באמצעות Hugging Face.
  2. מכינים את הסביבה.
  3. יוצרים אשכול GKE במצב אוטומטי.
  4. יוצרים סוד ב-Kubernetes לפרטי הכניסה של Hugging Face.
  5. יצירת קטגוריה של Cloud Storage.
  6. מורידים את המודל לקטגוריה של Cloud Storage.
  7. פורסים קונטיינר vLLM באשכול GKE.
  8. אינטראקציה עם מודל השפה gpt-oss באמצעות curl.
  9. לפנות מקום.

עלויות

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

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

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

  1. התקינו את ה-CLI של Google Cloud.

  2. הגדירו שה-CLI של gcloud ישתמש בזהות המאוחדת שלכם.

    איך נכנסים ל-CLI של gcloud באמצעות הזהות המאוחדת?

  3. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  4. יוצרים או בוחרים פרויקט ב- Google Cloud .

    התפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • בחירת פרויקט: כדי לבחור פרויקט לא נדרש תפקיד IAM ספציפי – אתם יכולים לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד "יצירת פרויקטים" (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים?
    • יוצרים פרויקט ב- Google Cloud :

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של הפרויקט ב- Google Cloud שאתם יוצרים.

    • בוחרים את הפרויקט שיצרתם ב- Google Cloud :

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  5. מוודאים שהחיוב מופעל בפרויקט ב- Google Cloud .

  6. מפעילים את ממשק ה-API הנדרש, אם הוא עדיין לא מופעל:

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

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

    gcloud services enable container.googleapis.com
  7. נותנים תפקידים לחשבון המשתמש. מריצים את הפקודה הבאה לכל אחד מהתפקידים הבאים ב-IAM: roles/container.admin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

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

  8. נכנסים לחשבון Hugging Face או יוצרים חשבון.

גישה ל-gpt-oss באמצעות Hugging Face

כדי להשתמש ב-Hugging Face כדי לגשת ל-gpt-oss:

  1. נכנסים ל-Hugging Face ומחפשים את המודל gpt-oss.
  2. thought יוצרים טוקן גישה ל-Hugging Face read.
  3. מעתיקים ושומרים את ערך האסימון של read access. תשתמשו בו בהמשך המדריך.

הכנת הסביבה

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

export PROJECT_ID="YOUR_PROJECT_ID"
export RESERVATION_URL="YOUR_RESERVATION_NAME"
export REGION="YOUR_REGION"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export GCS_BUCKET="YOUR_GCS_BUCKET"
export HUGGING_FACE_TOKEN="YOUR_HF_TOKEN"
export NETWORK="YOUR_NETWORK_NAME"
export SUBNETWORK="YOUR_SUBNETWORK_NAME"
export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")

gcloud config set project "${PROJECT_ID}"
gcloud config set billing/quota_project "${PROJECT_ID}"

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

  • ‫YOUR_PROJECT_ID: המזהה של הפרויקט ב- Google Cloud שבו רוצים ליצור את אשכול ה-GKE.

  • ‫YOUR_RESERVATION_NAME: כתובת ה-URL של ההזמנה שבה רוצים להשתמש כדי ליצור את אשכול GKE. בהתאם לפרויקט שבו נמצאת ההזמנה, מציינים את אחד מהערכים הבאים:

    • ההזמנה קיימת בפרויקט: RESERVATION_NAME

    • המקום השמור נמצא בפרויקט אחר, ואפשר להשתמש בו בפרויקט שלכם: projects/RESERVATION_PROJECT_ID/reservations/RESERVATION_NAME

  • ‫YOUR_REGION: האזור שבו רוצים ליצור את אשכול GKE. אפשר ליצור את האשכול רק באזור שבו נמצאת ההזמנה.

  • ‫YOUR_CLUSTER_NAME: השם של אשכול GKE שרוצים ליצור.

  • ‫YOUR_GCS_BUCKET: השם של הקטגוריה של Cloud Storage שממנה מורידים את המודל.

  • ‫YOUR_HF_TOKEN: טוקן הגישה ל-Hugging Face שיצרתם בקטע הקודם.

  • ‫YOUR_NETWORK_NAME: הרשת שבה משתמש אשכול GKE. מציינים את אחד מהערכים הבאים:

    • אם יצרתם רשת בהתאמה אישית, ציינו את שם הרשת.

    • אחרת, צריך לציין את default.

  • ‫YOUR_SUBNETWORK_NAME: רשת המשנה שבה משתמש אשכול GKE. מציינים את אחד מהערכים הבאים:

    • אם יצרתם רשת משנה בהתאמה אישית, ציינו את השם שלה. אפשר לציין רק רשת משנה שנמצאת באותו אזור של ההזמנה.

    • אחרת, צריך לציין את default.

יצירת אשכול GKE במצב אוטומטי

כדי ליצור אשכול GKE במצב אוטומטי, מריצים את הפקודה הבאה:

gcloud container clusters create-auto $CLUSTER_NAME \
    --project=$PROJECT_ID \
    --region=$REGION \
    --release-channel=rapid \
    --network=$NETWORK \
    --subnetwork=$SUBNETWORK

יצירת אשכול GKE עשויה להימשך זמן מה. כדי לוודא ש- Google Cloud סיים ליצור את האשכול, נכנסים לדף Kubernetes clusters במסוף Google Cloud .

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

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

  1. מגדירים את kubectl לתקשורת עם אשכול GKE:

    gcloud container clusters get-credentials $CLUSTER_NAME \
        --location=$REGION
  2. יוצרים סוד ב-Kubernetes כדי לאחסן את הטוקן של Hugging Face:

    kubectl create secret generic hf-secret \
        --from-literal=hf_token=${HUGGING_FACE_TOKEN} \
        --dry-run=client -o yaml | kubectl apply -f -

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

אם אתם משתמשים בקטגוריה קיימת של Cloud Storage, ודאו שהתנאים הבאים מתקיימים:

  • הקטגוריה של Cloud Storage נמצאת באותו אזור שבו נמצא אשכול GKE.
  • לחשבון השירות יש את ההרשאות הנדרשות של write בקטגוריה.

כדי לאחסן את המודל בקטגוריה חדשה של Cloud Storage:

  1. מריצים את הפקודה הבאה כדי ליצור קטגוריה:

    gcloud storage buckets create gs://$GCS_BUCKET --location=$REGION --uniform-bucket-level-access
  2. נותנים לחשבון השירות שמוגדר כברירת מחדל את ההרשאות של write בקטגוריה של Cloud Storage.

    gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET \
        --member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/default/sa/default" \
        --role="roles/storage.objectAdmin"

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

כדי להוריד את המודל לקטגוריה של Cloud Storage:

  1. יוצרים קובץ gpt-download-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gpt-download-job
      namespace: default
    spec:
      template:
        metadata:
          labels:
            app: gpt-oss-downloader
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          restartPolicy: OnFailure
          containers:
          - name: downloader
            image: python:3.11-slim
            resources:
              requests:
                cpu: "4"
                memory: "16Gi"
              limits:
                cpu: "4"
                memory: "16Gi"
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            - name: HF_HUB_ENABLE_HF_TRANSFER
              value: "0"
            - name: HF_HOME
              value: "/tmp/hf_cache"
            command: ["/bin/sh", "-c"]
            args:
            - |
              echo "Installing Hugging Face Hub library..."
              pip install -U "huggingface_hub"
    
              echo "Beginning model snapshot download to GCS Fuse..."
              hf download openai/gpt-oss-120b \
                --token "$HUGGING_FACE_HUB_TOKEN" \
                --local-dir /mnt/gcs/gpt-oss-120b \
                --max-workers 1
    
              DOWNLOAD_STATUS=$?
    
              if [ $DOWNLOAD_STATUS -eq 0 ]; then
                echo "Download Complete!"
              else 
                echo "ERROR: Model download failed with exit code $DOWNLOAD_STATUS"
                exit $DOWNLOAD_STATUS
              fi
    
            volumeMounts:
            - mountPath: /mnt/gcs
              name: gcs-bucket-volume
          volumes:
          - name: gcs-bucket-volume
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: $GCS_BUCKET
                mountOptions: "implicit-dirs"
  2. כדי להפעיל את משימת ההורדה, צריך להחיל את המניפסט gpt-download-job.yaml.

    envsubst '$GCS_BUCKET' < gpt-download-job.yaml | kubectl apply -f -

    משאב המשימה מוריד את משקלי המודל של gpt-oss-120b מ-Hugging Face לקטגוריה של Cloud Storage. ההורדה נמשכת כ-30 דקות. אחרי שההורדה מסתיימת, עוברים לקטע הבא כדי להפעיל את פריסת המודל.

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

    kubectl wait \
        --for=condition=Complete \
        --timeout=7200s job/gpt-download-job

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

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

    kubectl delete job gpt-download-job

פריסת קונטיינר vLLM באשכול GKE

אחרי שמורידים את המודל לקטגוריה של Cloud Storage, פורסים קונטיינר vLLM באשכול GKE:

  1. יוצרים קובץ vllm-gpt-oss-120b.yaml עם פריסת ה-vLLM שבחרתם:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gpt-oss-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gpt-oss
      template:
        metadata:
          labels:
            app: gpt-oss
            ai.gke.io/model: gpt-oss-120b
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          containers:
          - name: vllm-inference
            image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250822_0916_RC01
            resources:
              requests:
                cpu: "10"
                memory: "128Gi"
                ephemeral-storage: "240Gi"
                nvidia.com/gpu: "8"
              limits:
                cpu: "10"
                memory: "128Gi"
                ephemeral-storage: "240Gi"
                nvidia.com/gpu: "8"
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --model=/mnt/gcs/gpt-oss-120b
            - --tensor-parallel-size=8
            - --host=0.0.0.0
            - --port=8000
            - --max-model-len=8192
            - --max-num-seqs=4
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /mnt/gcs
              name: gcs-bucket-volume
              readOnly: true
            livenessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 900
              periodSeconds: 10
            readinessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 900
              periodSeconds: 5
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          - name: gcs-bucket-volume
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: $GCS_BUCKET
                mountOptions: "implicit-dirs,file-cache:max-size-mb:-1,file-cache:enable-parallel-downloads:true,file-cache:max-parallel-downloads:32,file-cache:parallel-downloads-per-file:8,file-cache:download-chunk-size-mb:16"
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-b200
            cloud.google.com/reservation-name: $RESERVATION_URL
            cloud.google.com/reservation-affinity: "specific"
            cloud.google.com/gke-gpu-driver-version: latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: oss-service
    spec:
      selector:
        app: gpt-oss
      type: ClusterIP
      ports:
      - protocol: TCP
        port: 8000
        targetPort: 8000
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: vllm-gpt-oss-monitoring
    spec:
      selector:
        matchLabels:
          app: gpt-oss
      endpoints:
      - port: 8000
        path: /metrics
        interval: 30s
  2. מחילים את הקובץ vllm-gpt-oss-120b.yaml על אשכול GKE:

    envsubst < vllm-gpt-oss-120b.yaml | kubectl apply -f -
  3. כדי לראות את סטטוס ההשלמה, מריצים את הפקודה הבאה:

    kubectl wait \
        --for=condition=Available \
        --timeout=7200s deployment/vllm-gpt-oss-deployment
    הדגל --timeout מאפשר לפקודה לעקוב אחרי הפריסה למשך פרק הזמן שצוין.

אינטראקציה עם המודל gpt-oss באמצעות curl

כדי לאמת את המודל של gpt-oss שפרסתם:

  1. מגדירים העברה ליציאה אחרת למודל gpt-oss:

    kubectl port-forward service/oss-service 8000:8000
  2. פותחים חלון טרמינל חדש. אחרי זה, אתם יכולים לשוחח עם המודל באמצעות curl:

    curl http://127.0.0.1:8000/v1/chat/completions \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-oss-120b",
      "messages": [
        {
          "role": "user",
          "content": "Describe a sailboat in one short sentence?"
        }
      ]
    }' | jq .
  3. הפלט שמוצג אמור להיראות כך:

    {
      "id": "chatcmpl-2235c39759c040daae23ce2addc40c0a",
      "object": "chat.completion",
      "created": 1756831629,
      "model": "openai/gpt-oss-120b",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "A sleek vessel gliding on water, its cloth sails billowing like captured wind.",
            "refusal": null,
            "annotations": null,
            "audio": null,
            "function_call": null,
            "tool_calls": [],
            "reasoning_content": "User asks: \"Describe a sailboat in one short sentence?\" We need to produce a short sentence description. Should comply with policy. It's fine. Provide a short sentence."
          },
          "logprobs": null,
          "finish_reason": "stop",
          "stop_reason": null
        }
      ],
      "service_tier": null,
      "system_fingerprint": null,
      "usage": {
        "prompt_tokens": 80,
        "total_tokens": 142,
        "completion_tokens": 62,
        "prompt_tokens_details": null
      },
      "prompt_logprobs": null,
      "kv_transfer_params": null
    }
    

בדיקת הביצועים של המודל

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

הסרת המשאבים

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

מחיקת המשאבים

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

  1. כדי למחוק את הפריסה והשירות שהוגדרו בקובץ vllm-gpt-oss-120b.yaml ואת הסוד של Kubernetes מאשכול GKE, מריצים את הפקודה הבאה:

    envsubst < vllm-gpt-oss-120b.yaml | kubectl delete -f -
    kubectl delete secret hf-secret
  2. כדי למחוק את הקטגוריה של Cloud Storage, מריצים את הפקודה הבאה:

    gcloud storage rm --recursive gs://$GCS_BUCKET
  3. כדי למחוק את אשכול GKE:

    gcloud container clusters delete $CLUSTER_NAME \
        --region=$REGION \
        --quiet

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

כדי למחוק פרויקט ב- Google Cloud :

gcloud projects delete PROJECT_ID

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