הצגת מודל עם GPU יחיד ב-GKE

במדריך הזה נסביר איך לפרוס מודל שפה גדול (LLM) ולהכניס לשימוש בסביבת הייצור באמצעות GPUs ב-Google Kubernetes Engine ‏ (GKE) עם NVIDIA Triton Inference Server ו-TensorFlow Serving. המדריך הזה מספק בסיס להבנה ולבדיקה של פריסת LLM מעשית להיקש בסביבת Kubernetes מנוהלת. אתם פורסים קונטיינר מוכן מראש באשכול GKE עם GPU אחד מסוג L4 Tensor Core ומכינים את תשתית GKE לביצוע היקש אונליין.

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

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

מטרות

  1. יוצרים אשכול GKE Autopilot או אשכול רגיל.
  2. מגדירים קטגוריה של Cloud Storage שבה נמצא המודל שאומן מראש.
  3. פורסים את מסגרת ההסקה אונליין שבחרתם.
  4. שולחים בקשת בדיקה לשירות שנפרס.

עלויות

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

  • GKE
  • Cloud Storage
  • מאיצי GPU L4
  • תעבורת נתונים יוצאת

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

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

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

הגדרת הפרויקט

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Roles required to 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. Enable the GKE 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

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Roles required to 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

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

  7. Enable the GKE 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

הגדרת ברירות מחדל ל-Google Cloud CLI

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

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

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/ai-ml/gke-online-serving-single-gpu
    
  3. מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:

    gcloud config set project PROJECT_ID
    gcloud config set compute/region COMPUTE_REGION
    

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

  4. ב-Cloud Shell, יוצרים את משתני הסביבה הבאים:

    export PROJECT_ID=$(gcloud config get project)
    export REGION=$(gcloud config get compute/region)
    export K8S_SA_NAME=gpu-k8s-sa
    export GSBUCKET=$PROJECT_ID-gke-bucket
    export MODEL_NAME=mnist
    export CLUSTER_NAME=online-serving-cluster
    

יצירת אשכול GKE

אפשר להפעיל מודלים ב-GPU יחיד באשכול GKE Autopilot או באשכול רגיל. מומלץ להשתמש באשכול Autopilot כדי ליהנות מחוויית Kubernetes מנוהלת באופן מלא. ב-GKE Autopilot, המשאבים מותאמים אוטומטית לפי בקשות המודל.

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

טייס אוטומטי

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

  gcloud container clusters create-auto ${CLUSTER_NAME} \
      --location=${REGION} \
      --project=${PROJECT_ID} \
      --release-channel=rapid

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

רגילה

  1. מריצים את הפקודה הבאה כדי ליצור אשכול GKE Standard:

      gcloud container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID}  \
        --location=${REGION}  \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --addons GcsFuseCsiDriver \
        --release-channel=rapid \
        --num-nodes=1
    

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

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

      gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --node-locations=${REGION}-a \
        --cluster=${CLUSTER_NAME} \
        --machine-type=g2-standard-8 \
        --num-nodes=1
    

    ‫GKE יוצר מאגר צמתים יחיד שמכיל GPU אחד מסוג L4 לכל צומת.

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

יוצרים קטגוריה של Cloud Storage לאחסון המודל שעבר אימון מראש ויוצג.

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

gcloud storage buckets create gs://$GSBUCKET

הגדרת גישה לדלי באמצעות איחוד זהויות של עומסי עבודה ל-GKE

כדי לאפשר ל-cluster לגשת לקטגוריה של Cloud Storage, מבצעים את הפעולות הבאות:

  1. יוצרים Google Cloud חשבון שירות.
  2. יוצרים ServiceAccount של Kubernetes באשכול.
  3. מקשרים את חשבון השירות של Kubernetes לחשבון השירות Google Cloud .

יצירה של Google Cloud חשבון שירות

  1. במסוף Google Cloud , נכנסים לדף יצירת חשבון שירות:

    כניסה לדף Create service account

  2. בשדה מזהה חשבון שירות, מזינים gke-ai-sa.

  3. לוחצים על Create and continue.

  4. ברשימה Role בוחרים בתפקיד Cloud Storage > Storage Insights Collector Service.

  5. לוחצים על הוספת תפקיד נוסף.

  6. ברשימה Select a role, בוחרים בתפקיד Cloud Storage > Storage Object Admin.

  7. לוחצים על המשך ואז על סיום.

יצירת חשבון שירות של Kubernetes באשכול

ב-Cloud Shell, מבצעים את הפעולות הבאות:

  1. יוצרים מרחב שמות של Kubernetes:

    kubectl create namespace gke-ai-namespace
    
  2. יוצרים חשבון שירות של Kubernetes במרחב השמות:

    kubectl create serviceaccount gpu-k8s-sa --namespace=gke-ai-namespace
    

קישור חשבון השירות של Kubernetes לחשבון השירות Google Cloud

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

  1. מוסיפים קישור IAM ל Google Cloud חשבון השירות:

    gcloud iam service-accounts add-iam-policy-binding gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-ai-namespace/gpu-k8s-sa]"
    

    הדגל --member מספק את הזהות המלאה של חשבון השירות ב-Kubernetes ב- Google Cloud.

  2. הוספת הערה ל-ServiceAccount ב-Kubernetes:

    kubectl annotate serviceaccount gpu-k8s-sa \
        --namespace gke-ai-namespace \
        iam.gke.io/gcp-service-account=gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com
    

פריסת שרת ההיקשים אונליין

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

Triton

  1. ב-Cloud Shell, מעתיקים את המודל של למידת המכונה שאומן מראש לקטגוריה של Cloud Storage:

    gcloud storage cp src/triton-model-repository gs://$GSBUCKET --recursive
    
  2. פורסים את המסגרת באמצעות פריסה. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול:

    envsubst < src/gke-config/deployment-triton.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. מוודאים ש-GKE פרס את המסגרת:

    kubectl get deployments --namespace=gke-ai-namespace
    

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

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    triton-deployment    1/1     1            1           5m29s
    
  4. פורסים את השירותים כדי לגשת לפריסה:

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-triton.yaml
    
  5. בודקים שכתובת ה-IP החיצונית הוקצתה:

    kubectl get services --namespace=gke-ai-namespace
    

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

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    triton-server   LoadBalancer   34.118.227.176   35.239.54.228   8000:30866/TCP,8001:31035/TCP,8002:30516/TCP   5m14s
    

    שימו לב לכתובת ה-IP של triton-server בעמודה EXTERNAL-IP.

  6. בודקים שהשירות והפריסה פועלים בצורה תקינה:

    curl -v EXTERNAL_IP:8000/v2/health/ready
    

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

    ...
    < HTTP/1.1 200 OK
    < Content-Length: 0
    < Content-Type: text/plain
    ...
    

TF Serving

  1. ב-Cloud Shell, מעתיקים את המודל של למידת המכונה שאומן מראש לקטגוריה של Cloud Storage:

    gcloud storage cp src/tfserve-model-repository gs://$GSBUCKET --recursive
    
  2. פורסים את המסגרת באמצעות פריסה. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול:

    envsubst < src/gke-config/deployment-tfserve.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. מוודאים ש-GKE פרס את המסגרת:

    kubectl get deployments --namespace=gke-ai-namespace
    

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

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    tfserve-deployment   1/1     1            1           5m29s
    
  4. פורסים את השירותים כדי לגשת לפריסה:

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-tfserve.yaml
    
  5. בודקים שכתובת ה-IP החיצונית הוקצתה:

    kubectl get services --namespace=gke-ai-namespace
    

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

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    tfserve-server  LoadBalancer   34.118.227.176   35.239.54.228   8500:30003/TCP,8000:32194/TCP                  5m14s
    

    שימו לב לכתובת ה-IP של tfserve-server בעמודה EXTERNAL-IP.

  6. בודקים שהשירות והפריסה פועלים בצורה תקינה:

    curl -v EXTERNAL_IP:8000/v1/models/mnist
    

    מחליפים את EXTERNAL_IP בכתובת ה-IP החיצונית.

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

    ...
    < HTTP/1.1 200 OK
    < Content-Type: application/json
    < Date: Thu, 12 Oct 2023 19:01:19 GMT
    < Content-Length: 154
    <
    {
      "model_version_status": [
            {
            "version": "1",
            "state": "AVAILABLE",
            "status": {
              "error_code": "OK",
              "error_message": ""
            }
          }
        ]
    }
    

פרסום המודל

Triton

  1. יוצרים סביבה וירטואלית של Python ב-Cloud Shell.

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. מתקינים את חבילות Python הנדרשות.

    pip install -r src/client/triton-requirements.txt
    
  3. כדי לבדוק את שרת ההסקה של Triton על ידי טעינת תמונה:

    cd src/client
    python triton_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

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

    • EXTERNAL_IP: כתובת ה-IP החיצונית שלכם.
    • TEST_IMAGE: השם של הקובץ שתואם לתמונה שרוצים לבדוק. אפשר להשתמש בתמונות שמאוחסנות ב-src/client/images.

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

    Calling Triton HTTP Service      ->      Prediction result: 7
    

TF Serving

  1. יוצרים סביבה וירטואלית של Python ב-Cloud Shell.

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. מתקינים את חבילות Python הנדרשות.

    pip install -r src/client/tfserve-requirements.txt
    
  3. בודקים את TensorFlow Serving עם כמה תמונות.

    cd src/client
    python tfserve_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

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

  • EXTERNAL_IP: כתובת ה-IP החיצונית שלכם.
  • TEST_IMAGE: ערך מ-0 עד 9. אפשר להשתמש בתמונות שמאוחסנות ב-src/client/images.

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

  Calling TensorFlow Serve HTTP Service    ->      Prediction result: 5

מעקב אחר ביצועי המודל

Triton

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

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

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

TF Serving

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

כדי להשתמש בלוח הבקרה של TF Serving, צריך להפעיל את השירות המנוהל של Google Cloud ל-Prometheus, שאוסף את המדדים מ-TF Serving, באשכול GKE.

אחר כך תוכלו לראות את המדדים באמצעות לוח הבקרה של TF Serving. מידע על שימוש בשירות מנוהל של Google Cloud ל-Prometheus כדי לאסוף מדדים מהמודל זמין בהנחיות בנושא יכולת צפייה (observability) ב-TF Serving במסמכי Cloud Monitoring.

הסרת המשאבים

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

  • אם רוצים לשמור את אשכול GKE: מוחקים את משאבי Kubernetes באשכול ואת משאבי Google Cloud
  • שמירת הפרויקט: מחיקת אשכול GKE והמשאבים Google Cloud Google Cloud
  • מחיקת הפרויקט

מחיקת משאבי Kubernetes באשכול ובמשאבים Google Cloud

  1. מוחקים את מרחב השמות של Kubernetes ואת עומסי העבודה שפרסתם:

Triton

kubectl -n gke-ai-namespace delete -f src/gke-config/service-triton.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-triton.yaml
kubectl delete namespace gke-ai-namespace

TF Serving

kubectl -n gke-ai-namespace delete -f src/gke-config/service-tfserve.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-tfserve.yaml
kubectl delete namespace gke-ai-namespace
  1. מוחקים את הקטגוריה של Cloud Storage:

    1. נכנסים לדף Buckets:

      כניסה לדף Buckets

    2. מסמנים את התיבה PROJECT_ID-gke-bucket.

    3. לוחצים על מחיקה.

    4. כדי לאשר את המחיקה, מקלידים DELETE ולוחצים על מחיקה.

  2. מוחקים את Google Cloud חשבון השירות:

    1. עוברים לדף Service accounts:

      כניסה לדף Service accounts

    2. בוחרים את הפרויקט הרצוי.

    3. מסמנים את התיבה gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com.

    4. לוחצים על מחיקה.

    5. לוחצים על מחיקה כדי לאשר.

מחיקת אשכול GKE והמשאבים Google Cloud

  1. מחיקת אשכול GKE:

    1. עוברים לדף Clusters:

      מעבר אל Clusters

    2. מסמנים את התיבה של online-serving-cluster.

    3. לוחצים על מחיקה.

    4. כדי לאשר את המחיקה, מקלידים online-serving-cluster ולוחצים על מחיקה.

  2. מוחקים את הקטגוריה של Cloud Storage:

    1. נכנסים לדף Buckets:

      כניסה לדף Buckets

    2. מסמנים את התיבה PROJECT_ID-gke-bucket.

    3. לוחצים על מחיקה.

    4. כדי לאשר את המחיקה, מקלידים DELETE ולוחצים על מחיקה.

  3. מוחקים את Google Cloud חשבון השירות:

    1. עוברים לדף Service accounts:

      כניסה לדף Service accounts

    2. בוחרים את הפרויקט הרצוי.

    3. מסמנים את התיבה gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com.

    4. לוחצים על מחיקה.

    5. לוחצים על מחיקה כדי לאשר.

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

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

    כניסה לדף Manage resources

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

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