모델 서빙 시스템 설계 (1)
매주 일요일 저녁 약 50명 이상의 AI 인프라 담당자와 엔지니어들과 함께 온라인 스터디로 Hands-On LLM Serving and Optimization 책을 스터디 하는 데, 제 3 장 LLM 서빙 시스템 디자인의 내용을 읽고 궁금한 질문 사항을 답변과 함께 정리해보겠다.
LLM 서빙은 단순한 모델 실행 문제가 아니다. 제한된 GPU 자원을 다양한 요청 사이에서 배치하고, 스케줄링하고, 메모리를 관리하고, 지연시간과 비용을 조절하는 분산 시스템 설계 문제이다.
LLM Serving
│
┌───────────────┼────────────────┐
│ │ │
Scheduling Memory Isolation
│ │ │
Batching/Queue KV Cache API ↔ Engine
Priority Model Cache Process
Continuous LRU/Loading Failure
│ │ │
└───────────────┼────────────────┘
│
Routing
│
Multi-model / Replica
│
┌──────────┴──────────┐
│ │
Cost optimized Latency optimized
Shared resources Dedicated resources
│ │
└──────────┬──────────┘
│
SLO
TTFT / ITL / Throughput
│
Cost per token
다시 말해, LLLM 서빙은 model.generate()를 빠르게 실행하는 문제가 아니라, 제한된 GPU 메모리와 계산 자원을 수많은 가변 길이 요청 사이에서 어떻게 스케줄링하고, 캐싱하고, 격리하고, 라우팅하면서 SLO와 비용을 동시에 만족시킬 것인가의 문제이다. 그래서 vLLM이나 Triton을 쓸 줄 아는 것보다 더 중요한 것은 왜 vLLM과 Triton이 그런 구조와 스케줄러, 캐시, 워커 아키텍처를 가지고 있는지를 이해하는 것이 중요하다.
1. 프로세스 분리가 항상 최선인가?
항상 그렇지는 않다.프로세스 분리는 장애 격리, CPU/GPU 역할 분리, 독립 확장, 리소스 제어에 유리하다. 하지만 IPC, 직렬화(serialization), 컨텍스트 스위칭(context switching) 비용이 증가한다. 작은 서비스에서는 단순 구조가 유리할 수 있으며, 대규모 LLM 서빙 환경에서는 API 레이어와 추론 엔진(Inference Engine)을 분리하는 구조가 일반적이다.
2. CPU/GPU를 분리하면 GPU utilization이 반드시 증가하는가?
아니다. CPU 병목을 제거한다고 GPU 사용률이 반드시 증가하지는 않는다.
주요 원인:
- Tokenizer 처리 지연
- 작은 batch
- KV Cache 부족
- 데이터 전송 지연
- Scheduler 문제
- Memory bandwidth 병목
확인해야 할 지표:
- Queue time
- TTFT
- Tokens/sec
- KV Cache utilization
3. Batch size=4를 운영 수준 배칭(Production Batching)이라고 부를 수 있는가?
학습용 배칭(batching)으로는 가능하지만 운영 수준의 배칭(production-grade batching)이라고 하기는 어렵다. 실제 LLM 서빙 에서는 배치 크기(batch size)보다 총 토큰수(Total tokens), 컨텍스트 길이(Context length), KV 캐시 사용량, GPU 메모리 사용량(GPU memory capacity) 등과 같은 요소가 중요하다. 현대 서빙 엔진은 토큰 기반 배칭을 사용한다.
4. Batch size가 커지면 항상 처리량(throughput)이 증가하는가?
아니다. 초기에는 증가하지만 너무 커지면, GPU 메모리 증가, KV 캐시 압박, 큐 지연시간(Queue latency) 증가, OOM 위험 등이 발생한다. 최적점은 처리량(throughput)과 지연시간 SLO (Service Level Objective, 서비스 수준 목표)의 균형점이다.
5. 스트리밍(Streaming)이 지연시간(latency)를 줄이는가?
정확히는 TTFT(Time To First Token, 첫 번째 토큰 생성 시간)와 사용자 체감 지연시간를 줄인다. 전체 생성 시간이 같아도 첫 token을 빠르게 전달하면 사용자 경험이 좋아진다. 주요 latency 지표는 다음과 같다.
- TTFT : 사용자가 프롬프트를 전송한 시점부터 모델이 첫 번째 토큰을 생성하여 반환하기까지 걸리는 시간
- ITL (Inter-Token Latency, 토큰 간 지연 시간): 스트리밍 응답 중에 모델이 하나의 토큰을 생성한 뒤 바로 다음 토큰을 생성하여 반환하기까지 걸리는 시간
- 종단 간 지연 시간(End-to-End latency)
6. use_cache=False 스트리밍 구현은 성능을 왜곡하는가?
그렇다. KV 캐시가 없으면 이전 토큰 계산을 반복한다. 실제 LLM 서빙 엔진은 KV Cache를 사용하여 Attention 결과를 재사용한다.따라서 use_cache=False는 교육 목적에는 적합하지만 운영 벤치마크(production benchmark)에는 부적합하다.
7. 토큰 스트리밍(Streaming)과 연속 배칭(Continuous Batching)은 같은 개념인가?
아니다. 스트리밍은 결과 전달 방식이다. 연속 배칭은 GPU 스케쥴러 실행 방식이다. 운영(Production) 환경에서는 연속 배칭과 토큰 스트리밍 조합을 사용한다.
8. Sequence ID만 있으면 요청 추적이 가능한가?
아니다. 필요한 정보은 request_id, client connection, KV cache allocation, deadline, priority, cancellation 상태 등으로 요청 라이프싸이클 관리가 중요하다.
9. 하나의 ModelWorker는 Serialization Point가 되는가?
그럴 수 있다. 하나의 Worker가 모든 요청을 처리하면 긴 요청이 다른 요청을 막는 Head-of-Line Blocking이 발생한다. 운영 환경에서는 Scheduler가 token-step 단위로 실행을 조절한다.
10. Priority Scheduling은 언제 필요한가?
서로 다른 중요도의 workload가 같은 GPU를 공유할 때 필요하다.
예를 들어,
- Chat 서비스: latency 중요
- Batch inference: throughput 중요
- Agent 요청: 긴 context 처리 중요
사용 가능한 방법:
- Priority Queue
- Weighted Fair Scheduling
- Deadline Scheduling
- Preemption
댓글남기기