최신글

kubernetes에서 NVIDIA GPU를 여러 pod가 함께 쓰는 방법

반응형

TL;DR

kubernetes에서 NVIDIA GPU를 사용하는 기본 방식은 pod 하나가 GPU 1장을 요청하는 방식입니다. 이때 nvidia.com/gpu: 1은 아래처럼 resources.limits 아래에 적습니다.

resources:
  limits:
    nvidia.com/gpu: 1

 

여러 pod가 같은 NVIDIA GPU를 함께 쓰려면 NVIDIA GPU 공유 방식을 따로 설정해야 합니다. 대표적인 선택지는 세 가지입니다.
- MIG: GPU를 하드웨어 레벨에서 여러 GPU instance로 나눕니다. 격리가 가장 좋지만, 지원 GPU와 profile 제약이 있습니다.
- time-slicing: GPU 시간을 여러 pod가 나눠 씁니다. 설정은 비교적 쉽지만, 메모리 격리와 장애 격리가 없습니다.
- MPS: CUDA Multi-Process Service로 GPU를 공유합니다. time-slicing보다 메모리와 compute 사용량을 더 제한할 수 있지만, kubernetes device plugin 기준으로는 운영 전 지원 상태 확인이 필요합니다.

 

기본값: GPU 1장은 pod 하나에 할당된다

NVIDIA device plugin을 설치하면 노드의 GPU가 nvidia.com/gpu 리소스로 노출됩니다. pod가 아래처럼 GPU 1개를 요청하면 scheduler는 GPU가 남아 있는 노드에 pod를 배치합니다.

apiVersion: v1
kind: Pod
metadata:
  name: gpu-test
spec:
  containers:
    - name: cuda
      image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda12.5.0
      resources:
        limits:
          nvidia.com/gpu: 1

 

이 방식의 장점은 단순함입니다. pod가 GPU 1장을 독점하므로 성능 예측이 쉽고, 다른 pod의 GPU 메모리 사용량이나 커널 실행이 내 workload에 직접 끼어들 가능성이 낮습니다.

 

단점은 활용률입니다. GPU 1장을 요청한 pod가 실제로는 GPU를 10~20%만 사용해도, kubernetes 관점에서는 GPU 1개가 이미 소비된 상태입니다. 작은 inference 서버, notebook, 개발용 workload처럼 GPU를 계속 꽉 채우지 않는 작업에서는 낭비가 커질 수 있습니다.

 

방법 1: MIG로 GPU를 하드웨어 레벨에서 나누기

MIG는 Multi-Instance GPU의 약자입니다. NVIDIA Ampere 이후 일부 GPU에서 사용할 수 있는 기능이며, GPU 1장을 여러 개의 독립적인 GPU instance로 나눕니다. 각 instance는 정해진 compute slice와 memory slice를 가집니다.

 

예를 들어 H100 또는 A100 계열 GPU는 1g.10gb, 2g.20gb, 3g.40gb 같은 profile로 나눌 수 있습니다. 정확한 profile 이름과 개수는 GPU 모델, 드라이버, GPU Operator 버전에 따라 달라지므로 운영 전에 확인 필요입니다.

 

MIG의 핵심은 격리입니다. MIG instance는 하드웨어 레벨에서 메모리와 장애 영역을 나눕니다. 한 pod가 특정 MIG instance를 사용하더라도 다른 MIG instance를 쓰는 pod와 메모리 공간을 공유하지 않습니다.

 

MIG는 이런 상황에 잘 맞습니다.
- 여러 팀이나 여러 서비스가 같은 물리 GPU를 나눠 써야 한다.
- pod 간 성능 간섭을 줄여야 한다.
- GPU memory 한도를 강하게 나눠야 한다.
- 개발용 공유보다 운영 workload의 예측 가능성이 더 중요하다.

 

반대로 단점도 있습니다.
- MIG를 지원하는 GPU에서만 사용할 수 있습니다.
- profile이 정해져 있어서 workload 크기에 딱 맞지 않으면 자투리 리소스가 생깁니다.
- MIG 구성을 바꿀 때 GPU workload를 비우거나 노드를 재시작해야 하는 경우가 있습니다.
- 작은 pod를 아주 많이 올리는 용도에는 time-slicing보다 유연성이 낮을 수 있습니다.

 

정리하면 MIG는 “GPU를 작은 GPU 여러 개로 쪼갠다”에 가깝습니다. 여러 pod가 같은 물리 GPU를 쓰지만, 각 pod는 자기에게 할당된 MIG instance를 GPU처럼 봅니다.

 

방법 2: time-slicing으로 GPU 시간을 나눠 쓰기

time-slicing은 GPU 1장을 시간 단위로 나눠 여러 pod가 번갈아 쓰게 하는 방식입니다. CPU time-slicing과 비슷한 느낌으로 이해하면 됩니다. NVIDIA device plugin 또는 GPU Operator 설정에서 replicas 값을 늘리면, kubernetes에는 실제 GPU 개수보다 더 많은 GPU 리소스가 보입니다.

 

예를 들어 GPU 1장이 있는 노드에 replicas: 4를 설정하면, kubernetes는 이 노드에 nvidia.com/gpu 리소스가 4개 있는 것처럼 볼 수 있습니다.

version: v1
sharing:
  timeSlicing:
    resources:
      - name: nvidia.com/gpu
        replicas: 4

 

time-slicing의 장점은 유연성입니다. MIG를 지원하지 않는 오래된 GPU에서도 사용할 수 있고, GPU를 조금씩 쓰는 pod를 여러 개 올리기 쉽습니다. 개발용 notebook, 테스트용 inference, 낮은 트래픽의 내부 도구처럼 GPU를 항상 꽉 채우지 않는 workload에 잘 맞습니다.

 

하지만 time-slicing은 격리 방식이 아닙니다. NVIDIA 문서 기준으로 time-slicing은 MIG처럼 메모리 격리나 장애 격리를 제공하지 않습니다. 같은 GPU를 공유하는 pod들은 같은 GPU memory와 fault domain 안에서 실행됩니다.

 

또한 nvidia.com/gpu: 2를 요청한다고 해서 compute 시간을 두 배로 보장받는 것도 아닙니다. time-slicing에서 replica는 “공유 GPU에 접근할 수 있는 자리”에 가깝습니다. 그래서 NVIDIA 문서에서는 failRequestsGreaterThanOne=true 설정으로 공유 GPU 요청을 1개로 제한하는 방식을 권장합니다.

 

time-slicing은 이런 상황에 잘 맞습니다.
- GPU를 조금씩 쓰는 pod가 많다.
- 개발자 notebook이나 실험용 workload를 여러 개 올리고 싶다.
- MIG를 지원하지 않는 GPU를 공유해야 한다.
- 강한 격리보다 GPU 활용률이 더 중요하다.

 

주의할 점은 명확합니다.
- 메모리 격리가 없습니다.
- 한 workload의 장애가 같은 GPU를 공유하는 다른 workload에 영향을 줄 수 있습니다.
- pod별 GPU metric을 정확히 나눠 보기 어려울 수 있습니다.
- latency가 중요한 production inference에는 별도 부하 테스트가 필요합니다.

 

방법 3: MPS로 CUDA process를 함께 실행하기

MPS는 Multi-Process Service의 약자입니다. CUDA application 여러 개가 같은 GPU에서 더 효율적으로 동시에 실행되도록 돕는 NVIDIA 런타임 기능입니다.

 

time-slicing은 GPU 시간을 번갈아 나눠 쓰는 방식에 가깝습니다. 반면 MPS는 MPS control daemon이 GPU 접근을 관리하고, client별 memory와 compute capacity를 제한할 수 있습니다. NVIDIA device plugin 문서 기준으로 MPS는 각 replica가 전체 GPU memory와 compute capacity의 일정 비율을 사용하도록 제한할 수 있습니다.

 

MPS는 이런 상황에 어울립니다.
- 여러 CUDA process를 같은 GPU에서 동시에 실행하고 싶다.
- time-slicing보다 memory와 compute 사용량을 더 명시적으로 제한하고 싶다.
- workload가 CUDA MPS와 잘 맞는지 검증할 수 있다.

 

다만 kubernetes에서 MPS를 선택할 때는 조심해야 합니다.
- NVIDIA device plugin 문서 기준으로 MPS 지원은 experimental로 표시되어 있습니다.
- MIG가 활성화된 GPU에서는 MPS sharing을 함께 사용할 수 없습니다.
- 현재 문서 기준으로 MPS sharing은 full GPU의 nvidia.com/gpu 리소스에 대해서만 지원됩니다.
- 노드 안의 GPU별로 서로 다른 sharing 방식을 섞는 구성은 지원되지 않습니다.

 

따라서 MPS는 “운영 기본값”이라기보다, workload 특성을 알고 있고 직접 검증할 수 있을 때 선택하는 방식에 가깝습니다. production 적용 전에는 사용 중인 device plugin 버전, GPU 모델, CUDA workload 특성, 장애 격리 요구사항을 확인 필요입니다.

 

결론

kubernetes에서 nvidia.com/gpu: 1을 설정하는 것만으로는 GPU 공유가 되지 않습니다. 기본 설정은 pod가 GPU 1장을 요청하는 방식입니다. 여러 pod가 같은 NVIDIA GPU를 쓰게 하려면 MIG, time-slicing, MPS 중 하나를 선택하고 NVIDIA device plugin 또는 GPU Operator 설정을 바꿔야 합니다.

 

참고자료

반응형