יצירת אשכול GKE Edge A3 מותאם אישית ל-AI

בדף הזה מוסבר איך ליצור אשכול Google Kubernetes Engine ‏ (GKE) שעבר אופטימיזציה ל-AI, ומשתמש במכונות וירטואליות (VM) של A3 Edge כדי לתמוך בעומסי העבודה של הבינה המלאכותית (AI) ולמידת המכונה (ML). מכונות A3 Edge מיועדות להרצת אשכולות גדולים של AI ו-ML באמצעות תכונות כמו מיקום ממוקד של עומסי עבודה, מיקום קומפקטי, אמצעי בקרה מתקדמים לתחזוקת אשכולות ו-TAS. מידע נוסף מופיע במאמר סקירה כללית על ניהול אשכולות.

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

בדף הזה מוסבר איך ליצור אשכולות Standard ו-Autopilot של Google Kubernetes Engine ‏ (GKE) באמצעות GPUDirect-TCPX,‏ gVNIC וריבוי רשתות.

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

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

בדף הזה אנחנו מניחים שאתם מכירים טכנולוגיות רשת כמו כרטיסי ממשק רשת (NIC) ו-TCP, וטכנולוגיות האצה כמו NVIDIA Collective Communications Library ‏ (NCCL).

מידע על Google Cloud מחשבי-על עם GPU

Google Cloud יש לו מחשבי-על שעברו אופטימיזציה למאיצים, והם מיועדים למודלים גדולים וניתנים להרחבה. סוגי המכונות עם GPU האלה יכולים לקבל רוחב פס ברשת של עד ‎3,600 Gbps.

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

תכונות ויכולות נדרשות למיקסום רוחב הפס

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

  • GPUDirect networking stack: ‏ A3 Edge תומך בשלושה networking stack לגישה ישירה לזיכרון (RDMA) בהתאמה אישית ומרחוק. מכונות A3 Edge משתמשות ב-GPUDirect-TCPX כדי לצמצם את התקורה שנדרשת להעברת מטענים של מנות אל וממעבדי GPU, מה שמשפר משמעותית את קצב העברת הנתונים בהשוואה למעבדי GPU שלא משתמשים ב-GPUDirect.
  • gVNIC: הפעלה של יכולות GPUDirect כמו פיצול של כותרות מנות, ניהול זרימה וניהול מאגר. נדרש gVNIC כדי להשתמש ב-GPUDirect-TCPX. פרטים על gVNIC זמינים במאמר הגדלת מהירות תעבורת הרשת בצמתי GPU.

בנוסף, צריך להפעיל ולהגדיר את היכולות הבאות:

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

ראשי פרקים של התהליך

כדי להשתמש ב-GPUDirect-TCPX, ב-gVNIC, בריבוי רשתות ובמדיניות מיקום קומפקטית ביחד, צריך לבצע את הפעולות הבאות:

  1. יצירת עננים וירטואליים פרטיים (VPC) ותת-רשתות
  2. יצירת סביבת GKE
  3. התקנת הקובץ הבינארי של GPUDirect והפלאגין של NCCL
  4. פריסת הפלאגין NRI device injector
  5. פריסת עומס עבודה לבדיקה כדי לוודא שההגדרה של GPUDirect תקינה
  6. הטמעה של GPUDirect בעומסי העבודה שלכם

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

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

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • מוודאים שיש לכם קיבולת למכונות וירטואליות מסוג A3 Edge. כדי לקבל את הקיבולת הזו, קודם צריך לבחור מתוך אפשרויות הצריכה. כדי לפעול לפי ההוראות בדף הזה, אפשר להשתמש בקיבולת לפי דרישה, בהזמנות לפי דרישה או בהזמנות עתידיות לפרק זמן של עד 90 ימים (במצב לוח שנה). אחרי שבוחרים אפשרות צריכה, פועלים לפי ההוראות המתאימות כדי לקבל קיבולת באמצעות אפשרות הצריכה שבחרתם.
  • מוודאים שיש לכם מספיק מכסה לשימוש ב-GPU מסוג H100. לפרטים, ראו מכסות של GPU.

דרישות

הדרישות הבאות חלות על GPUDirect-TCPX:

רגילה

  • ‫GPUDirect-TCPX נתמך בכל הגרסאות המשניות הזמינות של GKE באמצעות גרסאות תיקון ספציפיות:
    • בגרסאות GKE‏ 1.30 עד 1.33, אפשר להשתמש בכל גרסת תיקון.
    • ב-GKE גרסה 1.34, צריך להשתמש בגרסת תיקון ‎1.34.5-gke.1153000 ואילך.
    • ב-GKE גרסה 1.35, צריך להשתמש בגרסת תיקון ‎1.35.2-gke.1485000 ואילך.
    • בגרסה 1.36 ואילך של GKE, אפשר להשתמש בכל גרסת תיקון.
  • הצומת של GKE חייב להשתמש בתמונת צומת של מערכת הפעלה שמותאמת לקונטיינרים (COS). אין תמיכה בתמונות של צמתים ב-Ubuntu וב-Windows.
  • בצמתי ה-GPU צריך להשתמש בדרייבר NVIDIA בגרסה 535 ואילך.
  • חובה להשתמש ב-GKE Dataplane V2.
  • ב-GKE בגרסה 1.34 ואילך, צריך להשתמש בגרסה 3.1.9 ואילך של כלי ההתקנה GPUDirect-TCPX ובגרסה 2.0.12 ואילך של GPUDirect-TCPX sidecar. הגרסאות של קובץ ההתקנה ושל קובץ העזר ממופות אחת לאחת וצריכות להיות זהות. לדוגמה, גרסת תוכנת ההתקנה 3.1.12 תואמת לגרסת ה-sidecar‏ 2.0.15. מידע נוסף על גרסאות של קובצי התקנה ושל sidecar זמין בהערות הגרסה של GPUDirect-TCPX.
  • בעומסי עבודה של GPUDirect-TCPX שפועלים בכמה מאגרי צמתים, כל מאגרי הצמתים צריכים להיות באותם אזורים של Compute Engine ולהשתמש באותן קבוצות רשת, כמו VPC ותתי-רשתות.

טייס אוטומטי

  • כדי להשתמש ב-GPUDirect-TCPX, האשכול צריך להריץ את גרסאות הטלאי המינימליות הבאות של GKE:
    • ב-GKE גרסה 1.31, צריך להשתמש בגרסת תיקון ‎1.31.1-gke.1621000 ואילך.
    • בגרסאות GKE‏ 1.32 עד 1.33, אפשר להשתמש בכל גרסת תיקון.
    • ב-GKE גרסה 1.34, צריך להשתמש בגרסת תיקון ‎1.34.5-gke.1153000 ואילך.
    • ב-GKE גרסה 1.35, צריך להשתמש בגרסת תיקון ‎1.35.2-gke.1485000 ואילך.
    • בגרסה 1.36 ואילך של GKE, אפשר להשתמש בכל גרסת תיקון.
  • בצמתי ה-GPU צריך להשתמש בדרייבר NVIDIA בגרסה 535 ואילך.
  • חובה להשתמש ב-GKE Dataplane V2.
  • ב-GKE בגרסה 1.34 ואילך, צריך להשתמש בגרסה 3.1.9 ואילך של כלי ההתקנה GPUDirect-TCPX ובגרסה 2.0.12 ואילך של GPUDirect-TCPX sidecar. הגרסאות של תוכנת ההתקנה ושל קובץ העזר צריכות להיות זהות. לדוגמה, גרסת המתקין 3.1.12 תואמת לגרסת ה-sidecar‏ 2.0.15. מידע נוסף על גרסאות של קובצי התקנה וקובצי sidecar זמין בהערות הגרסה של GPUDirect-TCPX.
  • עבור עומסי עבודה של GPUDirect-TCPX שפועלים בכמה מאגרי צמתים, כל מאגרי הצמתים צריכים להיות באותם אזורים של Compute Engine ולהשתמש באותן קבוצות רשת, כמו VPC ותתי-רשתות.

מגבלות

ההגבלות הבאות חלות:

  • אין תמיכה ב-GPUDirect-TCPX במעבדי GPU מרובים, בחלוקת זמן של GPU או ב-NVIDIA MPS.
  • אי אפשר להשתמש ב-NCCL FastSocket עם GPUDirect-TCPX.
  • עומס העבודה ב-GKE חייב להשתמש בכל ה-GPU הזמינים ובכל כרטיסי ה-NIC המשניים הזמינים בצומת יחיד. אי אפשר להשתמש ב-GPUDirect-TCPX בכמה פודים בצומת אחד.

יצירת רשתות VPC ורשתות משנה

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

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

    for N in $(seq 1 4); do
    gcloud compute networks create PREFIX-net-$N \
        --subnet-mode=custom \
        --mtu=8244
    
    gcloud compute networks subnets create PREFIX-sub-$N \
        --network=PREFIX-net-$N \
        --region=REGION \
        --range=SUBNET_RANGE
    
    gcloud compute firewall-rules create PREFIX-internal-$N \
    --network=PREFIX-net-$N \
    --action=ALLOW \
    --rules=tcp:0-65535,udp:0-65535,icmp \
    --source-ranges=SOURCE_RANGE
    done
    

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

    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • REGION: האזור ב-Compute Engine של כל רשת משנה.
    • SUBNET_RANGE: טווח כתובות ה-IP של כל רשת משנה בסימון CIDR. בפקודה לדוגמה הזו יש ארבע רשתות משנה, ולכן צריך להשתמש במשתנה כדי לשנות את כתובת ה-IP לכל רשת משנה. לדוגמה, מגדירים את 192.168.$N.0/24 כך שתת-הרשת הראשונה תשתמש ב-192.168.1.0/24, תת-הרשת השנייה תשתמש ב-192.168.2.0/24 וכו'.
    • SOURCE_RANGE: טווח כתובות ה-IP של המקור שכלל חומת האש יאפשר תעבורת נתונים נכנסת ממנו, בסימון CIDR. לדוגמה, 192.168.0.0/16.
  2. בודקים שהרשתות נוצרו:

    gcloud compute networks list
    

יצירת סביבת GKE

יוצרים אשכול GKE חדש שמשתמש בריבוי רשתות (גרסת Preview) ויוצרים מאגר צמתים של GPU עם המאפיינים הבאים:

  • ‫gVNIC מופעל
  • תת-רשתות מרובות שמוגדרות לכל כרטיס NIC משני
  • סדרת מכונות A3 Edge עם מעבדי GPU מסוג H100 שתומכים בצמתים
  • הדרייברים העדכניים של NVIDIA מותקנים

אי אפשר לעדכן קלאסטר קיים כדי להשתמש בריבוי רשתות.

  1. יצירת אשכול:

    רגילה

    gcloud beta container clusters create CLUSTER_NAME \
      --enable-dataplane-v2 \
      --enable-ip-alias \
      --location=CONTROL_PLANE_LOCATION \
      --enable-multi-networking \
      --cluster-version=VERSION \
      --no-enable-autoupgrade \
      --project=PROJECT_ID
    

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

    • CLUSTER_NAME: השם של האשכול החדש.
    • CONTROL_PLANE_LOCATION: המיקום של מישור הבקרה של האשכול ב-Compute Engine. מציינים אזור לאשכולות אזוריים או אזור זמין לאשכולות אזוריים.
    • VERSION: גרסת GKE שתומכת ב-GPUDirect-TCPX, כמו שמתואר בקטע דרישות.

    טייס אוטומטי

    gcloud beta container clusters create-auto CLUSTER_NAME \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION \
        --cluster-version=VERSION \
        --enable-multi-networking \
        --workload-policies=allow-net-admin
    

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

    • CLUSTER_NAME: השם של האשכול החדש.
    • CONTROL_PLANE_LOCATION: האזור ב-Compute Engine של מישור הבקרה של האשכול.
    • VERSION: גרסת GKE שתומכת ב-GPUDirect-TCPX, כמו שמתואר בקטע דרישות.
  2. יוצרים משאבים מסוג Network ו-GKENetworkParamSet באשכול שתואמים לרשתות ה-VPC ולרשתות המשנה שיצרתם:

    kubectl apply -f - <<EOF
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc1
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc1
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc2
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc2
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc3
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc3
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc4
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc4
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc1
    spec:
      vpc: PREFIX-net-1
      vpcSubnet: PREFIX-sub-1
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc2
    spec:
      vpc: PREFIX-net-2
      vpcSubnet: PREFIX-sub-2
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc3
    spec:
      vpc: PREFIX-net-3
      vpcSubnet: PREFIX-sub-3
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc4
    spec:
      vpc: PREFIX-net-4
      vpcSubnet: PREFIX-sub-4
      deviceMode: NetDevice
    EOF
    

    המשאבים האלה מנחים את GKE להגדיר את כרטיסי ה-NIC לתנועת GPU במצב passthrough. ‫GKE לא מחיל על התעבורה הזו תכנות רשת מובנה באמצעות eBPF.

יצירת מאגר צמתים של GPU (במהדורת Standard בלבד)

  1. יוצרים מאגר צמתים עבור יחידות ה-GPU מדגם H100:

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --machine-type=a3-edgegpu-8g \
        --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=LATEST \
        --additional-node-network=network=PREFIX-net-1,subnetwork=PREFIX-sub-1 \
        --additional-node-network=network=PREFIX-net-2,subnetwork=PREFIX-sub-2 \
        --additional-node-network=network=PREFIX-net-3,subnetwork=PREFIX-sub-3 \
        --additional-node-network=network=PREFIX-net-4,subnetwork=PREFIX-sub-4 \
        --enable-gvnic \
        --no-enable-autoupgrade \
        --placement-policy=POLICY_NAME \
        --reservation-affinity=specific \
        --reservation=projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME
    

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

    כדי להשתמש בהזמנה, משתמשים בדגלים --placement-policy, --reservation-affinity ו---reservation. מציינים את הדגלים האלה כדי להגדיר את שם המדיניות ואת ההזמנה במאגר הצמתים. אם ההזמנה לא דורשת מדיניות משאבים, משמיטים את הדגל --placement-policy.

    הערכים האפשריים של הדגל --reservation-affinity הם specific או any. עם זאת, כדי להשיג ביצועים גבוהים בעומסי עבודה מבוזרים של AI, מומלץ להשתמש בהזמנה ספציפית. תוכלו למצוא מידע על ההזמנה, כמו שם ההזמנה או השם של בלוק ספציפי בהזמנה. כדי למצוא את הערכים האלה להזמנות על פי דרישה, אפשר לראות רשימה של ההזמנות או לראות בקשות להזמנות עתידיות.

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

    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud(אופציונלי). אם ההזמנה נמצאת בפרויקט הנוכחי (ולא מדובר בהזמנה משותפת), אפשר להשמיט את projects/PROJECT_ID/reservations/ מהערך של ההזמנה.
    • RESERVATION_NAME: השם של ההזמנה.
    • BLOCK_NAME: אופציונלי, השם של בלוק ספציפי בהזמנה. ‫Omit /reservationBlocks/BLOCK_NAME if you don't want to use a specific block.

    אם הפקודה הזו נכשלת, יכול להיות שאין לכם מספיק מכסת GPU מסוג H100 בפרויקט. צריך לוודא שיש לכם מכסה ולנסות שוב להריץ את הפקודה.

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

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

      kubectl get nodes
      
    2. מוודאים שלכל צומת GPU יש שמונה יחידות GPU:

      kubectl describe node NODE_NAME
      

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

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

      Capacity:
        ...
        nvidia.com/gpu:             8
      Allocatable:
        ...
        nvidia.com/gpu:             8
      

התקנה של הקובץ הבינארי של GPUDirect והפלאגין של NCCL

בקטע הזה נסביר איך להתקין את הקובץ הבינארי של GPUDirect-TCPX וגרסה ספציפית של ספריית NCCL באמצעות DaemonSet.

ה-DaemonSet הזה מבצע את הפעולות הבאות:

  1. הפקודה מתקינה את ספריית NCCL ואת הקובץ הבינארי GPUDirect-TCPX בצומת.
  2. הספרייה והקובץ הבינארי מאוחסנים בספרייה /home/kubernetes/bin/nvidia/lib64 במכונה הווירטואלית. כברירת מחדל, GKE מטמיע את הספרייה הזו בנתיב /usr/local/nvidia/lib64 בקונטיינרים של GPU שצריכים להשתמש ב-NCCL וב-GPUDirect-TCPX.

כדי להתקין את הקובץ הבינארי ולהגדיר את NCCL:

רגילה

  1. בודקים את nccl-tcpx-installer.yaml מניפסט Daemonset ב-GitHub.

  2. פורסים את DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
    

    הפעלת הפלאגין NCCL נמשכת כשתי דקות.

  3. מאמתים את הסטטוס של ה-Pods של DaemonSet:

    kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
    

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

    nccl-tcpx-installer-6c2pv                    1/1     Running   0          2m11s
    nccl-tcpx-installer-qgg82                    1/1     Running   0          2m11s
    

טייס אוטומטי

  1. מעיינים במניפסט של Daemonset‏ nccl-tcpx-installer-autopilot.yaml ב-GitHub.

  2. יוצרים מרחב שמות ייעודי:

    kubectl create ns gpudirect-system
    
  3. פורסים את DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer-autopilot.yaml
    

    הפעלת הפלאגין NCCL נמשכת כשתי דקות.

פריסת הפלאגין NRI device injector

בקטע הזה נסביר איך להתקין את כלי ההזרקה של מכשיר NRI באמצעות DaemonSet. הפלאגין הזה מבצע את הפעולות הבאות:

  1. הפעלת Node Resource Interface ‏ (NRI) בצומת עם GPU מסוג H100. התכונה NRI מופעלת כברירת מחדל ב-GKE בגרסה 1.29 ואילך.
  2. פריסת קונטיינר של תוסף להזרקת מכשירי NRI שמזריק מכשירי GPU לקונטיינרים שצוינו בהערות של Pod.

כדי להתקין את הפלאגין:

רגילה

  1. בודקים את מניפסט הפריסה nri-device-injector.yaml ב-GitHub.

  2. פורסים את DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector.yaml
    

    הפעלת הפלאגין NCCL נמשכת כשתי דקות.

  3. מאמתים את הסטטוס של ה-Pods של DaemonSet:

    kubectl get pods -n=kube-system -l=name=device-injector
    

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

    # Output
    device-injector-md6hb                         1/1     Running   0       4h54m
    device-injector-vh9bm                         1/1     Running   0       4h54m
    

טייס אוטומטי

  1. בודקים את מניפסט הפריסה nri-device-injector-autopilot.yaml ב-GitHub.

  2. פורסים את DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector-autopilot.yaml
    

    הפעלת הפלאגין NCCL נמשכת כשתי דקות.

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

בקטע הזה תפרסו עומס עבודה לדוגמה כדי לוודא ש-NCCL ו-GPUDirect-TCPX פועלים כצפוי. עומס העבודה לדוגמה הזה מבצע את הפעולות הבאות:

  1. פורסות שני Pods, שכל אחד מהם פועל בצומת עם מעבדי GPU מסוג H100.
  2. פריסת קונטיינר sidecar בכל Pod כדי לאפשר ל-Pod האלה להשתמש ב-GPUDirect-TCPX.

עומס העבודה הזה כולל קונטיינר sidecar בשם tcpx-daemon, שמריץ שירות שמאפשר ל-Pod להשתמש ב-GPUDirect-TCPX. צריך להוסיף את קובץ ה-sidecar הזה לכל ה-Pods בסביבה שלכם שצריכים להשתמש ב-GPUDirect-TCPX. קטע קוד עם השדות הנדרשים להוספה למניפסטים זמין במאמר הוספת GPUDirect למניפסט.

  1. בודקים את nccl-config.yaml מניפסט ConfigMap ב-GitHub. קובץ המניפסט הזה פורס סקריפטים שמאתחלים בדיקה של NCCL all-gather ומגדירים הגדרות ספציפיות ל-NCCL.

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

  3. פורסים את ConfigMap ואת עומס העבודה של הבדיקה:

    רגילה

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest.yaml
    

    טייס אוטומטי

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest-autopilot.yaml
    
  4. מוודאים שה-Pods פועלים ומוכנים. הערה: התמונות גדולות (כ-5 GB) וההורדה שלהן עשויה להימשך כמה דקות.

    kubectl get pods -w
    

    הפקודה עוקבת אחרי עדכונים ומדפיסה שורה חדשה כשסטטוס ה-Pod משתנה. הפלט אמור להיראות כך:

    NAME               READY   STATUS              RESTARTS   AGE
    nccl-test-host-1   0/2     ContainerCreating   0          23s
    nccl-test-host-2   2/2     Running             0          23s
    nccl-test-host-1   2/2     Running             0          46s
    

    מחכים עד שההודעה STATUS לכל ה-Pods תהיה Running והערך של READY יהיה 2/2 לפני שממשיכים לשלב הבא.

  5. מריצים את הפקודות הבאות כדי להפעיל בדיקת NCCL all-gather לצמתים:

    kubectl exec \
      --stdin --tty --container=nccl-test nccl-test-host-1 \
      -- /configs/allgather.sh nccl-host-1 nccl-host-2
    

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

    רגילה

      #                                                              out-of-place                       in-place
      #        size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
      #         (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)
                  0             0     float    none      -1     0.24    0.00    0.00      0     0.18    0.00    0.00      0
                  0             0     float    none      -1     0.19    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                256             4     float    none      -1    235.2    0.00    0.00      0    235.1    0.00    0.00      0
                512             8     float    none      -1    241.0    0.00    0.00      0    236.1    0.00    0.00      0
               1024            16     float    none      -1    236.3    0.00    0.00      0    233.3    0.00    0.00      0
               2048            32     float    none      -1    234.1    0.01    0.01      0    233.4    0.01    0.01      0
               4096            64     float    none      -1    237.1    0.02    0.02      0    235.3    0.02    0.02      0
               8192           128     float    none      -1    236.2    0.03    0.03      0    235.2    0.03    0.03      0
              16384           256     float    none      -1    236.6    0.07    0.06      0    238.5    0.07    0.06      0
              32768           512     float    none      -1    237.9    0.14    0.13      0    238.8    0.14    0.13      0
              65536          1024     float    none      -1    242.3    0.27    0.25      0    239.4    0.27    0.26      0
             131072          2048     float    none      -1    263.0    0.50    0.47      0    275.1    0.48    0.45      0
             262144          4096     float    none      -1    279.2    0.94    0.88      0    269.9    0.97    0.91      0
             524288          8192     float    none      -1    273.5    1.92    1.80      0    273.5    1.92    1.80      0
            1048576         16384     float    none      -1    315.1    3.33    3.12      0    314.1    3.34    3.13      0
            2097152         32768     float    none      -1    319.2    6.57    6.16      0    311.5    6.73    6.31      0
            4194304         65536     float    none      -1    331.8   12.64   11.85      0    331.3   12.66   11.87      0
            8388608        131072     float    none      -1    356.3   23.54   22.07      0    353.8   23.71   22.23      0
           16777216        262144     float    none      -1    409.1   41.01   38.45      0    405.2   41.40   38.81      0
           33554432        524288     float    none      -1    451.4   74.34   69.69      0    447.7   74.94   70.26      0
           67108864       1048576     float    none      -1    713.4   94.07   88.19      0    713.8   94.01   88.13      0
          134217728       2097152     float    none      -1   1122.1  119.62  112.14      0   1116.3  120.23  112.72      0
          268435456       4194304     float    none      -1   1785.8  150.32  140.92      0   1769.2  151.72  142.24      0
          536870912       8388608     float    none      -1   2859.7  187.74  176.00      0   2852.6  188.20  176.44      0
         1073741824      16777216     float    none      -1   5494.1  195.44  183.22      0   5568.2  192.83  180.78      0
         2147483648      33554432     float    none      -1    10841  198.09  185.71      0    10798  198.88  186.45      0
         4294967296      67108864     float    none      -1    21453  200.21  187.70      0    21490  199.86  187.37      0
         8589934592     134217728     float    none      -1    42603  201.63  189.03      0    42670  201.31  188.73      0
      # Out of bounds values : 0 OK
      # Avg bus bandwidth    : 45.7587
      #
      ```
    

    טייס אוטומטי

    #                                                              out-of-place                       in-place
    #       size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
    #        (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)
        1048576         16384     float    none      -1    696.8    1.50    1.41      0    729.0    1.44    1.35      0
        2097152         32768     float    none      -1    776.4    2.70    2.53      0    726.7    2.89    2.71      0
        4194304         65536     float    none      -1    774.3    5.42    5.08      0    805.1    5.21    4.88      0
        8388608        131072     float    none      -1    812.1   10.33    9.68      0    817.6   10.26    9.62      0
       16777216        262144     float    none      -1   1035.2   16.21   15.19      0   1067.8   15.71   14.73      0
       33554432        524288     float    none      -1   1183.3   28.36   26.59      0   1211.8   27.69   25.96      0
       67108864       1048576     float    none      -1   1593.4   42.12   39.49      0   1510.5   44.43   41.65      0
      134217728       2097152     float    none      -1   2127.8   63.08   59.13      0   2312.7   58.03   54.41      0
      268435456       4194304     float    none      -1   3603.0   74.50   69.85      0   3586.2   74.85   70.17      0
      536870912       8388608     float    none      -1   7101.7   75.60   70.87      0   7060.9   76.03   71.28      0
    # Out of bounds values : 0 OK
    # Avg bus bandwidth    : 29.8293
    

איך משתמשים ב-GPUDirect בעומסי עבודה

אחרי שמוודאים שהרשת של האשכול פועלת בצורה תקינה עם עומס העבודה לדוגמה, השלב הבא הוא להטמיע את GPUDirect בעומסי העבודה בפועל. כדי להשתמש ב-GPUDirect, צריך לעדכן את ההגדרות של NCCL ואת מניפסטים של Kubernetes Pod.

שימוש בהגדרות החובה של NCCL לשיפור הביצועים

צמדי המפתח/ערך הבאים הם הגדרות החובה של NCCL ל-GPUDirect-TCPX. כשפורסים את עומסי העבודה שמשתמשים ב-NCCL, צריך להגדיר אותם כמשתני סביבה כדי לשפר את הביצועים.

"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_SOCKET_IFNAME=\"eth0\"",
"NCCL_ALGO=Ring",
"NCCL_PROTO=Simple",
"NCCL_CROSS_NIC=0",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_P2P_PXN_LEVEL=0",
"NCCL_GPUDIRECTTCPX_SOCKET_IFNAME=eth1,eth2,eth3,eth4",
"NCCL_GPUDIRECTTCPX_CTRL_DEV=eth0",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_BUFFSIZE=4194304",
"NCCL_NSOCKS_PERTHREAD=4",
"NCCL_SOCKET_NTHREADS=1",
"NCCL_GPUDIRECTTCPX_TX_BINDINGS=\"eth1:8-21,112-125;eth2:8-21,112-125;eth3:60-73,164-177;eth4:60-73,164-177\"",
"NCCL_GPUDIRECTTCPX_RX_BINDINGS=\"eth1:22-35,126-139;eth2:22-35,126-139;eth3:74-87,178-191;eth4:74-87,178-191\"",
"NCCL_GPUDIRECTTCPX_PROGRAM_FLOW_STEERING_WAIT_MICROS=500000"

הוספת GPUDirect למניפסטים

בקטע הזה מפורטים השדות הנדרשים שצריך להוסיף למניפסטים של Kubernetes כדי שה-Pods יוכלו להשתמש ב-GPUDirect.

בהתאם למצב האשכול, מבצעים את הפעולות הבאות:

רגילה

  1. מוסיפים את ההערות הבאות למטא-נתונים של ה-Pod. בלי ההערות האלה, נדרש hostNetwork:true עבור ה-Pod ונדרש privileged:true עבור מאגר tcpx-daemon.

    metadata:
      annotations:
        devices.gke.io/container.tcpx-daemon: |+
          - path: /dev/nvidia0
          - path: /dev/nvidia1
          - path: /dev/nvidia2
          - path: /dev/nvidia3
          - path: /dev/nvidia4
          - path: /dev/nvidia5
          - path: /dev/nvidia6
          - path: /dev/nvidia7
          - path: /dev/nvidiactl
          - path: /dev/nvidia-uvm
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"vpc1"},
            {"interfaceName":"eth2","network":"vpc2"},
            {"interfaceName":"eth3","network":"vpc3"},
            {"interfaceName":"eth4","network":"vpc4"},
          ]
    
  2. מוסיפים את השדות הבאים למפרט של ה-Pod:

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. מוסיפים את הקונטיינר הבא למניפסט כדי להריץ את השירות tcpx-daemon:

    - name: tcpx-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9
      command:
        - /tcpgpudmarxd/build/app/tcpgpudmarxd
        - --gpu_nic_preset
        - a3vm
        - --gpu_shmem_type
        - fd
        - --uds_path
        - /run/tcpx
        - --setup_param
        - \"--verbose 128 2 0 \"
      securityContext:
        capabilities:
            add:
              - NET_ADMIN
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. מוסיפים את נקודות הגישה הבאות לנפח אחסון לכל קונטיינר שמבקש יחידות GPU:

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. מוסיפים משתני סביבה כדי להגדיר את האפשרויות של NCCL. פרטים נוספים מופיעים בקטע שימוש בהגדרות מומלצות של NCCL לשיפור הביצועים במאמר הזה.

  6. מוסיפים את משתנה הסביבה הבא לכל קונטיינר GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    

דוגמה למפרט Pod מלא מופיעה במניפסט nccl-test-latest.yaml ב-GitHub.

טייס אוטומטי

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

מוסיפים את בוררי הצמתים הבאים ל-Pod:

nodeSelector:
  cloud.google.com/gke-accelerator: a3-edgegpu-8g
  cloud.google.com/gke-gpu-driver-version: latest

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

  1. מוסיפים את ההערות הבאות למטא-נתונים של ה-Pod:

    metadata:
      annotations:
        devices.gke.io/container.tcpx-daemon: |+
          - path: /dev/nvidia0
          - path: /dev/nvidia1
          - path: /dev/nvidia2
          - path: /dev/nvidia3
          - path: /dev/nvidia4
          - path: /dev/nvidia5
          - path: /dev/nvidia6
          - path: /dev/nvidia7
          - path: /dev/nvidiactl
          - path: /dev/nvidia-uvm
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"vpc1"},
            {"interfaceName":"eth2","network":"vpc2"},
            {"interfaceName":"eth3","network":"vpc3"},
            {"interfaceName":"eth4","network":"vpc4"},
          ]
    
  2. מוסיפים את השדות הבאים למפרט של ה-Pod:

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. מוסיפים את הקונטיינר הבא למניפסט כדי להריץ את שירות tcpx-daemon:

    - name: tcpx-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9
      command:
        - /tcpgpudmarxd/build/app/tcpgpudmarxd
        - --gpu_nic_preset
        - a3vm
        - --gpu_shmem_type
        - fd
        - --uds_path
        - /run/tcpx
        - --setup_param
        - \"--verbose 128 2 0 \"
      securityContext:
        capabilities:
            add:
              - NET_ADMIN
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. מוסיפים את נקודות הגישה הבאות לנפח אחסון לכל קונטיינר שמבקש יחידות GPU:

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. מוסיפים משתני סביבה כדי להגדיר את האפשרויות של NCCL. פרטים נוספים מופיעים בקטע שימוש בהגדרות מומלצות של NCCL לשיפור הביצועים במאמר הזה.

דוגמה למפרט Pod מלא מופיעה במניפסט nccl-test-latest-autopilot.yaml ב-GitHub.

איסוף יומני ניפוי באגים של NCCL

כדי לרשום ביומן שגיאות של NCCL, מומלץ להוסיף את ההגדרה הבאה של NCCL:

NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET,ENV,COLL,GRAPH
NCCL_DEBUG_FILE=/DIRECTORY/FILE_NAME.%h.%p
  • NCCL_DEBUG=INFO: מדפיס מידע על תוצאות ניפוי הבאגים.
    • בעומסי עבודה גדולים (64 צמתים או יותר), יכול להיות שיתבצע רישום נרחב ביומן. כדי להימנע מהתרחיש הזה – אלא אם ציינתם NCCL_DEBUG_FILE – מומלץ להגדיר את NCCL_DEBUG=WARN כדי להגביל את היומנים לשגיאות בלבד.
  • NCCL_DEBUG_SUBSYS: מסנן את מערכות המשנה ש-NCCL אוסף לגביהן מידע על תוצאות ניפוי הבאגים. מומלץ לאסוף יומנים עבור מערכות המשנה הבאות:

    • INIT: שלב האתחול של NCCL.
    • NET: רשת NCCL.
    • ENV: משתני הסביבה ש-NCCL משתמש בהם.
    • COLL: פעולות קולקטיביות.
    • GRAPH: זיהוי טופולוגיה וחיפוש גרפים.

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

  • NCCL_DEBUG_FILE (אופציונלי): מכוון את פלט הרישום של ניפוי הבאגים של NCCL לקובץ שאתם מציינים. המשתנה הזה כותב יומנים של NCCL לקבצים רגילים, וכך מונע ערבוב של פלט היומן עם פלט האפליקציה. המשתנה הזה גם כותב יומנים מדרגות שונות של NCCL לקבצים שונים, וכך מונע ערבוב של היומנים.

    צריך להשתמש בפורמט הבא לשם הקובץ:

    /DIRECTORY/FILE_NAME.%h.%p
    

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

    • DIRECTORY: הספרייה שבה רוצים לאחסן את קובצי היומן.
    • FILE_NAME: השם של קובצי היומן.

    ה-placeholder ‏%h מומר לשם המארח של הצומת, וה-placeholder ‏%p מומר למזהה התהליך (PID) של התהליך שיוצר את היומן.

למידע נוסף על ניפוי באגים ביומני NCCL, ראו פתרון בעיות ב-GPU ב-GKE.

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