View a markdown version of this page

Amazon EKS에서 NVIDIA GPU와 함께 시간 분할 사용 - Amazon EKS

이 페이지 개선에 도움 주기

이 사용자 가이드에 기여하려면 모든 페이지의 오른쪽 창에 있는 GitHub에서 이 페이지 편집 링크를 선택합니다.

Amazon EKS에서 NVIDIA GPU와 함께 시간 분할 사용

시간 분할을 사용하면 여러 포드가 단일 물리적 NVIDIA GPU를 공유할 수 있습니다. Kubernetes 스케줄러는 동일한 GPU에 여러 포드를 배치하고, GPU의 CUDA 스케줄러는 작업을 시간 멀티플렉싱합니다. 시간 분할은 가장 단순한 GPU 공유 전략입니다. 이 전략은 소프트웨어만 사용하고, 특별한 하드웨어가 필요하지 않으며, AWS의 모든 NVIDIA GPU 인스턴스 유형에서 작동합니다. 시간 분할은 GPU를 공유하는 포드 간에 메모리 또는 컴퓨팅 격리를 제공하지 않습니다. 요청 사이에 유휴 상태를 유지하는 추론 서비스나 여러 사용자가 GPU를 공유하는 개발 환경과 같이 GPU 사용률이 낮은 워크로드에 가장 적합합니다. 하드웨어 수준의 메모리 및 컴퓨팅 격리가 필요한 워크로드의 경우 대신 다중 인스턴스 GPU(MIG)를 사용하세요.

Amazon EKS에서는 NVIDIA DRA 드라이버 또는 NVIDIA 디바이스 플러그인을 사용하여 시간 분할을 관리할 수 있습니다.

정적 용량 프로비저닝을 사용하는 경우에만 Karpenter와 함께 시간 분할을 사용할 수 있습니다. 시간 분할은 현재 EKS Auto Mode에서 사용할 수 없습니다.

시간 분할은 다음과 같은 경우에 적합합니다.

  • GPU 사용률이 일관되게 낮습니다. 예를 들어 요청 간에 유휴 상태를 유지하는 지연 시간에 민감한 추론 서비스입니다.

  • 여러 개발자가 노트북 또는 개발 작업을 위해 단일 GPU 노드를 공유합니다.

  • 노드가 g5, g6 또는 g6e 패밀리와 같이 MIG를 지원하지 않는 GPU 인스턴스 유형을 사용합니다.

  • 동일한 GPU의 다른 포드가 사용 중이기 때문에 포드 속도가 느려질 수 있다는 점을 감수할 수 있습니다.

다음과 같은 경우 다른 접근 방식을 고려하세요.

  • 메모리 격리가 필요합니다. 시간 분할 구성 GPU의 포드는 동일한 GPU 메모리를 공유하며, 한 포드가 다른 포드에 필요한 메모리를 소진할 수 있습니다. 메모리 격리에는 MIG를 사용합니다.

  • 예측 가능한 포드별 지연 시간 또는 서비스 품질이 필요합니다. GPU 스케줄러는 보장 없이 최선으로 슬롯 간에 컴퓨팅을 공유합니다.

  • 훈련 워크로드를 실행합니다. 시간 분할은 훈련 효율을 저하시키는 컨텍스트 전환을 추가합니다. 다른 포드로 인해 속도가 느려진 체크포인트 작업은 마지막 체크포인트에서 다시 시도해야 합니다.

고려 사항

프로덕션에서 시간 분할을 사용하기 전에 다음 고려 사항을 검토하세요.

일반적인 고려 사항

  • 메모리 격리 없음: 시간 분할 구성 GPU를 공유하는 포드는 해당 메모리를 공유합니다. 한 포드가 다른 포드에 필요한 메모리를 할당할 수 있으며, 이로 인해 메모리 부족 오류가 발생할 수 있습니다. 각 GPU를 공유하는 포드 수를 워크로드의 메모리 공간과 일치시킵니다. 포드가 정기적으로 대형 모델을 로드하는 경우 GPU당 더 적은 포드를 공유하거나 MIG를 사용합니다.

  • 최선의 컴퓨팅 공유: GPU 스케줄러는 최선의 노력 기반으로 포드 간에 컴퓨팅을 공유하며 각 포드에 비례적인 컴퓨팅을 보장하지 않습니다.

  • 시간 분할과 MPS는 동일한 GPU를 공유할 수 없음: 시간 분할은 GPU 컴퓨팅 모드를 DEFAULT로 설정하는 반면, NVIDIA Multi-Process Service(MPS)에는 EXCLUSIVE_PROCESS가 필요합니다. 동일한 클러스터에서 두 전략을 모두 사용할 수 있지만 동일한 물리적 GPU에서는 동시에 사용할 수 없습니다. 시간 분할은 MIG 인스턴스에 아무런 영향도 미치지 않습니다. 컨테이너 간에 단일 MIG 인스턴스를 공유하려면 대신 MPS를 사용합니다.

  • 컨테이너별 지표: 시간 분할이 활성화된 경우 NVIDIA Data Center GPU Manager(DCGM)는 개별 컨테이너에 지표를 할당할 수 없습니다. GPU 수준 지표는 계속 사용할 수 있지만 특정 양의 GPU 리소스를 소비한 포드는 식별할 수는 없습니다.

NVIDIA DRA 드라이버 고려 사항

  • 알파 기능: DRA 드라이버를 통한 시간 분할에는 기본적으로 비활성화된 알파 기능인 TimeSlicingSettings 기능 게이트가 필요합니다. 자세한 내용은 NVIDIA DRA 드라이버를 통해 GPU 시간 분할 사용 섹션을 참조하세요.

  • 사용자 매개 공유만 해당: 포드는 네임스페이스 범위에 속하는 동일한 ResourceClaim 또는 ResourceClaimTemplate을 참조하여 GPU를 공유하므로 네임스페이스 간 공유는 불가능합니다. 시스템 매개 공유는 제안된 향후 기능입니다.

  • Bottlerocket에서 내장 디바이스 플러그인 비활성화: DRA 드라이버는 동일한 노드에서 NVIDIA 디바이스 플러그인과 함께 실행할 수 없습니다. Bottlerocket에서 내장 디바이스 플러그인을 비활성화합니다. 이 작업에는 Bottlerocket 버전 1.63.0 이상이 필요합니다. 자세한 내용은 NVIDIA DRA 드라이버 설치 섹션을 참조하세요.

  • 컴퓨팅 지원: NVIDIA DRA 드라이버는 Karpenter, EKS 관리형 노드 그룹 또는 자체 관리형 노드의 정적 용량 프로비저닝에서 지원되며 EKS Auto Mode에서는 지원되지 않습니다. 자세한 내용은 Karpenter 웹사이트의 Karpenter 정적 NodePool 설명서를 참조하세요.

NVIDIA 디바이스 플러그인 고려 사항

  • 슬롯을 사용한 최선의 컴퓨팅 공유: 디바이스 플러그인은 GPU당 고정된 수의 슬롯을 광고합니다. 단일 포드가 둘 이상의 슬롯을 요청하는 경우 추가 컴퓨팅을 할당받지 않습니다. 둘 이상의 슬롯을 요청하는 포드를 거부하려면 fail-requests-greater-than-one 옵션을 활성화합니다.

  • Karpenter를 사용한 프로비저닝: Karpenter는 GPU에서 시간 분할이 활성화된 경우에도 각 nvidia.com/gpu 요청을 하나의 물리적 GPU로 계산합니다. 자세한 내용은 GitHub의 Karpenter issue #2140을 참조하세요.

  • EKS Auto Mode 지원 안 함: EKS Auto Mode는 NVIDIA 디바이스 플러그인을 관리하며 해당 구성을 노출하지 않습니다. 시간 분할에는 디바이스 플러그인 구성이 필요하므로 EKS Auto Mode 노드에 시간 분할 구성을 적용할 수 없습니다.

  • 시간 분할 구성 변경 사항: NVIDIA 디바이스 플러그인은 시간 분할 ConfigMap의 변경 사항을 모니터링하지 않습니다. 구성을 업데이트한 후 디바이스 플러그인을 다시 시작합니다.

구성 옵션

EKS 최적화 AL2023 및 Bottlerocket NVIDIA AMI에서 NVIDIA GPU에 시간 분할을 사용할 수 있습니다. 시간 분할 설정은 NVIDIA DRA 드라이버를 사용하는지 아니면 NVIDIA 디바이스 플러그인을 사용하는지에 따라 달라집니다.

NVIDIA DRA driver

EKS 최적화 가속 AMI에는 NVIDIA DRA 드라이버가 포함되어 있지 않습니다. Bottlerocket을 사용하는 경우 NVIDIA DRA 드라이버를 사용하기 전에 노드 사용자 데이터에서 settings.kubelet-device-plugins.nvidia.enabled = false를 설정하여 기본 제공 NVIDIA 디바이스 플러그인을 비활성화해야 합니다. 이 설정에는 Bottlerocket 버전 1.63.0 이상이 필요합니다. 자세한 내용은 NVIDIA DRA 드라이버 설치 섹션을 참조하세요.

NVIDIA DRA 드라이버를 사용하면 ResourceClaimTemplates를 통해 시간 분할이 구성됩니다. interval 필드는 CUDA 시간 분할 기간을 제어합니다.

간격 설명

기본값

NVIDIA GPU 드라이버의 기본 간격을 사용합니다.

Short

더 짧은 간격, 컨텍스트가 더 자주 전환됨

중간

중간 간격

Long

각 컨텍스트는 선점되기 전까지 턴당 더 오래 실행됩니다.

NVIDIA device plugin
  • Bottlerocket – AMI에 사전 설치된 NVIDIA 디바이스 플러그인이 포함되어 있습니다. 별도의 디바이스 플러그인 설치, 헬름 차트 또는 ConfigMap 없이 Bottlerocket 설정을 통해 시간 분할을 구성합니다.

  • AL2023NVIDIA Kubernetes 디바이스 플러그인 설치에 설명된 대로 NVIDIA 디바이스 플러그인을 설치하고 ConfigMap을 통해 시간 분할 구성을 제공합니다.

    다음 옵션은 NVIDIA 디바이스 플러그인이 시간 분할 구성 GPU를 광고하고 관리하는 방법을 제어합니다. 필드 이름은 다음 절차에 표시된 대로 Bottlerocket 설정과 AL2023 ConfigMap 간에 다릅니다.

    옵션 권장 값 설명

    복제본

    2~8

    물리적 GPU당 광고할 예약 가능한 슬롯 수입니다. 값이 클수록 더 많은 공유가 가능하지만 포드 간의 경합은 증가합니다.

    기본적으로 이름 바꾸기

    false

    false인 경우 포드는 기존 매니페스트와의 호환성을 유지하는 nvidia.com/gpu를 요청합니다. true인 경우 디바이스 플러그인은 리소스를 nvidia.com/gpu.shared로 광고하며 포드는 해당 이름을 요청해야 합니다. 공유 및 전용 GPU 노드 풀을 모두 실행하고 워크로드가 공유 리소스를 명시적으로 선택하도록 하려면 이 값을 true로 설정합니다.

    둘 이상의 요청 실패

    true

    둘 이상의 시간 분할되는 슬롯을 요청하는 포드를 거부합니다. 둘 이상의 슬롯을 요청하는 포드는 컴퓨팅이 비례적으로 할당되지 않습니다. 일반적인 구성 오류를 방지하려면 이 설정을 활성화합니다.

    GPU 공유 옵션 및 기본값의 전체 목록은 GitHub의 NVIDIA Kubernetes device plugin documentation을 참조하세요.

NVIDIA DRA 드라이버를 통해 GPU 시간 분할 사용

NVIDIA DRA 드라이버를 사용하면 포드가 시간 분할 GpuConfig를 사용하여 gpu.nvidia.com DeviceClass를 요청하는 공통 ResourceClaim을 참조하여 GPU를 공유합니다.

NVIDIA DRA 드라이버는 현재 사용자 매개 시간 분할을 구현합니다. GPU는 사용자가 동일한 클레임을 명시적으로 가리키는 포드 및 컨테이너에서만 공유됩니다. ResourceClaimResourceClaimTemplate은 네임스페이스 범위이므로 이러한 방식으로 GPU를 공유하는 포드는 동일한 네임스페이스에 있어야 합니다. 단일 포드의 컨테이너 간에 GPU를 공유하려면 각 컨테이너가 클레임에서 동일한 요청 이름을 참조하도록 합니다. 서로 다른 요청 이름을 참조하는 컨테이너는 각각 별도의 GPU를 할당받습니다. 필요한 각 시간 분할 간격에 대해 별도의 ResourceClaimTemplate을 생성하고, GPU를 공유하려는 각 네임스페이스에 하나씩 생성합니다.

시스템 매개 시간 분할은 사용자가 구성한 클레임이 아닌 시스템이 정의한 기준에 따라 드라이버가 독립적인 클레임(네임스페이스 포함) 간에 GPU를 공유하는 경우입니다. 시스템 매개 시간 분할에 대한 자세한 내용은 GitHub의 System-mediated time-slicing of GPUs (issue #659)pull request #1257을 참조하세요.

중요

DRA 드라이버를 통한 시간 분할에는 기본적으로 비활성화된 알파 기능인 TimeSlicingSettings 기능 게이트가 필요합니다. 이 기능 게이트를 활성화하지 않고 TimeSlicing 공유 전략을 요청하면 드라이버가 디바이스를 준비하지 못하고 포드가 error validating GPU config: unknown GPU sharing strategy: TimeSlicing을 보고하는 FailedPrepareDynamicResources 이벤트와 함께 ContainerCreating 상태로 유지됩니다. 알파 기능 사용의 위험을 감수하는 경우에만 기능 게이트를 활성화합니다.

사전 조건

  • Kubernetes 버전 1.34 이상을 실행하는 Amazon EKS 클러스터. NVIDIA DRA 드라이버는 Karpenter, EKS 관리형 노드 그룹 또는 자체 관리형 노드의 정적 용량 프로비저닝에서 지원됩니다.

  • EKS 최적화 AL2023 NVIDIA AMI를 사용하는 NVIDIA GPU 인스턴스 유형이 있는 노드.

  • TimeSlicingSettings 기능 게이트가 활성화된 상태로 NVIDIA DRA 드라이버 설치에 설명된 대로 설치된 NVIDIA DRA 드라이버.

절차

  1. TimeSlicing 공유 전략을 사용하여 GPU를 요청하는 ResourceClaim을 생성합니다. 이 클레임을 참조하는 여러 포드가 동일한 물리적 GPU를 공유합니다.

    cat <<EOF | kubectl apply -f - apiVersion: resource.k8s.io/v1 kind: ResourceClaim metadata: name: shared-timeslice-gpu spec: devices: requests: - name: gpu exactly: deviceClassName: gpu.nvidia.com count: 1 config: - requests: ["gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: TimeSlicing timeSlicingConfig: interval: Long EOF
  2. 공유된 ResourceClaim을 이름으로 참조하는 두 개 이상의 포드를 배포합니다. 각 포드는 resourceClaimsresources.claims를 통해 클레임을 참조합니다.

    cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: share-a spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: cuda image: nvidia/cuda:12.6.0-base-ubuntu22.04 command: ["nvidia-smi", "-L"] resources: claims: - name: gpu resourceClaims: - name: gpu resourceClaimName: shared-timeslice-gpu restartPolicy: OnFailure EOF
  3. 포드가 동일한 물리적 GPU를 공유하는지 확인합니다. 각 포드에서 nvidia-smi -L을 실행하고 동일한 GPU UUID를 보고하는지 확인합니다.

    kubectl logs share-a

    예제 출력은 다음과 같습니다. 동일한 클레임을 참조하는 두 번째 포드는 동일한 GPU UUID를 보고하며, 이를 통해 두 포드가 하나의 물리적 GPU를 공유하고 있음을 확인할 수 있습니다.

    GPU 0: NVIDIA L4 (UUID: GPU-b41973ee-5d0a-cde8-6287-12b53f861f02)

NVIDIA 디바이스 플러그인을 통해 Bottlerocket 노드에서 GPU 시간 분할 사용

Bottlerocket에서 EKS 최적화 가속 AMI에는 NVIDIA 디바이스 플러그인이 포함되어 있습니다. settings.kubelet-device-plugins.nvidia 설정을 통해 시간 분할을 활성화합니다. 이 설정은 노드가 부팅될 때 Bottlerocket이 디바이스 플러그인 구성으로 렌더링합니다.

사전 조건

  • Amazon EKS 클러스터. 다음 절차에서는 EKS 최적화 Bottlerocket NVIDIA AMI를 사용하여 NVIDIA GPU 노드를 프로비저닝합니다.

  • 클러스터에 설치 및 구성된 Karpenter. 다음 절차에서는 Karpenter EC2NodeClass를 사용하여 Bottlerocket 노드 사용자 데이터에 시간 분할 설정을 제공합니다. 자세한 내용은 Karpenter 웹사이트의 Karpenter 시작하기를 참조하세요.

  • 클러스터와 통신하도록 구성된 kubectl. 자세한 내용은 kubectl 설치 또는 업데이트 섹션을 참조하세요.

절차

GPU 노드의 Bottlerocket 사용자 데이터에 시간 분할 설정을 추가합니다. 다음 예제에서는 GPU당 4개의 슬롯을 구성합니다. 사용자 데이터를 제공하는 방법은 노드를 프로비저닝하는 방법에 따라 달라집니다. 다음 예제는 Karpenter EC2NodeClass를 보여 줍니다.

cat <<EOF | kubectl apply -f - apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: gpu-bottlerocket-timeslicing spec: amiFamily: Bottlerocket amiSelectorTerms: - alias: bottlerocket@latest role: eksctl-KarpenterNodeRole-<cluster-name> subnetSelectorTerms: - tags: karpenter.sh/discovery: <cluster-name> securityGroupSelectorTerms: - tags: karpenter.sh/discovery: <cluster-name> userData: | [settings.kubelet-device-plugins.nvidia] device-sharing-strategy = "time-slicing" [settings.kubelet-device-plugins.nvidia.time-slicing] replicas = 4 rename-by-default = false fail-requests-greater-than-one = true EOF

이러한 설정으로 프로비저닝된 노드가 클러스터에 조인하면 디바이스 플러그인은 각 물리적 GPU에 대해 4개의 nvidia.com/gpu 슬롯을 광고합니다. nvidia.com/gpu 확장 리소스에 대한 컨테이너 리소스 요청 또는 한도를 사용하여 워크로드 사양에서 슬롯을 요청합니다.

NVIDIA 디바이스 플러그인을 통해 AL2023 노드에서 GPU 시간 분할 사용

AL2023에서는 NVIDIA Kubernetes 디바이스 플러그인 설치에 설명된 대로 NVIDIA 디바이스 플러그인을 설치하고 ConfigMap에 시간 분할 구성을 제공합니다.

사전 조건

  • NVIDIA GPU 인스턴스 유형 및 EKS 최적화 AL2023 NVIDIA AMI를 사용하는 노드가 있는 Amazon EKS 클러스터.

  • 명령줄 환경에 설치된 Helm에 대한 자세한 내용은 Helm 설정 지침을 참조하세요.

  • 클러스터와 통신하도록 구성된 kubectl. 자세한 내용은 kubectl 설치 또는 업데이트 섹션을 참조하세요.

절차

  1. NVIDIA Kubernetes 디바이스 플러그인 설치에 디바이스 플러그인을 설치한 nvidia 네임스페이스에서 시간 분할 ConfigMap을 생성합니다. 이 예제에서는 GPU당 4개의 슬롯을 구성합니다.

    cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: nvidia-device-plugin-config namespace: nvidia data: config.yaml: | version: v1 sharing: timeSlicing: renameByDefault: false failRequestsGreaterThanOne: true resources: - name: nvidia.com/gpu replicas: 4 EOF
  2. ConfigMapconfig.name 값으로 참조하도록 기존 NVIDIA 디바이스 플러그인 릴리스를 업데이트합니다. --reuse-values 플래그는 NVIDIA Kubernetes 디바이스 플러그인 설치에 디바이스 플러그인을 설치할 때 설정한 값을 유지합니다.

    helm upgrade nvdp nvdp/nvidia-device-plugin \ --namespace nvidia \ --reuse-values \ --set config.name=nvidia-device-plugin-config
참고

ConfigMap을 변경해도 디바이스 플러그인이 자동으로 다시 로드되지 않습니다. 시간 분할 구성을 업데이트한 후 디바이스 플러그인 포드를 다시 시작하여 변경 사항을 적용합니다.

GPU 시간 분할이 활성 상태인지 확인

시간 분할 노드가 Ready 상태로 된 후 디바이스 플러그인이 예상 슬롯 수를 광고하고 포드가 물리적 GPU를 공유하는지 확인합니다.

참고

이 절차의 공유 UUID 검사는 포드가 동일한 물리적 GPU에 도착할 때 시간 분할을 가장 명확하게 보여줍니다. 단일 GPU가 있는 노드에서 디바이스 플러그인은 슬롯 4개를 광고하고 포드 4개가 모두 해당 GPU를 공유하므로 동일한 UUID를 보고합니다. 물리적 GPU가 여러 개인 노드에서 스케줄러는 서로 다른 GPU에 포드를 배치할 수 있습니다. 이러한 포드는 시간 분할이 활성 상태인 경우에도 서로 다른 UUID를 보고합니다. 단일 GPU에서의 공유를 시연하려면 워크로드를 단일 GPU 인스턴스 유형으로 예약합니다. 예를 들어 node.kubernetes.io/instance-type: g6.2xlarge와 같은 노드 선택기를 포드 사양에 추가합니다.

  1. 노드가 구성된 GPU 슬롯 수를 광고하는지 확인합니다. GPU당 슬롯이 4개인 경우 물리적 GPU가 1개인 노드는 4를 보고합니다.

    kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"

    예제 출력은 다음과 같습니다.

    NAME GPU ip-192-168-11-225.us-west-2.compute.internal 4
  2. 각각 하나의 GPU 슬롯을 요청하는 복제본을 4개 실행하는 배포를 생성합니다.

    cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: timeslicing-demo spec: replicas: 4 selector: matchLabels: app: timeslicing-demo template: metadata: labels: app: timeslicing-demo spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: cuda image: nvidia/cuda:12.6.0-base-ubuntu22.04 command: ["bash", "-c", "nvidia-smi --query-gpu=uuid --format=csv,noheader; sleep infinity"] resources: limits: nvidia.com/gpu: 1 EOF
  3. 4개의 포드가 모두 동일한 노드에 예약되어 있는지 확인합니다.

    kubectl get pods -l app=timeslicing-demo -o wide
  4. 4개의 포드가 모두 동일한 GPU UUID를 보고하는지 확인합니다. 4개의 포드 모두에서 공유되는 단일 UUID는 하나의 물리적 GPU가 시간 멀티플렉싱되고 있음을 확인해 줍니다.

    kubectl logs -l app=timeslicing-demo --prefix

    예제 출력은 다음과 같습니다.

    [pod/timeslicing-demo-xxxxxxxxxx-aaaaa/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-bbbbb/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-ccccc/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-ddddd/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03