איך ממקסמים את רוחב הפס של רשת ה-GPU באשכולות במצב רגיל

בדף הזה מוסבר איך למקסם את רוחב הפס ואת קצב העברת הנתונים ברשת עבור עומסי עבודה של GPU עם ביצועים גבוהים באשכולות רגילים של Google Kubernetes Engine ‏ (GKE) באמצעות GPUDirect-TCPXO,‏ GPUDirect-TCPX,‏ gVNIC וריבוי רשתות. אם אתם משתמשים באשכולות Autopilot, כדאי לעיין במאמר בנושא הגדלת רוחב הפס של רשת ה-GPU באשכולות במצב אוטומטי.

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

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

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

מידע על Google Cloud סוגי מכונות עם GPU

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

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

התכונות והיכולות שנדרשות כדי להגדיל את רוחב הפס

כדי למקסם את רוחב הפס ברשת בסדרת המכונות A3 – כולל סוגי המכונות A3 Mega ו-A3 High שמשמשים בהוראות כאן – צריך להשתמש בכל התכונות הבאות:

  • חבילת רשת GPUDirect: סדרת מכונות A3 תומכת בשלוש חבילות רשת לגישה ישירה מרחוק לזיכרון (RDMA) בהתאמה אישית:
    • בסוגי המכונות A3 High ו-A3 Edge ובמעבדי GPU מסוג NVIDIA H100, משתמשים ב-GPUDirect-TCPX כדי להפחית את התקורה שנדרשת להעברת המטען הייעודי (payload) של חבילות אל מעבדי ה-GPU ומעבדי ה-GPU, וכך לשפר משמעותית את הקיבולת בהשוואה למעבדי GPU שלא משתמשים ב-GPUDirect.
    • בסוגי מכונות A3 Mega ובמעבדי NVIDIA H100 Mega GPU, משתמשים ב-GPUDirect-TCPXO שמשפר עוד יותר את התקשורת בין ה-GPU לבין המכונה הווירטואלית.
    • בסוגי מכונות A3 Ultra וב-GPU מסוג NVIDIA H200, ובסדרות מכונות מאוחרות יותר כמו A4,‏ A4X ו-A4X Max, אפשר להשתמש ב-GPUDirect RDMA כדי להריץ עומסי עבודה מבוססי-AI מבוזרים עם שיפורים נוספים בנפח התפוקה. כדי להתחיל, יוצרים אשכול GKE שעבר אופטימיזציה ל-AI ומשתמש ב-A4 או ב-A3 Ultra.
  • ‫gVNIC: הפעלת יכולות של GPUDirect כמו פיצול כותרות של חבילות, ניתוב זרימה וניהול מאגר נתונים זמני (buffer). כדי להשתמש ב-GPUDirect-TCPX או ב-GPUDirect-TCPXO, צריך להשתמש ב-gVNIC. פרטים נוספים על gVNIC זמינים במאמר הגברת מהירות התנועה ברשת של צומתי GPU.
  • רישות מרובה: הוספת כרטיסי NIC משניים למכונה שעברה אופטימיזציה להאצה. כל כרטיס NIC משויך לרשת משנה נפרדת ב-VPC שלו כדי למנוע התנגשויות. לפרטים על תמיכה בכמה רשתות, ראו הגדרת תמיכה בכמה רשתות לפודים.
  • כללי מדיניות למיקום: אפשר להשתמש בכללי מדיניות למיקום משאבים כדי למקם את כל צומתי ה-GPU של עומס עבודה מסוים בשרתים קרובים פיזית, וכך לצמצם את זמן האחזור. פרטים נוספים זמינים במאמר הגדרת מיקום קומפקטי לצומתי GKE.

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

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

  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 Mega או A3 High. כדי לקבל את הקיבולת הזו, קודם צריך לבחור מתוך אפשרויות הצריכה. כדי לפעול לפי ההוראות בדף הזה, אתם יכולים להשתמש בקיבולת לפי דרישה, בהזמנות לפי דרישה, בהזמנות לעתיד או בהזמנות לעתיד לפרק זמן של עד 90 יום (במצב לוח שנה). אחרי שבוחרים אפשרות צריכה, פועלים לפי ההוראות המתאימות כדי לקבל קיבולת באמצעות אפשרות הצריכה שנבחרה.
  • מוודאים שיש לכם מספיק מכסה ל-GPU מסוג H100. לפרטים על הגדלת המכסות, ראו מכסות של GPU.

דרישות

הדרישות הבאות חלות על GPUDirect-TCPX ועל GPUDirect-TCPXO, אלא אם צוין אחרת.

  • ‫GPUDirect-TCPX דורש את סוג המכונה a3-highgpu-8g ויש לו תמיכה בכל הגרסאות המשניות הזמינות של GKE באמצעות גרסאות תיקון ספציפיות:

    • בגרסאות GKE‏ 1.30 עד 1.33, אפשר להשתמש בכל גרסת תיקון.
    • ב-GKE גרסה 1.34, צריך להשתמש בגרסת תיקון ‎1.34.5-gke.1153000 ואילך.
    • בגרסה 1.35 של GKE, צריך להשתמש בגרסת התיקון ‎1.35.2-gke.1485000 ואילך.
    • בגרסה 1.36 ואילך של GKE, אפשר להשתמש בכל גרסת תיקון.
  • ‫GPUDirect-TCPXO דורש את סוג המכונה a3-megagpu-8g, ויש תמיכה בכל הגרסאות המשניות הזמינות של GKE באמצעות גרסאות תיקון ספציפיות:

    • בגרסה 1.30 של GKE, צריך להשתמש בגרסת התיקון ‎1.30.4-gke.1129000 או בגרסה חדשה יותר.
    • בגרסה 1.31 של GKE, צריך להשתמש בגרסת התיקון 1.31.1-gke.2008000 או בגרסה חדשה יותר.
    • בגרסה 1.32 של GKE, צריך להשתמש בגרסת התיקון 1.32.2-gke.1489001 או בגרסה מאוחרת יותר.
    • בגרסה 1.33 של GKE או בכל גרסה משנית מאוחרת יותר, אפשר להשתמש בכל גרסת תיקון.
  • הצומת של GKE צריך להשתמש בתמונת צומת של מערכת הפעלה שמותאמת לקונטיינרים (COS). אין תמיכה בתמונות של צומתי Ubuntu ו-Windows.

  • בצומתי ה-GPU צריכה להיות מותקנת גרסה 535 ומעלה של מנהל ההתקן של NVIDIA.
  • חובה להשתמש ב-GKE Dataplane V2.
  • בגרסה 1.34 ואילך של GKE, צריך להשתמש בגרסה 3.1.9 ואילך של תוכנת ההתקנה של GPUDirect-TCPX ובגרסה 2.0.12 ואילך של ה-sidecar של GPUDirect-TCPX. גרסאות קובץ ההתקנה וקובץ העזר ממופות אחת לאחת וצריכות להיות זהות. לדוגמה, גרסת המתקין 3.1.12 תואמת לגרסת ה-sidecar‏ 2.0.15. מידע נוסף על גרסאות של קובצי התקנה וקובצי sidecar זמין בהערות לגבי הגרסה של GPUDirect-TCPX.
  • בעומסי עבודה של GPUDirect-TCPX או GPUDirect-TCPXO שפועלים בכמה מאגרי צמתים, כל מאגרי הצמתים צריכים להיות באותם אזורים של Compute Engine ולהשתמש באותם מערכי רשת, כמו רשתות VPC ותתי-רשתות.

מגבלות

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

  • אין תמיכה ב-GPUDirect-TCPX וב-GPUDirect-TCPXO עם מעבדי GPU מרובי-מופעים, שיתוף זמן של GPU או NVIDIA MPS.
  • אי אפשר להשתמש ב-NCCL FastSocket עם GPUDirect-TCPX או GPUDirect-TCPXO.
  • עומס העבודה ב-GKE חייב להשתמש בכל ה-GPU הזמינים ובכל כרטיסי ה-NIC המשניים הזמינים בצומת יחיד. אי אפשר להשתמש בכמה פודים ב-GPUDirect-TCPX או ב-GPUDirect-TCPXO בצומת יחיד.
  • אפשר להשתמש רק בסוגי המכונות a3-highgpu-8g, a3-megagpu-8g ו-a3-edgegpu-8g. אין תמיכה בסוגים אחרים של מכונות A3.

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

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

  1. יוצרים את רשתות ה-VPC עבור GPUDirect בפרויקט, כל אחת עם תת-רשת וכלל חומת אש. בוחרים בכרטיסייה GPUDirect-TCPX עבור סוגי מכונות A3 High, או בכרטיסייה GPUDirect-TCPXO עבור סוגי מכונות A3 Mega, ואז מבצעים את ההוראות הבאות:

    GPUDirect-TCPXO

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

    for N in $(seq 1 8); 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 של המקור לכלל חומת האש שמאפשר תעבורת נתונים נכנסת (ingress), בסימון CIDR. לדוגמה, 192.168.0.0/16.

    GPUDirect-TCPX

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

    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 של המקור לכלל חומת האש שמאפשר תעבורת נתונים נכנסת (ingress), בסימון CIDR. לדוגמה, 192.168.0.0/16.
  2. מוודאים שהרשתות נוצרו:

    gcloud compute networks list
    

יצירת סביבת GKE

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

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

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

GPUDirect-TCPXO

  1. בוחרים גרסת GKE זמינה שתומכת ב-GPUDirect-TCPXO. כדי להציג את הגרסאות, מריצים את הפקודה הבאה:

    gcloud container get-server-config \
        --format="yaml(validMasterVersions)" \
        --region=REGION \
        --project=PROJECT_ID
    

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

    • ‫REGION: אזור המחשוב של מישור הבקרה של האשכול.
    • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
  2. יוצרים אשכול:

    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: השם של האשכול החדש.
    • ‫VERSION: גרסת GKE שתומכת ב-GPUDirect-TCPXO, כמו שמתואר בדרישות.
    • ‫CONTROL_PLANE_LOCATION: המיקום של מישור הבקרה של האשכול ב-Compute Engine. מציינים אזור לאשכולות אזוריים או אזור לאשכולות אזוריים.
  3. יוצרים באשכול משאבים מסוג 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: Network
    metadata:
      name: vpc5
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc5
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc6
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc6
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc7
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc7
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc8
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc8
      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
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc5
    spec:
      vpc: PREFIX-net-5
      vpcSubnet: PREFIX-sub-5
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc6
    spec:
      vpc: PREFIX-net-6
      vpcSubnet: PREFIX-sub-6
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc7
    spec:
      vpc: PREFIX-net-7
      vpcSubnet: PREFIX-sub-7
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc8
    spec:
      vpc: PREFIX-net-8
      vpcSubnet: PREFIX-sub-8
      deviceMode: NetDevice
    EOF
    

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

GPUDirect-TCPX

  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, כמו שמתואר בדרישות.
  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

GPUDirect-TCPXO

יוצרים מאגר צמתים ל-GPU מסוג H100:

gcloud beta container node-pools create NODE_POOL_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --cluster=CLUSTER_NAME \
    --project=PROJECT_ID \
    --accelerator=type=nvidia-h100-mega-80gb,count=8,gpu-driver-version=LATEST \
    --machine-type=a3-megagpu-8g \
    --num-nodes=2 \
    --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 \
    --additional-node-network network=PREFIX-net-5,subnetwork=PREFIX-sub-5 \
    --additional-node-network network=PREFIX-net-6,subnetwork=PREFIX-sub-6 \
    --additional-node-network network=PREFIX-net-7,subnetwork=PREFIX-sub-7 \
    --additional-node-network network=PREFIX-net-8,subnetwork=PREFIX-sub-8 \
    --enable-gvnic \
    --no-enable-autoupgrade \
    --scopes "https://www.googleapis.com/auth/cloud-platform" [\
    --placement-policy=POLICY_NAME \
    --reservation-affinity=specific \
    --reservation=projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME \
    --host-maintenance-interval=PERIODIC]

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

בדוגמה, הארגומנט --scopes https://www.googleapis.com/auth/cloud-platform מגדיר את ההיקף של מופע הצומת ל-cloud-platform כדי להקל על הבדיקה. בסביבת ייצור, יכול להיות שתרצו להגביל את ההיקף כדי להגדיר פרטי כניסה עם רמת גרנולריות גבוהה יותר.

כדי להשתמש בהזמנה, משתמשים בדגלים --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 בפרויקט. מוודאים שיש לכם מכסת שימוש ומנסים שוב להריץ את הפקודה.

GPUDirect-TCPX

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

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --machine-type=a3-highgpu-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 בפרויקט. מוודאים שיש לכם מכסת שימוש ומנסים שוב להריץ את הפקודה.

אחרי שיוצרים את מאגר הצמתים, מוודאים שלכל צומת מצורפים מעבדי ה-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, בהתאם לסוג המכונה של A3‏ (GPUDirect-TCPX ל-A3 High, ‏ GPUDirect-TCPXO ל-A3 Mega) ולגרסה ספציפית של ספריית NCCL באמצעות DaemonSet.

GPUDirect-TCPXO

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

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

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

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

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

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

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

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

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

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

    # Output
    nccl-tcpxo-installer-6c2pv                    1/1     Running   0          2m11s
    nccl-tcpxo-installer-qgg82                    1/1     Running   0          2m11s
    

GPUDirect-TCPX

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

  1. הפקודה מתקינה את ספריית NCCL ואת הקובץ הבינארי GPUDirect-TCPX בצומת.
  2. שומר את הספרייה ואת הקובץ הבינארי בספרייה /home/kubernetes/bin/nvidia/lib64 ב-VM. כברירת מחדל, 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
    

פריסת הפלאגין להזרקת מכשירים של NRI

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

  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
    

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

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

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

כדי לפרוס את עומס העבודה לדוגמה:

GPUDirect-TCPXO

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

  1. בודקים את המניפסט של nccl-test-latest.yaml ב-GitHub.

  2. פורסים שני פודים עם עומס העבודה של הבדיקה:

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

    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.

  4. אחרי פריסת ה-Pods, מפעילים בדיקה של all-gather:

    kubectl exec --stdin --tty --container=nccl-test nccl-test-host-1 -- /scripts/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
    #
    

GPUDirect-TCPX

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

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

  2. בודקים את מניפסט הפריסה של nccl-test-latest.yaml ב-GitHub.

  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
    
  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)
        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 בעומסי העבודה בפועל. כדי לעשות את זה, צריך לעדכן את הגדרות ה-NCCL ואת המניפסטים של Pod ב-Kubernetes.

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

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

GPUDirect-TCPXO


"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_FASTRAK_CTRL_DEV=eth0",
"NCCL_FASTRAK_IFNAME=eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8",
"NCCL_SOCKET_IFNAME=eth0",
"NCCL_CROSS_NIC=0",
"NCCL_ALGO=Ring,Tree",
"NCCL_PROTO=Simple,LL128",
"NCCL_MIN_NCHANNELS=4",
"NCCL_TUNER_PLUGIN=libnccl-tuner.so",
"NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config.textproto",
"NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_guest_config.textproto",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_FASTRAK_NUM_FLOWS=2",
"NCCL_FASTRAK_USE_SNAP=1",
"NCCL_FASTRAK_PLUGIN_ACCEPT_TIMEOUT_MS=600000",
"NCCL_FASTRAK_ENABLE_CONTROL_CHANNEL=0",
"NCCL_BUFFSIZE=8388608",
"CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_FASTRAK_ENABLE_HOTPATH_LOGGING=0",
"NCCL_FASTRAK_USE_LLCM=1",
"NCCL_NVLS_ENABLE=0"

אפשר גם להגדיר את כל ההגדרות בבת אחת. כך עושים את זה:

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

    NCCL_LIB_DIR="/usr/local/nvidia/lib64"
    
  2. מוודאים שהסקריפט nccl-env-profile.sh מופעל כשקונטיינר עומס העבודה מתחיל. לדוגמה, אפשר לעשות את זה במפרט של ה-Pod על ידי שינוי הפקודה של הקונטיינר כך שתכלול את הפקודה הבאה:

    source ${NCCL_LIB_DIR}/nccl-env-profile.sh
    

תמיכה ב-LL128

פרוטוקול התקשורת NVIDIA LL128 (זמן אחזור נמוך 128) NCCL יכול לשפר באופן משמעותי את הביצועים של קולקטיבים קטנים עד בינוניים. ‫GPUDirect-TCPXO תומך בפרוטוקול LL128.

כדי להשתמש ב-LL128, ודאו שבקובץ nccl-tcpxo-installer.yaml שבקטע התקנת הקובץ הבינארי של GPUDirect והגדרת NCCL נעשה שימוש בגרסה הבאה של קובץ האימג' של הקונטיינר או בגרסה מאוחרת יותר:

us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx-
dev:v1.0.8-1

כדי להגדיר LL128:

  • לגרסת הפלאגין us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx- dev:v1.0.8-1 NCCL, מבצעים את השלבים הבאים:

    1. במניפסט של עומס העבודה, מגדירים את משתנה הסביבה הבא:

      NCCL_LIB_DIR="/usr/local/nvidia/lib64
      
    2. מגדירים את עומס העבודה להפעלה של סקריפט nccl-env-profile-ll128.sh כשהקונטיינר מתחיל. במניפסט של עומס העבודה, מגדירים את הפקודה הבאה:

      source ${NCCL_LIB_DIR}/nccl-env-profile-ll128.sh
      

      לסקריפט nccl-env-profile-ll128.sh יש את משתני הסביבה הבאים:

      NCCL_PROTO=Simple,LL128
      NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config_ll128.textproto
      NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_guest_config_ll128.textproto
      
  • בגרסה של תוסף NCCL‏ us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx-dev:v1.0.9-1 ומעלה, LL128 הופך לפרמטר ברירת מחדל, כך ששימוש בסקריפט nccl-env-profile.sh או בסקריפט nccl-env-profile-ll128.sh מפעיל את LL128. כדי להשבית את LL128:

    1. במניפסט של עומס העבודה, מגדירים את משתנה הסביבה הבא:

      NCCL_LIB_DIR="/usr/local/nvidia/lib64
      
    2. מגדירים את עומס העבודה להפעלה של סקריפט nccl-env-profile-ll128.sh כשהקונטיינר מתחיל. במניפסט של עומס העבודה, מגדירים את הפקודה הבאה:

      source ${NCCL_LIB_DIR}/nccl-env-profile-simple.sh
      

      לסקריפט nccl-env-profile-simple.sh יש את משתני הסביבה הבאים:

      NCCL_PROTO=Simple
      NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config_simple.textproto
      NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_tuner_config_simple.textproto
      

GPUDirect-TCPX

"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/tcpx/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 כדי שהפודים ישתמשו ב-GPUDirect.

בהתאם לסוג ה-GPUDirect, מבצעים את הפעולות הבאות:

GPUDirect-TCPXO

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

    metadata:
      annotations:
        devices.gke.io/container.tcpxo-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
          - path: /dev/dmabuf_import_helper
        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"},
            {"interfaceName":"eth5","network":"vpc5"},
            {"interfaceName":"eth6","network":"vpc6"},
            {"interfaceName":"eth7","network":"vpc7"},
            {"interfaceName":"eth8","network":"vpc8"}
          ]
    
  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
      - name: aperture-devices
        hostPath:
          path: /dev/aperture_devices
    
  3. מוסיפים את הקונטיינר הבא למניפסט כדי להריץ את שירות tcpxo-daemon. מחליפים את (TCPXO_DAEMON_IMAGE) בתמונה האחרונה, לדוגמה, us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.17:

    - name: tcpxo-daemon
      image: TCPXO_DAEMON_IMAGE
      imagePullPolicy: Always
      command: ["/bin/sh", "-c"]
      args:
        - |
          set -ex
          chmod 755 /fts/entrypoint_rxdm_container.sh
          /fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr
      securityContext:
        capabilities:
          add:
            - NET_ADMIN
            - NET_BIND_SERVICE
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. מוסיפים את משתנה הסביבה הבא לכל קונטיינר GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
      value: /dev/aperture_devices
    
  5. מוסיפים את volumeMounts הבאים לכל מאגר GPU. אם לא מגדירים את aperture_devices, צריך להשתמש ב-privileged:true לקונטיינרים של GPU:

    volumeMounts:
      - name: aperture-devices
        mountPath: /dev/aperture_devices
    
  6. מוסיפים משתני סביבה כדי להגדיר את האפשרויות של NCCL. פרטים נוספים מופיעים במאמר שימוש בהגדרות מומלצות של NCCL לשיפור הביצועים.

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

GPUDirect-TCPX

  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.12
      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.

איסוף יומני ניפוי באגים של 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=WARN כך שהיומנים יוגבלו לשגיאות בלבד, אלא אם ציינתם את NCCL_DEBUG_FILE.
  • ‫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: השם של קובצי היומן.

    הפלייסהולדר %h מייצג את שם המארח של הצומת, והפלייסהולדר %p מייצג את מזהה התהליך (PID) שיוצר את היומן.

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

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