NVIDIA MPS를 사용하여 여러 워크로드와 GPU 공유


이 페이지에서는 CUDA Multi-Process Service(MPS)를 사용하여 여러 워크로드가 Google Kubernetes Engine(GKE) 노드에서 단일 NVIDIA GPU 하드웨어 가속기를 공유하도록 허용하는 방법을 보여줍니다.

개요

NVIDIA MPS는 여러 컨테이너가 노드에 연결된 단일 물리적 NVIDIA GPU 하드웨어를 공유하도록 허용하는 GPU 공유 솔루션입니다.

NVIDIA MPS는 CUDA에서 NVIDIA MPS(Multi-Process Service를 사용합니다. NVIDIA MPS는 단일 GPU 기기에서 동시에 실행할 수 있는 협업 방식의 멀티 프로세스 CUDA 애플리케이션을 투명하게 지원하도록 설계된 CUDA API의 바이너리 호환 구현 대안입니다.

NVIDIA MPS를 사용하면 물리적 GPU의 최대 공유 컨테이너 수를 지정할 수 있습니다. 이 값은 다음 특성과 관련하여 각 컨테이너가 얻는 물리적 GPU 성능을 결정합니다.

NVIDIA MPS로 GPU를 예약하는 방법과 CUDA MPS를 사용해야 하는 경우에 대한 자세한 내용은 GKE의 GPU 공유 솔루션 정보를 참조하세요.

이 가이드의 대상

이 섹션에 나와 있는 안내는 다음 중 하나에 해당하는 경우에 적용됩니다.

  • 플랫폼 관리자: GKE 클러스터를 생성 및 관리하고, 인프라 및 리소싱 요구사항을 계획하며, 클러스터 성능을 모니터링합니다.
  • 애플리케이션 개발자: GKE 클러스터에서 워크로드를 설계하고 배포합니다. GPU가 포함된 NVIDIA MPS 요청에 대한 안내는 GPU가 포함된 NVIDIA MPS를 사용하는 워크로드 배포를 참조하세요.

요구사항

  • GKE 버전: GKE 버전 1.27.7-gke.1088000 이상을 실행하는 GKE Standard 클러스터에서 NVIDIA MPS로 GPU 공유를 사용 설정할 수 있습니다.
  • GPU 유형: 모든 NVIDIA Tesla® GPU 유형에 NVIDIA MPS를 사용 설정할 수 있습니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우 gcloud components update를 실행하여 최신 버전을 가져옵니다.

GKE 클러스터에서 GPU가 포함된 NVIDIA MPS 사용 설정

플랫폼 관리자는 GKE Standard 클러스터에서 GPU가 포함된 NVIDIA MPS를 사용 설정해야 합니다. 그런 다음 애플리케이션 개발자가 GPU가 포함된 NVIDIA MPS를 사용하도록 워크로드를 배포할 수 있습니다. GKE에서 GPU가 포함된 NVIDIA MPS를 사용 설정하려면 다음을 수행합니다.

  1. 새 GKE 클러스터에서 GPU가 포함된 NVIDIA MPS를 사용 설정합니다.
  2. NVIDIA GPU 기기 드라이버 설치(필요한 경우)
  3. 노드에서 사용 가능한 GPU 리소스 확인

GKE 클러스터에서 GPU가 포함된 NVIDIA MPS 사용 설정

GKE Standard 클러스터를 만들 때 GPU가 포함된 NVIDIA MPS를 사용 설정할 수 있습니다. 클러스터의 기본 노드 풀에 기능이 사용 설정되어 있습니다. 클러스터에서 새 노드 풀을 수동으로 만들 때는 GPU가 포함된 NVIDIA MPS를 사용 설정해야 합니다.

Google Cloud CLI를 사용하여 NVIDIA MPS가 사용 설정된 클러스터를 만듭니다.

gcloud container clusters create CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --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: 새 클러스터의 이름입니다.
  • COMPUTE_REGION: 새 클러스터의 Compute Engine 리전입니다. 영역 클러스터의 경우 --zone=COMPUTE_ZONE을 지정합니다. 사용하는 GPU 유형이 선택한 영역에서 사용 가능해야 합니다.
  • CLUSTER_VERSION: 클러스터 제어 영역과 노드의 GKE 버전입니다. GKE 버전 1.27.7-gke.1088000 이상을 사용합니다. 또는 --release-channel=RELEASE_CHANNEL 플래그를 사용하여 해당 GKE 버전으로 출시 채널을 지정합니다.
  • MACHINE_TYPE: 노드의 Compute Engine 머신 유형입니다.
  • GPU_TYPE: GPU 유형으로, nvidia-tesla-v100과 같은 NVIDIA Tesla GPU 플랫폼이어야 합니다.
  • GPU_QUANTITY: 기본 노드 풀의 각 노드에 연결할 물리적 GPU 수입니다.
  • CLIENTS_PER_GPU: 각 물리적 GPU를 공유할 수 있는 최대 컨테이너 수입니다.
  • DRIVER_VERSION: 설치할 NVIDIA 드라이버 버전입니다. 다음 중 하나일 수 있습니다.
    • default: GKE 버전의 기본 드라이버 버전을 설치합니다.
    • latest: GKE 버전에 사용 가능한 최신 드라이버 버전을 설치합니다. Container-Optimized OS를 사용하는 노드에서만 사용할 수 있습니다.
    • disabled: 자동 드라이버 설치를 건너뜁니다. 노드 풀을 만든 후에는 수동으로 드라이버를 설치해야 합니다. gpu-driver-version을 생략한 경우 기본 옵션입니다.

새 노드 풀에서 GPU가 포함된 NVIDIA MPS 사용 설정

GKE 클러스터에서 새 노드 풀을 수동으로 만들 때 GPU가 포함된 NVIDIA MPS를 사용 설정할 수 있습니다. Google Cloud CLI를 사용하여 NVIDIA MPS가 사용 설정된 노드 풀을 만듭니다.

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --region=COMPUTE_REGION \
    --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 이상을 실행해야 합니다.
  • COMPUTE_REGION: 클러스터의 Compute Engine 리전. 영역 클러스터의 경우 --zone=COMPUTE_ZONE을 지정합니다.
  • MACHINE_TYPE: 노드의 Compute Engine 머신 유형입니다. A100 GPU의 경우 A2 머신 유형을 사용합니다. 다른 모든 GPU에는 N1 머신 유형을 사용합니다.
  • GPU_TYPE: GPU 유형으로, nvidia-tesla-v100과 같은 NVIDIA Tesla GPU 플랫폼이어야 합니다.
  • GPU_QUANTITY: 노드 풀의 각 노드에 연결할 물리적 GPU 수입니다.
  • CONTAINER_PER_GPU: 각 물리적 GPU를 공유할 수 있는 최대 컨테이너 수입니다.
  • DRIVER_VERSION: 설치할 NVIDIA 드라이버 버전입니다. 다음 중 하나일 수 있습니다.

    • default: GKE 버전의 기본 드라이버 버전을 설치합니다.
    • latest: GKE 버전에 사용 가능한 최신 드라이버 버전을 설치합니다. Container-Optimized OS를 사용하는 노드에서만 사용할 수 있습니다.
    • disabled: 자동 드라이버 설치를 건너뜁니다. 노드 풀을 만든 후에는 수동으로 드라이버를 설치해야 합니다. gpu-driver-version을 생략한 경우 기본 옵션입니다.

NVIDIA GPU 기기 드라이버 설치

클러스터를 만들 때 자동 드라이버 설치를 사용 중지한 경우 또는 1.27.2-gke.1200 이전의 GKE 버전을 사용하는 경우 호환되는 NVIDIA 드라이버를 수동으로 설치하여 물리적 GPU의 NVIDIA MPS 분할을 관리해야 합니다. 드라이버를 설치하려면 드라이버를 설정하는 GKE 설치 DaemonSet를 배포합니다.

자세한 내용은 NVIDIA GPU 기기 드라이버 설치를 참조하세요.

사용 가능한 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의 count1입니다. 물리적 GPU의 count2인 경우 출력은 6개의 할당 가능한 GPU 리소스를 표시하며, 물리적 GPU 하나당 3개씩입니다.

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 워크로드를 배포하는 애플리케이션 운영자는 동일한 물리적 GPU에서 MPS 공유 단위를 공유하도록 GKE에 지시할 수 있습니다. 다음 매니페스트에서 물리적 GPU 하나를 요청하고 max-shared-clients-per-gpu=3를 설정합니다. 물리적 GPU는 MPS 공유 단위 3개를 가져오고 병렬로 실행되는 3개의 포드(컨테이너)로 nvidia/samples:nbody 작업을 시작합니다.

  1. 매니페스트를 gpu-mps.yaml로 저장합니다.

      apiVersion: batch/v1
      kind: Job
      metadata:
        name: nbody-sample
      spec:
        completions: 3
        parallelism: 3
        template:
          spec:
            hostIPC: true
            nodeSelector:
              cloud.google.com/gke-gpu-sharing-strategy: mps
            containers:
              - name: nbody-sample
                image: nvidia/samples:nbody
                command: ["/tmp/nbody"]
                args: ["-benchmark", "-i=5000"]
                resources:
                  limits:
                    nvidia.com/gpu: 1
            restartPolicy: "Never"
        backoffLimit: 1
    

    이 매니페스트에서 각 항목은 다음을 수행합니다.

    • hostIPC: true는 포드가 MPS 제어 데몬과 통신할 수 있도록 합니다. 필수 항목입니다. 하지만 hostIPC: true 구성은 컨테이너가 호스트 리소스에 액세스하도록 허용하여 보안 위험을 야기한다는 점을 고려하세요.
    • 벤치마크 모드에서 5,000회 반복 실행됩니다.
  2. 매니페스트를 적용합니다.

    kubectl apply -f gpu-mps.yaml
    
  3. 모든 포드가 실행 중인지 확인합니다.

    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
    
  4. 포드의 로그를 확인하여 작업이 완료되었는지 확인합니다.

    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회 반복을 실행하므로 로그 생성에 몇 분 정도 걸릴 수 있습니다.

삭제

다음 명령어를 실행하여 작업 및 모든 해당 포드를 삭제합니다.

kubectl delete job --all

NVIDIA MPS로 고정된 기기 메모리 및 활성 스레드 제한

기본적으로 GKE에서 NVIDIA MPS와 함께 GPU를 사용할 경우 다음 CUDA 환경 변수가 GPU 워크로드에 삽입됩니다.

  • CUDA_MPS_ACTIVE_THREAD_PERCENTAGE: 이 변수는 각 MPS 공유 단위가 사용할 수 있는 사용 가능한 스레드의 비율을 나타냅니다. 기본적으로 GPU의 각 MPS 공유 단위는 100 / MaxSharedClientsPerGPU로 설정되어 스트림 멀티 프로세서 측면에서 GPU 컴퓨팅의 동일한 슬라이스를 얻습니다.
  • CUDA_MPS_PINNED_DEVICE_MEM_LIMIT: 이 변수는 GPU의 MPS 공유 단위로 할당할 수 있는 GPU 메모리의 양을 제한합니다. 기본적으로 GPU의 각 MPS 공유 단위는 total mem / MaxSharedClientsPerGPU로 설정되어 GPU 메모리의 동일한 슬라이스를 얻습니다.

GPU 워크로드의 리소스 한도를 설정하려면 다음 NVIDIA MPS 환경 변수를 구성합니다.

  1. GitHub의 cuda-mps 예시 이미지를 검토하고 빌드합니다.

  2. 다음 매니페스트를 cuda-mem-and-sm-count.yaml로 저장합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: cuda-mem-and-sm-count
    spec:
      hostIPC: true
      nodeSelector:
        cloud.google.com/gke-gpu-sharing-strategy: mps
      containers:
        - name: CUDA_MPS_IMAGE
          image: gcr.io/gracegao-gke-dev/cuda-mem-and-sm-count:latest
          securityContext:
            privileged: true
          resources:
            limits:
              nvidia.com/gpu: 1
    

    CUDA_MPS_IMAGEcuda-mps 예시용으로 빌드한 이미지의 이름으로 바꿉니다.

    NVIDIA MPS를 사용하려면 포드에 hostIPC:true를 설정해야 합니다. hostIPC:true 구성은 컨테이너가 호스트 리소스에 액세스하도록 허용하여 보안 위험을 야기합니다.

  3. 매니페스트를 적용합니다.

    kubectl apply -f cuda-mem-and-sm-count.yaml
    
  4. 이 포드의 로그를 확인합니다.

    kubectl logs cuda-mem-and-sm-count
    

    gpu-sharing-strategy=mpsmax-shared-clients-per-gpu=3와 함께 NVIDIA Tesla® L4를 사용하는 예시에서 출력은 다음과 비슷합니다.

    For device 0:  Free memory: 7607 M, Total memory: 22491 M
    For device 0:  multiProcessorCount: 18
    

    이 예시에서 NVIDIA Tesla® L4 GPU에는 60개의 SM과 24GB 메모리가 있습니다. 각 MPS 공유 단위에는 약 33%의 활성 스레드와 8GB 메모리가 제공됩니다.

  5. 매니페스트를 업데이트하여 nvidia.com/gpu 2개를 요청합니다.

      resources:
            limits:
              nvidia.com/gpu: 2
    

    출력은 다음과 비슷합니다.

    For device 0:  Free memory: 15230 M, Total memory: 22491 M
    For device 0:  multiProcessorCount: 38
    
  6. 매니페스트를 업데이트하여 CUDA_MPS_ACTIVE_THREAD_PERCENTAGECUDA_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
    

제한사항

  • Volta 이전 GPU(P100)의 MPS는 Volta 이후의 GPU 유형에 비해 제한된 기능을 가집니다.
  • NVIDIA MPS를 사용하면 GKE는 각 컨테이너에 고정된 기기 메모리 및 활성 스레드 한도가 적용되도록 합니다. 하지만 메모리 대역폭, 인코더, 디코더와 같은 다른 리소스는 이러한 리소스 한도의 일부로 캡처되지 않습니다. 따라서 컨테이너가 모두 동일한 무제한 리소스를 요청하는 경우 다른 컨테이너의 성능에 부정적인 영향을 미칠 수 있습니다.
  • NVIDIA MPS에는 메모리 보호 및 오류 억제 제한사항이 있습니다. 워크로드와의 호환성을 보장하기 위해 이 제한사항을 평가하는 것이 좋습니다.
  • NVIDIA MPS를 사용하려면 포드에 hostIPC:true를 설정해야 합니다. hostIPC:true 구성은 컨테이너가 호스트 리소스에 액세스하도록 허용하여 보안 위험을 야기합니다.
  • GKE는 용량 할당 중에 예기치 않은 동작을 방지하도록 NVIDIA MPS를 사용할 때 특정 GPU 요청을 거부할 수 있습니다. 자세한 내용은 GPU 공유 솔루션 요청 한도를 참조하세요.
  • NVIDIA MPS와 단일 물리적 GPU를 공유할 수 있는 최대 컨테이너 수는 48개입니다(Volta 이전 GPU는 16개만 지원). NVIDIA MPS 구성을 계획할 때는 성능과 응답성이 최적화되도록 워크로드의 리소스 요구사항과 기본 물리적 GPU의 용량을 고려합니다.
  • NVIDIA MPS API 구성은 Google Cloud CLI 또는 Google Cloud 콘솔을 통해서만 지원됩니다.

다음 단계