학습일지/AI

Scaling AI Workloads with kubernetes: Sharing GPU Resources Across Multiple Containers

inspirit941 2025. 5. 22. 16:33
반응형

https://youtu.be/t68ayhtaUQ8?si=GdmoGCpO6qdBQqur

 

screenCapture_2025-05-22_10.07.37

 

screenCapture_2025-05-22_10.07.45



AI는 GPU를 많이 사용하지만, GPU는 비싸다. 따라서, 한 번 받았다면 GPU를 최대한 활용해야 한다.

 

 

screenCapture_2025-05-22_10.09.54



k8s는 GPU Management에도 훌륭한 역할을 하는 도구.

  • GPU Operator를 활용하면 nvidia drivers / shared library 지원을 받을 수 있다.
  • 수많은 Node에 있는 GPU configuration을 중앙 관리할 수 있다. (ConfigMap 같은 거)
  • GPU Monitoring / Telemetry 지원 가능.

따라서, k8s로 GPU resource 관리하는 방법을 소개할 예정

Understanding GPU Resource Management

MIG: GPU instance Partitioning

screenCapture_2025-05-22_10.12.53



MIG (Multi-instance GPU): Nvidia에서 지원하는 feature.

  • 보통 inference 수행할 때, 특정 인스턴스에 있는 GPU 리소스 전체를 다 쓰지는 않는 경우가 있음.
    • 전체 리소스가 80GB of VRAM인데, 특정 inference는 최대 5GB까지만 메모리가 필요하다거나..
  • GPU를 샤딩해서, 하나의 gpu를 여러 개처럼 사용하는 방식. 최대 7개까지 샤딩 가능.

screenCapture_2025-05-22_11.10.58

 

screenCapture_2025-05-22_11.14.57



예컨대 40GB 메모리, 108SM (streaming multiprocessors) 의 A100이 있다고 할 때

  • Memory Slices는 최대 8, Compute Slices 는 최대 7까지 분할 가능. (108은 8로 나누어떨어지지 않으므로..)
    • streaming multiprocessors: GPU에서 kernel 실행을 담당하는 프로세서.

screenCapture_2025-05-22_11.15.24

근데 compute 리소스는 왜 7로 나눠야 함? 8로 하면 안됨?

  • 엔비디아의 공식 설명으로는 chip yield (칩 수율)이 7일 때 더 좋아서 그렇다고 함
  • 메모리와 processor 개수가 일치하지 않아서 생기는 문제들이 있긴 한데, 뒤에서 설명하겠다

screenCapture_2025-05-22_11.18.07



GPU의 processor / memory slice를 할당 요청할 땐, 아래와 같은 네이밍을 사용함.

  • {fixed partition of processors}.{fixed partition of memory}
    • 1g.5gb: 프로세서 1개, 메모리 5GB slice
    • 2g.10gb: 프로세스 2개, 메모리 10GB slice

screenCapture_2025-05-22_11.21.12

 

screenCapture_2025-05-22_11.22.36



  • 근데 3개 할당받을 땐 3g.15gb가 아니라 3g.20gb로 써야 한다. 그냥 엔비디아 설계가 그렇다.
  • 4g.20gb는 문제 없고
  • 프로세서 5개, 6개는 할당 요청 자체가 안 된다. 그 다음으로 가능한 건 7g.40gb

정리하자면

  • processor 개수는 1, 2, 3, 4, 7만 선택 가능하고
  • 2의 배수가 아니라면 (= 3, 7인 경우) extra memory slice가 필요하다

screenCapture_2025-05-22_11.24.13

 

screenCapture_2025-05-22_11.25.33

 

screenCapture_2025-05-22_11.27.46



위 방식을 조합해서 Partition을 만들면 되는데

  • k8s Operator가 아니라 nvidia-smi 같은 도구를 사용해서 파티셔닝할 경우, 파티셔닝은 left to right 방식으로 진행됨.
  • 즉, order of partition이 중요해진다. processor와 메모리 갯수가 달라져야 하는 파티셔닝이라면, 뒷순서로 정의해야 한다. (3 processor 먼저 정의하지 마라)

screenCapture_2025-05-22_14.16.56



compute instance 기준으로도 slice할 수 있다.

  • 예컨대 위 예시는 2 * 2c.4g.20gb로, 메모리는 공유하되 compute process는 분리하는 것.
  • 대신 이렇게 되면 isolation이 깨진다. 메모리를 공유하기 때문. 문제가 생기면 kick process하는 과정에서 다른 작업에 영향이 갈 수 있다.
  • 따라서 K8s에서는 compute instance 기준 slice는 지원하지 않고 있다

Time-Slicing

screenCapture_2025-05-22_15.52.16

 

screenCapture_2025-05-22_16.00.25

 

screenCapture_2025-05-22_16.00.10



여러 개의 process가 take turns of GPU. context switching처럼 일정 시간 단위로 GPU를 공유하면서 쓰는 것.

  • configmap에서 설정하면 된다
    • replica 개수를 설정해야 하는데, 기준은 해당 GPU node에서 실행 가능한 Max Pod 개수.
    • 위 예시를 보면 두 개의 slice가 있다. 하나는 replica 4, 하나는 replica 10
  • 설정하면, Node의 label에 replicas 개수가 저장되고, allocatable gpu 개수는 (gpu count * replica)가 된다.

renameByDefault 필드를

  • true: gpu product 이름은 그대로 두고 allocatable 항목의 gpu를 shared로 라벨링한다.
    • pod spec을 쓸 때 resource 정의 부분에서 "shared resource"를 호출할 것임을 알 수 있음
  • false: allocatable 항목은 그냥 gpu로 남고, product 이름이 shared로 바뀐다.
    • pod spec 쓰는 입장에서는 node selector의 label을 보면 shared resource라는 걸 알 수 있음

MIG vs Time-Slicing

screenCapture_2025-05-22_16.04.10



MIG는 하드웨어 샤딩이고, time-slicing은 논리적 단위.

  • times slicing에서도 partition이 너무 많으면, Context switching 비용이 너무 커질 수 있으므로 유의할 것.
  • QoS 관점
    • MIG는 물리적인 분리이므로 다양한 QoS를 보장함. processor / memory...
    • time-slicing은 '동등한 시간'만을 QoS로 보장하며, 하드웨어 리소스의 QoS는 보장하지 않음. replica 개수가 많아질수록, 개별 pod가 점유할 수 있는 하드웨어 리소스 사용량은 줄어들게 됨
  • Error isolation의 경우 time-slicing은 보장 못함.
    • Process fail -> restart gpu -> other process kills as well

Managing GPU Resources in kubernetes

screenCapture_2025-05-22_14.17.57



nvidia에서 제공하는 Operator를 설치하면 됨.

  • 다양한 클러스터 (AWS EKS, GCP GKE...)를 지원
  • BareMetal, VM, vGPU 지원
  • docker / containerd 등 container runtime 지원

helm install 형태로 설치 가능.

screenCapture_2025-05-22_14.18.20



설치하면 Daemonset으로 nvidia-gpu-plugin이 배포된다. Daemonset의 용도는 gpu 관련 정보를 노드에 label로 추가하는 것.

  • how many cards (GPU) you have on your node
  • GPU capabilities 정보
    • cuda runtime version
    • mig strategy
    • nvidia driver version
    • etc...

 

screenCapture_2025-05-22_14.18.20



GPU 사용하는 Pod를 정의하기

  • nodeSelector 옵션으로 gpu product label 명시 (사용하고 싶은 GPU 설정이 있는 node label을 명시하면 됨)
  • resources.limits.nvidia.com/gpu: 1

screenCapture_2025-05-22_14.58.25



GPU 안쓰는 workload는 GPU node에 스케줄되면 안 된다.

  • lock을 잡아서, gpu가 필요한 pod가 적절한 노드에 스케줄되지 못하기 때문.
  • 반대로, gpu 다 쓰고 반납해야 하는데 반납을 못하는 경우도 생길 수 있음

이런 경우 taint 써서 스케줄링하는 게 좋다. 필요한 pod에 toleration

 

screenCapture_2025-05-22_14.58.31



namespace Quota를 붙여서 gpu 요청량을 제한할 수도 있다.

Sharing GPU between Containers

screenCapture_2025-05-22_15.02.28

 

screenCapture_2025-05-22_15.02.39



보통 k8s pod에서 resource 정의할 때는 fractional request가 가능했다. cpu: 0.25m 같은 형태.

gpu는 nvidia plugin에서 지원하는 문법을 따르는데, 두 가지 한계점이 있다.

  • integer type만 지원한다. fractional request는 허용되지 않음
  • overcommitted / undercommit 불가능. 하나의 GPU를 여러 pod에 나눠서 동시에 실행할 수 없다.
    • 1 GPU에는 1 pod만 실행될 수 있다.
    • pod가 요청한 gpu 수의 합계가 실제 노드의 gpu 수를 초과하면 pending상태가 됨
    • request와 limit은 값이 똑같아야 함.

screenCapture_2025-05-22_15.35.30

 

screenCapture_2025-05-22_15.35.40



그래서 workaround를 적용해야 함. 그 방법 중 하나가 Multi-instance GPU (MIG)

  • 하나의 A100 GPU를 7개의 instance로 샤딩했으므로, allocatable resource는 7이 된다. (1 Card, 7 instances)

helm으로 설치할 때 MIG Manager 옵션을 활성화하면 됨.

screenCapture_2025-05-22_15.46.53

mig.strategy 필드는 single / mixed 두 가지 옵션이 있음.

  • single: nvidia.com/gpu: "7" 형태로 allocatable instance 갯수만 명시.
    • label을 보면, 이 gpu가 어떤 방식으로 partitioning되었는지 알 수 있음.
  • mixed: partition naming을 명시할 수 있음.
    • 노드마다 GPU 스펙이나 종류가 달라서 다르게 대응하고 싶을 때 유용하다.

screenCapture_2025-05-22_15.46.59



MIG-manager는 GPU Operator namespace에 배포된 Configmap 정보를 사용한다.

  • profile 정보를 저장해두고 재사용하기 위한 목적
  • 혹시라도 정보가 수정되면, configmap 값 바꾸고 MIG Controller 재시작하면 된다

Techniques for Optimizing Deep Learning Workloads

screenCapture_2025-05-22_16.10.36



Low precision arithmetic

  • fp16: 정밀도가 낮은 대신 연산 속도가 빠르다. fp32 타입보다 메모리 사용량도 절반 수준임.
  • 사람 눈으로 구별하기 어려운 수준의 이미지라면 연산속도 빠르고 리소스 덜 먹는 게 좋음

Attention slicing / Flash attention (for Transformers)

  • transformers는 matrix 연산을 하는데, O(n^2) 메모리 사용.
  • fuse operation (연산 여러 개를 하나의 레이어로 합쳐서 효율을 높이는 것) / softmax 등으로 O(n) 메모리 사용하도록 한다

Speculative Decoding

  • LLM의 추론속도 높이기 위한 목적. 강연에서 자세한 설명은 하지 않았음.

Distilation

  • Train Small model with large Teacher model.

Summary

screenCapture_2025-05-22_16.19.14

Q&A

Q1. MIG 설정 바꾸면 driver system만 리부트해야 함? 아니면 시스템 전체 리부트해야 함?

  • 이론상으로는 GPU 관련 프로세스만 reboot하면 됨. 모든 프로세스를 날리면 GPU reboot이 된다.
    • 문제는, telemetry 등 GPU 사용량 측정을 위한 프로세스도 GPU에 붙어 있거나 하기에... 이런 거 하나씩 다 찾아서 프로세스 내려줘야함.
    • 그래서 보통은 그냥 시스템 전체 리부트한다.

Q2. MIG이랑 time-slicing을 동시에 쓸 수 있나?

  • 가능함. MIG으로 나누고, 나눠진 각 instance에 time-slicing 적용하면 됨

Q3. 뭐라는지 안들림

  • nvidia GPU Operator: enterprise usecase라면 라이센스 필요
반응형