שימוש בחלוקה דינמית עם מתזמן מותאם אישית

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

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

למה כדאי להשתמש בחלוקה דינמית עם מתזמן מותאם אישית?

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

אם אתם מעדיפים להשתמש בכלי לתזמון במקום לנהל ישירות משאבים מותאמים אישית של Slice, ‏ GKE מספק שילוב עם Kueue ועם Topology Aware Scheduling‏ (TAS). מידע נוסף זמין במאמר בנושא תזמון פלחים דינמיים באמצעות Kueue ו-TAS.

סקירה כללית של תהליך העבודה

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

  1. הפעלת אמצעי הבקרה של תבניות התוכן הדינמי.
  2. יצירת מאגרי צמתים עם הקצאת משאבים מצטברת
  3. יוצרים משאבים מותאמים אישית של Slice על סמך הדרישות של עומס העבודה. מחילים את משאב ה-Slice המותאם אישית על האשכול.
  4. מעקב אחרי מצבי המחיצות והתקינות של הפרוסות.
  5. בסיום, מוחקים את הפרוסה.

מידע נוסף על השדות והסטטוס של המשאב המותאם אישית Slice זמין במאמר בנושא המשאב המותאם אישית Slice.

דרישות

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

  • להשתמש באשכול רגיל בגרסה 1.35.2-gke.1842000 ואילך, בערוץ Rapid.
  • שימוש בגרסת Ironwood‏ (TPU7x).
  • משתמשים בקובץ אימג' של מערכת הפעלה שמותאמת לקונטיינרים עבור הצמתים.
  • כדי להשתמש בהקצאת משאבים מצטברת, צריך להשתמש בהזמנות במצב 'כל הקיבולת'. כל מצב הקיבולת הוא תכונה שמופעלת על ידי TPU Cluster Director.

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

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

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

הפעלת אמצעי הבקרה של התבנית

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

  1. מעדכנים את האשכול:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --enable-slice-controller
    

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

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

    gcloud config set container/cluster CLUSTER_NAME
    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    
  3. בפלט של הפקודה הבאה, מוודאים שהערך slices.accelerator.gke.io מופיע:

    kubectl get crd slices.accelerator.gke.io
    

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

    slices.accelerator.gke.io                2026-01-09T23:58:02Z
    

יצירת מאגרי צמתים עם הקצאת משאבים מצטברת

בקטע הזה מוסבר איך ליצור מאגרי צמתים של TPU עם הקצאת משאבים מצטברת. ‫GKE ממיר את כל קיבולת ה-TPU שלכם למאגרי צמתים של קבוצת מכונות וירטואליות של TPU עם 16 צמתים, או בלוקים משנה. ‫GKE מקצה את מאגרי הצמתים האלה גם אם הוא לא מצליח למצוא את כל 16 המכונות הווירטואליות התקינות, על ידי הצבת צמתים בחלקים תקינים של המכונה המארחת והקצאה מצטברת של מכונות לא תקינות בזמן שהן מתוקנות.

אתם יכולים לטרגט את מאגר הצמתים כך שישתייך לאחת מהקטגוריות הבאות:

  • בלוק ספציפי של יחידות TPU, שמוצג בהזמנות במצב 'כל הקיבולת'. טירגוט בלוקים מאפשר ל-GKE ליצור את מאגר הצמתים בכל תת-בלוק זמין בתוך הבלוק שצוין.
  • תת-בלוק ספציפי או קבוצה ספציפית של 16 צמתים של מכונות וירטואליות של TPU, כדי לקבל שליטה מפורטת יותר.

יצירת מדיניות של עומס עבודה

כדי ליצור מאגר צמתים של פרוסת TPU עם Ironwood‏ (TPU7x), קודם צריך ליצור מדיניות עומס עבודה עם השדה accelerator-topology-mode שמוגדר ל-provision_only. ההגדרה הזו מפעילה את תהליך ההקצאה המצטבר.

יוצרים מדיניות של עומסי עבודה:

gcloud compute resource-policies create workload-policy WORKLOAD_POLICY_NAME \
        --project=PROJECT_ID \
        --region=REGION  \
        --type=HIGH_THROUGHPUT \
        --accelerator-topology=4x4x4 \
        --accelerator-topology-mode=provision_only

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

  • WORKLOAD_POLICY_NAME: שם למדיניות של עומס העבודה.
  • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
  • REGION: האזור של מדיניות עומס העבודה.

בפקודה הזו, מבצעים את הפעולות הבאות:

  • תמיד מגדירים את השדה accelerator-topology לערך 4x4x4 כדי להתאים למספר הכולל של הצ'יפים בתוך בלוק משנה יחיד.
  • כדי להפעיל את תהליך ההקצאה המצטבר, צריך תמיד להגדיר את השדה accelerator-topology-mode לערך provision_only. כשמגדירים את השדה provision_only, מאגר הצמתים מספק צמתי TPU בלי ליצור קישורי ICI או OCS.

הגדרת מאגר הצמתים כך שישתייך לבלוק או לתת-בלוק

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

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

חסימה

  1. כדי לאחזר את השם של הבלוק בהזמנה ואת מספר תתי הבלוקים הזמינים בבלוק, צריך לבצע את השלבים הבאים במסמך View the topology and health status of All Capacity Mode reservations:

    1. מזהים את שם הבלוק על ידי הצגת רשימה של כל בלוקי ההזמנות והעתקת הערך בשדה name:. הערך הזה הוא שם הבלוק או BLOCK_NAME במסמך הזה.

    2. כדי לקבוע כמה מאגרי צמתים צריך ליצור, מתארים בלוק של הזמנה ומזהים את הערך בשדה reservationSubBlockCount. הערך הזה הוא מספר תתי-הבלוקים הזמינים. לדוגמה, הערך reservationSubBlockCount: 4 מציין שיש ארבעה בלוקים משניים זמינים בבלוק, וצריך ליצור ארבעה מאגרי צמתים נפרדים.

  2. מגדירים את נתיב ההזמנה:

    export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME"
    

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

    • RESERVATION_NAME: השם של הזמנת ה-TPU.
    • BLOCK_NAME: השם של הבלוק.
  3. יוצרים מאגר צמתים לכל תת-בלוק שזוהה בשלב הקודם. לדוגמה, אם המספר הוא 4, מריצים את הפקודה הזו ארבע פעמים. צריך להשתמש בשם ייחודי לכל מאגר צמתים.

    gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --node-locations=ZONE \
          --machine-type=tpu7x-standard-4t \
          --num-nodes=16 \
          --placement-policy=WORKLOAD_POLICY_NAME \
          --reservation-affinity=specific \
          --reservation=${RESERVATION_PATH}
    

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

    • NODE_POOL_NAME: השם של מאגר הצמתים החדש.
    • CLUSTER_NAME: השם של אשכול GKE.
    • WORKLOAD_POLICY_NAME: השם של מדיניות עומס העבודה שיצרתם.
    • ZONE: האזור של מאגר הצמתים, לדוגמה, us-central1-a.

Sub-block

  1. כדי לאחזר את השם של הבלוק ואת המזהים של תתי הבלוקים הזמינים, צריך לבצע את השלבים הבאים במסמך View the topology and health status of All Capacity Mode reservations (הצגת הטופולוגיה וסטטוס התקינות של כל ההזמנות במצב קיבולת):

    1. כדי לזהות את השם של הבלוק, מציגים רשימה של כל בלוקי ההזמנות ומעתיקים את הערך בשדה name:. הערך הזה הוא השם של הבלוק או של BLOCK_NAME במסמך הזה.

    2. כדי לזהות את השם של תת-הבלוקים, צריך לרשום את כל תת-הבלוקים של בלוק ולהעתיק את הערך בשדה name: לכל רשומה בקטע reservationSubBlocks. הערך הזה הוא השם של בלוק המשנה או SUBBLOCK_NAME במסמך הזה.

  2. מגדירים את נתיב ההזמנה:

    export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME/reservationSubBlocks/SUBBLOCK_NAME"
    

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

    • RESERVATION_NAME: השם של הזמנת ה-TPU.
    • BLOCK_NAME: השם של הבלוק.
    • SUBBLOCK_NAME: השם של בלוק המשנה.
  3. יוצרים את מאגר הצמתים:

    gcloud container node-pools create NODE_POOL_NAME \
            --project=PROJECT_ID \
            --cluster=CLUSTER_NAME \
            --node-locations=ZONE \
            --machine-type=tpu7x-standard-4t \
            --num-nodes=16 \
            --placement-policy=WORKLOAD_POLICY_NAME \
            --reservation-affinity=specific \
            --reservation=${RESERVATION_PATH}
    

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

    • NODE_POOL_NAME: שם ייחודי למאגר הצמתים החדש, לדוגמה, sub-block-pool-1.
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • CLUSTER_NAME: השם של אשכול GKE.
    • ZONE: האזור של מאגר הצמתים, לדוגמה, us-central2-b.
    • WORKLOAD_POLICY_NAME: השם של מדיניות העומס שיצרתם.

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

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

  • יוצרים משאב מותאם אישית של Slice. במקום Pods, משתמשים במשאב מותאם אישית מסוג Slice כדי להגדיר את הטופולוגיה שצוינה, והבקר של ה-Slice מפעיל אותה.
  • תזמון עומסי עבודה ב-GKE באמצעות Kueue ו-TAS. ‫Kueue מטפל אוטומטית ביצירה ובמחיקה של משאבים מותאמים אישית מסוג Slice. מומלץ להימנע משינוי ידני של משאבים מותאמים אישית של Slice שנוצרו על ידי Kueue.

יצירת פלח דינמי

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

אימות הסטטוס של הצמתים והמחיצות

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

    kubectl get nodes -l cloud.google.com/gke-nodepool=${NODE_POOL_NAME}
    

    התוצאה אמורה להיראות כך:

    NAME                                 STATUS   ROLES    AGE    VERSION
    gke-np-status-update-7b4c890c-0jhp   Ready    <none>   2d1h   v1.35.1-gke.1396002
    gke-np-status-update-7b4c890c-377r   Ready    <none>   2d1h   v1.35.1-gke.1396002
    gke-np-status-update-7b4c890c-gb51   Ready    <none>   2d1h   v1.35.1-gke.1396002
    
  2. בודקים את מודל ההקצאה של הצומת:

    kubectl describe node NODE_NAME | grep "cloud.google.com/gke-accelerator-topology-mode"
    

    התוצאה אמורה להיראות כך:

    cloud.google.com/gke-accelerator-topology-mode: PROVISION_ONLY
    

    הערך הזה תואם להגדרה accelerator-topology-mode=provision_only שהגדרתם כשנוצרה מדיניות עומס העבודה.

  3. מאחזרים את פרטי התווית של הצומת:

    kubectl describe node NODE_NAME | grep "cloud.google.com/gke-tpu-partition-4x4x4-id"
    

    מחליפים את NODE_NAME בשם של אחד מהצמתים במאגר הצמתים.

    התוצאה אמורה להיראות כך:

    cloud.google.com/gke-tpu-partition-4x4x4-id=fba785f80d18552357dcdef6d3d16c27
    

    ההערה cloud.google.com/gke-tpu-partition-4x4x4-state מציינת אם הצומת זמין ליצירת פרוסה דינמית. אפשר להזין בתווית הזו את הערכים הבאים:

    • HEALTHY: הצומת תקין ופועל באופן מלא.
    • DEGRADED: הצומת פגום אבל עדיין אפשר להשתמש בו ליצירת פרוסות דינמיות.
    • UNHEALTHY: הצומת לא פועל בצורה תקינה ואי אפשר להשתמש בו כדי ליצור פרוסה.
    • UNSET: המצב לא מוגדר בגלל שלא קיימים מספיק צמתים במאגר הצמתים.
    • INCOMPLETE: לא כל הצמתים במחיצה הוקצו.
  4. מוודאים שהצומת כולל את ההערה node.gke.io/created-by-mig:

    kubectl describe node NODE_NAME | grep "node.gke.io/created-by-mig"
    

    מחליפים את NODE_NAME בשם של אחד מהצמתים במאגר הצמתים.

    התוצאה אמורה להיראות כך:

    node.gke.io/created-by-mig: projects/735972712744/zones/us-central1-ai1a/team/string
    

    הפלט כולל את התווית node.gke.io/created-by-mig, שמאפשרת למישור הבקרה של GKE לקשר בין צמתי Kubernetes לבין משאבי Compute Engine הבסיסיים שלהם.

יצירת משאב מותאם אישית של Slice

  1. מגדירים את המשאב המותאם אישית Slice:

    apiVersion: accelerator.gke.io/v1beta1
    kind: Slice
    metadata:
      # Name of the slice resource
      name: SLICE_NAME
    spec:
      # Specify the type of accelerator for this slice
      type: "tpu7x"
      # Define the desired topology for the accelerator slice
      topology: TOPOLOGY
      partitionIds:
        - PARTITION_ID # Example: a9476d1b02bd4f4e75ffffae3bd23c01
        - PARTITION_ID_2
        # ... add more partition IDs as needed
    

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

    • SLICE_NAME: שם לפרוסה. השם צריך לעמוד בתנאים של metadata.name.
    • TOPOLOGY: הטופולוגיה של הפרוסה הדינמית. הטופולוגיה צריכה לעמוד בתנאים הבאים:
      • כל מאפיין בטופולוגיה המבוקשת חייב להיות כפולה של ארבע, לדוגמה 4A x 4B x 4C.
      • שלושת הערכים במאפייני הטופולוגיה, AxBxC, צריכים להיות בסדר לא יורד (A ≤ B ≤ C). לדוגמה, 4x4x8 הוא ערך תקין, אבל 4x8x4 לא. הסדר הזה עוזר לוודא שנוצרים פלחים עקביים ומונע התנהגות לא צפויה.
      • המכפלה של שלושת הערכים במאפייני הטופולוגיה, A × B × C, לא יכולה להיות גדולה מ-9,216.
    • PARTITION_ID: רשימה של מחרוזות שמזהות את המחיצות 4x4x4 שמרכיבות את הפרוסה. מחשבים את מספר המחיצות על סמך המספר הכולל של השבבים, כאשר כל מחיצה מורכבת מ-64 שבבים. מספר הפריטים ברשימה spec.partitionIds צריך להיות זהה בדיוק למספר המחיצות המחושב ((A × B × C) / 64). המאפיין partitionIds צריך לעמוד בתנאים הבאים:
      • כל מחיצה צריכה להיות ממופה לתת-בלוק של הזמנה.
      • כל בלוקי המשנה המשויכים חייבים להיות שייכים לאותה הזמנה.
      • כל הבלוקים המשויכים צריכים להיות באותו הזמנה.
      • כל הצמתים במאגרי הצמתים המשויכים צריכים להיות במצב ready.
    • הערך בשדה type חייב להיות tpu7x.
    • אם רוצים שהבקרה על הפלחים תנסה שוב באופן אוטומטי במהלך יצירת הפלחים, אפשר להוסיף את ההערה slice.gke.io/retry-on-failure: "true" למשאב המותאם אישית של הפלח. אם הפרוסה לא נוצרת בגלל סיבת הסטטוס SliceCreationFailed, הבקר ינסה שוב עד שהפרוסה תיווצר בהצלחה.

    לדוגמה, כדי ליצור 4x8x8 פרוסה, צריך לספק ארבעה מזהי מחיצות ייחודיים.

    apiVersion: accelerator.gke.io/v1beta1
    kind: Slice
    metadata:
        name: test-slice-example
        annotations:
          slice.gke.io/retry-on-failure: "true" # Optional annotation to retry slice formation
    spec:
        type: "tpu7x"
        topology: "4x8x8" # (4*8*8)/64 = 4 partitions
        partitionIds:
            - "p0"
            - "p1"
            - "p2"
            - "p3"
    
  2. מחילים את משאב ה-Slice המותאם אישית:

    kubectl apply -f test-slice-example.yaml
    

    בשלב הזה, GKE מנסה ליצור את הפרוסה. אם מתרחשת אחת מהבעיות הבאות, יצירת הפלח נכשלת והסיבה לסטטוס במשאב המותאם אישית של Slice מתעדכנת ל-SliceCreationFailed או ל-FAILED:

    • אם הצמתים שנבחרו במשאב המותאם אישית לא קיימים, הסיבה לסטטוס היא SliceCreationFailed.
    • אם צמתים במשאב המותאם אישית נמצאים בשימוש של פרוסה אחרת, סיבת הסטטוס היא SliceCreationFailed.
    • אם הצמתים במשאב המותאם אישית לא שייכים לאותו בלוק הזמנה, הסיבה לסטטוס היא FAILED.
    • אם הצמתים לא נמצאים באותה הזמנה, הסיבה לסטטוס היא FAILED.
    • אם הטופולוגיה לא תואמת למספר המחיצות, הסיבה לסטטוס היא SliceCreationFailed.

    מידע נוסף על הסטטוס של המשאב המותאם אישית Slice זמין במאמר סטטוס Slice.

מעקב אחרי הסטטוס של משאב בהתאמה אישית מסוג Slice

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

kubectl describe slice SLICE_NAME

מחליפים את SLICE_NAME בשם הפרוסה.

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

Name:         test-slice
Namespace:
Labels:       <none>
Annotations:  <none>
API Version:  accelerator.gke.io/v1beta1
Kind:         Slice
Metadata:
  Creation Timestamp:  2026-01-11T23:45:15Z
  Finalizers:
    accelerator.gke.io/slice-finalizer
  Generation:        1
  Resource Version:  1768175347356335006
  UID:               d0b71e5c-be3f-4788-aead-930c7afec4f2
Spec:
  Partition Ids:
    2c79463990ff67c4e3c2648666bfedfa
    ba898ffcac0ad0946e8ff036d771ee53
    [more partition IDs]
  Topology:  8x16x16
  Type:      tpu7x
Status:
  Conditions:
    Last Transition Time:  2026-01-11T23:45:38Z
    Message:               ""
    
    Reason:                FAILED
    
    Status:                False
    Type:                  Ready
Events:

השדה reason בסטטוס של המשאב המותאם אישית Slice מציין את המצב הנוכחי של הפרוסה. מחזור החיים של משאב מותאם אישית מסוג Slice מתנהל לפי הרצף הבא:

  • SliceNotCreated: בקר המדיניות מבצע אתחול ובדיקות של משאבים.
    • אם לא מתקיימות הדרישות המוקדמות, המצב משתנה לSliceCreationFailed.
    • אם האימות עובר בהצלחה, המצב משתנה לACTIVATING.
  • ACTIVATING: פרוסת ה-GKE נוצרת.
    • אם הפעולה בוצעה בהצלחה, הסטטוס ישתנה ל-ACTIVE.
    • אם יש ירידה ברמת השירות של תת-בלוקים אבל הפרוסה ניתנת לשימוש, המצב משתנה ל-ACTIVE_DEGRADED.
    • אם ההקמה נכשלת, המצב משתנה לFAILED.
  • DEACTIVATING: אם משאב מותאם אישית מסוג Slice נמחק או מתרחש כשל קריטי במצב פעיל או במצב של כשל, מתחיל פירוק של ה-Slice.
  • INCOMPLETE: השלב האחרון לפני שהמשאב נמחק לחלוטין.

מידע נוסף על הסטטוס של המשאב המותאם אישית Slice זמין במאמר סטטוס Slice.

הפעלת עומסי עבודה בחלוקה דינמית

כשמשאב מותאם אישית מסוג Slice נמצא במצב ACTIVE, אפשר להריץ עליו עומסי עבודה. בקטע הבא יש דוגמאות לעומסי עבודה שמשתמשים בחלוקה דינמית. עומסי העבודה נשלחים כ-Jobs או כ-JobSets.

דוגמה 1: עומס עבודה יחיד משתמש בפרוסה יחידה

בדוגמה הבאה מוצגת עומס עבודה שמשתמש בפרוסת משנה אחת של בלוק.

  1. שומרים את קובץ המניפסט לדוגמה הבא בשם tpu-job-jax-v7x-64.yaml:

    apiVersion: v1
    kind: Service
    metadata:
    name: headless-svc
    spec:
    clusterIP: None
    selector:
        job-name: tpu-job-jax-v7x-64
    ---
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tpu-job-jax-v7x-64
    spec:
    backoffLimit: 0
    completions: 16
    parallelism: 16
    completionMode: Indexed
    template:
        metadata:
        annotations:
            cloud.google.com/gke-tpu-slice-topology: 4x4x4
        spec:
        nodeSelector:
            cloud.google.com/gke-tpu-topology: 4x4x4
            cloud.google.com/gke-tpu-accelerator: tpu7x
            cloud.google.com/gke-tpu-slice: test-slice
        subdomain: headless-svc
        restartPolicy: Never
        containers:
        - name: tpu-job-jax
            env:
            - name: TPU_ACCELERATOR_TYPE
              value: tpu7x-128
            image: python:3.12
            securityContext:
            privileged: false
            command:
            - bash
            - -c
            - |
            set -ex
            pip install -U --pre jax jaxlib libtpu requests -i https://us-python.pkg.dev/ml-oss-artifacts-published/jax/simple/ -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
            pip list
            python -c 'import jax; print("Total TPU devices (cores):", jax.device_count())'
            resources:
            requests:
                google.com/tpu: 4
            limits:
                google.com/tpu: 4
    

    במניפסט הזה:

    • cloud.google.com/gke-tpu-slice-topology ו-cloud.google.com/gke-tpu-topology מגדירים את הטופולוגיה של הפלח הדינמי.
    • env.value: tpu7x-128 הוא סוג מאיץ ה-TPU והמספר הכולל של ליבות בפרוסת ה-TPU. מספר הליבות מחושב על ידי הכפלת הממדים של הטופולוגיה במספר הליבות לכל שבב. לדוגמה, בטופולוגיה 4x4x4, החישוב הוא 4 × 4 × 4 × 2 = 128, כאשר 2 הוא מספר ליבות לכל שבב עבור tpu7x (Ironwood (TPU7x)). לכן, TPU_ACCELERATOR_TYPE הוא tpu7x-128.
  2. החלת המניפסט tpu-job-jax-v7x-64.yaml:

    kubectl apply -f tpu-job-jax-v7x-64.yaml
    

דוגמה 2: פריסת עומס עבודה במאגרי צמתים מרובי-פרוסות באמצעות JobSet

בדוגמה הזו מוסבר איך לפרוס עומס עבודה במאגרי צמתים עם כמה פרוסות באמצעות JobSet.

  1. מתקינים את JobSet:

    kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/v0.10.1/manifests.yaml
    
  2. שומרים את קובץ המניפסט לדוגמה הבא בשם tpu-multislice-jax.yaml:

    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: tpu-multislice-jax
      annotations:
        alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-tpu-slice
    spec:
      failurePolicy:
        maxRestarts: 3
      replicatedJobs:
      - name: slice-job
        replicas: 2
        template:
          spec:
            parallelism: 16
            completions: 16
            backoffLimit: 0
            completionMode: Indexed
            template:
              metadata:
                annotations:
                  # The shape of the slice
                  cloud.google.com/gke-tpu-slice-topology: 4x4x4
              spec:
                hostNetwork: true
                dnsPolicy: ClusterFirstWithHostNet
                nodeSelector:
                  cloud.google.com/gke-tpu-topology: 4x4x4
                  cloud.google.com/gke-tpu-accelerator: tpu7x
                  # IMPORTANT: Do NOT put 'cloud.google.com/gke-tpu-slice' here manually.
                  # The exclusive-topology annotation handles the slice assignment automatically.
                containers:
                - name: jax-worker
                  image: python:3.12
                  securityContext:
                    privileged: true
                  ports:
                  - containerPort: 8471
                  command:
                  - bash
                  - -c
                  - |
                    set -ex
                    pip install -U --pre jax jaxlib libtpu requests -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                    # Verify JobSet injected the specific slice ID for this worker
                    echo "JobSet Index: $JOB_COMPLETION_INDEX"
                    python -c 'import jax; print("Total TPU devices:", jax.device_count())'
                  resources:
                    requests:
                      google.com/tpu: 4
                    limits:
                      google.com/tpu: 4
    
  3. החלת המניפסט tpu-multislice-jax.yaml:

    kubectl apply -f tpu-multislice-jax.yaml
    

    במניפסט הזה:

    • השדה replicas: 2 בקטע replicatedJobs מציין ש-JobSet יוצר שני ג'ובים נפרדים, שכל אחד מהם תואם ל-TPU slice‏ 4x4x4.
    • ההערה alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-tpu-slice עוזרת להבטיח שכל משימה תוקצה לפרוסת TPU ייחודית.
    • ההערה cloud.google.com/gke-tpu-slice-topology: 4x4x4 מגדירה את הטופולוגיה של כל פרוסה דינמית.
    • במקרה הזה, משתנה הסביבה TPU_ACCELERATOR_TYPE לא מוגדר באופן מפורש, כי JobSet מטפל בהקצאת הפרוסות. קוד ה-JAX מזהה באופן אוטומטי את מכשירי ה-TPU הזמינים בתוך הפרוסה שהוקצתה לו.

מחיקת הפלח

  1. מוחקים את הפלח:

    kubectl patch slice $SLICE_NAME --type json \
      -p='[{"op": "remove", "path": "/metadata/finalizers"}]'
    
  2. מוודאים שהפרוסה נמחקה:

    kubectl get slices
    

השבתת כלי הבחירה

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

  1. בודקים שהמשאבים המותאמים אישית של Slice ריקים:

    kubectl get slice -A
    
  2. מעדכנים את האשכול כדי להשבית את בקר הפרוסות:

    gcloud container clusters update ${CLUSTER_NAME} \
        --location=${REGION} \
        --no-enable-slice-controller
    
  3. מחיקת המשאב המותאם אישית של Slice :

    kubectl delete crd slices.accelerator.gke.io
    
  4. מוודאים שהמשאב המותאם אישית של Slice נמחק:

    kubectl get crd | grep slices.accelerator.gke.io
    
  5. מסירים את התוויות שנוספו על ידי הכלי לבחירת פרוסות. צריך להסיר את התוויות האלה:

    • cloud.google.com/gke-tpu-slice
    • cloud.google.com/gke-tpu-topology
    1. כדי להסיר מצומת ספציפי, מעדכנים את שם הצומת
    export NODE_NAME="gke-tpu-bdac9600-3bdg"
    kubectl label node $NODE_NAME cloud.google.com/gke-tpu-slice- cloud.google.com/gke-tpu-slice-topology-
    
    1. אם רוצים להסיר את התוויות האלה מכל צומת באשכול:
    kubectl label nodes --all cloud.google.com/gke-tpu-slice- cloud.google.com/gke-tpu-slice-topology-
    
    1. בודקים את תוויות הצמתים ומוודאים שהן ריקות:
    export NODE_NAME="gke-tpu-bdac9600-3bdg"
    kubectl describe node $NODE_NAME | grep "cloud.google.com/gke-tpu-slice"
    

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