머신러닝과 딥러닝이 기업의 핵심 전략으로 자리 잡으면서 데이터 과학자들은 점점 더 복잡하고 연산 집약적인 모델을 다루게 되었습니다. 이러한 모델을 학습시키거나 배포할 때는 막대한 계산 자원이 필요하며, 특히 GPU는 병렬 연산에 강점을 갖기 때문에 필수적인 선택지입니다.
하지만 기존 GPU 사용 방식에는 여러 가지 한계가 존재했습니다.
문제점 | 설명 |
환경 구성의 복잡성 | CUDA, cuDNN 등 복잡한 드라이버 스택 설치가 필요하며, 프레임워크마다 요구하는 버전이 달라 호환성 문제가 빈번하게 발생 |
재현성 부족 | 동일한 환경을 다른 시스템에서 구현하기 어려움 |
리소스 비효율성 | GPU 리소스가 특정 프로젝트나 사용자에 고정되어 활용도가 낮은 편 (일반적으로 30% 미만 활용률) |
확장성 한계 | 새로운 서버를 추가할 때마다 복잡한 환경 구성을 반복해야 하는 부담이 존재 |
결국 컨테이너 기술이 이러한 문제를 해결할 대안으로 부상했습니다.
컨테이너는 다음과 같은 Linux 커널 기능에 기반하여 리소스를 효율적으로 관리하는 구조입니다.
하지만 GPU와 같은 특수 하드웨어 장치에 대해서는 여전히 다음과 같은 제약이 있었습니다.
이런 문제를 해결하기 위해 나온 기술이 바로 MIG 와 vGPU 입니다.
■ MIG(Multi-Instance GPU)
MIG는 하나의 물리적인 GPU를 여러 개의 독립된 인스턴스로 나누어 사용하는 기술로 NVIDIA의 A100 GPU에서 처음 도입되었으며, 하드웨어 수준에서 메모리, 캐시, 컴퓨팅 코어가 완전히 격리됩니다.
참고 : https://blogs.nvidia.co.kr/blog/multi-instance-gpus/
■ vGPU(Virtual GPU)
vGPU는 하이퍼바이저 계층에서 GPU를 가상화하여 여러 가상 머신이 GPU 리소스를 공유하는 방식입니다.
참고 : 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 자원을 더욱 효율적으로 활용하는 방법을 제시하고 있습니다.
AWS에서는 GPU 인스턴스 타입을 포함하여 Accelerated Computing (가속 컴퓨팅) 카테고리로 분류합니다.
Accelerated Computing 인스턴스는 하드웨어 액셀러레이터 또는 코프로세서를 사용하여 CPU 기반 소프트웨어보다 훨씬 빠르게 특정 작업을 처리할 수 있도록 설계되어 있습니다.
대표적으로 부동 소수점 수 계산, 그래픽 처리, 데이터 패턴 일치 등 고성능 연산이 필요한 워크로드를 지원합니다.
♣ 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 신청을 진행해야 합니다.
2. 로컬 환경 준비
실습을 위해 로컬 개발 환경에 다음 도구들이 설치되어 있어야 합니다.
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 노드 그룹을 추가할 계획입니다.
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
# 참고: 노드 그룹 스케일링 (할당량 한도 내에서 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
# 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}'
eksdemo delete cluster gpusharing-demo
■ 분산 학습에서 발생하는 네트워크 병목 현상
대규모 모델의 등장은 단일 GPU만으로 학습이 불가능한 시대를 만들었습니다.
AWS 역시 이러한 흐름에 맞춰 인프라를 발전시키고 있습니다.
2025년 현재 AWS는 대규모 모델 학습과 추론을 위해 분산 컴퓨팅 기술을 적극적으로 활용하고 있으며, 단일 GPU로는 감당할 수 없는 모델 개발을 지원하고 있습니다.
이러한 초대형 모델들은 필연적으로 여러 GPU와 여러 노드에 걸친 분산 학습이 요구됩니다.
■ 분산 학습 주요 통신 패턴
■ 분산 학습 시 발생하는 주요 이슈
분산 학습에서 GPU 간 통신 성능이 매우 중요해지면서 NVIDIA는 NCCL(NVIDIA Collective Communications Library)을 개발했습니다.
NCCL은 여러 GPU 간 집합 통신 연산을 최적화하기 위해 설계된 라이브러리입니다.
■ NCCL 주요 특징
NCCL은 PyTorch, TensorFlow 같은 주요 딥러닝 프레임워크에 통합되어 있어 사용자가 명시적으로 통신 코드를 작성하지 않아도 효율적인 분산 학습이 가능하도록 돕습니다.
다만, NCCL만으로는 노드 간 네트워크 병목 현상을 완전히 해결할 수 없습니다.
GPU 네트워크 병목 문제를 해결하기 위해 AWS는 EFA(Elastic Fabric Adapter)를 설계했습니다.
■ EFA 핵심 기술
EFA 지원 인스턴스 : https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/efa.html#efa-instance-types
■ Amazon EKS와 EFA 통합 시 기대 효과
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 할당량을 상향 조정한 후 관련 실습을 재진행할 계획입니다.
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 |