Komputasi dan Penskalaan Otomatis - Amazon EKS

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Komputasi dan Penskalaan Otomatis

Optimalisasi Sumber Daya GPU dan Manajemen Biaya

Jadwalkan beban kerja dengan persyaratan GPU menggunakan label Terkenal

Untuk AI/ML beban kerja yang sensitif terhadap karakteristik GPU yang berbeda (misalnya GPU, memori GPU), kami merekomendasikan untuk menentukan persyaratan GPU menggunakan label penjadwalan yang diketahui yang didukung oleh tipe node yang digunakan dengan Karpenter dan grup node terkelola. Gagal mendefinisikan ini dapat mengakibatkan pod dijadwalkan pada instance dengan sumber daya GPU yang tidak memadai, menyebabkan kegagalan atau penurunan kinerja. Kami merekomendasikan penggunaan afinitas nodeSelector atau Node untuk menentukan node mana yang harus dijalankan pod dan menyetel sumber daya komputasi (CPU, memori, GPUs dll) di bagian sumber daya pod.

Contoh

Misalnya, menggunakan pemilih node nama GPU saat menggunakan Karpenter:

apiVersion: v1 kind: Pod metadata: name: gpu-pod-example spec: containers: - name: ml-workload image: <image> resources: limits: nvidia.com/gpu: 1 # Request one NVIDIA GPU nodeSelector: karpenter.k8s.aws/instance-gpu-name: "l40s" # Run on nodes with NVIDIA L40S GPUs

Gunakan Plugin Perangkat Kubernetes untuk mengekspos GPUs

Untuk mengekspos GPUs pada node, driver GPU NVIDIA harus diinstal pada sistem operasi node dan runtime kontainer yang dikonfigurasi untuk memungkinkan penjadwal Kubernetes menetapkan pod ke node yang tersedia. GPUs Proses penyiapan untuk Plugin Perangkat NVIDIA Kubernetes bergantung pada AMI Akselerasi EKS yang Anda gunakan:

  • Bottlerocket Accelerated AMI: AMI ini mencakup driver GPU NVIDIA dan Plugin Perangkat NVIDIA Kubernetes sudah diinstal sebelumnya dan siap digunakan, memungkinkan dukungan GPU di luar kotak. Tidak diperlukan konfigurasi tambahan untuk mengekspos GPUs ke penjadwal Kubernetes.

  • AL2023 AMI yang Dipercepat: AMI ini menyertakan driver GPU NVIDIA tetapi Plugin Perangkat NVIDIA Kubernetes belum diinstal sebelumnya. Anda harus menginstal dan mengkonfigurasi plugin perangkat secara terpisah, biasanya melalui file DaemonSet. Perhatikan bahwa jika Anda menggunakan eksctl untuk membuat cluster Anda dan menentukan jenis instans GPU (misalnya,g5.xlarge) di Anda ClusterConfig, eksctl akan secara otomatis memilih AMI yang dipercepat dan menginstal Plugin Perangkat NVIDIA Kubernetes pada setiap instance dalam grup node. Untuk mempelajari lebih lanjut, lihat Dukungan GPU dalam dokumentasi eksctl.

Untuk memverifikasi bahwa Plugin Perangkat NVIDIA aktif dan GPUs terpapar dengan benar, jalankan:

kubectl describe node | grep nvidia.com/gpu

Perintah ini memeriksa apakah nvidia.com/gpu sumber daya berada dalam kapasitas node dan sumber daya yang dapat dialokasikan. Misalnya, sebuah node dengan satu GPU harus ditampilkannvidia.com/gpu: 1. Lihat Panduan Penjadwalan GPU Kubernetes untuk informasi selengkapnya.

Gunakan Blok Kapasitas ML untuk jaminan kapasitas instans P dan Trainium

Blok Kapasitas untuk ML memungkinkan Anda untuk memesan instans GPU yang sangat dicari, khususnya instans P (misalnya, p6-b200, p5, p5e, p5en, p4d, p4de) dan instans Trainium (misalnya, trn1, trn2), untuk memulai baik segera atau di masa mendatang untuk mendukung beban kerja machine learning (ML) durasi pendek Anda. Reservasi ini ideal untuk memastikan kapasitas untuk tugas-tugas komputasi intensif seperti pelatihan model dan fine-tuning. EC2 Harga Blok Kapasitas terdiri dari biaya reservasi dan biaya sistem operasi. Untuk mempelajari lebih lanjut tentang harga, lihat Blok EC2 Kapasitas untuk harga ML.

GPUs Untuk memesan AI/ML beban kerja di Amazon EKS untuk jaminan kapasitas yang dapat diprediksi, kami merekomendasikan untuk memanfaatkan Blok Kapasitas ML untuk Reservasi Kapasitas jangka pendek atau Sesuai Permintaan () ODCRs untuk jaminan kapasitas tujuan umum.

  • ODCRs memungkinkan Anda untuk memesan kapasitas EC2 instans (misalnya, instans GPU seperti g5 atau p5) di Availability Zone tertentu selama durasi tertentu, memastikan ketersediaan, bahkan selama permintaan tinggi. ODCRs tidak memiliki komitmen jangka panjang, tetapi Anda membayar tarif On-Demand untuk kapasitas cadangan, baik digunakan atau tidak digunakan. Di EKS, ODCRs didukung oleh tipe node seperti Karpenter dan grup node terkelola. Untuk memprioritaskan ODCRs di Karpenter, konfigurasikan NodeClass untuk menggunakan bidang. capacityReservationSelectorTerms Lihat Dokumentasi Karpenter NodePools .

  • Blok Kapasitas adalah mekanisme reservasi khusus untuk instans GPU (misalnya, p5, p4d) atau Trainium (trn1, trn2), yang dirancang untuk beban kerja MS jangka pendek seperti pelatihan model, fine-tuning, atau eksperimen. Anda memesan kapasitas untuk jangka waktu tertentu (biasanya 24 jam hingga 182 hari) dimulai pada tanggal future, hanya membayar untuk waktu yang dipesan. Mereka pra-bayar, memerlukan pra-perencanaan untuk kebutuhan kapasitas dan tidak mendukung penskalaan otomatis, tetapi mereka ditempatkan untuk jaringan latensi rendah. EC2 UltraClusters Mereka hanya mengenakan biaya untuk periode yang dipesan. Untuk mempelajari selengkapnya, lihat Temukan dan beli Blok Kapasitas, atau mulai dengan menyiapkan grup node terkelola dengan Blok Kapasitas menggunakan instruksi dalam Membuat grup node terkelola dengan Blok Kapasitas untuk ML.

Cadangan kapasitas melalui AWS Management Console dan konfigurasikan node Anda untuk menggunakan blok kapasitas ML. Rencanakan reservasi berdasarkan jadwal beban kerja dan uji dalam klaster pementasan. Lihat Dokumentasi Blok Kapasitas untuk informasi lebih lanjut.

Pertimbangkan Pemesanan Kapasitas Sesuai Permintaan, Amazon EC2 Spot, atau Sesuai Permintaan (ODCRs) untuk instans G Amazon EC2

Untuk EC2 Instans G Amazon, pertimbangkan berbagai opsi pembelian dari On-Demand, Instans EC2 Spot Amazon, dan Reservasi Kapasitas Sesuai Permintaan. ODCRsmemungkinkan Anda untuk memesan kapasitas EC2 instans di Availability Zone tertentu untuk durasi tertentu, memastikan ketersediaan bahkan selama permintaan tinggi. Tidak seperti Blok Kapasitas ML, yang hanya tersedia untuk instans P dan Trainium, ODCRs dapat digunakan untuk berbagai jenis instans yang lebih luas, termasuk instans G, sehingga cocok untuk beban kerja yang memerlukan kemampuan GPU berbeda, seperti inferensi atau grafik. Saat menggunakan Instans EC2 Spot Amazon, dapat beragam di berbagai jenis instans, ukuran, dan zona ketersediaan adalah kunci untuk dapat tetap berada di Spot lebih lama.

ODCRs tidak memiliki komitmen jangka panjang, tetapi Anda membayar tarif On-Demand untuk kapasitas cadangan, baik digunakan atau tidak digunakan. ODCRs dapat dibuat untuk segera digunakan atau dijadwalkan untuk masa depan, memberikan fleksibilitas dalam perencanaan kapasitas. Di Amazon EKS, ODCRs didukung oleh tipe node seperti Karpenter dan grup node terkelola. Untuk memprioritaskan ODCRs di Karpenter, konfigurasikan NodeClass untuk menggunakan bidang. capacityReservationSelectorTerms Lihat Dokumentasi Karpenter NodePools . Untuk informasi selengkapnya tentang pembuatan ODCRs, termasuk perintah CLI, lihat Memulai Reservasi Kapasitas Sesuai Permintaan.

Pertimbangkan jenis dan ukuran instans akselerasi lainnya

Memilih instans dan ukuran akselerasi yang sesuai sangat penting untuk mengoptimalkan kinerja dan biaya dalam beban kerja ML Anda di Amazon EKS. Misalnya, keluarga instans GPU yang berbeda memiliki kinerja dan kemampuan yang berbeda seperti memori GPU. Untuk membantu Anda memilih opsi berkinerja harga paling tinggi, tinjau instans GPU yang tersedia di halaman Jenis Instans di bawah Komputasi EC2 Akselerasi. Evaluasi beberapa jenis dan ukuran instans untuk menemukan yang paling sesuai dengan kebutuhan beban kerja spesifik Anda. Pertimbangkan faktor-faktor seperti jumlah GPUs, memori, dan kinerja jaringan. Dengan hati-hati memilih jenis dan ukuran instans GPU yang tepat, Anda dapat mencapai pemanfaatan sumber daya dan efisiensi biaya yang lebih baik di kluster EKS Anda.

Jika Anda menggunakan instance GPU di node EKS maka nvidia-device-plugin-daemonset pod akan ada di kube-system namespace secara default. Untuk mengetahui dengan cepat apakah Anda sepenuhnya menggunakan GPU dalam instance Anda, Anda dapat menggunakan nvidia-smi seperti yang ditunjukkan di sini:

kubectl exec nvidia-device-plugin-daemonset-xxxxx \ -n kube-system -- nvidia-smi \ --query-gpu=index,power.draw,power.limit,temperature.gpu,utilization.gpu,utilization.memory,memory.free,memory.used \ --format=csv -l 5
  • Jika utilization.memory mendekati 100%, maka kode Anda kemungkinan terikat memori. Ini berarti bahwa GPU (memori) sepenuhnya digunakan tetapi dapat menyarankan bahwa optimasi kinerja lebih lanjut harus diselidiki.

  • Jika mendekati 100%, ini tidak berarti GPU sepenuhnya digunakan. utilization.gpu Metrik yang lebih baik untuk dilihat adalah rasio power.draw topower.limit. Jika rasio ini 100% atau lebih, maka kode Anda sepenuhnya memanfaatkan kapasitas komputasi GPU.

  • -l 5Bendera mengatakan untuk menampilkan metrik setiap 5 detik. Dalam kasus jenis instans GPU tunggal, flag kueri indeks tidak diperlukan.

Untuk mempelajari selengkapnya, lihat instans GPU dalam dokumentasi AWS.

Optimalkan Alokasi Sumber Daya GPU dengan Time-Slicing, MIG, dan Alokasi GPU Fraksional

Batas sumber daya statis di Kubernetes (misalnya, CPU, memori, jumlah GPU) dapat menyebabkan penyediaan berlebih atau kurang dimanfaatkan, terutama untuk beban kerja dinamis seperti inferensi. AI/ML Memilih GPU yang tepat adalah penting. Untuk beban kerja bervolume rendah atau runcing, time-slicing memungkinkan beberapa beban kerja untuk berbagi satu GPU dengan berbagi sumber daya komputasi, berpotensi meningkatkan efisiensi dan mengurangi pemborosan. Berbagi GPU dapat dicapai melalui berbagai opsi:

  • Memanfaatkan Node Selectors/Node affinity untuk mempengaruhi penjadwalan: Pastikan node yang disediakan dan pod dijadwalkan sesuai GPUs untuk beban kerja (mis.,) karpenter.k8s.aws/instance-gpu-name: "a100"

  • Time-Slicing: Menjadwalkan beban kerja untuk berbagi sumber daya komputasi GPU dari waktu ke waktu, memungkinkan eksekusi bersamaan tanpa partisi fisik. Ini sangat ideal untuk beban kerja dengan tuntutan komputasi variabel, tetapi mungkin tidak memiliki isolasi memori.

  • Multi-Instance GPU (MIG): MIG memungkinkan satu GPU NVIDIA untuk dipartisi menjadi beberapa instance yang terisolasi dan didukung dengan NVIDIA Ampere (misalnya, GPU A100), NVIDIA Hopper (misalnya, GPU H100), dan NVIDIA Blackwell (misalnya, Blackwell). GPUs GPUs Setiap instans MIG menerima sumber daya komputasi dan memori khusus, memungkinkan berbagi sumber daya di lingkungan multi-penyewa atau beban kerja yang memerlukan jaminan sumber daya, yang memungkinkan Anda mengoptimalkan pemanfaatan sumber daya GPU, termasuk skenario seperti menyajikan beberapa model dengan ukuran batch berbeda melalui pengiris waktu.

  • Alokasi GPU pecahan: Menggunakan penjadwalan berbasis perangkat lunak untuk mengalokasikan bagian dari komputasi atau memori GPU ke beban kerja, menawarkan fleksibilitas untuk beban kerja dinamis. NVIDIA KAI Scheduler, bagian dari platform Run:AI, memungkinkan pod untuk meminta sumber daya GPU fraksional.

Untuk mengaktifkan fitur-fitur ini di EKS, Anda dapat menerapkan Plugin Perangkat NVIDIA, yang mengekspos GPUs sebagai sumber daya yang dapat dijadwalkan dan mendukung pengiris waktu dan MIG. Untuk mempelajari lebih lanjut, lihat Time-Slicing GPUs di Kubernetes dan berbagi GPU di Amazon EKS dengan instans pengiris waktu dan akselerasi NVIDIA. EC2

Contoh

Misalnya, untuk mengaktifkan pengiris waktu dengan Plugin Perangkat NVIDIA:

apiVersion: v1 kind: ConfigMap metadata: name: nvidia-device-plugin-config namespace: kube-system data: config.yaml: | version: v1 sharing: timeSlicing: resources: - name: nvidia.com/gpu replicas: 4 # Allow 4 pods to share each GPU

Contoh

Misalnya, untuk menggunakan KAI Scheduler untuk alokasi GPU fraksional, terapkan bersama Operator GPU NVIDIA dan tentukan sumber daya GPU fraksional dalam spesifikasi pod:

apiVersion: v1 kind: Pod metadata: name: fractional-gpu-pod-example annotations: gpu-fraction: "0.5" # Annotation for 50% GPU labels: runai/queue: "default" # Required queue assignment spec: containers: - name: ml-workload image: nvcr.io/nvidia/pytorch:25.04-py3 resources: limits: nvidia.com/gpu: 1 nodeSelector: nvidia.com/gpu: "true" schedulerName: kai-scheduler

Ketahanan Node dan Manajemen Job Pelatihan

Menerapkan Pemeriksaan Kesehatan Node dengan Pemulihan Otomatis

Untuk pekerjaan pelatihan terdistribusi di Amazon EKS yang memerlukan komunikasi antar simpul yang sering, seperti pelatihan model multi-GPU di beberapa node, masalah perangkat keras seperti kegagalan GPU atau EFA dapat menyebabkan gangguan pada pekerjaan pelatihan. Gangguan ini dapat menyebabkan hilangnya kemajuan pelatihan dan peningkatan biaya, terutama untuk AI/ML beban kerja jangka panjang yang bergantung pada perangkat keras yang stabil.

Untuk membantu menambah ketahanan terhadap kegagalan perangkat keras, seperti kegagalan GPU di kluster EKS yang menjalankan beban kerja GPU, kami sarankan untuk memanfaatkan Agen Pemantauan Node EKS dengan Perbaikan Otomatis atau Amazon. SageMaker HyperPod Sementara Agen Pemantauan Node EKS dengan Perbaikan Otomatis menyediakan fitur-fitur seperti pemantauan kesehatan node dan perbaikan otomatis menggunakan mekanisme Kubernetes standar, SageMaker HyperPod menawarkan ketahanan yang ditargetkan dan fitur tambahan yang dirancang khusus untuk pelatihan ML skala besar, seperti pemeriksaan kesehatan mendalam dan dimulainya kembali pekerjaan otomatis.

  • Agen Pemantauan Node EKS dengan Perbaikan Otomatis Node terus memantau kesehatan node dengan membaca log dan menerapkan NodeConditions, termasuk kondisi standar seperti Ready dan kondisi khusus untuk perangkat keras yang dipercepat untuk mengidentifikasi masalah seperti GPU atau kegagalan jaringan. Ketika sebuah node dianggap tidak sehat, Node Auto Repair mengikatnya dan menggantinya dengan node baru. Penjadwalan ulang pod dan restart pekerjaan bergantung pada mekanisme Kubernetes standar dan kebijakan restart pekerjaan.

  • Pemeriksaan kesehatan SageMaker HyperPodmendalam dan agen pemantauan kesehatan terus memantau status kesehatan GPU dan instance berbasis Trainium. Ini disesuaikan untuk AI/ML beban kerja, menggunakan label (misalnya, node-health-status) untuk mengelola kesehatan node. Ketika sebuah node dianggap tidak sehat, HyperPod memicu penggantian otomatis perangkat keras yang rusak, seperti. GPUs Ini mendeteksi kegagalan terkait jaringan untuk EFA melalui pemeriksaan kesehatan dasarnya secara default dan mendukung resume otomatis untuk pekerjaan pelatihan yang terputus, memungkinkan pekerjaan untuk melanjutkan dari pos pemeriksaan terakhir, meminimalkan gangguan untuk tugas-tugas ML skala besar.

Untuk Agen Pemantau Node EKS dengan Perbaikan Otomatis dan SageMaker HyperPod cluster yang menggunakan EFA, untuk memantau metrik khusus EFA seperti kesalahan Remote Direct Memory Access (RDMA) dan penurunan paket, pastikan driver AWS EFA diinstal. Selain itu, kami merekomendasikan untuk menggunakan Pengaya CloudWatch Observabilitas atau menggunakan alat seperti Eksportir DCGM dengan Prometheus dan Grafana untuk memantau EFA, GPU, dan, untuk, metrik spesifik yang terkait dengan fitur-fiturnya. SageMaker HyperPod

Nonaktifkan Konsolidasi Karpenter untuk beban kerja sensitif interupsi

Untuk beban kerja yang sensitif terhadap gangguan, seperti pemrosesan, tugas AI/ML prediksi skala besar, atau pelatihan, kami merekomendasikan untuk menyetel kebijakan konsolidasi Karpenter untuk mencegah gangguan selama pelaksanaan pekerjaan. Fitur konsolidasi Karpenter secara otomatis mengoptimalkan biaya cluster dengan menghentikan node yang kurang dimanfaatkan atau menggantinya dengan alternatif yang lebih murah. Namun, bahkan ketika beban kerja sepenuhnya menggunakan GPU, Karpenter dapat mengkonsolidasikan node jika mengidentifikasi jenis instance berukuran tepat dengan harga lebih rendah yang memenuhi persyaratan pod, yang mengarah ke gangguan pekerjaan.

Kebijakan WhenEmptyOrUnderutilized konsolidasi dapat menghentikan node sebelum waktunya, yang mengarah ke waktu eksekusi yang lebih lama. Misalnya, interupsi dapat menunda dimulainya kembali pekerjaan karena penjadwalan ulang pod, pemuatan ulang data, yang bisa mahal untuk pekerjaan inferensi batch yang berjalan lama. Untuk mengurangi ini, Anda dapat mengatur consolidationPolicy ke WhenEmpty dan mengonfigurasi consolidateAfter durasi, seperti 1 jam, untuk mempertahankan node selama lonjakan beban kerja. Misalnya:

disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m

Pendekatan ini meningkatkan latensi startup pod untuk beban kerja inferensi batch runcing dan pekerjaan sensitif interupsi lainnya, seperti pemrosesan data inferensi online real-time atau pelatihan model, di mana biaya interupsi melebihi penghematan biaya komputasi. Anggaran NodePool Gangguan Karpenter adalah fitur lain untuk mengelola gangguan Karpenter. Dengan anggaran, Anda dapat memastikan bahwa tidak lebih dari sejumlah node node akan terganggu pada yang dipilih NodePool pada suatu titik waktu. Anda juga dapat menggunakan anggaran gangguan untuk mencegah semua node terganggu pada waktu tertentu (misalnya jam sibuk). Untuk mempelajari lebih lanjut, lihat dokumentasi Konsolidasi Karpenter.

Gunakan Pekerjaan ttlSecondsAfter Kubernetes Selesai untuk Membersihkan Otomatis

Kami merekomendasikan pengaturan ttlSecondsAfterFinished untuk pekerjaan Kubernetes di Amazon EKS untuk secara otomatis menghapus objek pekerjaan yang sudah selesai. Objek pekerjaan yang tersisa menggunakan sumber daya klaster, seperti memori server API, dan mempersulit pemantauan dengan mengacaukan dasbor (misalnya, Grafana, Amazon). CloudWatch Misalnya, menyetel TTL 1 jam memastikan pekerjaan dihapus segera setelah selesai, menjaga cluster Anda tetap rapi. Untuk detail selengkapnya, lihat Pembersihan Otomatis untuk Pekerjaan Selesai.

Konfigurasikan Preemption Job Prioritas Rendah untuk Pekerjaan/Beban Kerja Prioritas Tinggi

Untuk beban AI/ML kerja prioritas campuran di Amazon EKS, Anda dapat mengonfigurasi preemption pekerjaan dengan prioritas rendah untuk memastikan tugas dengan prioritas lebih tinggi (misalnya, inferensi waktu nyata) menerima sumber daya dengan segera. Tanpa preemption, beban kerja dengan prioritas rendah seperti proses batch (misalnya, inferensi batch, pemrosesan data), layanan non-batch (misalnya, tugas latar belakang, pekerjaan cron), atau pekerjaan intensif CPU/memori (misalnya, layanan web) dapat menunda pod kritis dengan menempati node. Preemption memungkinkan Kubernetes untuk mengusir Pod dengan prioritas rendah ketika Pod dengan prioritas tinggi membutuhkan sumber daya, memastikan alokasi sumber daya yang efisien pada node dengan, atau memori. GPUs CPUs Sebaiknya gunakan Kubernetes PriorityClass untuk menetapkan prioritas dan PodDisruptionBudget mengendalikan perilaku penggusuran.

apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 100 --- spec: priorityClassName: low-priority

Lihat Dokumentasi Prioritas dan Preemption Kubernetes untuk informasi selengkapnya.

Penskalaan dan Kinerja Aplikasi

Sesuaikan Kapasitas Komputasi untuk beban kerja ML dengan Karpenter atau Static Nodes

Untuk memastikan kapasitas komputasi yang hemat biaya dan responsif untuk alur kerja machine learning (ML) di Amazon EKS, sebaiknya sesuaikan strategi penyediaan node Anda dengan karakteristik beban kerja dan komitmen biaya Anda. Di bawah ini adalah dua pendekatan yang perlu dipertimbangkan: just-in-time penskalaan dengan Karpenter dan grup node statis untuk kapasitas cadangan.

  • Just-in-time scaler bidang data seperti Karpenter: Untuk alur kerja HTML dinamis dengan tuntutan komputasi variabel (misalnya, inferensi berbasis GPU diikuti oleh plotting berbasis CPU), kami merekomendasikan penggunaan scaler bidang data seperti Karpenter. just-in-time

  • Gunakan grup simpul statis untuk beban kerja yang dapat diprediksi: Untuk beban kerja HTML kondisi mapan yang dapat diprediksi atau saat menggunakan instans Cadangan, grup node terkelola EKS dapat membantu memastikan kapasitas cadangan sepenuhnya disediakan dan digunakan, memaksimalkan penghematan. Pendekatan ini sangat ideal untuk jenis contoh tertentu yang dilakukan melalui RIs atau ODCRs.

Contoh

Ini adalah contoh dari Karpenter beragam NodePoolyang memungkinkan peluncuran EC2 instance g Amazon di mana pembuatan instance lebih dari tiga.

apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inference spec: template: spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: default requirements: - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] - key: karpenter.k8s.aws/instance-category operator: In values: ["g"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] - key: kubernetes.io/arch operator: In values: ["amd64"] taints: - key: nvidia.com/gpu effect: NoSchedule limits: cpu: "1000" memory: "4000Gi" nvidia.com/gpu: "10" *# Limit the total number of GPUs to 10 for the NodePool* disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m expireAfter: 720h

Contoh

Contoh menggunakan grup node statis untuk beban kerja pelatihan:

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ml-cluster region: us-west-2 managedNodeGroups: - name: gpu-node-group instanceType: p4d.24xlarge minSize: 2 maxSize: 2 desiredCapacity: 2 taints: - key: nvidia.com/gpu effect: NoSchedule

Gunakan taint dan toleransi untuk mencegah beban kerja yang tidak dipercepat dijadwalkan pada instans yang dipercepat

Menjadwalkan beban kerja yang tidak dipercepat pada sumber daya GPU tidak efisien komputasi, kami merekomendasikan penggunaan taint dan toleransi untuk memastikan pod beban kerja yang tidak dipercepat tidak dijadwalkan pada node yang tidak sesuai. Lihat dokumentasi Kubernetes untuk informasi selengkapnya.

Skala Berdasarkan Kinerja Model

Untuk beban kerja inferensi, sebaiknya gunakan Kubernetes Event-Driven Autoscaling (KEDA) untuk menskalakan berdasarkan metrik kinerja model seperti permintaan inferensi atau throughput token, dengan periode cooldown yang sesuai. Kebijakan penskalaan statis dapat menyediakan sumber daya yang berlebihan atau kurang, berdampak pada biaya dan latensi. Pelajari lebih lanjut di Dokumentasi KEDA.

Alokasi sumber daya dinamis untuk manajemen GPU tingkat lanjut

Alokasi sumber daya dinamis (DRA) merupakan kemajuan mendasar dalam manajemen sumber daya GPU Kubernetes. DRA bergerak melampaui batasan plugin perangkat tradisional untuk memungkinkan berbagi GPU yang canggih, kesadaran topologi, dan koordinasi sumber daya lintas simpul. Tersedia di Amazon EKS versi 1.33, DRA mengatasi tantangan kritis dalam AI/ML beban kerja dengan menyediakan hal-hal berikut:

  • Alokasi GPU berbutir halus

  • Mekanisme berbagi tingkat lanjut, seperti Multi-Process service (MPS) dan Multi-Instance GPU (MIG)

  • Dukungan untuk arsitektur perangkat keras generasi berikutnya, termasuk NVIDIA 00 GB2 UltraClusters

Alokasi GPU tradisional diperlakukan GPUs sebagai sumber daya bilangan bulat buram, menciptakan pemanfaatan yang kurang signifikan (seringkali 30-40% dalam cluster produksi). Ini terjadi karena beban kerja menerima akses eksklusif ke seluruh GPUs bahkan ketika hanya membutuhkan sumber daya fraksional. DRA mengubah model ini dengan memperkenalkan alokasi deklaratif terstruktur yang menyediakan penjadwal Kubernetes dengan visibilitas lengkap ke dalam karakteristik perangkat keras dan persyaratan beban kerja. Hal ini memungkinkan keputusan penempatan cerdas dan berbagi sumber daya yang efisien.

Keuntungan menggunakan DRA bukan plugin perangkat NVIDIA

Plugin perangkat NVIDIA (mulai dari versi0.12.0) mendukung mekanisme berbagi GPU termasuk time-slicing, MPS, dan MIG. Namun, ada keterbatasan arsitektur yang ditangani DRA.

Keterbatasan plugin perangkat NVIDIA

  • Konfigurasi statis: Konfigurasi berbagi GPU (replika pengiris waktu dan pengaturan MPS) memerlukan pra-konfigurasi di seluruh klaster. ConfigMaps Ini membuat penyediaan strategi berbagi yang berbeda untuk beban kerja yang berbeda menjadi sulit.

  • Pemilihan granular terbatas: Meskipun plugin perangkat mengekspos karakteristik GPU melalui label node, beban kerja tidak dapat secara dinamis meminta konfigurasi GPU tertentu (ukuran memori dan kemampuan komputasi) sebagai bagian dari keputusan penjadwalan.

  • Tidak ada koordinasi sumber daya lintas simpul: Tidak dapat mengelola sumber daya GPU terdistribusi di beberapa node atau mengekspresikan persyaratan topologi kompleks seperti NVLink domain untuk sistem seperti NVIDIA 00. GB2

  • Batasan penjadwal: Penjadwal Kubernetes memperlakukan sumber daya GPU sebagai bilangan bulat buram, membatasi kemampuannya untuk membuat keputusan sadar topologi atau menangani dependensi sumber daya yang kompleks.

  • Kompleksitas konfigurasi: Menyiapkan strategi berbagi yang berbeda membutuhkan pelabelan node yang banyak ConfigMaps dan hati-hati, menciptakan kompleksitas operasional.

Solusi dengan DRA

  • Pemilihan sumber daya dinamis: DRA memungkinkan beban kerja untuk menentukan persyaratan terperinci (memori GPU, versi driver, dan atribut tertentu) pada saat permintaan selesai. resourceclaims Ini memungkinkan pencocokan sumber daya yang lebih fleksibel.

  • Kesadaran topologi: Melalui parameter terstruktur dan pemilih perangkat, DRA menangani persyaratan kompleks seperti komunikasi GPU lintas simpul dan interkoneksi yang koheren memori.

  • Manajemen sumber daya lintas-node: computeDomains memungkinkan koordinasi sumber daya GPU terdistribusi di beberapa node, penting untuk sistem seperti GB2 00 dengan saluran IMEX.

  • Konfigurasi khusus beban kerja: Masing-masing ResourceClaim menentukan strategi dan konfigurasi berbagi yang berbeda, memungkinkan kontrol berbutir halus per beban kerja daripada pengaturan di seluruh klaster.

  • Integrasi penjadwal yang disempurnakan: DRA menyediakan penjadwal dengan informasi perangkat yang terperinci dan memungkinkan keputusan penempatan yang lebih cerdas berdasarkan topologi perangkat keras dan karakteristik sumber daya.

Penting: DRA tidak menggantikan plugin perangkat NVIDIA sepenuhnya. Driver NVIDIA DRA bekerja bersama plugin perangkat untuk memberikan kemampuan yang ditingkatkan. Plugin perangkat terus menangani penemuan dan manajemen GPU dasar, sementara DRA menambahkan fitur alokasi dan penjadwalan lanjutan.

Instans yang didukung oleh DRA dan fitur-fiturnya

Dukungan DRA bervariasi menurut keluarga EC2 instans Amazon dan arsitektur GPU, seperti yang ditunjukkan pada tabel berikut.

Keluarga instans Jenis GPU Mengiris waktu Dukungan MIG Dukungan MPS Dukungan IMEX Kasus penggunaan

G5

NVIDIA A10G

Ya

Tidak

Ya

Tidak

Beban kerja inferensi dan grafis

G6

NVIDIA L4

Ya

Tidak

Ya

Tidak

Inferensi AI dan pemrosesan video

G6e

NVIDIA L40-AN

Ya

Tidak

Ya

Tidak

Pelatihan, inferensi, dan grafik

P4D/P4DE

NVIDIA A100

Ya

Ya

Ya

Tidak

Pelatihan skala besar dan HPC

P5

NVIDIA H100

Ya

Ya

Ya

Tidak

Pelatihan model pondasi

P6

NVIDIA B200

Ya

Ya

Ya

Tidak

Model miliaran atau triliunan parameter, pelatihan terdistribusi, dan inferensi

P6e

NVIDIA GB2 00

Ya

Ya

Ya

Ya

Model miliaran atau triliunan parameter, pelatihan terdistribusi, dan inferensi

Berikut ini adalah deskripsi dari setiap fitur dalam tabel:

  • Time-slicing: Memungkinkan beberapa beban kerja untuk berbagi sumber daya komputasi GPU dari waktu ke waktu.

  • Multi-Instance GPU (MIG): Partisi tingkat perangkat keras yang membuat instance GPU terisolasi.

  • Multi-Process service (MPS): Memungkinkan eksekusi bersamaan dari beberapa proses CUDA pada satu GPU.

  • Internode Memory Exchange (IMEX): Komunikasi koheren memori di seluruh node untuk 00. GB2 UltraClusters

Sumber daya tambahan

Untuk informasi selengkapnya tentang driver Kubernetes DRA dan NVIDIA DRA, lihat sumber daya berikut di: GitHub

Siapkan alokasi sumber daya dinamis untuk manajemen GPU tingkat lanjut

Topik berikut menunjukkan cara mengatur alokasi sumber daya dinamis (DRA) untuk manajemen GPU tingkat lanjut.

Prasyarat

Sebelum menerapkan DRA di Amazon EKS, pastikan lingkungan Anda memenuhi persyaratan berikut.

Konfigurasi cluster
Komponen yang dibutuhkan
  • Versi plugin perangkat NVIDIA 0.17.1 atau yang lebih baru

  • Versi driver NVIDIA DRA 25.3.0 atau yang lebih baru

Langkah 1: Buat cluster dengan grup node yang mendukung DRA menggunakan eksctl

  1. Buat file konfigurasi cluster bernamadra-eks-cluster.yaml:

    --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dra-eks-cluster region: us-west-2 version: '1.33' managedNodeGroups: - name: gpu-dra-nodes amiFamily: AmazonLinux2023 instanceType: g6.12xlarge desiredCapacity: 2 minSize: 1 maxSize: 3 labels: node-type: "gpu-dra" nvidia.com/gpu.present: "true" taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule
  2. Buat cluster:

    eksctl create cluster -f dra-eks-cluster.yaml

Langkah 2: Menyebarkan plugin perangkat NVIDIA

Terapkan plugin perangkat NVIDIA untuk mengaktifkan penemuan GPU dasar:

  1. Tambahkan repositori Helm plugin perangkat NVIDIA:

    helm repo add nvidia https://nvidia.github.io/k8s-device-plugin helm repo update
  2. Buat nilai khusus untuk plugin perangkat:

    cat <<EOF > nvidia-device-plugin-values.yaml gfd: enabled: true nfd: enabled: true tolerations: - key: [nvidia.com/gpu](http://nvidia.com/gpu) operator: Exists effect: NoSchedule EOF
  3. Instal plug-in perangkat NVIDIA:

    helm install nvidia-device-plugin nvidia/nvidia-device-plugin \ --namespace nvidia-device-plugin \ --create-namespace \ --version v0.17.1 \ --values nvidia-device-plugin-values.yaml

Langkah 3: Menyebarkan bagan Helm driver NVIDIA DRA

  1. Buat file dra-driver-values.yaml nilai untuk driver DRA:

    --- nvidiaDriverRoot: / gpuResourcesEnabledOverride: true resources: gpus: enabled: true computeDomains: enabled: true # Enable for GB200 IMEX support controller: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule kubeletPlugin: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "nvidia.com/gpu.present" operator: In values: ["true"] tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
  2. Tambahkan repositori NVIDIA NGC Helm:

    helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm repo update
  3. Instal driver NVIDIA DRA:

    helm install nvidia-dra-driver nvidia/nvidia-dra-driver-gpu \ --version="25.3.0-rc.2" \ --namespace nvidia-dra-driver \ --create-namespace \ --values dra-driver-values.yaml

Langkah 4: Verifikasi instalasi DRA

  1. Verifikasi bahwa sumber daya DRA API tersedia:

    kubectl api-resources | grep [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1)

    Berikut ini adalah output yang diharapkan:

    deviceclasses [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) false DeviceClass resourceclaims [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) true ResourceClaim resourceclaimtemplates [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) true ResourceClaimTemplate resourceslices [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) false ResourceSlice
  2. Periksa kelas perangkat yang tersedia:

    kubectl get deviceclasses

    Berikut ini adalah contoh output yang diharapkan:

    NAME AGE compute-domain-daemon.nvidia.com 4h39m compute-domain-default-channel.nvidia.com 4h39m gpu.nvidia.com 4h39m mig.nvidia.com 4h39m

    Saat instans GPU G6 yang baru dibuat bergabung dengan cluster Amazon EKS Anda dengan DRA diaktifkan, tindakan berikut akan terjadi:

    • Driver NVIDIA DRA secara otomatis menemukan GPU A10G dan membuat dua resourceslices pada node itu.

    • gpu.nvidia.comSlice mendaftarkan perangkat GPU A10G fisik dengan spesifikasinya (memori, kemampuan komputasi, dan banyak lagi).

    • Karena A10G tidak mendukung partisi MIG, compute-domain.nvidia.com irisan membuat domain komputasi tunggal yang mewakili seluruh konteks komputasi GPU.

    • Ini kemudian resourceslices dipublikasikan ke server API Kubernetes, membuat sumber daya GPU tersedia untuk penjadwalan. resourceclaims

      Penjadwal DRA sekarang dapat dengan cerdas mengalokasikan GPU ini ke Pod yang meminta sumber daya GPU melaluiresourceclaimtemplates, menyediakan manajemen sumber daya yang lebih fleksibel dibandingkan dengan pendekatan plugin perangkat tradisional. Ini terjadi secara otomatis tanpa intervensi manual. Node hanya tersedia untuk beban kerja GPU setelah driver DRA menyelesaikan penemuan sumber daya dan proses pendaftaran.

      Ketika Anda menjalankan perintah berikut:

      kubectl get resourceslices

      Berikut ini adalah contoh output yang diharapkan:

      NAME NODE DRIVER POOL AGE ip-100-64-129-47.ec2.internal-compute-domain.nvidia.com-rwsts ip-100-64-129-47.ec2.internal compute-domain.nvidia.com ip-100-64-129-47.ec2.internal 35m ip-100-64-129-47.ec2.internal-gpu.nvidia.com-6kndg ip-100-64-129-47.ec2.internal gpu.nvidia.com ip-100-64-129-47.ec2.internal 35m

Lanjutkan ke Jadwalkan beban kerja GPU sederhana menggunakan alokasi sumber daya dinamis.

Jadwalkan beban kerja GPU sederhana menggunakan alokasi sumber daya dinamis

Untuk menjadwalkan beban kerja GPU sederhana menggunakan alokasi sumber daya dinamis (DRA), lakukan langkah-langkah berikut. Sebelum melanjutkan, pastikan Anda telah mengikutiSiapkan alokasi sumber daya dinamis untuk manajemen GPU tingkat lanjut.

  1. Buat dasar ResourceClaimTemplate untuk alokasi GPU dengan file bernama: basic-gpu-claim-template.yaml

    --- apiVersion: v1 kind: Namespace metadata: name: gpu-test1 --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: namespace: gpu-test1 name: single-gpu spec: spec: devices: requests: - name: gpu deviceClassName: gpu.nvidia.com
  2. Terapkan template:

    kubectl apply -f basic-gpu-claim-template.yaml
  3. Verifikasi status:

    kubectl get resourceclaimtemplates -n gpu-test1

    Berikut ini adalah output contoh:

    NAME AGE single-gpu 9m16s
  4. Buat Pod yang menggunakan file ResourceClaimTemplate dengan namabasic-gpu-pod.yaml:

    --- apiVersion: v1 kind: Pod metadata: namespace: gpu-test1 name: gpu-pod labels: app: pod spec: containers: - name: ctr0 image: ubuntu:22.04 command: ["bash", "-c"] args: ["nvidia-smi -L; trap 'exit 0' TERM; sleep 9999 & wait"] resources: claims: - name: gpu0 resourceClaims: - name: gpu0 resourceClaimTemplateName: single-gpu nodeSelector: NodeGroupType: gpu-dra nvidia.com/gpu.present: "true" tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule"
  5. Terapkan dan pantau Pod:

    kubectl apply -f basic-gpu-pod.yaml
  6. Periksa status Pod:

    kubectl get pod -n gpu-test1

    Berikut ini adalah contoh output yang diharapkan:

    NAME READY STATUS RESTARTS AGE gpu-pod 1/1 Running 0 13m
  7. Periksa ResourceClaim statusnya:

    kubectl get resourceclaims -n gpu-test1

    Berikut ini adalah contoh output yang diharapkan:

    NAME STATE AGE gpu-pod-gpu0-l76cg allocated,reserved 9m6s
  8. Lihat log Pod untuk melihat informasi GPU:

    kubectl logs gpu-pod -n gpu-test1

    Berikut ini adalah contoh output yang diharapkan:

    GPU 0: NVIDIA L4 (UUID: GPU-da7c24d7-c7e3-ed3b-418c-bcecc32af7c5)

Lanjutkan ke Teknik optimasi GPU dengan alokasi sumber daya dinamis teknik optimasi GPU yang lebih canggih menggunakan DRA.

Teknik optimasi GPU dengan alokasi sumber daya dinamis

Beban kerja GPU modern membutuhkan manajemen sumber daya yang canggih untuk mencapai pemanfaatan dan efisiensi biaya yang optimal. DRA memungkinkan beberapa teknik optimasi canggih yang menangani berbagai kasus penggunaan dan kemampuan perangkat keras:

Teknik-teknik ini secara signifikan dapat meningkatkan pemanfaatan sumber daya. Organizations melaporkan pemanfaatan GPU meningkat dari 30-40% dengan alokasi tradisional menjadi 80-90% dengan strategi berbagi yang dioptimalkan. Pilihan teknik tergantung pada karakteristik beban kerja, persyaratan isolasi, dan kemampuan perangkat keras.

Optimalkan beban kerja GPU dengan pengiris waktu

Time-slicing memungkinkan beberapa beban kerja untuk berbagi sumber daya komputasi GPU dengan menjadwalkannya untuk berjalan secara berurutan pada GPU fisik yang sama. Ini sangat ideal untuk beban kerja inferensi dengan penggunaan GPU sporadis.

Lakukan langkah-langkah berikut.

  1. Tentukan a ResourceClaimTemplate for time-slicing dengan file bernama: timeslicing-claim-template.yaml

    --- apiVersion: v1 kind: Namespace metadata: name: timeslicing-gpu --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: timeslicing-gpu-template namespace: timeslicing-gpu spec: spec: devices: requests: - name: shared-gpu deviceClassName: gpu.nvidia.com config: - requests: ["shared-gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: TimeSlicing
  2. Mendefinisikan sebuah Pod menggunakan time-slicing dengan sebuah file bernama: timeslicing-pod.yaml

    --- # Pod 1 - Inference workload apiVersion: v1 kind: Pod metadata: name: inference-pod-1 namespace: timeslicing-gpu labels: app: gpu-inference spec: restartPolicy: Never containers: - name: inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import time import os print(f"=== POD 1 STARTING ===") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Simulate inference workload for i in range(20): x = torch.randn(1000, 1000).cuda() y = torch.mm(x, x.t()) print(f"Pod 1 - Iteration {i+1} completed at {time.strftime('%H:%M:%S')}") time.sleep(60) else: print("No GPU available!") time.sleep(5) resources: claims: - name: shared-gpu-claim resourceClaims: - name: shared-gpu-claim resourceClaimTemplateName: timeslicing-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule --- # Pod 2 - Training workload apiVersion: v1 kind: Pod metadata: name: training-pod-2 namespace: timeslicing-gpu labels: app: gpu-training spec: restartPolicy: Never containers: - name: training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import time import os print(f"=== POD 2 STARTING ===") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Simulate training workload with heavier compute for i in range(15): x = torch.randn(2000, 2000).cuda() y = torch.mm(x, x.t()) loss = torch.sum(y) print(f"Pod 2 - Training step {i+1}, Loss: {loss.item():.2f} at {time.strftime('%H:%M:%S')}") time.sleep(5) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim-2 resourceClaims: - name: shared-gpu-claim-2 resourceClaimTemplateName: timeslicing-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
  3. Terapkan template dan Pod:

    kubectl apply -f timeslicing-claim-template.yaml kubectl apply -f timeslicing-pod.yaml
  4. Pantau klaim sumber daya:

    kubectl get resourceclaims -n timeslicing-gpu -w

    Berikut ini adalah output contoh:

    NAME STATE AGE inference-pod-1-shared-gpu-claim-9p97x allocated,reserved 21s training-pod-2-shared-gpu-claim-2-qghnb pending 21s inference-pod-1-shared-gpu-claim-9p97x pending 105s training-pod-2-shared-gpu-claim-2-qghnb pending 105s inference-pod-1-shared-gpu-claim-9p97x pending 105s training-pod-2-shared-gpu-claim-2-qghnb allocated,reserved 105s inference-pod-1-shared-gpu-claim-9p97x pending 105s

Pod Pertama (inference-pod-1)

  • Negara: allocated,reserved

  • Artinya: DRA menemukan GPU yang tersedia dan memesannya untuk Pod ini

  • Status pod: Mulai berjalan segera

Pod Kedua (training-pod-2)

  • Negara: pending

  • Artinya: Menunggu DRA mengonfigurasi pengiris waktu pada GPU yang sama

  • Status pod: Menunggu untuk dijadwalkan

  • Negara akan beralih dari pending allocated,reserved ke running

Optimalkan beban kerja GPU dengan MPS

Multi-Process Service (MPS) memungkinkan eksekusi bersamaan dari beberapa konteks CUDA pada satu GPU dengan isolasi yang lebih baik daripada time-slicing.

Lakukan langkah-langkah berikut.

  1. Tentukan ResourceClaimTemplate untuk MPS dengan file bernamamps-claim-template.yaml:

    --- apiVersion: v1 kind: Namespace metadata: name: mps-gpu --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mps-gpu-template namespace: mps-gpu spec: spec: devices: requests: - name: shared-gpu deviceClassName: gpu.nvidia.com config: - requests: ["shared-gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: MPS
  2. Mendefinisikan Pod menggunakan MPS dengan file bernamamps-pod.yaml:

    --- # Single Pod with Multiple Containers sharing GPU via MPS apiVersion: v1 kind: Pod metadata: name: mps-multi-container-pod namespace: mps-gpu labels: app: mps-demo spec: restartPolicy: Never containers: # Container 1 - Inference workload - name: inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import torch.nn as nn import time import os print(f"=== INFERENCE CONTAINER STARTING ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Create inference model model = nn.Sequential( nn.Linear(1000, 500), nn.ReLU(), nn.Linear(500, 100) ).cuda() # Run inference for i in range(1, 999999): with torch.no_grad(): x = torch.randn(128, 1000).cuda() output = model(x) result = torch.sum(output) print(f"Inference Container PID {os.getpid()}: Batch {i}, Result: {result.item():.2f} at {time.strftime('%H:%M:%S')}") time.sleep(2) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim request: shared-gpu # Container 2 - Training workload - name: training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import torch.nn as nn import time import os print(f"=== TRAINING CONTAINER STARTING ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Create training model model = nn.Sequential( nn.Linear(2000, 1000), nn.ReLU(), nn.Linear(1000, 500), nn.ReLU(), nn.Linear(500, 10) ).cuda() criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # Run training for epoch in range(1, 999999): x = torch.randn(64, 2000).cuda() target = torch.randn(64, 10).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, target) loss.backward() optimizer.step() print(f"Training Container PID {os.getpid()}: Epoch {epoch}, Loss: {loss.item():.4f} at {time.strftime('%H:%M:%S')}") time.sleep(3) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim request: shared-gpu resourceClaims: - name: shared-gpu-claim resourceClaimTemplateName: mps-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
  3. Terapkan template dan buat beberapa MPS Pod:

    kubectl apply -f mps-claim-template.yaml kubectl apply -f mps-pod.yaml
  4. Pantau klaim sumber daya:

    kubectl get resourceclaims -n mps-gpu -w

    Berikut ini adalah output contoh:

    NAME STATE AGE mps-multi-container-pod-shared-gpu-claim-2p9kx allocated,reserved 86s

Konfigurasi ini menunjukkan berbagi GPU sejati menggunakan NVIDIA Multi-Process Service (MPS) melalui alokasi sumber daya dinamis (DRA). Tidak seperti time-slicing di mana beban kerja bergiliran menggunakan GPU secara berurutan, MPS memungkinkan kedua kontainer berjalan secara bersamaan pada GPU fisik yang sama. Insight kuncinya adalah bahwa berbagi MPS DRA membutuhkan beberapa kontainer dalam satu Pod, bukan beberapa Pod terpisah. Ketika di-deploy, driver DRA mengalokasikan satu ResourceClaim ke Pod dan secara otomatis mengkonfigurasi MPS untuk memungkinkan kedua kontainer inferensi dan pelatihan untuk mengeksekusi secara bersamaan.

Setiap kontainer mendapatkan ruang memori GPU yang terisolasi dan sumber daya komputasi, dengan daemon MPS mengoordinasikan akses ke perangkat keras yang mendasarinya. Anda dapat memverifikasi bahwa ini berfungsi dengan melakukan hal berikut:

  • Memeriksanvidia-smi, yang akan menampilkan kedua kontainer sebagai proses M+C (MPS + Compute) berbagi perangkat GPU yang sama.

  • Memantau log dari kedua kontainer, yang akan menampilkan stempel waktu yang disisipkan yang membuktikan eksekusi simultan.

Pendekatan ini memaksimalkan pemanfaatan GPU dengan memungkinkan beban kerja pelengkap untuk berbagi perangkat keras GPU yang mahal secara efisien, daripada membiarkannya kurang dimanfaatkan oleh satu proses.

Kontainer1: inference-container
root@mps-multi-container-pod:/workspace# nvidia-smi Wed Jul 16 21:09:30 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.9 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA L4 On | 00000000:35:00.0 Off | 0 | | N/A 48C P0 28W / 72W | 597MiB / 23034MiB | 0% E. Process | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 1 M+C python 246MiB | +-----------------------------------------------------------------------------------------+
Kontainer2: training-container
root@mps-multi-container-pod:/workspace# nvidia-smi Wed Jul 16 21:16:00 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.9 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA L4 On | 00000000:35:00.0 Off | 0 | | N/A 51C P0 28W / 72W | 597MiB / 23034MiB | 0% E. Process | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 1 M+C python 314MiB | +-----------------------------------------------------------------------------------------+

Optimalkan beban kerja GPU dengan GPU Multi-Instance

Multi-instance GPU (MIG) menyediakan partisi tingkat perangkat keras, membuat instance GPU terisolasi dengan sumber daya komputasi dan memori khusus.

Menggunakan partisi MIG dinamis dengan berbagai profil memerlukan Operator GPU NVIDIA. Operator GPU NVIDIA menggunakan MIG Manager untuk membuat profil MIG dan me-reboot instance GPU seperti P4D, P4De, P5, P6, dan lainnya untuk menerapkan perubahan konfigurasi. Operator GPU mencakup kemampuan manajemen MIG yang komprehensif melalui komponen MIG Manager, yang mengawasi perubahan label node dan secara otomatis menerapkan konfigurasi MIG yang sesuai. Ketika perubahan profil MIG diminta, operator dengan anggun mematikan semua klien GPU, menerapkan geometri partisi baru, dan memulai ulang layanan yang terpengaruh. Proses ini memerlukan reboot node untuk instance GPU untuk memastikan transisi status GPU yang bersih. Inilah sebabnya mengapa mengaktifkan WITH–0—REBOOT=true konfigurasi MIG Manager sangat penting untuk penerapan MIG yang sukses.

Anda memerlukan Driver NVIDIA DRA dan Operator GPU NVIDIA untuk bekerja dengan MIG di Amazon EKS. Anda tidak memerlukan Plugin Perangkat NVIDIA dan Eksportir DCGM selain ini karena ini adalah bagian dari Operator GPU NVIDIA. Karena EKS NVIDIA AMIs datang dengan Driver NVIDIA yang sudah diinstal sebelumnya, kami menonaktifkan penyebaran driver oleh Operator GPU untuk menghindari konflik dan memanfaatkan driver yang dioptimalkan yang sudah ada pada instance. Driver NVIDIA DRA menangani alokasi sumber daya dinamis untuk instans MIG, sementara Operator GPU mengelola seluruh siklus hidup GPU. Ini termasuk konfigurasi MIG, fungsionalitas plugin perangkat, pemantauan melalui DCGM, dan penemuan fitur node. Pendekatan terintegrasi ini memberikan solusi lengkap untuk manajemen GPU perusahaan, dengan isolasi tingkat perangkat keras dan kemampuan alokasi sumber daya dinamis.

Langkah 1: Menyebarkan Operator GPU NVIDIA
  1. Tambahkan repositori Operator GPU NVIDIA:

    helm repo add nvidia https://nvidia.github.io/gpu-operator helm repo update
  2. Buat gpu-operator-values.yaml file:

    driver: enabled: false mig: strategy: mixed migManager: enabled: true env: - name: WITH_REBOOT value: "true" config: create: true name: custom-mig-parted-configs default: "all-disabled" data: config.yaml: |- version: v1 mig-configs: all-disabled: - devices: all mig-enabled: false # P4D profiles (A100 40GB) p4d-half-balanced: - devices: [0, 1, 2, 3] mig-enabled: true mig-devices: "1g.5gb": 2 "2g.10gb": 1 "3g.20gb": 1 - devices: [4, 5, 6, 7] mig-enabled: false # P4DE profiles (A100 80GB) p4de-half-balanced: - devices: [0, 1, 2, 3] mig-enabled: true mig-devices: "1g.10gb": 2 "2g.20gb": 1 "3g.40gb": 1 - devices: [4, 5, 6, 7] mig-enabled: false devicePlugin: enabled: true config: name: "" create: false default: "" toolkit: enabled: true nfd: enabled: true gfd: enabled: true dcgmExporter: enabled: true serviceMonitor: enabled: true interval: 15s honorLabels: false additionalLabels: release: kube-prometheus-stack nodeStatusExporter: enabled: false operator: defaultRuntime: containerd runtimeClass: nvidia resources: limits: cpu: 500m memory: 350Mi requests: cpu: 200m memory: 100Mi daemonsets: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" nodeSelector: accelerator: nvidia priorityClassName: system-node-critical
  3. Instal GPU Operator menggunakan gpu-operator-values.yaml file:

    helm install gpu-operator nvidia/gpu-operator \ --namespace gpu-operator \ --create-namespace \ --version v25.3.1 \ --values gpu-operator-values.yaml

    Bagan Helm ini menyebarkan komponen berikut dan beberapa profil MIG:

    • Plugin Perangkat (penjadwalan sumber daya GPU)

    • Eksportir DCGM (metrik dan pemantauan GPU)

    • Penemuan Fitur Node (NFD - pelabelan perangkat keras)

    • Penemuan Fitur GPU (GFD - pelabelan khusus GPU)

    • Manajer MIG (partisi GPU multi-instance)

    • Toolkit Kontainer (runtime kontainer GPU)

    • Operator Controller (manajemen siklus hidup)

  4. Verifikasi Pod penerapan:

    kubectl get pods -n gpu-operator

    Berikut ini adalah output contoh:

    NAME READY STATUS RESTARTS AGE gpu-feature-discovery-27rdq 1/1 Running 0 3h31m gpu-operator-555774698d-48brn 1/1 Running 0 4h8m nvidia-container-toolkit-daemonset-sxmh9 1/1 Running 1 (3h32m ago) 4h1m nvidia-cuda-validator-qb77g 0/1 Completed 0 3h31m nvidia-dcgm-exporter-cvzd7 1/1 Running 0 3h31m nvidia-device-plugin-daemonset-5ljm5 1/1 Running 0 3h31m nvidia-gpu-operator-node-feature-discovery-gc-67f66fc557-q5wkt 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-master-5d8ffddcsl6s6 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-worker-6t4w7 1/1 Running 1 (3h32m ago) 4h1m nvidia-gpu-operator-node-feature-discovery-worker-9w7g8 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-worker-k5fgs 1/1 Running 0 4h8m nvidia-mig-manager-zvf54 1/1 Running 1 (3h32m ago) 3h35m
  5. Buat klaster Amazon EKS dengan grup node terkelola P4DE untuk menguji contoh MIG:

    apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dra-eks-cluster region: us-east-1 version: '1.33' managedNodeGroups: # P4DE MIG Node Group with Capacity Block Reservation - name: p4de-mig-nodes amiFamily: AmazonLinux2023 instanceType: p4de.24xlarge # Capacity settings desiredCapacity: 0 minSize: 0 maxSize: 1 # Use specific subnet in us-east-1b for capacity reservation subnets: - us-east-1b # AL2023 NodeConfig for RAID0 local storage only nodeadmConfig: apiVersion: node.eks.aws/v1alpha1 kind: NodeConfig spec: instance: localStorage: strategy: RAID0 # Node labels for MIG configuration labels: nvidia.com/gpu.present: "true" nvidia.com/gpu.product: "A100-SXM4-80GB" nvidia.com/mig.config: "p4de-half-balanced" node-type: "p4de" vpc.amazonaws.com/efa.present: "true" accelerator: "nvidia" # Node taints taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule # EFA support efaEnabled: true # Placement group for high-performance networking placementGroup: groupName: p4de-placement-group strategy: cluster # Capacity Block Reservation (CBR) # Ensure CBR ID matches the subnet AZ with the Nodegroup subnet spot: false capacityReservation: capacityReservationTarget: capacityReservationId: "cr-abcdefghij" # Replace with your capacity reservation ID

    NVIDIA GPU Operator menggunakan label ditambahkan ke node nvidia.com/mig.config: "p4de-half-balanced" dan partisi GPU dengan profil yang diberikan.

  6. Login ke p4de instance.

  7. Jalankan perintah berikut:

    nvidia-smi -L

    Anda akan melihat contoh output berikut:

    [root@ip-100-64-173-145 bin]# nvidia-smi -L GPU 0: NVIDIA A100-SXM4-80GB (UUID: GPU-ab52e33c-be48-38f2-119e-b62b9935925a) MIG 3g.40gb Device 0: (UUID: MIG-da972af8-a20a-5f51-849f-bc0439f7970e) MIG 2g.20gb Device 1: (UUID: MIG-7f9768b7-11a6-5de9-a8aa-e9c424400da4) MIG 1g.10gb Device 2: (UUID: MIG-498adad6-6cf7-53af-9d1a-10cfd1fa53b2) MIG 1g.10gb Device 3: (UUID: MIG-3f55ef65-1991-571a-ac50-0dbf50d80c5a) GPU 1: NVIDIA A100-SXM4-80GB (UUID: GPU-0eabeccc-7498-c282-0ac7-d3c09f6af0c8) MIG 3g.40gb Device 0: (UUID: MIG-80543849-ea3b-595b-b162-847568fe6e0e) MIG 2g.20gb Device 1: (UUID: MIG-3af1958f-fac4-59f1-8477-9f8d08c55029) MIG 1g.10gb Device 2: (UUID: MIG-401088d2-716f-527b-a970-b1fc7a4ac6b2) MIG 1g.10gb Device 3: (UUID: MIG-8c56c75e-5141-501c-8f43-8cf22f422569) GPU 2: NVIDIA A100-SXM4-80GB (UUID: GPU-1c7a1289-243f-7872-a35c-1d2d8af22dd0) MIG 3g.40gb Device 0: (UUID: MIG-e9b44486-09fc-591a-b904-0d378caf2276) MIG 2g.20gb Device 1: (UUID: MIG-ded93941-9f64-56a3-a9b1-a129c6edf6e4) MIG 1g.10gb Device 2: (UUID: MIG-6c317d83-a078-5c25-9fa3-c8308b379aa1) MIG 1g.10gb Device 3: (UUID: MIG-2b070d39-d4e9-5b11-bda6-e903372e3d08) GPU 3: NVIDIA A100-SXM4-80GB (UUID: GPU-9a6250e2-5c59-10b7-2da8-b61d8a937233) MIG 3g.40gb Device 0: (UUID: MIG-20e3cd87-7a57-5f1b-82e7-97b14ab1a5aa) MIG 2g.20gb Device 1: (UUID: MIG-04430354-1575-5b42-95f4-bda6901f1ace) MIG 1g.10gb Device 2: (UUID: MIG-d62ec8b6-e097-5e99-a60c-abf8eb906f91) MIG 1g.10gb Device 3: (UUID: MIG-fce20069-2baa-5dd4-988a-cead08348ada) GPU 4: NVIDIA A100-SXM4-80GB (UUID: GPU-5d09daf0-c2eb-75fd-3919-7ad8fafa5f86) GPU 5: NVIDIA A100-SXM4-80GB (UUID: GPU-99194e04-ab2a-b519-4793-81cb2e8e9179) GPU 6: NVIDIA A100-SXM4-80GB (UUID: GPU-c1a1910f-465a-e16f-5af1-c6aafe499cd6) GPU 7: NVIDIA A100-SXM4-80GB (UUID: GPU-c2cfafbc-fd6e-2679-e955-2a9e09377f78)

Operator GPU NVIDIA telah berhasil menerapkan profil p4de-half-balanced MIG ke instans P4DE Anda, membuat partisi GPU tingkat perangkat keras seperti yang dikonfigurasi. Begini cara kerja partisi:

Operator GPU menerapkan konfigurasi ini dari profil MIG yang disematkan:

p4de-half-balanced: - devices: [0, 1, 2, 3] # First 4 GPUs: MIG enabled mig-enabled: true mig-devices: "1g.10gb": 2 # 2x small instances (10GB each) "2g.20gb": 1 # 1x medium instance (20GB) "3g.40gb": 1 # 1x large instance (40GB) - devices: [4, 5, 6, 7] # Last 4 GPUs: Full GPUs mig-enabled: false

Dari nvidia-smi -L output Anda, inilah yang dibuat oleh Operator GPU:

  • MiG-enabled GPUs (0-3): perangkat keras dipartisi

    • GPU 0: NVIDIA A100- -80GB SXM4

      • MIG 3g.40gb Perangkat 0 - Beban kerja besar (memori 40GB, 42) SMs

      • MIG 2g.20gb Perangkat 1 - Beban kerja sedang (memori 20GB, 28) SMs

      • MIG 1g.10gb Perangkat 2 - Beban kerja kecil (memori 10GB, 14) SMs

      • MIG 1g.10gb Perangkat 3 - Beban kerja kecil (memori 10GB, 14) SMs

    • GPU 1: NVIDIA A100- -80GB SXM4

      • MIG 3g.40gb Perangkat 0 - Tata letak partisi identik

      • Perangkat MIG 2g.20gb 1

      • Perangkat MIG 1g.10gb 2

      • Perangkat MIG 1g.10gb 3

    • GPU 2 dan GPU 3 — Pola yang sama dengan GPU 0 dan GPU 1

  • Penuh GPUs (4-7): Tidak ada partisi MIG

    • GPU 4: NVIDIA A100- SXM4 -80GB - GPU 80GB Penuh

    • GPU 5: NVIDIA A100- SXM4 -80GB - GPU 80GB Penuh

    • GPU 6: NVIDIA A100- SXM4 -80GB - GPU 80GB Penuh

    • GPU 7: NVIDIA A100- SXM4 -80GB - GPU 80GB Penuh

Setelah Operator GPU NVIDIA membuat partisi MIG, Driver NVIDIA DRA secara otomatis mendeteksi instans terisolasi perangkat keras ini dan membuatnya tersedia untuk alokasi sumber daya dinamis di Kubernetes. Driver DRA menemukan setiap instance MIG dengan profil spesifiknya (1g.10gb, 2g.20gb, 3g.40gb) dan mengeksposnya sebagai sumber daya yang dapat dijadwalkan melalui kelas perangkat. mig.nvidia.com

Driver DRA terus memantau topologi MIG dan memelihara inventaris instance yang tersedia di semua. GPUs Ketika Pod meminta profil MIG tertentu melalui aResourceClaimTemplate, driver DRA secara cerdas memilih instance MIG yang sesuai dari GPU yang tersedia, memungkinkan multi-tenancy tingkat perangkat keras yang sebenarnya. Alokasi dinamis ini memungkinkan beberapa beban kerja yang terisolasi berjalan secara bersamaan pada GPU fisik yang sama sambil mempertahankan batasan sumber daya yang ketat dan jaminan kinerja.

Langkah 2: Uji alokasi sumber daya MIG

Sekarang mari kita jalankan beberapa contoh untuk menunjukkan bagaimana DRA secara dinamis mengalokasikan instance MIG ke beban kerja yang berbeda. Terapkan resourceclaimtemplates dan uji pod untuk melihat bagaimana driver DRA menempatkan beban kerja di seluruh partisi MIG yang tersedia, memungkinkan beberapa kontainer untuk berbagi sumber daya GPU dengan isolasi tingkat perangkat keras.

  1. Buat mig-claim-template.yaml untuk memuat MIGresourceclaimtemplates:

    apiVersion: v1 kind: Namespace metadata: name: mig-gpu --- # Template for 3g.40gb MIG instance (Large training) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-large-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-large deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '3g.40gb' --- # Template for 2g.20gb MIG instance (Medium training) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-medium-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-medium deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '2g.20gb' --- # Template for 1g.10gb MIG instance (Small inference) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-small-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-small deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '1g.10gb'
  2. Terapkan tiga templat:

    kubectl apply -f mig-claim-template.yaml
  3. Jalankan perintah berikut:

    kubectl get resourceclaimtemplates -n mig-gpu

    Berikut ini adalah output contoh:

    NAME AGE mig-large-template 71m mig-medium-template 71m mig-small-template 71m
  4. Buat mig-pod.yaml untuk menjadwalkan beberapa pekerjaan untuk memanfaatkan iniresourceclaimtemplates:

    --- # ConfigMap containing Python scripts for MIG pods apiVersion: v1 kind: ConfigMap metadata: name: mig-scripts-configmap namespace: mig-gpu data: large-training-script.py: | import torch import torch.nn as nn import torch.optim as optim import time import os print(f"=== LARGE TRAINING POD (3g.40gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Large model for 3g.40gb instance model = nn.Sequential( nn.Linear(2048, 1024), nn.ReLU(), nn.Linear(1024, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() optimizer = optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Training loop for epoch in range(100): # Large batch for 3g.40gb x = torch.randn(256, 2048).cuda() y = torch.randint(0, 10, (256,)).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Large Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(3) print("Large training completed on 3g.40gb MIG instance") medium-training-script.py: | import torch import torch.nn as nn import torch.optim as optim import time import os print(f"=== MEDIUM TRAINING POD (2g.20gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Medium model for 2g.20gb instance model = nn.Sequential( nn.Linear(1024, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() optimizer = optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Training loop for epoch in range(100): # Medium batch for 2g.20gb x = torch.randn(128, 1024).cuda() y = torch.randint(0, 10, (128,)).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Medium Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(4) print("Medium training completed on 2g.20gb MIG instance") small-inference-script.py: | import torch import torch.nn as nn import time import os print(f"=== SMALL INFERENCE POD (1g.10gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Small model for 1g.10gb instance model = nn.Sequential( nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Inference loop for i in range(200): with torch.no_grad(): # Small batch for 1g.10gb x = torch.randn(32, 512).cuda() output = model(x) prediction = torch.argmax(output, dim=1) if i % 20 == 0: print(f"Small Inference - Batch {i}, Predictions: {prediction[:5].tolist()}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(2) print("Small inference completed on 1g.10gb MIG instance") --- # Pod 1: Large training workload (3g.40gb) apiVersion: v1 kind: Pod metadata: name: mig-large-training-pod namespace: mig-gpu labels: app: mig-large-training workload-type: training spec: restartPolicy: Never containers: - name: large-training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/large-training-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-large-claim resourceClaims: - name: mig-large-claim resourceClaimTemplateName: mig-large-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 --- # Pod 2: Medium training workload (2g.20gb) - can run on SAME GPU as Pod 1 apiVersion: v1 kind: Pod metadata: name: mig-medium-training-pod namespace: mig-gpu labels: app: mig-medium-training workload-type: training spec: restartPolicy: Never containers: - name: medium-training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/medium-training-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-medium-claim resourceClaims: - name: mig-medium-claim resourceClaimTemplateName: mig-medium-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 --- # Pod 3: Small inference workload (1g.10gb) - can run on SAME GPU as Pod 1 & 2 apiVersion: v1 kind: Pod metadata: name: mig-small-inference-pod namespace: mig-gpu labels: app: mig-small-inference workload-type: inference spec: restartPolicy: Never containers: - name: small-inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/small-inference-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-small-claim resourceClaims: - name: mig-small-claim resourceClaimTemplateName: mig-small-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755
  5. Terapkan spesifikasi ini, yang seharusnya menyebarkan tiga Pod:

    kubctl apply -f mig-pod.yaml

    Pod ini harus dijadwalkan oleh driver DRA.

  6. Periksa log DRA driver Pod dan Anda akan melihat output yang mirip dengan ini:

    I0717 21:50:22.925811 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:22.932499 1 driver.go:129] Returning newly prepared devices for claim '933e9c72-6fd6-49c5-933c-a896407dc6d1': [&Device{RequestNames:[mig-large],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-0-mig-9-4-4,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-0-mig-9-4-4**],}] I0717 21:50:23.186472 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:23.191226 1 driver.go:129] Returning newly prepared devices for claim '61e5ddd2-8c2e-4c19-93ae-d317fecb44a4': [&Device{RequestNames:[mig-medium],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-2-mig-14-0-2,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-2-mig-14-0-2**],}] I0717 21:50:23.450024 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:23.455991 1 driver.go:129] Returning newly prepared devices for claim '1eda9b2c-2ea6-401e-96d0-90e9b3c111b5': [&Device{RequestNames:[mig-small],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-1-mig-19-2-1,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-1-mig-19-2-1**],}]
  7. Verifikasi resourceclaims untuk melihat status Pod:

    kubectl get resourceclaims -n mig-gpu -w

    Berikut ini adalah output contoh:

    NAME STATE AGE mig-large-training-pod-mig-large-claim-6dpn8 pending 0s mig-large-training-pod-mig-large-claim-6dpn8 pending 0s mig-large-training-pod-mig-large-claim-6dpn8 allocated,reserved 0s mig-medium-training-pod-mig-medium-claim-bk596 pending 0s mig-medium-training-pod-mig-medium-claim-bk596 pending 0s mig-medium-training-pod-mig-medium-claim-bk596 allocated,reserved 0s mig-small-inference-pod-mig-small-claim-d2t58 pending 0s mig-small-inference-pod-mig-small-claim-d2t58 pending 0s mig-small-inference-pod-mig-small-claim-d2t58 allocated,reserved 0s

    Seperti yang Anda lihat, semua Pod dipindahkan dari pending ke allocated,reserved driver DRA.

  8. Jalankan nvidia-smi dari node. Anda akan melihat tiga prosesor Python sedang berjalan:

    root@ip-100-64-173-145 bin]# nvidia-smi +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.8 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA A100-SXM4-80GB On | 00000000:10:1C.0 Off | On | | N/A 63C P0 127W / 400W | 569MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA A100-SXM4-80GB On | 00000000:10:1D.0 Off | On | | N/A 56C P0 121W / 400W | 374MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 2 NVIDIA A100-SXM4-80GB On | 00000000:20:1C.0 Off | On | | N/A 63C P0 128W / 400W | 467MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 3 NVIDIA A100-SXM4-80GB On | 00000000:20:1D.0 Off | On | | N/A 57C P0 118W / 400W | 249MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 4 NVIDIA A100-SXM4-80GB On | 00000000:90:1C.0 Off | 0 | | N/A 51C P0 77W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 5 NVIDIA A100-SXM4-80GB On | 00000000:90:1D.0 Off | 0 | | N/A 46C P0 69W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 6 NVIDIA A100-SXM4-80GB On | 00000000:A0:1C.0 Off | 0 | | N/A 52C P0 74W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 7 NVIDIA A100-SXM4-80GB On | 00000000:A0:1D.0 Off | 0 | | N/A 47C P0 72W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | MIG devices: | +------------------+----------------------------------+-----------+-----------------------+ | GPU GI CI MIG | Memory-Usage | Vol| Shared | | ID ID Dev | BAR1-Usage | SM Unc| CE ENC DEC OFA JPG | | | | ECC| | |==================+==================================+===========+=======================| | 0 2 0 0 | 428MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 2MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 3 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 9 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 10 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 13 0 2 | 161MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 2MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 5 0 1 | 289MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 2MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| **| 0 2 0 64080 C python 312MiB | | 1 13 0 64085 C python 118MiB | | 2 5 0 64073 C python 210MiB |** +-----------------------------------------------------------------------------------------+

Optimalkan beban kerja GPU dengan IMEX menggunakan GB2 instans 00 P6e

IMEX (Internode Memory Exchange) memungkinkan komunikasi yang koheren memori di seluruh node untuk pelatihan terdistribusi di NVIDIA 00. GB2 UltraClusters

Lakukan langkah-langkah berikut.

  1. Tentukan pelatihan ComputeDomain untuk multi-node dengan file bernamaimex-compute-domain.yaml:

    apiVersion: resource.nvidia.com/v1beta1 kind: ComputeDomain metadata: name: distributed-training-domain namespace: default spec: numNodes: 2 channel: resourceClaimTemplate: name: imex-channel-template
  2. Mendefinisikan Pod menggunakan saluran IMEX dengan file bernamaimex-pod.yaml:

    apiVersion: v1 kind: Pod metadata: name: imex-distributed-training namespace: default labels: app: imex-training spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: nvidia.com/gpu.clique operator: Exists containers: - name: distributed-training image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["bash", "-c"] args: - | echo "=== IMEX Channel Verification ===" ls -la /dev/nvidia-caps-imex-channels/ echo "" echo "=== GPU Information ===" nvidia-smi echo "" echo "=== NCCL Test (if available) ===" python -c " import torch import torch.distributed as dist import os print(f'CUDA available: {torch.cuda.is_available()}') print(f'CUDA device count: {torch.cuda.device_count()}') if torch.cuda.is_available(): for i in range(torch.cuda.device_count()): print(f'GPU {i}: {torch.cuda.get_device_name(i)}') # Check for IMEX environment variables imex_vars = [k for k in os.environ.keys() if 'IMEX' in k or 'NVLINK' in k] if imex_vars: print('IMEX Environment Variables:') for var in imex_vars: print(f' {var}={os.environ[var]}') print('IMEX channel verification completed') " # Keep container running for inspection sleep 3600 resources: claims: - name: imex-channel-0 - name: imex-channel-1 resourceClaims: - name: imex-channel-0 resourceClaimTemplateName: imex-channel-template - name: imex-channel-1 resourceClaimTemplateName: imex-channel-template tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
    catatan

    Ini membutuhkan instance P6e GB2 00.

  3. Menyebarkan IMEX dengan menerapkan ComputeDomain dan template:

    kubectl apply -f imex-claim-template.yaml kubectl apply -f imex-compute-domain.yaml kubectl apply -f imex-pod.yaml
  4. Periksa ComputeDomain statusnya.

    kubectl get computedomain distributed-training-domain
  5. Pantau penyebaran daemon IMEX.

    kubectl get pods -n nvidia-dra-driver -l [resource.nvidia.com/computeDomain](http://resource.nvidia.com/computeDomain)
  6. Periksa saluran IMEX di Pod:

    kubectl exec imex-distributed-training -- ls -la /dev/nvidia-caps-imex-channels/
  7. Lihat log Pod:

    kubectl logs imex-distributed-training

    Berikut ini adalah contoh output yang diharapkan:

    === IMEX Channel Verification === total 0 drwxr-xr-x. 2 root root 80 Jul 8 10:45 . drwxr-xr-x. 6 root root 380 Jul 8 10:45 .. crw-rw-rw-. 1 root root 241, 0 Jul 8 10:45 channel0 crw-rw-rw-. 1 root root 241, 1 Jul 8 10:45 channel1

Untuk informasi selengkapnya, lihat contoh NVIDIA di GitHub.