שימוש ב-vLLM ב-GKE כדי להריץ היקש עם DeepSeek-V3.2-Speciale

במדריך הזה נסביר איך לפרוס את מודל השפה DeepSeek-V3.2-Speciale ולפרסם אותו באמצעות מסגרת vLLM. אתם פורסים את המודל הזה באשכול Autopilot של מהדורת Google Kubernetes Engine ‏(GKE) Enterprise וצורכים מכונה וירטואלית אחת מסוג A4 עם 8 יחידות GPU מסוג B200.

במדריך הזה אנחנו מניחים שבדקתם את מודל השפה DeepSeek-V3.2-Speciale ושהיכולות שלו עונות על הדרישות של התרחיש לדוגמה שלכם.

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

מטרות

  1. אפשר לגשת אל DeepSeek-V3.2-Speciale באמצעות Hugging Face.

  2. מכינים את הסביבה.

  3. יוצרים אשכול GKE במצב אוטומטי.

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

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

  6. מורידים את המודל לקטגוריה של Cloud Storage.

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

  8. כדי לקיים אינטראקציה עם DeepSeek-V3.2-Speciale, משתמשים ב-curl.

  9. לפנות.

עלויות

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

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

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

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

  3. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

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

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

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

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (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 .

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

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

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

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

    gcloud services enable container.googleapis.com
  8. התקינו את ה-CLI של Google Cloud.

  9. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

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

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

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

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (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 .

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

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

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

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

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

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

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

    • ‫PROJECT_ID: מזהה הפרויקט.
    • ‫USER_IDENTIFIER: המזהה של חשבון המשתמש . לדוגמה, myemail@example.com.
    • ‫ROLE: תפקיד ה-IAM שאתם מקצים לחשבון המשתמש.
  15. נכנסים לחשבון Hugging Face או יוצרים חשבון חדש.

גישה ל-DeepSeek-V3.2-Speciale באמצעות Hugging Face

כדי להשתמש ב-Hugging Face כדי לגשת למודל DeepSeek-V3.2-Speciale, פועלים לפי השלבים הבאים:

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

הכנת הסביבה

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

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: השם של ההזמנה שרוצים להשתמש בה כדי ליצור את אשכול GKE. בהתאם לפרויקט שבו קיימת ההזמנה, מציינים אחד מהערכים הבאים:

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

    • ההזמנה קיימת בפרויקט אחר, והפרויקט שלכם יכול להשתמש בה: projects/RESERVATION_PROJECT_ID/reservations/YOUR_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, אפשר לדלג על השלב הזה. עם זאת, צריך לוודא שהקטגוריה נמצאת באותו אזור כמו האשכול, ושלחשבון השירות יש את ההרשאות הנדרשות write.

אם רוצים להשתמש בדלי חדש לאחסון המודל, מריצים את הפקודה הבאה:

gcloud storage buckets create gs://"$GCS_BUCKET" --location="$REGION" --uniform-bucket-level-access

נותנים הרשאות 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

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

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: deepseek-download-job
      namespace: default
    spec:
      template:
        metadata:
          labels:
            app: deepseek-oss-downloader
        spec:
          restartPolicy: OnFailure
          containers:
          - name: downloader
            image: google/cloud-sdk:slim
            resources:
              requests:
                cpu: "8"
                memory: "32Gi"
              limits:
                cpu: "8"
                memory: "32Gi"
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            - name: HF_XET_HIGH_PERFORMANCE
              value: "0"
            - name: PIP_BREAK_SYSTEM_PACKAGES
              value: "1"
            command: ["/bin/sh", "-c"]
            args:
            - |
              set -e
              echo "Installing Hugging Face Hub CLI..."
              pip install -U "huggingface_hub[cli]"
    
              LOCAL_DIR="/mnt/model-download/deepseek-v3-2"
              mkdir -p "$LOCAL_DIR"
    
              echo "Downloading model from HF to local SSD using parallel workers..."
              hf download deepseek-ai/DeepSeek-V3.2-Speciale \
                --token "$HUGGING_FACE_HUB_TOKEN" \
                --local-dir "$LOCAL_DIR" \
                --max-workers 8
    
              DOWNLOAD_STATUS=$?
    
              if [ $DOWNLOAD_STATUS -ne 0 ]; then
                echo "ERROR: Model download failed with exit code $DOWNLOAD_STATUS"
                exit $DOWNLOAD_STATUS
              fi
    
              echo "Download to SSD complete. Syncing to GCS..."
              gcloud storage rsync "$LOCAL_DIR" "gs://$GCS_BUCKET/deepseek-v3-2" --recursive
    
              echo "Process successfully completed!"
            volumeMounts:
            - mountPath: /mnt/model-download
              name: download-storage
          volumes:
          - name: download-storage
            ephemeral:
              volumeClaimTemplate:
                spec:
                  accessModes: [ "ReadWriteOnce" ]
                  storageClassName: premium-rwo
                  resources:
                    requests:
                      storage: 800Gi
  2. מחילים את קובץ המניפסט deepseek-download-job.yaml כדי לאתחל את משימת ההורדה:

    envsubst '$GCS_BUCKET' < deepseek-download-job.yaml | kubectl apply -f -
  3. כדי לראות את סטטוס ההשלמה, מריצים את הפקודה הבאה:

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

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

    משאב העבודה מוריד את משקלי המודל DeepSeek-V3.2-Speciale מ-Hugging Face לקטגוריית האחסון Google Cloud באמצעות נפח SSD. ההורדה נמשכת כ-40 דקות. אחרי שההורדה מסתיימת, ממשיכים לקטע הבא כדי להפעיל את פריסת המודל.

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

    kubectl delete job deepseek-download-job

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

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

  1. יוצרים קובץ vllm-deepseek3-2.yaml עם הפריסה של vLLM שבחרתם:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deepseek3-2-deploy
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: deepseek
      template:
        metadata:
          labels:
            app: deepseek
            ai.gke.io/model: deepseek-v3-2
            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:model-garden.pytorch-vllm-serve-release_20251126.00_p0
            resources:
              requests:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "1Ti"
                nvidia.com/gpu: "8"
              limits:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "1Ti"
                nvidia.com/gpu: "8"
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --model=/mnt/gcs/deepseek-v3-2
            - --tensor-parallel-size=8
            - --host=0.0.0.0
            - --port=8000
            - --max-model-len=131072
            - --max-num-seqs=16
            - --enable-chunked-prefill
            - --gpu-memory-utilization=0.90
            - --enforce-eager
            - --trust-remote-code
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /mnt/gcs
              name: gcs-bucket-volume
              readOnly: true
            livenessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 1800
              periodSeconds: 10
            readinessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 1800
              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: deepseek-service
    spec:
      selector:
        app: deepseek
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: deepseek-monitoring
    spec:
      selector:
        matchLabels:
          app: deepseek
      endpoints:
      - port: 8000
        path: /metrics
        interval: 30s
  2. מחילים את קובץ vllm-deepseek3-2.yaml על אשכול GKE:

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

    kubectl wait \
      --for=condition=Available \
      --timeout=7200s deployment/deepseek3-2-deploy

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

אינטראקציה עם DeepSeek-V3.2-Speciale באמצעות curl

כדי לאמת את מודל DeepSeek-V3.2-Speciale שפרסתם:

  1. הגדרת העברה ליציאה אחרת ל-DeepSeek-V3.2-Speciale:

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

    time curl http://127.0.0.1:8000/v1/completions \
       -X POST \
       -H "Content-Type: application/json" \
       -d '{
         "model": "deepseek-ai/DeepSeek-V3.2-Speciale",
         "prompt": "<|im_start|>user\nExplain the ReAct (Reasoning + Acting) pattern in Agentic AI. Provide a concise Python pseudocode example showing the loop. Keep the explanation under 300 words.<|im_end|>\n<|im_start|>assistant\n",
         "max_tokens": 1024,
         "temperature": 0.7,
         "stream": false,
         "stop": ["<|im_end|>"]
       }' | jq .
  3. הפלט שיוצג יהיה דומה לזה:

    {
      "id": "cmpl-be345f0499e949ed8500e533be2cfe3f",
      "object": "text_completion",
      "created": 1764803171,
      "model": "deepseek-ai/DeepSeek-V3.2-Speciale",
      "choices": [
        {
          "index": 0,
          "text": "The ReAct pattern integrates reasoning (thoughts) and actions (tool calls) within an agentic loop... [TRUNCATED FOR BREVITY] ...ReAct improves transparency and reliability by explicit reasoning steps.",
          "logprobs": null,
          "finish_reason": "stop",
          "stop_reason": "<|im_end|>",
          "token_ids": null,
          "prompt_logprobs": null,
          "prompt_token_ids": null
        }
      ],
      "service_tier": null,
      "system_fingerprint": null,
      "usage": {
        "prompt_tokens": 57,
        "total_tokens": 317,
        "completion_tokens": 260,
        "prompt_tokens_details": null
      },
      "kv_transfer_params": null
    }
    

התבוננות בביצועי המודל

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

מידע על שימוש בשירות מנוהל של Google Cloud ל-Prometheus כדי לאסוף מדדים מהמודל זמין במאמר בנושא vLLM בתיעוד של Monitoring.

הסרת המשאבים

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

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

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

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

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

    envsubst < vllm-deepseek3-2.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

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