상세 컨텐츠

본문 제목

11주차 - ML Infra(GPU) on EKS

[AWS]/[EKS]

by scdo 2025. 4. 20. 02:27

본문

1. AI 워크로드에 대한 컨테이너 사용

머신러닝과 딥러닝이 기업의 핵심 전략으로 자리 잡으면서 데이터 과학자들은 점점 더 복잡하고 연산 집약적인 모델을 다루게 되었습니다. 이러한 모델을 학습시키거나 배포할 때는 막대한 계산 자원이 필요하며, 특히 GPU는 병렬 연산에 강점을 갖기 때문에 필수적인 선택지입니다.

하지만 기존 GPU 사용 방식에는 여러 가지 한계가 존재했습니다.

문제점 설명
환경 구성의 복잡성 CUDA, cuDNN 등 복잡한 드라이버 스택 설치가 필요하며, 프레임워크마다 요구하는 버전이 달라 호환성 문제가 빈번하게 발생
재현성 부족 동일한 환경을 다른 시스템에서 구현하기 어려움
리소스 비효율성 GPU 리소스가 특정 프로젝트나 사용자에 고정되어 활용도가 낮은 편 (일반적으로 30% 미만 활용률)
확장성 한계 새로운 서버를 추가할 때마다 복잡한 환경 구성을 반복해야 하는 부담이 존재

 

결국 컨테이너 기술이 이러한 문제를 해결할 대안으로 부상했습니다.

 

컨테이너는 다음과 같은 Linux 커널 기능에 기반하여 리소스를 효율적으로 관리하는 구조입니다.

  • Cgroups (Control Groups) : 프로세스들이 사용할 수 있는 CPU, 메모리, 디스크 I/O, 네트워크 등 자원을 제한하거나 격리
  • Namespaces : 프로세스가 시스템의 특정 리소스만 볼 수 있도록 격리하는 기능으로, PID, 네트워크, 마운트, UTS, IPC, 사용자 등 다양한 유형이 존재

하지만 GPU와 같은 특수 하드웨어 장치에 대해서는 여전히 다음과 같은 제약이 있었습니다.

  • GPU는 CPU 코어나 메모리와 달리, 초기에는 물리적으로 분할하여 여러 컨테이너에서 동시에 사용하기 어려웠음
  • GPU 드라이버와 라이브러리 복잡성, 그리고 /dev/nvidia* 와 같은 장치 파일 접근 제어가 필요했음

이런 문제를 해결하기 위해 나온 기술이 바로 MIGvGPU 입니다.

■ MIG(Multi-Instance GPU)

MIG는 하나의 물리적인 GPU를 여러 개의 독립된 인스턴스로 나누어 사용하는 기술로 NVIDIA의 A100 GPU에서 처음 도입되었으며, 하드웨어 수준에서 메모리, 캐시, 컴퓨팅 코어가 완전히 격리됩니다.

  • 최대 7개의 GPU 인스턴스를 하나의 A100 GPU에서 제공
  • 서로 다른 작업이 완전히 독립된 환경에서 실행 가능
  • 각 인스턴스별로 별도의 워크로드 수행
  • 필요에 따라 인스턴스 프로비저닝 가능  
    • 예 : NVIDIA A100 40GB GPU로 20GB 인스턴스 2개 또는 10GB 인스턴스 2개 + 5GB 인스턴스 4개 구성 가능와 같은 구성이 가능합니다.
  • 주의 : 베어메탈 환경에서도 사용 가능하지만 NVIDIA GPU에 의존 (다른 벤더 GPU에서는 불가능)
참고 : https://blogs.nvidia.co.kr/blog/multi-instance-gpus/

 

■ vGPU(Virtual GPU)

vGPU는 하이퍼바이저 계층에서 GPU를 가상화하여 여러 가상 머신이 GPU 리소스를 공유하는 방식입니다.

  • GPU 메모리를 vGPU마다 전용 구간으로 할당
  • 컴퓨팅 자원은 time-shared 방식으로 나눔
  • vGPU 소프트웨어가 하이퍼바이저와 함께 설치되어 vCPU처럼 vGPU 제공
  • GPU 기능을 여러 VM으로 확장
  • 서로 다른 작업이나 사용자 간 데이터 분리
  • 클라우드 서비스 제공업체에서 GPU as a Service 형태로 활용
참고 : https://www.nvidia.com/ko-kr/data-center/virtualization/it-management/

 

♣ 컨테이너 환경 내 GPU 사용 방식의 발전

① 초기 단계 (2016~2018)

초기에는 GPU 장치 파일을 컨테이너에 직접 마운트하고 라이브러리를 공유하는 방식이 사용되었습니다.

docker run --device=/dev/nvidia0:/dev/nvidia0 \
           --device=/dev/nvidiactl:/dev/nvidiactl \
           -v /usr/local/cuda:/usr/local/cuda \
           tensorflow/tensorflow:latest-gpu

※ 문제점

· 장치 파일을 수동으로 지정해야 했음

· 호스트와 컨테이너 간 라이브러리 버전 충돌 가능성이 존재

· 여러 컨테이너 간 GPU 공유 메커니즘이 부재

· 오케스트레이션 도구를 통한 자동화가 어려웠음

 

② NVIDIA Container Runtime (2018~2020)

NVIDIA에서는 이러한 문제를 해결하기 위해 Container Runtime을 개발하여 Docker, CRI-O 등에서 사용할 수 있도록 지원합니다.

※ 주요 기능

· GPU 장치 파일 자동 마운트

· NVIDIA 드라이버 라이브러리 자동 주입

· CUDA 호환성 검사

· GPU 기능 자동 감지 및 노출

# Docker 19.03 이전
docker run --runtime=nvidia nvidia/cuda:11.0-base nvidia-smi

# Docker 19.03 이후
docker run --gpus '"device=0,1"' nvidia/cuda:11.0-base nvidia-smi

◎ 개선 사항

· GPU 검출 및 설정이 자동화되어 관리가 간편함

· 호스트와 컨테이너 간 드라이버 호환성이 자동으로 관리됨

· 컨테이너 이미지 이식성이 향상됨

 

③ Kubernetes 장치 플러그인 (2020~현재)

Kubernetes는 Device Plugin을 통해 GPU 리소스를 선언적으로 관리할 수 있도록 발전하였습니다.
대표적으로 NVIDIA Device Plugin이 사용되며, Pod 스펙에 GPU 리소스를 선언하여 요청할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: gpu-container
    image: nvidia/cuda:11.0-base
    command: ["nvidia-smi"]
    resources:
      limits:
        nvidia.com/gpu: 2

※ 장점

· 선언적 리소스 관리가 가능함

· 클러스터 수준에서 GPU 리소스를 스케줄링할 수 있음

· GPU 할당 및 격리가 자동화되어 운영 효율성이 높아짐

· 다중 테넌트 환경에서도 공정한 리소스 분배가 가능함

 

♣ GPU 활용 방식

방식 설명 사용 사례
CUDA 단일 프로세스 단일 프로세스가 GPU 전체를 사용하는 기본적인 방식 독립형 애플리케이션, GPU 성능이 필요한 작업
CUDA MPS (Multi-Process Service) 여러 프로세스가 단일 GPU 컨텍스트를 공유하는 방식 여러 애플리케이션이 동시에 GPU를 사용해야 하는 경우
시간 분할 (Time-Slicing) GPU 접근 시간을 분할하여 다수의 작업이 사용하도록 구성 간헐적으로 GPU 접근이 필요한 다중 작업 환경
MIG (Multi-Instance GPU) GPU를 하드웨어 수준에서 다수 인스턴스로 분할하여 사용하는 방식 격리가 필요한 다중 테넌트 환경, 클라우드 데이터센터
vGPU (Virtual GPU) 하이퍼바이저 기반으로 GPU를 가상화하는 방식 VM 간 GPU 공유, 서비스형 GPU 제공

 

참고 : AWS에서는 Kubernetes 환경에서 vGPU와 NVIDIA MPS를 결합하여 GPU 자원을 더욱 효율적으로 활용하는 방법을 제시하고 있습니다.

출처 - https://aws.amazon.com/ko/blogs/opensource/virtual-gpu-device-plugin-for-inference-workload-in-kubernetes/


AWS에서 지원하는 GPU 인스턴스 타입

AWS에서는 GPU 인스턴스 타입을 포함하여 Accelerated Computing (가속 컴퓨팅) 카테고리로 분류합니다.
Accelerated Computing 인스턴스는 하드웨어 액셀러레이터 또는 코프로세서를 사용하여 CPU 기반 소프트웨어보다 훨씬 빠르게 특정 작업을 처리할 수 있도록 설계되어 있습니다.
대표적으로 부동 소수점 수 계산, 그래픽 처리, 데이터 패턴 일치 등 고성능 연산이 필요한 워크로드를 지원합니다.

출처 - https://aws.amazon.com/ko/ec2/instance-types/#Accelerated_Computing
AI/ML을 위한 인스턴스 유형, 출처 - https://reinvent.awsevents.com/content/dam/reinvent/2024/slides/cmp/CMP207_AWS-accelerated-computing-enables-customer-success-with-generative-AI.pdf

 

♣ AWS GPU 기반 주요 인스턴스 타입

인스턴스 시리즈 설명
P 시리즈 머신러닝 학습, 고성능 컴퓨팅 (HPC), 과학적 시뮬레이션에 적합한 인스턴스
G 시리즈 기계 학습 추론, 그래픽 애플리케이션 가속 및 고해상도 스트리밍에 최적화
Inf 시리즈 머신러닝 추론 전용으로 설계된 AWS 자체 ML 칩인 Inferentia 기반 인스턴스
Trn 시리즈 AWS Trainium 칩 기반 인스턴스로, 대규모 딥러닝 모델 학습에 최적화
VT 시리즈 AWS Graviton 프로세서 기반 인스턴스로, 다양한 가상 데스크톱 및 그래픽 집약형 워크로드 지원
F 시리즈 FPGA(현장 프로그래머블 게이트 어레이) 기반으로, 맞춤형 하드웨어 가속 워크로드 처리

▶ 실습 환경 구성

1. Quota 신청

GPU Time-Slicing 실습을 진행하기 위해서는 AWS 계정에 적절한 EC2 인스턴스 Quota 가 설정되어 있어야 합니다.
Quota가 충분하지 않을 경우 실습 진행이 불가능하므로, 먼저 Quota 신청을 진행해야 합니다.

  • “on-demand G”로 검색 → “Running On-Demand G and VT instances” 선택 →  “Request increase at account level” 클릭 →  원하는 vCPU 수량 입력 (예: 24) →  요청 제출
  • trn 및 inf 인스턴스 타입도 동일한 방식으로 요청 가능

2. 로컬 환경 준비

실습을 위해 로컬 개발 환경에 다음 도구들이 설치되어 있어야 합니다.

  • eksdemo : Amazon EKS 학습 및 데모용 도구
  • helm : Kubernetes 패키지 매니저
  • AWS CLI : AWS 명령줄 인터페이스 도구
  • kubectl : Kubernetes 클러스터를 제어하는 명령줄 도구
  • jq : JSON 데이터를 필터링 및 가공하는 도구
  • Terraform : 인프라스트럭처를 코드로 관리하는 도구

 [실습 준비 1] GPU Time-slicing on Amazon EKS(약 20분 소요)

Amazon EKS 클러스터를 생성하여 GPU Time-Slicing을 위한 환경을 준비합니다.
초기에는 일반 t3.large 인스턴스를 사용하여 클러스터를 구성하고, 이후 단계에서 GPU 노드 그룹을 추가할 예정입니다.

# EKS 클러스터 생성을 Dry-run으로 실행하여 예상되는 리소스 구성 확인
eksdemo create cluster gpusharing-demo -i t3.large -N 2 --region us-west-2 --dry-run

# EKS 클러스터 생성
eksdemo create cluster gpusharing-demo -i t3.large -N 2 --region us-west-2

※ 이후 단계에서 GPU 노드 그룹을 추가할 계획입니다.

dry-run
클러스터 생성 완료
AWS 콘솔 확인

 

 [실습 준비 2] GPU Time-Slicing on Amazon EKS - GPU 노드 그룹 추가

Amazon EKS 클러스터에 GPU Time-Slicing을 위한 노드 그룹을 추가하여 g5.2xlarge 인스턴스를 사용하는 환경을 구성합니다.

(g5.8xlarge 인스턴스로 실습하려고 하였으나 Service Quotas를 8로 신청하여 g5.2xlarge로 진행하게 되었습니다.)

※ 실습 계획
EC2 인스턴스 타입: g5.2xlarge(GPU 가속이 적용된 인스턴스, NVIDIA A10G GPU 포함)
노드 수: 1대
클러스터 이름: gpusharing-demo
실습 명령어: eksdemo 사용 (AWS EKS 데모 클러스터 관리 도구)
# Dry-run 모드로 실행하여 실제로 리소스를 생성하지 않고 확인
eksdemo create nodegroup gpu -i g5.2xlarge -N 1 -c gpusharing-demo --dry-run

# 실제로 GPU 노드 그룹 생성
eksdemo create nodegroup gpu -i g5.2xlarge -N 1 -c gpusharing-demo

dry-run
생성 완료
AWS 콘솔 확인

 

 [실습진행] Amazon EKS GPU Time-slicing 미사용 환경 테스트

노드 확인
g5 - GPU 노드에 label 지정

# 참고: 노드 그룹 스케일링 (할당량 한도 내에서 2 등으로 변경 가능)
eksctl scale nodegroup --name gpu --cluster gpusharing-demo --nodes 2
# nvidia-device-plugin을 helm을 사용하여 설치
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update
helm upgrade -i nvdp nvdp/nvidia-device-plugin \
  --namespace kube-system \
  --set nodeSelector.eks-node=gpu \
  --version 0.14.0

설치 완료

# time-slicing을 활성화하지 않았을 때: GPU가 1개임
kubectl get nodes -o json | jq -r '.items[] | select(.status.capacity."nvidia.com/gpu" != null) | {name: .metadata.name, capacity: .status.capacity}'

확인

 

◎ GPU 모델 배포

# 네임스페이스 생성
kubectl create namespace gpu-demo
cat << EOF > cifar10-train-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tensorflow-cifar10-deployment
  namespace: gpu-demo
  labels:
    app: tensorflow-cifar10
spec:
  replicas: 5
  selector:
    matchLabels:
      app: tensorflow-cifar10
  template:
    metadata:
      labels:
        app: tensorflow-cifar10
    spec:
      containers:
      - name: tensorflow-cifar10
        image: public.ecr.aws/r5m2h0c9/cifar10_cnn:v2
        resources:
          limits:
            nvidia.com/gpu: 1
EOF
# 배포
kubectl apply -f cifar10-train-deploy.yaml

상태 살펴보기: 모델 다운로드 중
시간이 지나면 ContainerCreating -> Running으로 변경됨
다른 pod를 조회해보면 GPU 리소스 부족으로 생성 불가능한 상황

 

 [실습진행] Amazon EKS GPU Time-slicing 사용 환경 테스트

# Time-slicing 적용하기
cat << EOF > nvidia-device-plugin.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nvidia-device-plugin
  namespace: kube-system
data:
  any: |-
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        resources:
        - name: nvidia.com/gpu
          replicas: 10
EOF
# 새로운 ConfigMap 기반으로 반영하기
helm upgrade -i nvdp nvdp/nvidia-device-plugin \
  --namespace kube-system \
  --version 0.14.0 \
  --set nodeSelector.eks-node=gpu \
  --set config.name=nvidia-device-plugin \
  --force
# 시간 지나고 다시 조회해보기
kubectl get nodes -o json | jq -r '.items[] | select(.status.capacity."nvidia.com/gpu" != null) | {name: .metadata.name, capacity: .status.capacity}'

GPU값이 변함
모두 실행됨
하지만 계속 재시작되고 있는 것을 확인할 수 있음
메모리 부족

 

  실습 완료 후 리소스 삭제

eksdemo delete cluster gpusharing-demo

2. 멀티 GPU 활용을 위한 AI/ML 인프라 with EKS

컨테이너 환경에서의 GPU 리소스 사용 진화 (멀티 GPU)

  분산 학습에서 발생하는 네트워크 병목 현상
대규모 모델의 등장은 단일 GPU만으로 학습이 불가능한 시대를 만들었습니다.

  • GPT-3: 1,750억 파라미터
  • Megatron-Turing NLG: 5,300억 파라미터
  • PaLM: 5,400억 파라미터

AWS 역시 이러한 흐름에 맞춰 인프라를 발전시키고 있습니다.

  • Amazon Bedrock은 100개 이상의 LLM을 지원
  • Trainium 및 Inferentia 칩을 통해 모델 성능 향상을 추구

2025년 현재 AWS는 대규모 모델 학습과 추론을 위해 분산 컴퓨팅 기술을 적극적으로 활용하고 있으며, 단일 GPU로는 감당할 수 없는 모델 개발을 지원하고 있습니다.
이러한 초대형 모델들은 필연적으로 여러 GPU와 여러 노드에 걸친 분산 학습이 요구됩니다.

 

■ 분산 학습 주요 통신 패턴

  • AllReduce : 딥러닝 학습 시 그래디언트(Gradient) 동기화를 위해 모든 GPU가 데이터를 교환하고 집계하는 방식

AllReduce, 출처 https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/usage/operations.html

 

  • AllGather : 각 GPU의 데이터를 모든 GPU에 복제하여 공유하는 방식

AllGather, 출처 - https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/usage/operations.html

 

  • ReduceScatter : 데이터를 집계(Reduce)한 후 나누어(Scatter) 각 GPU에 분산하는 방식

ReduceScatter, 출처 - https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/usage/operations.html

 

  분산 학습 시 발생하는 주요 이슈

  • 8개 GPU 노드 간 AllReduce 작업에서 최대 70%의 시간이 통신에 소모됨
  • GPU 활용률 저하 (60~70% 수준)
  • 학습 시간 증가 (최대 2~3배 소요)

NCCL: GPU 간 통신을 위한 NVIDIA의 해결책

분산 학습에서 GPU 간 통신 성능이 매우 중요해지면서 NVIDIA는 NCCL(NVIDIA Collective Communications Library)을 개발했습니다.
NCCL은 여러 GPU 간 집합 통신 연산을 최적화하기 위해 설계된 라이브러리입니다.

 

■ NCCL 주요 특징

  • 고성능 집합 통신 연산 지원 - AllReduce, Broadcast, Reduce, AllGather, ReduceScatter 등 딥러닝에서 핵심적인 통신 패턴을 최적화
  • 다양한 토폴로지 지원 - PCIe, NVLink, NVSwitch 등 GPU 간 연결 토폴로지를 자동으로 감지하고 최적화
  • 멀티 노드 확장성 확보 - InfiniBand, RoCE, IP 소켓 등을 통한 노드 간 통신 지원
  • CUDA 통합 - CUDA 스트림과 통합되어 계산과 통신의 오버랩이 가능

 

NCCL은 PyTorch, TensorFlow 같은 주요 딥러닝 프레임워크에 통합되어 있어 사용자가 명시적으로 통신 코드를 작성하지 않아도 효율적인 분산 학습이 가능하도록 돕습니다.
다만, NCCL만으로는 노드 간 네트워크 병목 현상을 완전히 해결할 수 없습니다.

 

AWS EFA (Elastic Fabric Adapter) 기술

GPU 네트워크 병목 문제를 해결하기 위해 AWS는 EFA(Elastic Fabric Adapter)를 설계했습니다.

EFA 아키텍처

 

■ EFA 핵심 기술

  • OS 바이패스 기술 - EFA는 운영 체제 커널을 우회하여 애플리케이션이 네트워크 어댑터와 직접 통신할 수 있도록 지원
    • 커널 컨텍스트 스위칭 제거
    • 시스템 콜 오버헤드 제거
  • RDMA (Remote Direct Memory Access) - 원격 시스템 메모리에 CPU 개입 없이 직접 접근 가능
    • 원격 시스템 CPU를 사용하지 않고 메모리 읽기/쓰기
    • Zero-copy 데이터 전송
    • DMA(Direct Memory Access) 기반 데이터 이동
  • NCCL과 EFA의 통합 - NVIDIA NCCL 라이브러리는 EFA와 최적화된 통합을 제공
    • GPU 직접 통신 최적화
    • 토폴로지 인식 통신 알고리즘
    • 자동 튜닝 메커니즘
EFA 지원 인스턴스 : https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/efa.html#efa-instance-types

 

■ Amazon EKS와 EFA 통합 시 기대 효과

  1. 인프라 관리 간소화
    • Kubernetes를 통한 선언적 인프라 관리
    • GPU 및 EFA 리소스 자동 검출 및 할당
    • 자동 확장 및 축소 기능 제공
  2. 비용 최적화
    • GPU 활용률을 90% 이상으로 향상
    • 학습 시간 단축으로 인스턴스 비용 절감
    • Spot 인스턴스와의 통합 가능성
  3. 성능 최적화
    • 노드 간 초저지연 통신
    • 분산 학습 확장성 향상
    • 대규모 모델 학습 가속화
  4. 개발자 경험 개선
    • 일관된 개발 및 배포 환경
    • 재현 가능한 실험 설정
    • CI/CD 파이프라인과의 통합 용이성

EKS Blueprint with Terraform 기반 환경에서 g5.8xlarge 인스턴스를 활용하여 RDMA(EFA) 미지원 구성을 전제로 한 실습들을 진행하고자 하였습니다.

[주요 실습 항목]

RDMA 미지원 g5.8xlarge 인스턴스를 활용한 EKS Blueprint 구성

MPI Operator를 활용한 Job 실행 테스트

EFA를 활용하지 않는 NCCL 기반 통신 테스트

 

다만 g5.8xlarge 인스턴스는 단일 노드당 32 vCPU를 필요로 하며, 당시 계정에 할당된 G/VT 계열 온디맨드 인스턴스의 vCPU 제한이 8로 설정되어 있어, Auto Scaling Group의 인스턴스 프로비저닝 단계에서 반복적으로 실패가 발생하였습니다.

 

이로 인해 실습 항목에 대한 테스트를 완전히 진행하지 못하였으며, 향후 vCPU 할당량을 상향 조정한 관련 실습을 재진행할 계획입니다.

'[AWS] > [EKS]' 카테고리의 다른 글

12주차 - Amazon VPC Lattice for Amazon EKS  (0) 2025.04.27
10주차 - K8S 시크릿 관리 (2)  (0) 2025.04.12
10주차 - K8S 시크릿 관리 (1)  (0) 2025.04.12
9주차 - EKS Upgrade  (0) 2025.04.03
8주차 - K8S CI/CD (3)  (0) 2025.03.30

관련글 더보기