
KAI Scheduler와 KubeAI로 실천하는 GPU 프랙셔널 공유와 갱 스케줄링
요약
KAI Scheduler와 KubeAI를 활용하여 Kubernetes 환경에서 GPU 자원을 효율적으로 관리하고 최적화하는 방법을 다룹니다. GPU 프랙셔널 공유, 갱 스케줄링, PrefixHash 로드 밸런싱을 통해 자원 유휴 시간을 줄이고 LLM 추론 성능을 극대화하는 기술적 메커니즘을 설명합니다.
핵심 포인트
- KAI Scheduler를 통한 GPU 프랙셔널 공유로 자원 유휴 시간 20~30% 절감
- KubeAI의 PrefixHash 기술로 LLM 추론 TTFT 95% 절감 및 처리량 향상
- 세컨더리 스케줄러 방식으로 기존 kube-scheduler와 병행 운영 가능
- 갱 스케줄링을 통한 분산 학습 작업의 부분 배치 문제 해결
-
KAI Scheduler를 사용한 GPU 프랙셔널 (Fractional) 공유 (0.25~0.5 GPU 단위)의 메커니즘과 설정 방법
-
갱 스케줄링 (Gang Scheduling)으로 분산 학습 작업의 부분 배치 문제를 해결하는 방법
-
KubeAI의 PrefixHash 로드 밸런싱이 LLM 추론의 TTFT를 95% 절감하는 메커니즘
-
계층형 큐와 시간 기반 페어 셰어 (Time-based Fair Share)를 통한 멀티테넌트 GPU 클러스터 운영
-
DRA (Dynamic Resource Allocation)와 KAI Scheduler를 결합한 2026년의 GPU 오케스트레이션 구성
대상 독자: Kubernetes 상에서 GPU 추론·학습 기반을 구축·운영하는 MLE 및 인프라 엔지니어 -
필요한 전제 지식:
- Kubernetes 기본 조작 (kubectl, Helm)
- GPU 워크로드 (PyTorch, vLLM 등)의 기초 이해
- Pod, Deployment, Namespace 등 Kubernetes 리소스의 개념
KAI Scheduler의 GPU 프랙셔널 공유와 bin packing 전략을 적용하면, 공식 문서에 따르면 GPU 파편화로 인한 20~30%의 유휴 시간을 절감할 수 있습니다. KubeAI의 PrefixHash 로드 밸런싱은 Llama 3.1 8B · L4 GPU × 8 환경의 벤치마크에서 TTFT (Time to First Token)를 95% 절감하고, 처리량(Throughput)을 127% 향상시켰다고 KubeAI 공식 블로그에서 보고되었습니다. 갱 스케줄링 (Gang Scheduling)을 통해 분산 학습의 부분 배치 문제가 해결되며, 계층형 큐와 시간 기반 페어 셰어 (Time-based Fair Share)로 멀티테넌트 환경의 공정한 GPU 배분이 실현됩니다.
KAI Scheduler (Kubernetes AI Scheduler)는 NVIDIA가 2025년 4월에 Apache 2.0 라이선스로 오픈 소스화한 GPU 워크로드 전용 스케줄러입니다. 원래는 Run:ai 플랫폼의 핵심 컴포넌트로 개발되었으며, 상용 버전인 NVIDIA Run:ai에도 계속 포함되어 있습니다.
KAI Scheduler는 기본 kube-scheduler와 병행하여 **세컨더리 스케줄러 (Secondary Scheduler)**로 동작합니다. GPU를 필요로 하는 Pod만 KAI Scheduler에 위임되며, CPU 중심의 워크로드는 기존 방식대로 kube-scheduler가 처리합니다.
KAI Scheduler의 내부 구조는 무한 루프로 다음 4단계를 반복합니다.
Snapshot: 클러스터 전체의 GPU/CPU/메모리 사용 상황을 캡처 -
FairShare: 각 큐의 Deserved Quota와 Over Quota 배분을 계산 -
Actions: 할당 (Allocation), 통합 (Consolidation), 회수 (Reclaim), 선점 (Preemption)을 실행 -
Update: PodGroup 및 큐의 상태를 업데이트
Helm을 사용하여 KAI Scheduler를 설치합니다.
# KAI Scheduler 설치 (GPU 공유 활성화, bin pack 전략)
helm upgrade -i kai-scheduler \
oci://ghcr.io/nvidia/kai-scheduler/kai-scheduler \
...
왜 세컨더리 스케줄러인가:
- kube-scheduler를 대체하는 것이 아니라, GPU 워크로드만을 대상으로 함으로써 기존 CPU 워크로드에 미치는 영향을 제로로 만드는 설계입니다.
- Karpenter와 같은 동적 클라우드 오토스케일러 (Auto-scaler)와의 호환성이 유지됩니다.
- 기존 클러스터 도입 시 단계적인 이행이 가능합니다.
주의 사항:
KAI Scheduler를 사용하는 Pod에서는 spec.schedulerName: kai-scheduler를 명시적으로 지정해야 합니다. 지정을 잊으면 기본 kube-scheduler로 처리되어 GPU 공유나 갱 스케줄링의 혜택을 받을 수 없습니다.
기존의 Kubernetes 디바이스 플러그인 (Device Plugin) 모델에서는 GPU를 정수 단위 (1, 2, 4...)로만 요청할 수 있었습니다. 추론 서비스와 같이 작은 GPU 메모리로도 충분한 워크로드에서도 1 GPU를 통째로 점유하게 되어, 고가의 GPU 리소스가 낭비됩니다.
KAI Scheduler는 GPU를 0.25, 0.5와 같은 분수 단위로 요청할 수 있는 프랙셔널 공유 (Fractional Sharing)를 실현합니다. 이를 통해 1대의 GPU에 여러 개의 Pod를 배치하여 이용률을 향상시킵니다.
KAI Scheduler에는 두 가지 GPU 할당 방식이 있습니다.
| 방식 | 어노테이션 (Annotation) | 지정 예시 | 유스케이스 (Use Case) |
|---|---|---|---|
| 비율 지정 | gpu-fraction | "0.5" | GPU 메모리의 50% 사용 |
| 절대값 지정 | gpu-memory | "2000" | 2000 MiB를 명시적으로 확보 |
다음은 GPU의 25%를 요청하는 Pod의 정의 예시입니다.
apiVersion: v1
kind: Pod
metadata
...
nvidia.com/gpu: 1은 디바이스 플러그인 (Device Plugin)에 대한 GPU 디바이스 요청이며, 실제 할당 비율은 gpu-fraction 어노테이션으로 제어됩니다. KAI Scheduler의 바인더 (Binder)가 리저베이션 포드 (Reservation Pod) 메커니즘을 통해 동일 GPU 상의 여러 Pod에 대한 할당을 관리합니다.
특정 모델에 필요한 메모리량을 알고 있는 경우에는 MiB 단위로 지정할 수 있습니다.
apiVersion: v1
kind: Pod
metadata
...
KAI Scheduler는 두 가지 스케줄링 (Scheduling) 전략을 제공하며, 워크로드 특성에 따라 구분하여 사용합니다.
# Bin Packing 설정 (ConfigMap)
apiVersion: v1
kind: ConfigMap
...
| 전략 | 동작 | 적용 시나리오 |
|---|---|---|
| Bin Packing | 소수의 노드에 Pod를 밀집시켜 배치하여 빈 노드를 확보 | 학습 작업 (Training Job): 대규모 작업을 위해 연속된 GPU 블록을 비워둠 |
| Spread | Pod를 노드 간에 분산 배치 | 추론 서비스 (Inference Service): 노드 장애 시 가용성 확보 |
흔히 하는 실수: 처음에는 모든 워크로드에 Bin Packing을 적용하고 싶어지지만, 추론 서비스에 Bin Packing을 적용하면 1개의 노드 장애로 인해 여러 추론 Pod가 동시에 다운될 위험이 있습니다. 추론에는 Spread, 학습에는 Bin Packing을 사용하는 구분 방식이 중요합니다.
KAI Scheduler가 프랙셔널 공유를 실현하는 메커니즘을 살펴보겠습니다.
리저베이션 Pod는 kai-resource-reservation 네임스페이스 (Namespace)에 생성되며, NVIDIA 런타임 클래스 (Runtime Class)를 통해 NVML에 접근하여 GPU의 UUID를 가져옵니다. 이 정보를 바탕으로 KAI Scheduler가 사용자의 워크로드를 올바른 물리 GPU에 할당합니다.
제약 조건:
KAI Scheduler는 메모리 격리나 제한을 강제하지 않습니다. 각 컨테이너는 자신의 GPU 메모리 사용량이 요청한 할당량 내에 들어오도록 스스로 관리해야 합니다. vLLM의 --gpu-memory-utilization 플래그나 PyTorch의 torch.cuda.set_per_process_memory_fraction()을 사용하여 제어하십시오.
분산 학습 작업 (예: PyTorch DDP 8 워커)을 Kubernetes에 제출하면, 기본 스케줄러는 각 Pod를 개별적으로 스케줄링합니다. 8개의 Pod 중 7개는 배치할 수 있었지만, 8번째 GPU 노드가 다른 작업에 의해 점유되어 있는 경우, 7개의 Pod는 GPU 리소스를 소비하면서 유휴 (Idle) 상태가 됩니다.
이것이 **부분 배치 문제 (Partial Admission)**이며, 대규모 GPU 클러스터에서 심각한 리소스 낭비의 원인이 됩니다.
KAI Scheduler는 PodGroup이라는 개념을 통해 여러 Pod를 하나의 원자적 (Atomic) 스케줄링 단위로 취급합니다. 모든 Pod가 동시에 배치될 수 있거나, 아니면 하나도 배치하지 않는 것 중 하나를 선택하는 방식 (all-or-nothing)입니다.
# PodGroup 정의 예시 (PyTorch 분산 학습)
apiVersion: scheduling.run.ai/v2
kind: PodGroup
...
KAI Scheduler에는 **빌트인 PodGrouper (Built-in PodGrouper)**가 탑재되어 있어, Kubeflow Training Operator, Ray (KubeRay), Argo Workflows 등 주요 프레임워크와 자동으로 연동됩니다. 수동으로 PodGroup을 생성하지 않아도 프레임워크의 작업(Job) 정의로부터 자동으로 PodGroup이 생성됩니다.
KAI Scheduler에서는 4가지 사전 정의된 우선순위 클래스 (Priority Class)를 사용할 수 있습니다.
| 우선순위 클래스 | 값 | 프리엠션 (Preemption) | 용도 |
|---|---|---|---|
inference | 125 | 불가 | 추론 서비스 (SLA 보장) |
build | 100 | 불가 | 인터랙티브 개발 |
build-preemptible | 75 | 가능 | 프리엠티블 (Preemptible) 개발 |
train | 50 | 가능 | 배치 학습 작업 |
우선순위 값 100 이상의 워크로드(Workload)는 **비프리엠티블 (Non-preemptible)**이며, 쿼터 (Quota) 내의 리소스만 사용할 수 있습니다. 100 미만은 프리엠티블하며 오버쿼터 (Over-quota) 리소스도 이용할 수 있지만, 더 높은 우선순위의 작업에 의해 밀려날(Evicted) 가능성이 있습니다.
# 추론 작업 (비프리엠티블)
apiVersion: v1
kind: Pod
...
트레이드오프 (Trade-off): 비프리엠티블한 추론 작업은 SLA가 보장되는 반면, 쿼터 범위 내에서만 리소스를 이용할 수 있습니다. 급격한(Burst) 추론 부하에 대응하려면 쿼터를 여유 있게 설정하거나, KubeAI의 스케일 아웃 (Scale-out) 기능과 조합해야 합니다.
KAI Scheduler는 2계층 큐 (Queue) 구조를 가지며, 조직의 부서 구조에 맞춘 리소스 관리가 가능합니다.
# 상위 큐 (부서 레벨)
apiVersion: scheduling.run.ai/v2
kind: Queue
...
각 큐에는 다음과 같은 4가지 제어 파라미터 (Parameter)가 있습니다.
- quota: 보장되는 GPU 리소스 양 (Desired Quota)
- limit: 최대 이용 가능량 (
-1은 무제한) - overQuotaWeight: 오버쿼터 풀 (Over-quota pool)에서의 배분 비율
- priority (암묵적): PriorityClass와 연동
KAI Scheduler v0.10.0에서 도입된 시간 기반 페어 쉐어 (Time-based Fair Share)는 과거 사용 이력을 고려하여 오버쿼터 리소스를 배분하는 메커니즘입니다.
기존의 포인트 인 타임 (Point-in-time) 방식에서는 빈번하게 작은 작업을 투입하는 팀이 오버쿼터 리소스를 독점하고, 가끔 큰 작업을 투입하는 팀이 영원히 대기하게 되는 문제가 있었습니다.
시간 기반 페어 쉐어에서는 다음 3가지 요소로 페어 쉐어 값을 산출합니다.
- Weight: 설정된 상대적인 배분 비율
- Usage: 시간 윈도우 (Time window, 기본 1주일) 내의 실제 소비량
- K-value: 보정의 적극성 파라미터
NVIDIA 기술 블로그에서 소개된 100 GPU 클러스터의 예로 설명하겠습니다.
- LLM 팀: 보장 쿼터 30 GPU
- Vision 팀: 보장 쿼터 20 GPU
- 오버쿼터 풀: 50 GPU (공유)
시간 기반 페어 쉐어가 없는 경우: Vision 팀의 지속적인 학습 작업이 오버쿼터를 독점하여, LLM 팀의 60 GPU (보장 20 + 오버쿼터 40) 규모의 대규모 포스트 트레이닝 (Post-training) 작업이 무기한 대기하게 됩니다.
시간 기반 페어 쉐어가 있는 경우: LLM 팀의 오버쿼터 사용 이력이 적기 때문에 실효적인 페어 쉐어 값이 높아져, 대규모 작업을 배치할 수 있게 됩니다. 리소스는 주 단위로 팀 간을 적절하게 오갑니다.
주의 사항 (Pitfall): 큐의 계층 구조는 반드시 2레벨 (상위 큐 $\rightarrow$ 하위 큐)로 구성해야 합니다. 1레벨로만 설정하면 Pod가 Pending 상태로 머물며 동작하지 않습니다. KAI Scheduler 퀵스타트 (Quickstart)를 참조하여 default-parent-queue가 올바르게 생성되었는지 확인하십시오.
KubeAI는 Kubernetes 상의 AI 추론 오퍼레이터 (Inference Operator)입니다. LLM, 임베딩 (Embedding), 리랭킹 (Reranking), 음성 인식 (STT)을 지원하며, Knative, Istio, Prometheus 메트릭 어댑터 (Metrics Adapter)에 의존하지 않는 경량 설계가 특징입니다.
KubeAI는 두 가지 컴포넌트 (Component)로 구성됩니다.
| 컴포넌트 (Component) | 역할 |
|---|---|
| Model Proxy | OpenAI 호환 API 제공, 프리픽스 (Prefix) 대응 로드 밸런싱 (Load Balancing), 요청 큐잉 (Request Queuing) |
| Model Operator | 백엔드 서버 Pod 관리, 모델 다운로드, LoRA 어댑터 (LoRA Adapter) 오케스트레이션 (Orchestration) |
KubeAI의 Model
CRD를 사용하여 추론 서비스를 선언적으로 정의합니다.
apiVersion: kubeai.org/v1
kind: Model
metadata:
...
minReplicas: 0
을 통해, 요청이 없을 때는 레플리카 (Replica)를 0으로 스케일 다운 (Scale down) 하여 GPU 비용을 절감합니다. 요청이 들어오면 Model Proxy가 큐잉 (Queuing)을 수행하는 동시에, Model Operator가 자동으로 Pod를 스케일 업 (Scale up) 합니다.
KubeAI의 PrefixHash 전략은 Consistent Hashing with Bounded Loads (CHWBL) 알고리즘에 기반하고 있습니다.
- 요청의 프리픽스 (Prefix, 앞 100자)와 LoRA 어댑터 이름을 추출
- xxHash로 해시 (Hash) 값을 계산
- CHWBL 알고리즘으로 담당 레플리카를 결정
- 담당 레플리카의 부하가 평균의 125%를 초과하는 경우 다른 레플리카로 리다이렉트 (Redirect)
채팅 보완 (Chat Completion) 유스케이스 (Use case)에서는 대화 이력이 다음 요청의 프리픽스에 포함되기 때문에, 동일한 레플리카로 라우팅 (Routing) 하는 것이 KV 캐시 (KV Cache) 히트율을 대폭 향상시킵니다.
KubeAI 공식 벤치마크 (Benchmark)에 따르면, Llama 3.1 8B · L4 GPU × 8 · 1200 병렬 스레드 (Parallel Thread) 환경에서 다음과 같은 결과가 보고되었습니다.
| 지표 | K8s 표준 Service | LeastLoad | PrefixHash |
|---|---|---|---|
| TTFT | 기준값 | 개선됨 | 95% 감소 |
| 처리량 (Throughput) | 기준값 | 개선됨 | 127% 향상 |
제약 조건: PrefixHash의 효과는 프리픽스의 공통성이 높은 워크로드 (Workload, 채팅, RAG 등)에서 두드러집니다. 무작위 프롬프트 (Prompt)가 주를 이루는 배치 처리 (Batch Processing)에서는 LeastLoad 전략이 더 적절할 수 있습니다.
KAI Scheduler로 스케줄링과 공유를 관리하고, KubeAI로 애플리케이션 계층의 추론 최적화를 수행하는 구성이 실용적입니다.
# KubeAI의 Model CRD에 KAI Scheduler를 적용
apiVersion: kubeai.org/v1
kind: Model
...
이 구성을 통해 KubeAI의 스케일 아웃 (Scale-out) 및 PrefixHash LB의 혜택을 받으면서, KAI Scheduler의 우선순위 관리, 페어 셰어 (Fair Share), 갱 스케줄링 (Gang Scheduling)도 동시에 활용할 수 있습니다.
Kubernetes 1.34에서 안정화(stable)된 DRA는 기존의 디바이스 플러그인 (Device Plugin) 모델을 대체하는 API입니다. KubeCon Europe 2026에서 NVIDIA가 DRA 드라이버를 CNCF에 기증함에 따라 에코시스템 (Ecosystem)의 표준이 되었습니다.
| 관점 | 디바이스 플러그인 (Device Plugin) | DRA |
|---|---|---|
| GPU 할당 입도 (Granularity) | 정수 개수만 가능 | GPU, MIG 슬라이스, 프랙션 (Fraction) |
| ... |
DRA에서는 CEL (Common Expression Language)을 사용하여 GPU 요구 사항을 선언적으로 기술할 수 있습니다.
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
...
Grove는 NVIDIA가 개발한 추론 워크로드 관리 API로, 5가지 CRD를 통해 추론 파이프라인 (Inference Pipeline)을 선언적으로 정의합니다.
- PodClique: 특정 역할 (prefill, decode, router)을 가진 Pod 그룹
- PodCliqueScalingGroup: 고정된 레플리카 비율을 유지하는 PodClique의 집합
- PodCliqueSet: 시작 순서와 제약을 정의하는 최상위 리소스
- ClusterTopology: 물리적 클러스터 레이아웃 (NVLink, 랙 구성) 기술
- PodGang: 원자적 (Atomically)으로 스케줄링되는 Pod의 집합
Grove를 이용한 prefill/decode 분리 추론 파이프라인
apiVersion: grove.io/v1alpha1
kind: PodCliqueSet
...
Grove는 prefill/decode 분리 (Disaggregated Serving)를 선언적으로 정의할 수 있으며, llm-d 추론 스택과의 통합이 진행되고 있습니다.
주의 사항:
DRA는 Kubernetes 1.34 이상이 필요합니다. 또한, Grove는 아직 Alpha 단계 (v0.1.0)이므로, 운영 환경 도입을 위해서는 충분한 테스트와 검증이 필요합니다. 베어메탈 (Bare Metal) 환경이 아니면 NVLink 토폴로지 정보가 스케줄러로 전달되지 않을 수 있다는 점에도 주의하십시오.
| 문제 | 원인 | 해결 방법 |
|---|---|---|
| Pod가 Pending 상태로 움직이지 않음 | 큐 레이블 (Queue Label) 미지정 또는 큐 계층이 1단계뿐임 | kai.scheduler/queue 레이블 추가 및 2단계 계층 (부모→자식 큐) 확인 |
| 프랙셔널 (Fractional) GPU에서 OOM 발생 | KAI Scheduler는 메모리 분리를 강제하지 않음 | vLLM의 --gpu-memory-utilization 또는 PyTorch의 set_per_process_memory_fraction()을 통한 자기 제한 |
| PrefixHash 효과가 나타나지 않음 | 랜덤 프롬프트 중심의 워크로드 | LeastLoad 전략으로 전환하거나 프롬프트 템플릿을 공통화 |
| 갱 스케줄링 (Gang Scheduling)으로 작업이 시작되지 않음 | 클러스터 전체의 GPU 여유량이 minMember를 충족하지 못함 | 큐의 쿼터/리미트(Quota/Limit) 재검토 또는 저우선순위 작업의 선점 (Preemption) 설정 |
| KubeAI의 scale-from-zero가 느림 | 모델 다운로드에 시간이 소요됨 | EFS/GCP Filestore를 통한 모델 캐시 설정 |
요약:
- KAI Scheduler는 GPU 프랙셔널 공유 (0.25~0.5 GPU 단위), 갱 스케줄링 (Gang Scheduling), 계층형 큐, 시간 기반 페어 셰어 (Time-based Fair Share)를 제공하는 NVIDIA 제작 오픈 소스 스케줄러
- KubeAI는 Knative/Istio가 필요 없는 경량 추론 오퍼레이터로, PrefixHash LB를 통해 TTFT 95% 감소 및 처리량(Throughput) 127% 향상을 실현 - 추론에는 Spread + 비선점형 (Non-preemptible) 우선순위, 학습에는 Bin Packing + 선점형 (Preemptible) 우선순위를 구분하여 사용하는 것이 중요
- DRA (K8s 1.34에서 안정화)와 GPU 프랙셔널 공유의 조합이 2026년의 표준이 될 전망
- Grove는 아직 Alpha 단계이지만, prefill/decode 분리 등 차세대 추론 파이프라인을 선언적으로 관리할 수 있음
다음 단계:
-
기존 클러스터에 KAI Scheduler를 세컨더리 스케줄러로 설치하여 소규모 프랙셔널 공유 검증
-
KubeAI의 PrefixHash LB를 추론 서비스에 도입하여 KV 캐시 히트율 개선 측정
-
Kubernetes 1.34 업그레이드 및 DRA 드라이버 도입 계획 수립
-
NVIDIA KAI Scheduler GitHub
-
KAI Scheduler GPU Sharing 문서
-
NVIDIA 기술 블로그: 시간 기반 페어 셰어를 통한 GPU 배분
-
NVIDIA 기술 블로그: KAI Scheduler 오픈 소스화
-
KubeAI 공식 사이트
-
KubeAI: LLM Load Balancing at Scale (CHWBL)
-
Ray + KAI Scheduler 통합 문서
-
NVIDIA DRA 드라이버 CNCF 기증 (KubeCon 2026)
-
Kubernetes GPU Orchestration 2026 가이드
-
KAI Scheduler GPU Sharing & Bin Packing 레시피
-
Kubernetes Dynamic Resource Allocation 공식 문서
주의: 이 기사는 AI (Claude Code)에 의해 자동 생성되었습니다. 내용의 정확성에 대해서는 여러 정보원을 통해 검증하였으나, 실제 이용 시에는 공식 문서를 반드시 확인하시기 바랍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기