בדף הזה מוסבר איך להשתמש ב-CUDA Multi-Process Service (MPS) כדי לאפשר לכמה עומסי עבודה לשתף מאיץ חומרה יחיד של NVIDIA GPU בצמתים של Google Kubernetes Engine (GKE).
סקירה כללית
NVIDIA MPS הוא פתרון לשיתוף GPU שמאפשר לכמה קונטיינרים לשתף חומרה פיזית אחת של NVIDIA GPU שמחוברת לצומת.
NVIDIA MPS מסתמך על Multi-Process Service של NVIDIA ב-CUDA. NVIDIA MPS היא הטמעה חלופית של CUDA API, שתואמת לבינארי, ומיועדת להפעלה שקופה של אפליקציות CUDA מרובות תהליכים באופן מקביל במכשיר GPU יחיד.
באמצעות NVIDIA MPS, אפשר לציין את המספר המקסימלי של קונטיינרים משותפים של GPU פיזי. הערך הזה קובע כמה כוח עיבוד פיזי של ה-GPU מקבל כל קונטיינר, מבחינת המאפיינים הבאים:
מידע נוסף על תזמון של יחידות GPU באמצעות NVIDIA MPS ומתי כדאי להשתמש ב-CUDA MPS
למי מיועד המדריך הזה
ההוראות בקטע הזה רלוונטיות אם אתם:
- אדמין פלטפורמה: יוצר ומנהל אשכול GKE, מתכנן את התשתית ואת דרישות המשאבים ועוקב אחרי הביצועים של האשכול.
- מפתח אפליקציות: מעצב ופורס עומסי עבודה באשכולות GKE. אם אתם רוצים לקבל הוראות לבקשת NVIDIA MPS עם מעבדי GPU, תוכלו לעיין במאמר פריסת עומסי עבודה שמשתמשים ב-NVIDIA MPS עם מעבדי GPU.
דרישות
- גרסת GKE: אפשר להפעיל שיתוף GPU עם NVIDIA MPS באשכולות GKE Standard שפועלים בגרסת GKE 1.27.7-gke.1088000 ואילך.
- סוג ה-GPU: אפשר להפעיל NVIDIA MPS לכל סוגי ה-GPU של NVIDIA.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מוודאים שיש לכם מספיק מכסה של NVIDIA GPU. אם אתם צריכים מכסה גדולה יותר, אתם יכולים לעיין במאמר איך מבקשים להגדיל את המכסה.
- תכננו את קיבולת ה-GPU על סמך צורכי המשאבים של עומסי העבודה וקיבולת ה-GPU הבסיסי.
- מעיינים במגבלות של NVIDIA MPS עם GPU.
הפעלת NVIDIA MPS עם GPUs באשכולות GKE
אדמינים של פלטפורמות צריכים להפעיל NVIDIA MPS עם GPUs באשכול GKE Standard. לאחר מכן, מפתחי אפליקציות יכולים לפרוס עומסי עבודה כדי להשתמש ב-NVIDIA MPS עם GPUs. כדי להפעיל NVIDIA MPS עם GPU ב-GKE, מבצעים את הפעולות הבאות:
- הפעלת NVIDIA MPS עם GPUs באשכול GKE חדש.
- מתקינים דרייברים של מכשיר GPU של NVIDIA (אם נדרש).
- מוודאים שמשאבי ה-GPU זמינים בצמתים.
הפעלת NVIDIA MPS עם GPUs באשכול GKE
אפשר להפעיל NVIDIA MPS עם יחידות GPU כשיוצרים אשכולות GKE Standard. מאגר הצמתים שמוגדר כברירת מחדל באשכול כולל את התכונה. עדיין צריך להפעיל NVIDIA MPS עם יחידות GPU כשיוצרים ידנית מאגרי צמתים חדשים באותו אשכול.
כדי ליצור אשכול עם NVIDIA MPS מופעל באמצעות Google Cloud CLI:
gcloud container clusters create CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--cluster-version=CLUSTER_VERSION \
--machine-type=MACHINE_TYPE \
--accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=mps,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION
מחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_NAME: השם של האשכול החדש. -
CONTROL_PLANE_LOCATION: המיקום של מישור הבקרה של האשכול ב-Compute Engine. מציינים אזור לאשכולות אזוריים או אזור זמין לאשכולות אזוריים. סוג ה-GPU שבו אתם משתמשים צריך להיות זמין באזור שנבחר. -
CLUSTER_VERSION: גרסת GKE למישור הבקרה ולצמתים של האשכול. משתמשים בגרסה 1.27.7-gke.1088000 ואילך של GKE. אפשר גם לציין ערוץ הפצה עם גרסת GKE הזו באמצעות הדגל--release-channel=RELEASE_CHANNEL. -
MACHINE_TYPE: סוג המכונה של Compute Engine עבור הצמתים.- לשימוש ביחידות GPU מסוג GB200, צריך להשתמש בסוג המכונה A4X.
- למעבדי B200 GPU, משתמשים בסוג המכונה A4.
- למעבדי GPU מסוג H200, משתמשים בסוג המכונה A3 Ultra
- בכרטיסי GPU מסוג H100, צריך להשתמש בסוג מכונה A3שאינו Ultra (Mega, High או Edge)
- למעבדי GPU מסוג A100, משתמשים בסוג מכונה A2.
- לשימוש ביחידות GPU מסוג RTX PRO 6000, צריך להשתמש בסוג מכונה G4
- למעבדי L4 GPU, משתמשים בסוג מכונה G2.
- לכל שאר יחידות ה-GPU, צריך להשתמש בסוג מכונה N1
-
GPU_TYPE: סוג ה-GPU, שחייב להיות פלטפורמת NVIDIA GPU, כמוnvidia-tesla-v100. -
GPU_QUANTITY: מספר המעבדים הגרפיים הפיזיים לצירוף לכל צומת במאגר הצמתים שמוגדר כברירת מחדל. -
CLIENTS_PER_GPU: המספר המקסימלי של קונטיינרים שיכולים לשתף כל GPU פיזי. -
DRIVER_VERSION: גרסת הדרייבר של NVIDIA להתקנה. יכול להיות אחת מהאפשרויות הבאות:-
default: התקנת גרסת ברירת המחדל של הדרייבר לגרסת GKE. -
latest: התקנת הגרסה האחרונה של מנהל ההתקן שזמינה לגרסת GKE שלכם. האפשרות הזו זמינה רק לצמתים שמשתמשים במערכת הפעלה שמותאמת לקונטיינרים. -
disabled: דילוג על התקנה אוטומטית של מנהל התקן. חובה להתקין מנהל התקן באופן ידני אחרי שיוצרים את מאגר הצמתים. אם לא מציינים אתgpu-driver-version, זו אפשרות ברירת המחדל.
-
הפעלת NVIDIA MPS עם מעבדי GPU במאגר צמתים חדש
אפשר להפעיל NVIDIA MPS עם יחידות GPU כשיוצרים מאגרי צמתים חדשים באופן ידני באשכול GKE. כדי ליצור מאגר צמתים עם NVIDIA MPS מופעל באמצעות Google Cloud CLI:
gcloud container node-pools create NODEPOOL_NAME \
--cluster=CLUSTER_NAME \
--machine-type=MACHINE_TYPE \
--location=CONTROL_PLANE_LOCATION \
--accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=mps,max-shared-clients-per-gpu=CONTAINER_PER_GPU,gpu-driver-version=DRIVER_VERSION
מחליפים את מה שכתוב בשדות הבאים:
-
NODEPOOL_NAME: השם של מאגר הצמתים החדש. -
CLUSTER_NAME: שם האשכול, שצריך להריץ GKE בגרסה 1.27.7-gke.1088000 ואילך. -
CONTROL_PLANE_LOCATION: המיקום של מישור הבקרה של האשכול ב-Compute Engine. מציינים אזור לאשכולות אזוריים או אזור זמין לאשכולות אזוריים. -
MACHINE_TYPE: סוג המכונה של Compute Engine עבור הצמתים. למעבדי GPU מסוג A100, משתמשים בסוג מכונה A2. לכל שאר יחידות ה-GPU, צריך להשתמש בסוג מכונה N1. -
GPU_TYPE: סוג ה-GPU, שחייב להיות פלטפורמת NVIDIA GPU, כמוnvidia-tesla-v100. -
GPU_QUANTITY: מספר המעבדים הגרפיים הפיזיים לצירוף לכל צומת במאגר הצמתים. -
CONTAINER_PER_GPU: המספר המקסימלי של קונטיינרים שיכולים לשתף כל GPU פיזי.
DRIVER_VERSION: גרסת הדרייבר של NVIDIA להתקנה. יכול להיות אחת מהאפשרויות הבאות:-
default: התקנת גרסת ברירת המחדל של הדרייבר לגרסת GKE. -
latest: התקנת הגרסה האחרונה של מנהל ההתקן שזמינה לגרסת GKE שלכם. האפשרות הזו זמינה רק לצמתים שמשתמשים במערכת הפעלה שמותאמת לקונטיינרים. -
disabled: דילוג על התקנה אוטומטית של מנהל התקן. חובה להתקין מנהל התקן באופן ידני אחרי שיוצרים את מאגר הצמתים. אם לא מציינים אתgpu-driver-version, זו אפשרות ברירת המחדל.
-
התקנה של דרייברים של מכשירי NVIDIA GPU
אם בחרתם להשבית את ההתקנה האוטומטית של הדרייבר כשנוצר האשכול, או אם אתם משתמשים בגרסת GKE מוקדמת יותר מ-1.27.2-gke.1200, אתם צריכים להתקין באופן ידני דרייבר NVIDIA תואם כדי לנהל את החלוקה של NVIDIA MPS של ה-GPU הפיזי. כדי להתקין את מנהלי ההתקנים, צריך לפרוס DaemonSet של התקנת GKE שמגדיר את מנהלי ההתקנים.
הוראות מפורטות מופיעות במאמר בנושא התקנת דרייברים של מכשירי GPU של NVIDIA.
בדיקה של משאבי ה-GPU הזמינים
אתם יכולים לוודא שמספר ה-GPU בצמתים תואם למספר שציינתם כשהפעלתם את NVIDIA MPS. אפשר גם לוודא ששד השליטה של NVIDIA MPS פועל.
אימות משאבי ה-GPU שזמינים בצמתים
כדי לוודא שמשאבי ה-GPU זמינים בצמתים, מריצים את הפקודה הבאה:
kubectl describe nodes NODE_NAME
מחליפים את NODE_NAME בשם הצומת.
הפלט אמור להיראות כך:
...
Capacity:
...
nvidia.com/gpu: 3
Allocatable:
...
nvidia.com/gpu: 3
בפלט הזה, מספר משאבי ה-GPU בצומת הוא 3 בגלל הערכים הבאים:
- הערך בעמודה
max-shared-clients-per-gpuהוא3. - מספר יחידות ה-GPU הפיזיות לצירוף לצומת הוא
1.countאם הערך שלcountשל מעבדי GPU פיזיים היה2, בפלט היו מופיעים6משאבי GPU שניתנים להקצאה, שלושה בכל מעבד GPU פיזי.
איך מוודאים ששד בקרת ה-MPS פועל
תוסף המכשיר של ה-GPU מבצע בדיקת תקינות בשד של בקרת ה-MPS. אחרי שמוודאים שהדמון של בקרת ה-MPS תקין, אפשר לפרוס קונטיינר.
כדי לוודא שהסטטוס של ה-MPS הוא, מריצים את הפקודה הבאה:
kubectl logs -l k8s-app=nvidia-gpu-device-plugin -n kube-system --tail=100 | grep MPS
הפלט אמור להיראות כך:
I1118 08:08:41.732875 1 nvidia_gpu.go:75] device-plugin started
...
I1110 18:57:54.224832 1 manager.go:285] MPS is healthy, active thread percentage = 100.0
...
יכול להיות שבפלט יופיעו האירועים הבאים:
- השגיאה
failed to start GPU device managerקודמת לשגיאהMPS is healthy. השגיאה הזו היא זמנית. אם רואים את ההודעהMPS is healthyהבאה, אז דמון הבקרה פועל. - ההודעה
active thread percentage = 100.0מציינת שלמשאב ה-GPU הפיזי כולו יש שרשור פעיל לחלוטין.
פריסת עומסי עבודה שמשתמשים ב-MPS
מפעילים של אפליקציות שמבצעים פריסה של עומסי עבודה של GPU יכולים להגדיר ב-GKE שייעשה שיתוף של יחידות שיתוף של MPS באותו GPU פיזי. במניפסט הבא, אתם מבקשים GPU פיזי אחד ומגדירים את max-shared-clients-per-gpu=3. ה-GPU הפיזי מקבל שלוש יחידות שיתוף MPS, ומתחיל nvidia/samples:nbody עבודה עם שלושה פודים (קונטיינרים) שפועלים במקביל.
שומרים את קובץ המניפסט בשם
gpu-mps.yaml:apiVersion: batch/v1 kind: Job metadata: name: nbody-sample spec: # Specifies the desired number of successfully finished Pods. completions: 3 # Specifies the maximum desired number of Pods that should run at any given time. parallelism: 3 template: spec: # Allows the Pod to share the host's IPC namespace. # The following field is required for containers to communicate with the MPS control daemon. hostIPC: true # Selects a node with the 'mps' GPU sharing strategy. nodeSelector: cloud.google.com/gke-gpu-sharing-strategy: mps containers: - name: nbody-sample # A sample CUDA application from NVIDIA. image: nvidia/samples:nbody # The command to run in the container. command: ["/tmp/nbody"] # Arguments for the command. Runs the nbody simulation in benchmark mode. args: ["-benchmark", "-i=5000"] resources: limits: # Requests one MPS sharing unit from a physical GPU. nvidia.com/gpu: 1 restartPolicy: "Never" backoffLimit: 1במניפסט הזה:
-
hostIPC: trueמאפשר ל-Pods לתקשר עם דימון הבקרה של MPS. זהו שדה חובה. עם זאת, חשוב לזכור שההגדרהhostIPC: trueמאפשרת לקונטיינר לגשת למשאב המארח, מה שיוצר סיכוני אבטחה. - 5,000 איטרציות מופעלות במצב השוואה.
-
החלת המניפסט:
kubectl apply -f gpu-mps.yamlמוודאים שכל ה-Pods פועלים:
kubectl get podsהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE nbody-sample-6948ff4484-54p6q 1/1 Running 0 2m6s nbody-sample-6948ff4484-5qs6n 1/1 Running 0 2m6s nbody-sample-6948ff4484-5zpdc 1/1 Running 0 2m5sבודקים את היומנים מ-Pods כדי לוודא שהעבודה הושלמה:
kubectl logs -l job-name=nbody-sample -fהפלט אמור להיראות כך:
... > Compute 8.9 CUDA device: [NVIDIA L4] 18432 bodies, total time for 5000 iterations: 9907.976 ms = 171.447 billion interactions per second = 3428.941 single-precision GFLOP/s at 20 flops per interaction ...מכיוון ש-GKE מריץ 50,000 איטרציות, יכול להיות שיחלפו כמה דקות עד שהיומן יופיע.
הסרת המשאבים
כדי למחוק את המשימות ואת כל ה-Pods שלהן, מריצים את הפקודה הבאה:
kubectl delete job --all
הגבלת זיכרון המכשיר המוצמד ו-Thread פעיל באמצעות NVIDIA MPS
כברירת מחדל, כשמשתמשים ב-GPU עם NVIDIA MPS ב-GKE, משתני הסביבה הבאים של CUDA מוזרקים לעומס העבודה של ה-GPU:
-
CUDA_MPS_ACTIVE_THREAD_PERCENTAGE: המשתנה הזה מציין את אחוז ה-threads הזמינים שכל יחידת שיתוף של MPS יכולה להשתמש בהם. כברירת מחדל, כל יחידת שיתוף MPS של ה-GPU מוגדרת ל-100 / MaxSharedClientsPerGPUכדי לקבל נתח שווה של יכולת החישוב של ה-GPU מבחינת מעבד מרובה-ליבות.
CUDA_MPS_PINNED_DEVICE_MEM_LIMIT: המשתנה הזה מגביל את כמות זיכרון ה-GPU שאפשר להקצות ליחידת שיתוף MPS של GPU. כברירת מחדל, כל יחידת שיתוף של MPS ב-GPU מוגדרת ל-total mem / MaxSharedClientsPerGPUכדי לקבל נתח שווה מזיכרון ה-GPU.
כדי להגדיר מגבלת משאבים לעומסי העבודה של ה-GPU, צריך להגדיר את משתני הסביבה הבאים של NVIDIA MPS:
בודקים ויוצרים את התמונה של
cuda-mpsהדוגמה ב-GitHub.שומרים את קובץ המניפסט הבא בשם
cuda-mem-and-sm-count.yaml:apiVersion: v1 kind: Pod metadata: name: cuda-mem-and-sm-count spec: # Allows the Pod to share the host's IPC namespace. # The following field is required for containers to communicate with the MPS control daemon. hostIPC: true # Selects a node with the 'mps' GPU sharing strategy. nodeSelector: cloud.google.com/gke-gpu-sharing-strategy: mps containers: - name: cuda-mem-and-sm-count # The custom image built from the cuda-mps example. image: CUDA_MPS_IMAGE # Grants the container extended privileges on the host machine. securityContext: privileged: true resources: limits: # Requests one MPS sharing unit from a physical GPU. nvidia.com/gpu: 1מחליפים את
CUDA_MPS_IMAGEבשם של האימג' שיצרתם בדוגמהcuda-mps.כדי להשתמש ב-NVIDIA MPS, צריך להגדיר את
hostIPC:trueב-Pods. ההגדרה שלhostIPC:trueמאפשרת לקונטיינר לגשת למשאב המארח, מה שיוצר סיכוני אבטחה.החלת המניפסט:
kubectl apply -f cuda-mem-and-sm-count.yamlבודקים את היומנים של ה-Pod הזה:
kubectl logs cuda-mem-and-sm-countבדוגמה שבה נעשה שימוש ב-NVIDIA Tesla L4 עם
gpu-sharing-strategy=mpsו-max-shared-clients-per-gpu=3, הפלט דומה לזה שמופיע בהמשך:For device 0: Free memory: 7607 M, Total memory: 22491 M For device 0: multiProcessorCount: 18בדוגמה הזו, למעבד ה-GPU NVIDIA Tesla L4 יש 60 יחידות SM וזיכרון של 24GB. כל יחידת שיתוף של MPS מקבלת בערך 33% של שרשור פעיל וזיכרון בנפח 8GB.
מעדכנים את המניפסט כדי לבקש 2 הרשאות
nvidia.com/gpu:resources: limits: nvidia.com/gpu: 2הפלט אמור להיראות כך:
For device 0: Free memory: 15230 M, Total memory: 22491 M For device 0: multiProcessorCount: 38מעדכנים את המניפסט כדי לבטל את המשתנים
CUDA_MPS_ACTIVE_THREAD_PERCENTAGEו-CUDA_MPS_PINNED_DEVICE_MEM_LIMIT:env: - name: CUDA_MPS_ACTIVE_THREAD_PERCENTAGE value: "20" - name: CUDA_MPS_PINNED_DEVICE_MEM_LIMIT value: "0=8000M"הפלט אמור להיראות כך:
For device 0: Free memory: 7952 M, Total memory: 22491 M For device 0: multiProcessorCount: 10
מגבלות
- ל-MPS במעבדי GPU מסוג טרום-Volta (P100) יש יכולות מוגבלות בהשוואה לסוגי GPU ב-Volta ומעלה.
- בעזרת NVIDIA MPS, GKE מבטיח שלכל קונטיינר יהיה זיכרון מכשיר מוצמד מוגבל ושרשור פעיל. עם זאת, משאבים אחרים כמו רוחב פס של זיכרון, מקודדים או מפענחים לא נכללים במגבלות האלה. כתוצאה מכך, יכול להיות שמאגרי תגים ישפיעו לרעה על הביצועים של מאגרי תגים אחרים אם כולם מבקשים את אותו משאב בלתי מוגבל.
- ל-NVIDIA MPS יש הגנה על הזיכרון והגבלות על בלימת שגיאות. הגבלות מומלץ לבדוק את המגבלות האלה כדי לוודא שהן תואמות לעומסי העבודה שלכם.
- כדי להשתמש ב-NVIDIA MPS, צריך להגדיר את
hostIPC:trueב-Pods. ההגדרה שלhostIPC:trueמאפשרת לקונטיינר לגשת למשאב המארח, מה שיוצר סיכוני אבטחה. - יכול להיות ש-GKE ידחה בקשות מסוימות ל-GPU כשמשתמשים ב-NVIDIA MPS, כדי למנוע התנהגות לא צפויה במהלך הקצאת הקיבולת.
- המספר המקסימלי של קונטיינרים שיכולים לשתף מעבד גרפי פיזי אחד עם NVIDIA MPS הוא 48 (מעבד גרפי מדור קודם ל-Volta תומך ב-16 בלבד). כשמתכננים את ההגדרה של NVIDIA MPS, חשוב לקחת בחשבון את צורכי המשאבים של עומסי העבודה ואת הקיבולת של המעבדים הגרפיים הפיזיים הבסיסיים, כדי לשפר את הביצועים ואת מהירות התגובה.
המאמרים הבאים
- מידע נוסף על אסטרטגיות השיתוף של GPU שזמינות ב-GKE זמין במאמר מידע על אסטרטגיות שיתוף של GPU ב-GKE.
- למידע נוסף על Multi-Process Service (MPS), אפשר לעיין במסמכי התיעוד של NVIDIA.