הצגת מודל LLM עם מספר מעבדי GPU ב-GKE

במדריך הזה נסביר איך לפרוס מודל שפה גדול (LLM) ולהשתמש בו באמצעות כמה מעבדי GPU ב-GKE כדי להסיק מסקנות בצורה יעילה וניתנת להרחבה. אתם יוצרים אשכול GKE שמשתמש בכמה יחידות GPU מסוג L4 ומכינים תשתית להפעלת אחד מהמודלים הבאים:

מספר ה-GPU הנדרש משתנה בהתאם לפורמט הנתונים של המודל. במדריך הזה, כל מודל משתמש בשני מעבדי GPU מסוג L4. מידע נוסף זמין במאמר בנושא חישוב מספר מעבדי ה-GPU.

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

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

מטרות

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

  1. ליצור אשכול ומאגרי צמתים.
  2. הכנת עומס העבודה.
  3. פורסים את עומס העבודה.
  4. מנהלים אינטראקציה עם הממשק של מודל השפה הגדול.

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

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

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • יש מודלים עם דרישות נוספות. חשוב לוודא שאתם עומדים בדרישות הבאות:

הכנת הסביבה

  1. במסוף Google Cloud , מפעילים מכונת Cloud Shell:
    פתיחת Cloud Shell

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

    gcloud config set project PROJECT_ID
    gcloud config set billing/quota_project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export CONTROL_PLANE_LOCATION=us-central1
    

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

יצירת אשכול GKE ומאגר צמתים

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

טייס אוטומטי

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

    gcloud container clusters create-auto l4-demo \
      --project=${PROJECT_ID} \
      --location=${CONTROL_PLANE_LOCATION} \
      --release-channel=rapid
    

    ‫GKE יוצר אשכול Autopilot עם צמתים של מעבד ו-GPU לפי בקשת עומסי העבודה שנפרסו.

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

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

רגילה

  1. ב-Cloud Shell, מריצים את הפקודה הבאה כדי ליצור אשכול Standard שמשתמש באיחוד זהויות של עומסי עבודה ל-GKE:

    gcloud container clusters create l4-demo \
      --location ${CONTROL_PLANE_LOCATION} \
      --workload-pool ${PROJECT_ID}.svc.id.goog \
      --enable-image-streaming \
      --node-locations=${CONTROL_PLANE_LOCATION}-a \
      --workload-pool=${PROJECT_ID}.svc.id.goog \
      --machine-type n2d-standard-4 \
      --num-nodes 1 --min-nodes 1 --max-nodes 5 \
      --release-channel=rapid
    
    , צריך לבדוק באילו אזורים כרטיסי ה-GPU מדגם L4 זמינים.

    יצירת האשכול עשויה להימשך כמה דקות.

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

    gcloud container node-pools create g2-standard-24 --cluster l4-demo \
      --location ${CONTROL_PLANE_LOCATION} \
      --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \
      --machine-type g2-standard-24 \
      --enable-autoscaling --enable-image-streaming \
      --num-nodes=0 --min-nodes=0 --max-nodes=3 \
      --node-locations ${CONTROL_PLANE_LOCATION}-a,${CONTROL_PLANE_LOCATION}-c \
      --spot
    

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

    • אשכול Standard ציבורי.
    • מאגר צמתים עם g2-standard-24 סוג מכונה שהוקטן ל-0 צמתים. לא תחויבו על יחידות GPU עד שתפעילו Pods שמבקשים יחידות GPU. מאגר הצמתים הזה מספק מכונות וירטואליות מסוג Spot, שהמחיר שלהן נמוך יותר מהמחיר של מכונות וירטואליות רגילות של Compute Engine, ולא מובטחת זמינות שלהן. אפשר להסיר את הדגל --spot מהפקודה הזו, ואת בורר הצמתים cloud.google.com/gke-spot בהגדרות text-generation-inference.yaml כדי להשתמש במכונות וירטואליות לפי דרישה.
  3. מגדירים את kubectl כדי לתקשר עם האשכול:

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

הכנת עומס העבודה

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

Llama 3 70b

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

    export HF_TOKEN=HUGGING_FACE_TOKEN
    

    מחליפים את HUGGING_FACE_TOKEN באסימון HuggingFace.

  2. יוצרים סוד של Kubernetes עבור טוקן HuggingFace:

    kubectl create secret generic l4-demo \
        --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \
        --dry-run=client -o yaml | kubectl apply -f -
    
  3. יוצרים את מניפסט הפריסה הבא text-generation-inference.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llm
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llm
      template:
        metadata:
          labels:
            app: llm
        spec:
          containers:
          - name: llm
            image: us-docker.pkg.dev/deeplearning-platform-release/gcr.io/huggingface-text-generation-inference-cu121.2-1.ubuntu2204.py310
            resources:
              requests:
                cpu: "10"
                memory: "60Gi"
                nvidia.com/gpu: "2"
              limits:
                cpu: "10"
                memory: "60Gi"
                nvidia.com/gpu: "2"
            env:
            - name: MODEL_ID
              value: meta-llama/Meta-Llama-3-70B-Instruct
            - name: NUM_SHARD
              value: "2"
            - name: MAX_INPUT_TOKENS
              value: "2048"
            - name: PORT
              value: "8080"
            - name: QUANTIZE
              value: bitsandbytes-nf4
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: l4-demo
                  key: HUGGING_FACE_TOKEN
            volumeMounts:
              - mountPath: /dev/shm
                name: dshm
              # mountPath is set to /tmp as it's the path where the HUGGINGFACE_HUB_CACHE environment
              # variable in the TGI DLCs is set to instead of the default /data set within the TGI default image.
              # i.e. where the downloaded model from the Hub will be stored
              - mountPath: /tmp
                name: ephemeral-volume
          volumes:
            - name: dshm
              emptyDir:
                  medium: Memory
            - name: ephemeral-volume
              ephemeral:
                volumeClaimTemplate:
                  metadata:
                    labels:
                      type: ephemeral
                  spec:
                    accessModes: ["ReadWriteOnce"]
                    storageClassName: "premium-rwo"
                    resources:
                      requests:
                        storage: 150Gi
          nodeSelector:
            cloud.google.com/gke-accelerator: "nvidia-l4"
            cloud.google.com/gke-spot: "true"

    במניפסט הזה:

    • הערך של NUM_SHARD חייב להיות 2 כי המודל דורש שני מעבדי GPU מסוג NVIDIA L4.
    • הערך של QUANTIZE מוגדר כ-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט במקום ב-32 ביט. כך אפשר להקטין את כמות זיכרון ה-GPU שנדרשת ב-GKE ולשפר את מהירות ההסקה. עם זאת, רמת הדיוק של המודל עלולה לרדת. במאמר חישוב מספר ה-GPU מוסבר איך לחשב את מספר ה-GPU שצריך לבקש.
  4. החלת המניפסט:

    kubectl apply -f text-generation-inference.yaml
    

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

    deployment.apps/llm created
    
  5. מאמתים את הסטטוס של המודל:

    kubectl get deploy
    

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

    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    llm           1/1     1            1           20m
    
  6. צפייה ביומנים מהפריסה הפעילה:

    kubectl logs -l app=llm
    

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

    {"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291}
    {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328}
    {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329}
    {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
    

Mixtral 8x7b

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

    export HF_TOKEN=HUGGING_FACE_TOKEN
    

    מחליפים את HUGGING_FACE_TOKEN באסימון HuggingFace.

  2. יוצרים סוד של Kubernetes עבור טוקן HuggingFace:

    kubectl create secret generic l4-demo \
        --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \
        --dry-run=client -o yaml | kubectl apply -f -
    
  3. יוצרים את מניפסט הפריסה הבא text-generation-inference.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llm
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llm
      template:
        metadata:
          labels:
            app: llm
        spec:
          containers:
          - name: llm
            image: us-docker.pkg.dev/deeplearning-platform-release/gcr.io/huggingface-text-generation-inference-cu124.2-3.ubuntu2204.py311
            resources:
              requests:
                cpu: "5"
                memory: "40Gi"
                nvidia.com/gpu: "2"
              limits:
                cpu: "5"
                memory: "40Gi"
                nvidia.com/gpu: "2"
            env:
            - name: MODEL_ID
              value: mistralai/Mixtral-8x7B-Instruct-v0.1
            - name: NUM_SHARD
              value: "2"
            - name: PORT
              value: "8080"
            - name: QUANTIZE
              value: bitsandbytes-nf4
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: l4-demo
                  key: HUGGING_FACE_TOKEN          
            volumeMounts:
              - mountPath: /dev/shm
                name: dshm
              # mountPath is set to /tmp as it's the path where the HF_HOME environment
              # variable in the TGI DLCs is set to instead of the default /data set within the TGI default image.
              # i.e. where the downloaded model from the Hub will be stored
              - mountPath: /tmp
                name: ephemeral-volume
          volumes:
            - name: dshm
              emptyDir:
                  medium: Memory
            - name: ephemeral-volume
              ephemeral:
                volumeClaimTemplate:
                  metadata:
                    labels:
                      type: ephemeral
                  spec:
                    accessModes: ["ReadWriteOnce"]
                    storageClassName: "premium-rwo"
                    resources:
                      requests:
                        storage: 100Gi
          nodeSelector:
            cloud.google.com/gke-accelerator: "nvidia-l4"
            cloud.google.com/gke-spot: "true"

    במניפסט הזה:

    • הערך של NUM_SHARD חייב להיות 2 כי המודל דורש שני מעבדי GPU מסוג NVIDIA L4.
    • הערך של QUANTIZE מוגדר כ-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט במקום ב-32 ביט. כך אפשר להקטין את כמות זיכרון ה-GPU שנדרשת ב-GKE ולשפר את מהירות ההסקה. עם זאת, יכול להיות שהפעולה הזו תפגע ברמת הדיוק של המודל. במאמר חישוב מספר ה-GPU מוסבר איך מחשבים את מספר ה-GPU שצריך לבקש.
  4. החלת המניפסט:

    kubectl apply -f text-generation-inference.yaml
    

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

    deployment.apps/llm created
    
  5. מאמתים את הסטטוס של המודל:

    watch kubectl get deploy
    

    כשהפריסה מוכנה, הפלט אמור להיראות כך:

    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    llm           1/1     1            1           10m
    

    כדי לצאת מהשעון, מקלידים CTRL + C.

  6. צפייה ביומנים מהפריסה הפעילה:

    kubectl logs -l app=llm
    

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

    {"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291}
    {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328}
    {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329}
    {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
    

Falcon 40b

  1. יוצרים את מניפסט הפריסה הבא text-generation-inference.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llm
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llm
      template:
        metadata:
          labels:
            app: llm
        spec:
          containers:
          - name: llm
            image: us-docker.pkg.dev/deeplearning-platform-release/gcr.io/huggingface-text-generation-inference-cu121.1-4.ubuntu2204.py310
            resources:
              requests:
                cpu: "10"
                memory: "60Gi"
                nvidia.com/gpu: "2"
              limits:
                cpu: "10"
                memory: "60Gi"
                nvidia.com/gpu: "2"
            env:
            - name: MODEL_ID
              value: tiiuae/falcon-40b-instruct
            - name: NUM_SHARD
              value: "2"
            - name: PORT
              value: "8080"
            - name: QUANTIZE
              value: bitsandbytes-nf4
            volumeMounts:
              - mountPath: /dev/shm
                name: dshm
              # mountPath is set to /data as it's the path where the HUGGINGFACE_HUB_CACHE environment
              # variable points to in the TGI container image i.e. where the downloaded model from the Hub will be
              # stored
              - mountPath: /data
                name: ephemeral-volume
          volumes:
            - name: dshm
              emptyDir:
                  medium: Memory
            - name: ephemeral-volume
              ephemeral:
                volumeClaimTemplate:
                  metadata:
                    labels:
                      type: ephemeral
                  spec:
                    accessModes: ["ReadWriteOnce"]
                    storageClassName: "premium-rwo"
                    resources:
                      requests:
                        storage: 175Gi
          nodeSelector:
            cloud.google.com/gke-accelerator: "nvidia-l4"
            cloud.google.com/gke-spot: "true"

    במניפסט הזה:

    • הערך של NUM_SHARD חייב להיות 2 כי המודל דורש שני מעבדי GPU מסוג NVIDIA L4.
    • הערך של QUANTIZE מוגדר כ-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט במקום ב-32 ביט. כך אפשר להקטין את כמות זיכרון ה-GPU שנדרשת ב-GKE ולשפר את מהירות ההסקה. עם זאת, רמת הדיוק של המודל עלולה לרדת. במאמר חישוב מספר ה-GPU מוסבר איך מחשבים את מספר ה-GPU שצריך לבקש.
  2. החלת המניפסט:

    kubectl apply -f text-generation-inference.yaml
    

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

    deployment.apps/llm created
    
  3. מאמתים את הסטטוס של המודל:

    watch kubectl get deploy
    

    כשהפריסה מוכנה, הפלט אמור להיראות כך:

    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    llm           1/1     1            1           10m
    

    כדי לצאת מהשעון, מקלידים CTRL + C.

  4. צפייה ביומנים מהפריסה הפעילה:

    kubectl logs -l app=llm
    

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

    {"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291}
    {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328}
    {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329}
    {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
    

יצירת שירות מסוג ClusterIP

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

  1. יוצרים את קובץ המניפסט llm-service.yaml הבא:

    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: llm
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. החלת המניפסט:

    kubectl apply -f llm-service.yaml
    

פריסת ממשק צ'אט

משתמשים ב-Gradio כדי ליצור אפליקציית אינטרנט שמאפשרת אינטראקציה עם המודל. ‫Gradio היא ספריית Python שיש לה wrapper של ChatInterface שיוצר ממשקי משתמש לצ'אטבוטים.

Llama 3 70b

  1. יוצרים קובץ בשם gradio.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: gradio
      labels:
        app: gradio
    spec:
      strategy:
        type: Recreate
      replicas: 1
      selector:
        matchLabels:
          app: gradio
      template:
        metadata:
          labels:
            app: gradio
        spec:
          containers:
          - name: gradio
            image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.4
            resources:
              requests:
                cpu: "512m"
                memory: "512Mi"
              limits:
                cpu: "1"
                memory: "512Mi"
            env:
            - name: CONTEXT_PATH
              value: "/generate"
            - name: HOST
              value: "http://llm-service"
            - name: LLM_ENGINE
              value: "tgi"
            - name: MODEL_ID
              value: "meta-llama/Meta-Llama-3-70B-Instruct"
            - name: USER_PROMPT
              value: "<|begin_of_text|><|start_header_id|>user<|end_header_id|> prompt <|eot_id|><|start_header_id|>assistant<|end_header_id|>"
            - name: SYSTEM_PROMPT
              value: "prompt <|eot_id|>"
            ports:
            - containerPort: 7860
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: gradio-service
    spec:
      type: LoadBalancer
      selector:
        app: gradio
      ports:
      - port: 80
        targetPort: 7860
    
  2. החלת המניפסט:

    kubectl apply -f gradio.yaml
    
  3. מוצאים את כתובת ה-IP החיצונית של השירות:

    kubectl get svc
    

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

    NAME             TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
    gradio-service   LoadBalancer   10.24.29.197   34.172.115.35   80:30952/TCP   125m
    
  4. מעתיקים את כתובת ה-IP החיצונית מהעמודה EXTERNAL-IP.

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

    http://EXTERNAL_IP
    

Mixtral 8x7b

  1. יוצרים קובץ בשם gradio.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: gradio
      labels:
        app: gradio
    spec:
      strategy:
        type: Recreate
      replicas: 1
      selector:
        matchLabels:
          app: gradio
      template:
        metadata:
          labels:
            app: gradio
        spec:
          containers:
          - name: gradio
            image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.4
            resources:
              requests:
                cpu: "512m"
                memory: "512Mi"
              limits:
                cpu: "1"
                memory: "512Mi"
            env:
            - name: CONTEXT_PATH
              value: "/generate"
            - name: HOST
              value: "http://llm-service"
            - name: LLM_ENGINE
              value: "tgi"
            - name: MODEL_ID
              value: "mixtral-8x7b"
            - name: USER_PROMPT
              value: "[INST] prompt [/INST]"
            - name: SYSTEM_PROMPT
              value: "prompt"
            ports:
            - containerPort: 7860
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: gradio-service
    spec:
      type: LoadBalancer
      selector:
        app: gradio
      ports:
      - port: 80
        targetPort: 7860
    
  2. החלת המניפסט:

    kubectl apply -f gradio.yaml
    
  3. מוצאים את כתובת ה-IP החיצונית של השירות:

    kubectl get svc
    

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

    NAME             TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
    gradio-service   LoadBalancer   10.24.29.197   34.172.115.35   80:30952/TCP   125m
    
  4. מעתיקים את כתובת ה-IP החיצונית מהעמודה EXTERNAL-IP.

  5. אפשר לראות את ממשק המודל בדפדפן האינטרנט באמצעות כתובת ה-IP החיצונית עם היציאה שנחשפה:

    http://EXTERNAL_IP
    

Falcon 40b

  1. יוצרים קובץ בשם gradio.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: gradio
      labels:
        app: gradio
    spec:
      strategy:
        type: Recreate
      replicas: 1
      selector:
        matchLabels:
          app: gradio
      template:
        metadata:
          labels:
            app: gradio
        spec:
          containers:
          - name: gradio
            image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.4
            resources:
              requests:
                cpu: "512m"
                memory: "512Mi"
              limits:
                cpu: "1"
                memory: "512Mi"
            env:
            - name: CONTEXT_PATH
              value: "/generate"
            - name: HOST
              value: "http://llm-service"
            - name: LLM_ENGINE
              value: "tgi"
            - name: MODEL_ID
              value: "falcon-40b-instruct"
            - name: USER_PROMPT
              value: "User: prompt"
            - name: SYSTEM_PROMPT
              value: "Assistant: prompt"
            ports:
            - containerPort: 7860
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: gradio-service
    spec:
      type: LoadBalancer
      selector:
        app: gradio
      ports:
      - port: 80
        targetPort: 7860
    
  2. החלת המניפסט:

    kubectl apply -f gradio.yaml
    
  3. מוצאים את כתובת ה-IP החיצונית של השירות:

    kubectl get svc
    

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

    NAME             TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
    gradio-service   LoadBalancer   10.24.29.197   34.172.115.35   80:30952/TCP   125m
    
  4. מעתיקים את כתובת ה-IP החיצונית מהעמודה EXTERNAL-IP.

  5. אפשר לראות את ממשק המודל בדפדפן האינטרנט באמצעות כתובת ה-IP החיצונית עם היציאה שנחשפה:

    http://EXTERNAL_IP
    

חישוב מספר ה-GPU

מספר ה-GPU תלוי בערך של הדגל QUANTIZE. במדריך הזה, הערך של QUANTIZE מוגדר ל-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביטים.

מודל עם 70 מיליארד פרמטרים ידרוש זיכרון GPU בנפח 40GB לפחות, ששווה ל-70 מיליארד כפול 4 ביט (70 מיליארד x 4 ביט= 35GB), וכולל 5GB של תקורה. במקרה כזה, ל-GPU יחיד מסוג L4 לא יהיה מספיק זיכרון. לכן, בדוגמאות במדריך הזה נעשה שימוש ב-שני GPU L4 עם זיכרון (‎2 x 24 = 48 GB). ההגדרה הזו מספיקה להרצת Falcon 40b או Llama 3 70b במעבדי GPU מסוג L4.

הסרת המשאבים

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

מחיקת האשכול

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

gcloud container clusters delete l4-demo --location ${CONTROL_PLANE_LOCATION}

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