GPU 오토스케일링과 대형 모델 배포 운영
개요
LLM 서빙 운영에서 GPU 가동 시간은 비용과 직결되며, 트래픽 변동에 맞춰 자원을 탄력적으로 확장·축소하는 오토스케일링이 효율성의 핵심입니다. 본 문서는 LLM 서빙에 특화된 2-Tier 스케일링(Pod·노드), DRA(Dynamic Resource Allocation)의 현실적 제약, 그리고 GLM-5(744B), Kimi K2.5(1T) 등 대형 MoE 모델 배포 과정에서 축적된 실전 운영 교훈을 정리합니다.
GPU 비용 최적화(Spot·Consolidation·시간대별 스케줄링)는 EKS 비용 관리, GPU·vLLM 모니터링과 Cascade Fallback은 Agent 모니터링 & 운영, 온프레미스 GPU 통합은 EKS Hybrid Nodes 완전 가이드를 참조하세요.
GPU 리소스 관리 & 오토스케일링
2-Tier 스케일링 아키텍처
LLM 서빙에서는 Pod 스케일링과 노드 스케일링을 2단계로 구성합니다.
KEDA 스케일링 구성
LLM 서빙의 핵심 스케일링 시그널 3가지:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: llm-inference-scaler
spec:
scaleTargetRef:
name: vllm-deployment
minReplicaCount: 2
maxReplicaCount: 8
triggers:
# 1. KV Cache 포화 — 가장 민감한 시그널
- type: prometheus
metadata:
query: avg(vllm_gpu_cache_usage_perc)
threshold: "80"
# 2. 대기 중인 요청 수
- type: prometheus
metadata:
query: sum(vllm_num_requests_waiting)
threshold: "10"
# 3. TTFT SLO 위반 근접
- type: prometheus
metadata:
query: |
histogram_quantile(0.95,
rate(vllm_time_to_first_token_seconds_bucket[5m]))
threshold: "2"
Disaggregated Serving 스케일링 기준
Prefill과 Decode의 병목 시그널이 다릅니다.
| Prefill | Decode | |
|---|---|---|
| 병목 시그널 | TTFT 증가, 입력 큐 적체 | TPS 감소, KV Cache 포화 |
| 스케일 기준 | 입력 토큰 처리 대기시간 | 동시 생성 세션 수 |
| GPU 특성 | Compute 집약 (연산 병목) | Memory 집약 (대역폭 병목) |
DRA(Dynamic Resource Allocation) 현실
DRA는 K8s 1.34에서 GA(resource.k8s.io/v1, 기본 활성화)되어 GPU 파티셔닝/토폴로지 인식 스케줄링을 제공합니다. 그러나 Karpenter/Auto Mode와 호환되지 않는 아키텍처적 한계가 있습니다.
- Karpenter는 노드 생성 전 GPU 리소스를 시뮬레이션해야 하는데, DRA의 ResourceSlice는 노드 생성 후 DRA Driver가 발행
- 이 "닭과 달걀" 문제로 인해 DRA Pod는 Karpenter에서 skip됨
- DRA 사용 시: MNG + Cluster Autoscaler 필수
DRA가 필요한 경우: MIG 파티셔닝, CEL 기반 속성 GPU 선택, P6e-GB200 환경
Device Plugin이 충분한 경우: 전체 GPU 단위 할당, Karpenter/Auto Mode 사용
GPU 스케일링·DRA의 기초 개념은 GPU 리소스 관리를 참조하세요.
실전 교훈: 대형 MoE 모델 배포
이미지/모델 다운로드 실패 대응
대형 모델(744GB+)의 가중치 다운로드는 LLM 서빙에서 가장 흔한 Cold Start 병목입니다. HuggingFace Hub에서 수백 GB를 다운로드할 때 네트워크 불안정, 타임아웃, 디스크 부족 등으로 자주 실패합니다.
문제 유형과 대응
| 문제 | 증상 | 대응 |
|---|---|---|
| HF Hub 다운로드 타임아웃 | Pod CrashLoopBackOff, ConnectionError | 재시도 + resume 지원 (HF_HUB_ENABLE_HF_TRANSFER=1) |
| 대형 파일 부분 다운로드 | 모델 로딩 시 corruption 에러 | 체크섬 검증 + 재다운로드 |
| 컨테이너 이미지 Pull 느림 | ImagePullBackOff, 수 분 대기 | 이미지 사전 캐싱 (Bottlerocket 데이터 볼륨, SOCI) |
| 멀티노드 동시 다운로드 | 네트워크 대역폭 경합 | S3 캐싱 + init container 순차 로딩 |
| EFS 느린 다운로드 | 로딩 시간 30분+ | NVMe emptyDir로 전환 |
전략 1: HuggingFace Transfer 가속
hf_transfer는 Rust 기반 고속 다운로드 라이브러리로, 기본 다운로드 대비 3-5배 빠릅니다.
env:
- name: HF_HUB_ENABLE_HF_TRANSFER
value: "1"
- name: HF_TOKEN
valueFrom:
secretKeyRef:
name: hf-token
key: token
# 다운로드 재시도 설정
- name: HF_HUB_DOWNLOAD_TIMEOUT
value: "600" # 10분 타임아웃
전략 2: S3 사전 캐싱 + Init Container
가장 안정적인 방법입니다. 모델 가중치를 S3에 미리 업로드하고, init container에서 로컬 NVMe로 복사합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-with-s3-cache
spec:
template:
spec:
initContainers:
# 1단계: S3에서 NVMe로 모델 다운로드
- name: model-downloader
image: amazon/aws-cli:latest
command: ["/bin/sh", "-c"]
args:
- |
echo "Checking local cache..."
if [ -f /models/config.json ]; then
echo "Model already cached, skipping download"
exit 0
fi
echo "Downloading model from S3..."
aws s3 sync s3://model-cache/qwen3-32b-fp8/ /models/ \
--no-progress \
--expected-size 65000000000
echo "Download complete, verifying..."
# 체크섬 검증
if [ -f /models/model.safetensors.index.json ]; then
echo "Model verified successfully"
else
echo "ERROR: Model incomplete, retrying..."
rm -rf /models/*
aws s3 sync s3://model-cache/qwen3-32b-fp8/ /models/
fi
volumeMounts:
- name: model-cache
mountPath: /models
resources:
requests:
cpu: 2
memory: 4Gi
containers:
- name: vllm
image: vllm/vllm-openai:v0.23.0
args:
- /models
- "--gpu-memory-utilization=0.95"
volumeMounts:
- name: model-cache
mountPath: /models
volumes:
- name: model-cache
emptyDir:
sizeLimit: 200Gi # NVMe emptyDir
전략 3: 컨테이너 이미지 사전 캐싱
vLLM/SGLang 이미지(10-20GB)의 Pull 시간을 줄이는 방법입니다.
# Karpenter NodePool에서 이미지 사전 Pull 활성화
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu-inference
spec:
template:
spec:
kubelet:
# 이미지 GC 임계값을 높여 캐시 유지
imageGCHighThresholdPercent: 90
imageGCLowThresholdPercent: 85
SOCI (Seekable OCI) 인덱스 활용:
ECR에 SOCI 인덱스를 생성하면 이미지를 lazy-loading으로 Pull하여 컨테이너 시작 시간을 70-80% 단축합니다.
# SOCI 인덱스 생성 (ECR)
aws soci create \
--image-uri 123456789012.dkr.ecr.us-east-2.amazonaws.com/vllm:v0.6.3
# EKS Auto Mode는 SOCI를 자동 지원
# Karpenter: Bottlerocket AMI 사용 시 SOCI 네이티브 지원