LLM WikiAccess-protected knowledge portal

WIKI

Sarathi-Serve와 청크형 프리필: LLM 서빙에서 TTFT-처리량 균형을 찾는 방법

요약 LLM 서빙 시스템에서 두 가지 지표가 자주 충돌한다. TTFT Time To First Token 사용자가 요청을 보내고 첫 토큰을 받기까지 걸리는 시간이다. 처리량 throughput 시스템이 초당 처리하는 총 토큰 수다. 표준 연속 배칭 continuous batching 에서는 긴 프리필 요청이 배치에 들어오면 진행 중인 모든 디코딩 스텝이 멈춘다. 이를 Head of Line HoL 블로킹 이라 부른다. 인터랙티

경로human/study/content/ai-frontier/123-sarathi-serve-chunked-prefill-ttft-throughput.md
카테고리Study
태그#ai-review #chunked #prefill #serve #study #throughput #ttft

요약

LLM 서빙 시스템에서 두 가지 지표가 자주 충돌한다. TTFT(Time To First Token): 사용자가 요청을 보내고 첫 토큰을 받기까지 걸리는 시간이다. 처리량(throughput): 시스템이 초당 처리하는 총 토큰 수다.

표준 연속 배칭(continuous batching)에서는 긴 프리필 요청이 배치에 들어오면 진행 중인 모든 디코딩 스텝이 멈춘다. 이를 Head-of-Line(HoL) 블로킹이라 부른다. 인터랙티브 애플리케이션에서는 TTFT가 수 초로 치솟아 사용자 경험이 급격히 나빠진다.

Sarathi-Serve(arXiv:2308.16369, OSDI 2024)는 이 문제를 청크형 프리필(Chunked Prefill)로 해결한다. 프리필 요청을 고정 크기 청크로 나눠 디코딩 스텝과 인터리브한다. 각 스케줄링 스텝에서 최대 하나의 프리필 청크만 처리하고, 나머지 슬롯은 디코딩 요청이 채운다.

결과: TTFT 급등 없이 처리량을 유지하는 것이 가능하다. 청크 크기라는 단일 파라미터로 TTFT-처리량 균형을 조절할 수 있다.

2026년 현재 vLLM·SGLang·TRT-LLM 모두 청크형 프리필을 기본값 또는 권장 설정으로 채택했다.


배경: 연속 배칭의 HoL 블로킹 문제

연속 배칭 복습

연속 배칭은 각 디코딩 스텝 후 완료된 요청을 배치에서 제거하고 새 요청을 즉시 추가한다. 요청이 완료될 때까지 기다리지 않고 GPU를 최대한 활용한다. Orca(Yu et al., 2022)가 처음 제안한 이 방식은 현대 LLM 서빙 시스템의 기반이 됐다.

[연속 배칭 배치 상태]

스텝 1: [req-A decode] [req-B decode] [req-C decode]
스텝 2: [req-A done] [req-B decode] [req-C decode] [req-D prefill→decode]
스텝 3: [req-D decode] [req-B decode] [req-C decode]

HoL 블로킹 발생 조건

긴 프롬프트(예: 4096 토큰)를 가진 요청이 배치에 진입하면, 해당 프리필 연산이 완료될 때까지 GPU의 모든 연산이 해당 요청에 집중된다. 디코딩 중인 다른 요청들은 그 스텝 동안 응답을 내보낼 수 없다.

현실적인 영향: 8K 토큰 프롬프트 요청이 2초의 프리필 시간을 차지하면, 같은 배치에서 스트리밍 중인 모든 사용자가 2초 동안 응답이 멈춘다. p99 TTFT가 평균보다 10~100배 높아지는 이유가 여기 있다.


Sarathi-Serve: 청크형 프리필 스케줄링

핵심 아이디어

긴 프리필을 한 번에 처리하지 않는다. 최대 청크 크기(chunk size) 단위로 분할하고, 각 스케줄링 스텝에서 최대 하나의 프리필 청크만 처리한다. 나머지 배치 슬롯은 디코딩 요청이 채운다.

청크형 프리필 vs 표준 연속 배칭 표준 연속 배칭 — HoL 블로킹 스텝 1 A decode B decode C decode 스텝 2 LONG prefill (4096 tokens) — HoL Blocking ⚠ 스텝 3 A decode B decode LONG decode 스텝 2에서 A/B/C 응답 완전 중단 HoL 블로킹 영향 • 스트리밍 사용자: 갑작스러운 응답 중단 • TTFT 급등: 긴 요청이 배치에 들어올 때마다 반복 • p99 TTFT가 평균보다 10~100배 높아질 수 있음 • 프롬프트가 길수록 HoL 블로킹 지속 시간 비례 증가 청크형 프리필 — Sarathi-Serve 스텝 1 A dec B dec C dec LONG chunk 1/8 스텝 2 A dec B dec C dec LONG chunk 2/8 ... (스텝 3~7: 동일 패턴) ... 스텝 8 A dec B dec C dec LONG chunk 8/8 스텝 9 A dec B dec C dec LONG decode 청크형 프리필 효과 • A/B/C 스트리밍: 8 스텝 내내 응답 지속 (HoL 없음) • LONG TTFT: 8 스텝 후 첫 토큰 (표준과 동일) • GPU 활용률: 매 스텝 decode + 프리필 청크 1개 • 청크 크기 조절로 TTFT-처리량 균형 조정 가능
청크형 프리필 vs 표준 프리필 스케줄링

스케줄러 로직

Sarathi의 스케줄러는 매 스텝마다 다음 결정을 내린다:

  1. 디코딩 요청 수집: 진행 중인 모든 decode 요청을 배치에 포함
  2. 프리필 청크 선택: 대기열에서 하나의 요청을 골라 최대 chunk_size 토큰만 처리
  3. 배치 구성: 나머지 GPU 메모리와 연산 예산 내에서 슬롯 채우기

핵심 불변식: 한 스텝에서 최대 하나의 프리필 청크만 처리한다.

프리필이 완료되지 않은 요청은 다음 스텝에서 남은 청크를 이어 처리한다. 이 과정에서 이미 계산된 KV 캐시는 누적되어 재사용된다.


청크 크기와 TTFT-처리량 트레이드오프

청크 크기는 Sarathi-Serve의 핵심 조절 파라미터다.

청크 크기별 동작 요약

청크 크기TTFT 영향처리량 영향적합한 워크로드
64~128 토큰최소 (HoL 거의 없음)감소 (스케줄링 오버헤드 증가)인터랙티브 채팅, TTFT 민감
256~512 토큰양호양호일반 목적 API
1024~2048 토큰허용 가능최대화에 근접배치 처리, 처리량 우선

vLLM 기본값: --max-num-batched-tokens 2048과 함께 청크형 프리필 기본 활성화 (v0.4.0+)

처리량 손실이 생각보다 적은 이유

프리필 연산과 디코딩 연산은 GPU 자원 사용 패턴이 다르다.

청크형 프리필에서 프리필 청크와 디코딩 요청이 같은 스텝에 있으면, 서로 다른 GPU 자원을 주로 사용하므로 실제 충돌이 예상보다 적다. 이것이 청크형 프리필이 처리량 손실 없이 TTFT를 개선할 수 있는 핵심 이유다.

최적 청크 크기 선택 가이드

워크로드 프로파일링 → 청크 크기 결정

1. 평균 프롬프트 길이 측정
   짧음 (< 512 토큰): chunk_size 256 이하로 시작
   중간 (512~4096):   chunk_size 512~1024
   긺 (4096+):        chunk_size 1024~2048

2. TTFT SLO 확인
   p99 TTFT < 500ms: 작은 청크 (256~512)
   p99 TTFT < 2s:    중간 청크 (512~1024)

3. GPU 활용률 모니터링
   MFU < 60%: 청크 크기 늘려 처리량 개선
   TTFT p99 급등: 청크 크기 줄여 HoL 억제

운영 시스템별 구현 현황 (2026)

vLLM

vLLM v0.4.0부터 청크형 프리필을 지원하고, v0.25.0부터 기본값으로 전환됐다.

# 청크형 프리필 설정 (기본값으로 이미 활성화)
vllm serve meta-llama/Llama-4-Scout-17B-16E-Instruct \
  --enable-chunked-prefill \           # 기본값 true
  --max-num-batched-tokens 2048 \      # 청크 크기 제어 (토큰)
  --max-num-seqs 256

vLLM에서 --max-num-batched-tokens가 사실상 청크 크기를 결정한다. 프리필 요청이 이 값을 초과하면 자동으로 청크로 분할된다.

SGLang

SGLang은 ChunkFill이라는 자체 구현을 사용한다. 연속 배칭 루프에서 prefill-decode 인터리빙을 정밀하게 제어하며, 기본 스케줄러 정책으로 채택됐다.

TensorRT-LLM

TRT-LLM은 CHUNKED_CONTEXT 모드로 청크형 프리필을 지원한다. CUDA Graph와 함께 사용할 때는 별도 설정이 필요하다 — CUDA Graph는 고정 배치 크기를 가정하기 때문이다.


청크형 프리필과 PD 분리의 관계

청크형 프리필은 단일 서버 내 HoL 블로킹을 제거하는 기법이다. 더 나아가, Prefill-Decode 분리(PD Disaggregation)는 프리필과 디코드를 아예 다른 서버 풀에서 실행한다. (ai-frontier/23 참조)

두 기법은 계층적으로 적용 가능하다:

언제 PD 분리가 필요한가

상황청크형 프리필로 충분PD 분리 필요
평균 프롬프트 < 4K 토큰
실시간 스트리밍, p99 TTFT < 1s
평균 프롬프트 > 8K 토큰
TTFT SLO 매우 엄격 (< 200ms)
처리량을 극한까지 최적화

운영 체크리스트

설정 검증:

지표 모니터링:

주의 사항:


요점 정리

연속 배칭에서 긴 프리필 요청이 야기하는 HoL 블로킹은 인터랙티브 LLM 서빙의 근본적 도전이었다. Sarathi-Serve의 청크형 프리필은 단 하나의 파라미터(청크 크기)로 이 문제를 해결한다.

핵심 교훈:

청크형 프리필을 이해하지 않고 LLM 서빙 인프라를 운영하면, TTFT 이상 징후의 원인을 진단하기 어렵다. vLLM --max-num-batched-tokens 설정 하나가 사용자 경험을 크게 바꿀 수 있다.


References