LLM 서버리스 서빙 실무: KServe·Knative 기반 콜드 스타트 단축과 GPU 비용 최적화 전략
KServe와 Knative를 함께 사용하면 쿠버네티스 환경에서 LLM 추론 서비스를 요청량에 맞춰 자동 확장하고, 유휴 시간에는 파드를 0개까지 줄이는 서버리스 구조를 설계할 수 있습니다. 이전 리포트에서 다룬 TensorRT-LLM 가속 최적화 실무: 엔진 컴파일과 고처리량 프로덕션 서빙 구축 방법이 단일 노드의 추론 처리량을 높이는 데 초점을 맞췄다면, 이번 글에서는 사용하지 않는 시간대의 GPU 점유 비용을 줄이고 콜드 스타트 지연을 관리하는 KServe·Knative 기반 LLM 서버리스 운영 전략을 정리합니다.
이 글에서 바로 확인할 수 있는 내용
- LLM 추론 워크로드에서 서버리스 Scale-to-Zero가 실제로 비용 절감에 도움이 되는 조건을 정리합니다.
- KServe InferenceService와 Knative Pod Autoscaler(KPA)가 어떤 흐름으로 파드를 확장·축소하는지 설명합니다.
- vLLM 백엔드를 사용하는 KServe Hugging Face Runtime 기반 배포 매니페스트 예시를 확인합니다.
- LLM 서버리스 도입 시 가장 자주 문제가 되는 콜드 스타트, 타임아웃, 스케일링 진동 대응 방법을 다룹니다.
- Scale-to-Zero를 적용하면 안 되는 서비스 유형과 하이브리드 운영 기준을 함께 정리합니다.
- 운영 전 점검해야 할 스토리지, 이미지 캐시, 게이트웨이 타임아웃, 동시성 기준 체크리스트를 제공합니다.
1. 왜 LLM 서빙에 서버리스 아키텍처와 Scale-to-Zero가 필요할까?
LLM 추론 인프라의 가장 큰 부담은 GPU가 비싸다는 점입니다. 특히 부서별 챗봇, 내부 문서 요약기, 특정 업무용 분석 모델처럼 하루 종일 요청이 꾸준히 들어오지 않는 서비스라면 문제가 더 커집니다. 실제 사용량은 낮은데 GPU 파드나 GPU 노드를 계속 켜두면 요청이 없는 시간에도 비용이 발생하기 때문입니다.
KServe와 Knative 기반 서버리스 서빙은 이런 비정기 트래픽 워크로드에 잘 맞습니다. 요청이 없을 때는 Knative가 Revision의 파드 수를 0개까지 줄이고, 요청이 다시 들어오면 Activator와 Autoscaler가 파드를 다시 띄워 트래픽을 넘겨주는 방식으로 작동합니다. 이 구조를 잘 활용하면 GPU를 항상 점유하지 않고 필요한 시간에만 추론 리소스를 사용할 수 있습니다.
다만 Scale-to-Zero가 곧바로 클라우드 비용 0원을 의미하는 것은 아닙니다. GPU 파드가 0개가 되어도 GPU 노드 자체가 계속 켜져 있다면 노드 비용은 남을 수 있습니다. 따라서 실제 비용 절감 효과를 얻으려면 KServe·Knative 설정뿐 아니라 Cluster Autoscaler, Karpenter, 노드 풀 분리, 예약 인스턴스 여부까지 함께 검토해야 합니다.
Scale-to-Zero가 특히 잘 맞는 LLM 서비스
- 업무 시간에만 호출되는 사내 챗봇 또는 문서 요약 서비스
- 특정 이벤트나 배치 작업 때만 사용하는 임베딩·분류 모델
- 응답 지연보다 인프라 비용 절감이 더 중요한 내부 자동화 워크로드
- 모델 수는 많지만 각 모델의 호출 빈도는 낮은 멀티 모델 운영 환경
2. KServe와 Knative의 연동 구조: 요청이 들어오면 어떤 일이 발생할까?
KServe는 쿠버네티스 위에서 모델 서빙을 선언적으로 관리할 수 있도록 InferenceService라는 커스텀 리소스를 제공합니다. 운영자는 모델 포맷, 스토리지 위치, CPU·메모리·GPU 리소스, 오토스케일링 관련 어노테이션을 YAML로 정의하고, KServe는 이를 바탕으로 모델 서버와 라우팅 구성을 생성합니다.
Knative는 이 모델 서버를 서버리스 워크로드처럼 다룰 수 있게 해줍니다. Scale-to-Zero 상태에서는 실제 추론 파드가 존재하지 않습니다. 이때 최초 요청이 들어오면 Knative Activator가 요청을 받아 잠시 대기시키고, KPA가 동시성 또는 요청량 지표를 기준으로 새 파드를 생성합니다. 파드가 준비 상태가 되면 요청은 모델 서버로 전달됩니다.
이 방식의 장점은 명확합니다. 요청이 없을 때는 추론 파드가 리소스를 점유하지 않고, 요청이 몰릴 때는 max-scale 한도 안에서 여러 파드로 확장할 수 있습니다. 반대로 단점도 분명합니다. 파드가 0개인 상태에서 첫 요청이 들어오면 컨테이너 이미지 준비, 모델 파일 로딩, CUDA 런타임 초기화, KV 캐시 메모리 할당이 한꺼번에 발생합니다. 이 구간이 바로 LLM 서버리스에서 가장 까다로운 콜드 스타트입니다.
3. 프로덕션 배포 전 확인해야 할 기본 전제
LLM 서버리스를 YAML 하나로만 해결하려고 하면 실패할 가능성이 높습니다. KServe와 Knative가 설치되어 있어도 GPU 드라이버, NVIDIA Device Plugin, 스토리지 성능, 인그레스 타임아웃, 모델 접근 권한이 맞지 않으면 최초 요청부터 504 에러나 모델 로딩 실패가 발생할 수 있습니다.
| 점검 항목 | 확인해야 할 내용 | 문제가 생기면 나타나는 증상 |
|---|---|---|
| KServe 설치 모드 | Knative 기반 Serverless 모드 또는 RawDeployment 사용 여부를 확인합니다. | 어노테이션을 넣어도 기대한 방식으로 스케일링되지 않습니다. |
| GPU 런타임 | NVIDIA Device Plugin, 드라이버, CUDA 호환성을 확인합니다. | 파드는 뜨지만 GPU를 인식하지 못하거나 모델 로딩 중 종료됩니다. |
| 모델 스토리지 | PVC, Hugging Face Hub, S3, GCS 등 모델 위치와 접근 권한을 확인합니다. | 초기화 컨테이너가 실패하거나 콜드 스타트가 지나치게 길어집니다. |
| 인그레스 타임아웃 | Istio, Envoy, Gateway, Load Balancer의 요청 제한 시간을 확인합니다. | 파드는 정상 기동 중인데 사용자에게 504 Gateway Timeout이 먼저 발생합니다. |
4. KServe InferenceService 배포 매니페스트 예시
아래 매니페스트는 KServe의 Hugging Face Runtime을 사용해 Llama 계열 모델을 GPU 기반으로 서빙하는 예시입니다. KServe 문서 기준으로 Hugging Face Runtime은 vLLM 백엔드를 사용할 수 있으며, GPU 리소스를 요청하면 CUDA 지원 런타임 이미지가 선택됩니다. 실제 운영에서는 KServe 버전, 설치 방식, ServingRuntime 설정, 사내 이미지 정책에 따라 일부 필드가 달라질 수 있으므로 스테이징 네임스페이스에서 먼저 검증해야 합니다.
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: llm-serverless-service
namespace: llm-serverless
annotations:
# Knative KPA 기반 동시성 오토스케일링
autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev"
autoscaling.knative.dev/metric: "concurrency"
autoscaling.knative.dev/target: "10"
# 유휴 시 0개까지 축소, 과도한 확장은 5개로 제한
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "5"
# 스케일링 판단 구간과 스케일다운 지연 설정
autoscaling.knative.dev/window: "60s"
autoscaling.knative.dev/scale-down-delay: "5m"
spec:
predictor:
model:
modelFormat:
name: huggingface
storageUri: "hf://meta-llama/Meta-Llama-3-8B-Instruct"
args:
- --backend=vllm
- --model_name=llama3-8b
- --dtype=auto
- --max_model_len=4096
- --gpu_memory_utilization=0.85
resources:
requests:
cpu: "2"
memory: "16Gi"
nvidia.com/gpu: "1"
limits:
cpu: "4"
memory: "32Gi"
nvidia.com/gpu: "1"
원본 예시에서 lllm-serverless-service처럼 보였던 이름은 오타 가능성이 있어 llm-serverless-service로 정리했습니다. 또한 modelFormat.name은 임의의 vllm 값 대신 KServe Hugging Face Runtime 예시에 맞춰 huggingface로 구성했습니다. vLLM은 런타임의 백엔드 인자로 지정하는 편이 호환성 측면에서 더 안전합니다.
모델을 매번 외부 허브에서 다운로드하지 않고 사내 PVC에 배치하고 싶다면 storageUri를 아래처럼 바꿀 수 있습니다. 이 방식은 모델 파일을 클러스터 내부 스토리지에 유지할 수 있어 네트워크 의존성을 줄이는 데 도움이 됩니다. 단, PVC의 실제 성능이 낮으면 오히려 모델 로딩 시간이 길어질 수 있으므로 IOPS와 처리량을 반드시 확인해야 합니다.
storageUri: "pvc://llm-model-pvc/meta-llama/Meta-Llama-3-8B-Instruct/"
배포 후에는 아래 명령으로 InferenceService 상태와 URL을 확인합니다.
kubectl get inferenceservice llm-serverless-service -n llm-serverless
kubectl describe inferenceservice llm-serverless-service -n llm-serverless
5. 콜드 스타트는 왜 느리고, 어디서 줄일 수 있을까?
LLM 서버리스에서 가장 많이 받는 질문은 “Scale-to-Zero를 쓰면 첫 사용자가 너무 오래 기다리지 않느냐”입니다. 결론부터 말하면, 콜드 스타트는 완전히 없애기 어렵습니다. 대신 어느 구간에서 시간이 쓰이는지 분리해 관리하면 지연을 줄일 수 있습니다.
| 콜드 스타트 구간 | 주요 원인 | 실무 대응 방법 |
|---|---|---|
| 컨테이너 이미지 준비 | CUDA, vLLM, PyTorch 계열 라이브러리가 포함된 이미지가 커서 Pull 시간이 길어집니다. | GPU 노드에 이미지 사전 Pull DaemonSet을 배치하거나, 이미지 레이어를 줄이고 사내 레지스트리 캐시를 사용합니다. |
| 모델 파일 로딩 | 수 GB~수십 GB 모델 가중치를 디스크나 네트워크 스토리지에서 읽어야 합니다. | PVC, 로컬 NVMe 캐시, 모델 캐시 기능, safetensors 포맷, 양자화 모델을 검토합니다. |
| 런타임 초기화 | CUDA 컨텍스트 생성, vLLM 엔진 초기화, KV 캐시 메모리 예약이 필요합니다. | --gpu_memory_utilization, --max_model_len, 동시성 목표값을 실제 GPU 메모리에 맞춰 조정합니다. |
| 라우터 대기 시간 | 파드가 준비되기 전 앞단 게이트웨이 제한 시간이 먼저 끝날 수 있습니다. | Gateway, VirtualService, Knative Revision timeout을 장문 생성 서비스에 맞게 늘립니다. |
여기서 중요한 점은 “콜드 스타트가 몇 초로 줄어든다”라고 단정하지 않는 것입니다. 모델 크기, 이미지 캐시 여부, 스토리지 위치, 노드 스케줄링 시간, GPU 종류에 따라 결과가 달라집니다. 실무에서는 평균값보다 P95 또는 P99 콜드 스타트 시간을 기준으로 삼는 편이 안전합니다.
6. 비용 절감 효과는 어떻게 계산해야 할까?
Scale-to-Zero의 비용 효과를 판단할 때는 “파드가 0개가 된다”보다 “GPU 노드 점유 시간이 얼마나 줄었는가”를 봐야 합니다. 예를 들어 업무 시간 9시간 동안만 호출되는 내부 서비스라면 이론상 추론 파드 가동 시간은 24시간에서 9시간 안팎으로 줄어들 수 있습니다. 하지만 GPU 노드가 자동으로 내려가지 않거나, 다른 워크로드가 같은 노드를 점유하고 있거나, 최소 노드 수가 고정되어 있으면 실제 청구 비용은 덜 줄어듭니다.
| 비교 항목 | 상시 가동형 GPU 서빙 | KServe·Knative 서버리스 서빙 | 해석 기준 |
|---|---|---|---|
| 유휴 시간 비용 | 요청이 없어도 GPU 파드가 계속 실행됩니다. | 요청이 없으면 파드를 0개까지 줄일 수 있습니다. | 노드 자동 축소까지 연결되어야 비용 절감이 커집니다. |
| 피크 처리 | 고정 리소스 이상으로 요청이 몰리면 대기열이 길어집니다. | max-scale 범위 안에서 파드를 늘릴 수 있습니다. | 동시성 목표값이 너무 낮으면 과도한 GPU 점유가 발생합니다. |
| 첫 요청 지연 | 대부분 웜 상태로 응답합니다. | Scale-to-Zero 이후 첫 요청에서 콜드 스타트가 발생합니다. | 대고객 실시간 서비스는 min-scale 1이 더 적합할 수 있습니다. |
간단한 비용 계산식
월 GPU 비용 절감률은 대략 1 - (서버리스 환경의 월 GPU 노드 점유 시간 / 상시 가동 환경의 월 GPU 노드 점유 시간)으로 계산할 수 있습니다. 단, 이 계산에는 노드 자동 축소가 실제로 동작하는지, 최소 노드 수가 고정되어 있는지, 예약 인스턴스나 장기 약정이 적용되는지까지 함께 반영해야 합니다.
7. Scale-to-Zero를 적용하면 안 되는 경우
서버리스가 항상 정답은 아닙니다. 특히 사용자에게 즉시 응답해야 하는 대고객 챗봇, 결제·상담·장애 대응처럼 첫 응답 지연이 곧 서비스 품질 저하로 이어지는 시스템은 무리하게 min-scale 0을 적용하지 않는 편이 안전합니다.
이런 서비스는 최소 파드를 1개 이상 유지하고, 호출 빈도가 낮은 내부 배치성 워크로드에만 Scale-to-Zero를 적용하는 하이브리드 구조가 더 현실적입니다. 앞서 다룬 AX 보안 거버넌스 고도화 방법처럼 외부망과 내부망의 정책이 분리된 환경이라면, 실시간 요청과 배치 요청의 라우팅 경로도 분리하는 것이 좋습니다.
| 서비스 유형 | 권장 설정 | 이유 |
|---|---|---|
| 대고객 실시간 챗봇 | min-scale: "1" 이상 |
첫 응답 지연이 사용자 이탈로 이어질 수 있습니다. |
| 사내 업무 자동화 | min-scale: "0" |
호출 빈도가 낮아 유휴 시간 비용 절감 효과가 큽니다. |
| 문서 요약·임베딩 배치 | min-scale: "0" + 큐 기반 처리 |
대기 시간이 허용되므로 비용 최적화에 유리합니다. |
| 70B 이상 대형 모델 | 고정 웜풀 또는 별도 노드풀 | 모델 로딩과 멀티 GPU 초기화 비용이 커서 콜드 스타트 부담이 큽니다. |
8. 운영 중 자주 발생하는 장애와 해결 방법
문제 1: 최초 요청에서 504 Gateway Timeout이 발생한다
Scale-to-Zero 상태에서 첫 요청이 들어오면 파드 생성과 모델 로딩 시간이 필요합니다. 그런데 앞단 게이트웨이나 프록시의 타임아웃이 짧으면 모델 서버가 준비되기도 전에 504 에러가 발생할 수 있습니다.
이 문제는 KServe나 vLLM 자체의 오류가 아니라, 대기 시간보다 프록시 제한 시간이 짧아서 생기는 경우가 많습니다. Istio, Envoy, Gateway API, Load Balancer, Knative Revision timeout을 함께 확인해야 합니다.
# Knative Service 또는 Revision에 적용되는 timeout 예시
# 실제 적용 위치는 KServe/Knative 설치 방식과 인그레스 구성에 따라 달라질 수 있습니다.
metadata:
annotations:
serving.knative.dev/timeoutSeconds: "300"
문제 2: 파드가 계속 생겼다 사라지는 스케일링 진동이 발생한다
간헐적으로 요청이 들어오는 서비스에서 가장 흔한 문제입니다. 요청 하나가 들어와 파드가 올라오고, 처리 직후 파드가 내려간 뒤, 몇 초 뒤 다음 요청이 들어와 다시 콜드 스타트를 반복하는 형태입니다. 이 경우 비용은 줄지 않고 사용자는 매번 느린 응답을 경험하게 됩니다.
Knative KPA에서는 autoscaling.knative.dev/scale-down-delay를 사용해 스케일다운 결정을 늦출 수 있습니다. 예를 들어 5분 정도 파드를 유지하면 짧은 간격으로 들어오는 후속 요청을 웜 상태로 처리할 수 있습니다.
metadata:
annotations:
autoscaling.knative.dev/window: "60s"
autoscaling.knative.dev/scale-down-delay: "5m"
문제 3: 동시성 target을 낮게 잡았더니 GPU 비용이 오히려 증가한다
vLLM은 동적 배칭과 KV 캐시 관리를 활용해 단일 파드 안에서도 여러 요청을 처리할 수 있습니다. 그런데 KPA의 target 값을 너무 낮게 잡으면 아직 한 파드가 처리할 수 있는 요청도 새 파드로 분산되어 GPU 점유가 과도하게 늘어날 수 있습니다.
따라서 target 값은 감으로 정하면 안 됩니다. 부하 테스트를 통해 단일 파드가 허용 가능한 TTFT, ITL, 토큰 처리량을 유지하는 동시성 범위를 찾고, 그보다 약간 보수적인 값으로 설정하는 편이 안전합니다.
9. 배포 전 실무 체크리스트
- ✅ KServe가 Knative 기반 Serverless 모드로 동작하는지, 또는 RawDeployment 모드인지 확인했나요?
- ✅ GPU 노드에 NVIDIA Device Plugin과 드라이버가 정상 설치되어 있나요?
- ✅ 모델 파일을 Hugging Face Hub에서 직접 받을지, PVC나 오브젝트 스토리지에 둘지 결정했나요?
- ✅ 콜드 스타트 시간을 평균이 아니라 P95 기준으로 측정했나요?
- ✅ Gateway, VirtualService, Load Balancer, Knative timeout이 LLM 장문 응답에 맞게 조정되어 있나요?
- ✅ 이미지 Pull 시간을 줄이기 위해 사전 Pull, 사내 레지스트리 캐시, 이미지 경량화를 검토했나요?
- ✅ min-scale 0을 적용할 서비스와 min-scale 1 이상을 유지할 서비스를 분리했나요?
- ✅ max-scale 값을 무제한으로 두지 않고 GPU 예산과 노드풀 한도에 맞게 제한했나요?
- ✅ 스케일다운 직전 처리 중인 요청이 끊기지 않도록 graceful shutdown과 preStop 정책을 점검했나요?
10. 참고한 기술 자료
- KServe 공식 Hugging Face Runtime 및 vLLM 백엔드 개요 문서
- KServe 공식 PVC 기반 모델 스토리지 배포 가이드
- Knative Serving 오토스케일링 기본 구조 문서
- Knative Scale Bounds, Stable Window, Scale Down Delay 설정 문서
- vLLM 공식 KServe 통합 문서
📊 KServe · Knative 서버리스 LLM 서빙 실무 Q&A
Q. LLM 서버리스에서 Scale-to-Zero를 쓰면 첫 사용자는 항상 느린 응답을 받나요?
A. 파드가 0개인 상태에서 들어오는 첫 요청은 콜드 스타트를 피하기 어렵습니다. 다만 이미지 사전 Pull, 모델 캐시, 빠른 스토리지, 적절한 timeout 설정, scale-down-delay 조정을 적용하면 지연을 줄일 수 있습니다. 실시간 대고객 서비스처럼 첫 응답 시간이 중요한 경우에는 min-scale을 1 이상으로 유지하고, 호출 빈도가 낮은 내부 업무용 모델에만 min-scale 0을 적용하는 방식이 더 안전합니다.
Q. 모델을 PVC에 두면 콜드 스타트가 무조건 빨라지나요?
A. 무조건 빨라지는 것은 아닙니다. PVC가 고성능 로컬 NVMe나 충분한 처리량을 가진 스토리지라면 외부 다운로드보다 유리할 수 있습니다. 반대로 네트워크 스토리지의 IOPS가 낮거나 여러 파드가 동시에 같은 볼륨을 읽으면 병목이 생길 수 있습니다. PVC 사용 여부보다 중요한 것은 실제 모델 로딩 시간을 측정하고, 스토리지 처리량을 콜드 스타트 목표에 맞게 확보하는 것입니다.
Q. KPA target 값은 몇으로 설정하는 것이 좋나요?
A. 정답은 모델 크기, GPU, 평균 프롬프트 길이, 출력 토큰 수에 따라 달라집니다. Llama-3-8B급 모델이라도 짧은 질의와 긴 문서 요약의 부하 특성은 완전히 다릅니다. 운영 전에는 단일 파드 기준으로 동시성 1, 5, 10, 20 같은 구간을 나누어 TTFT, ITL, 처리량, GPU 메모리 사용량을 측정한 뒤, 안정적인 범위의 70~80% 수준을 target 값으로 잡는 방식이 실무적으로 안전합니다.
Q. 서버리스 LLM 서빙으로 비용을 얼마나 줄일 수 있나요?
A. 비용 절감률은 요청 패턴과 노드 자동 축소 정책에 따라 달라집니다. 하루 24시간 중 실제 호출이 6~9시간에 몰려 있고, GPU 노드까지 자동으로 내려갈 수 있는 구조라면 절감 폭이 커질 수 있습니다. 하지만 GPU 노드를 항상 켜두는 정책이거나 예약 인스턴스 기반으로 이미 비용이 고정되어 있다면 파드 수를 0개로 줄여도 청구 비용 절감은 제한적입니다. 따라서 서버리스 도입 전에는 파드 가동 시간, 노드 가동 시간, 실제 청구 비용을 분리해서 계산해야 합니다.
결론: LLM 서버리스의 핵심은 Scale-to-Zero 자체가 아니라 지연과 비용의 균형입니다
LLM 서버리스 서빙은 단순히 파드를 0개로 줄이는 기술이 아닙니다. 사용자가 감당할 수 있는 지연 시간, 모델이 요구하는 GPU 메모리, 스토리지 로딩 속도, 게이트웨이 타임아웃, 노드 자동 축소 정책을 함께 맞춰야 효과가 납니다.
KServe InferenceService는 모델 배포를 선언적으로 관리하게 해주고, Knative KPA는 요청량에 따라 파드를 늘리거나 줄이는 서버리스 제어를 담당합니다. 여기에 vLLM 기반 런타임, 모델 캐시, 이미지 사전 Pull, 적절한 scale-down-delay를 조합하면 호출 빈도가 낮은 LLM 워크로드에서 GPU 점유 비용을 줄일 수 있습니다.
반대로 실시간 응답이 중요한 서비스에는 무리한 Scale-to-Zero보다 min-scale 1 이상의 웜풀 구성이 더 적합합니다. 결국 실무에서 중요한 것은 “서버리스가 좋은가”가 아니라 “어떤 모델과 어떤 요청 패턴에 서버리스를 적용할 것인가”입니다. 이 기준만 명확히 잡아도 KServe와 Knative는 엔터프라이즈 LLM 인프라의 비용과 운영 복잡도를 줄이는 강력한 선택지가 될 수 있습니다.
작성자 메모: 이 글은 2026년 6월 기준 KServe, Knative Serving, vLLM 공식 문서의 공개 배포 지침을 바탕으로 정리한 실무형 가이드입니다. 실제 매니페스트 필드, 런타임 이미지, 오토스케일링 동작은 KServe 설치 방식, Knative 버전, 인그레스 컨트롤러, GPU 드라이버, 모델 스토리지 구성에 따라 달라질 수 있습니다. 운영 환경에 적용하기 전에는 반드시 스테이징 네임스페이스에서 콜드 스타트 시간, P95 응답 지연, GPU 메모리 사용량, 노드 자동 축소 여부를 별도로 검증하시기 바랍니다.
디지털 아키텍트 (Digital Architect)
댓글
댓글 쓰기