Field Log · Entry
LLM Serving SLO 운영: Admission Control·Fairness·Autoscaling (9/10)
오늘의 결론
- LLM SLO는 응답 시간 하나가 아닙니다. Queue·prefill이 지배하는 TTFT, streaming 체감인 ITL/TPOT, 완료 시간, 성공·취소를 분리해야 합니다.
- Throughput이 높아도 deadline을 넘긴 token은 사용자 가치가 낮습니다. Goodput은 SLO를 만족한 요청 또는 token의 비율·속도로 정의하고 capacity와 release 판단에 사용합니다.
- Admission control은 실패를 만드는 장치가 아니라 이미 회복 불가능한 요청이 정상 요청까지 밀어내지 않게 하는 overload boundary입니다. Deadline slack, KV memory, tenant budget, retry cost를 입구에서 확인합니다.
- Request count fairness는 긴 prompt와 긴 reasoning을 같은 비용으로 취급합니다. Input prefill과 매 decode token의 가중 비용을 tenant별 virtual counter에 반영하고, priority·deadline과 starvation 방지를 함께 설계합니다.
- Autoscaler는 GPU utilization 하나를 쫓지 않습니다. Queue의 남은 work, 가장 이른 slack, KV pressure, goodput, worker ready time을 보고 scale-out하며, cold-start보다 짧은 burst는 warm capacity·admission·degradation으로 흡수합니다.
앞 글에서는 한 worker의 memory와 kernel 경로를 최적화했습니다. 이번 글은 여러 tenant와 burst가 동시에 들어올 때 어떤 요청을 받을지, 어떤 순서로 token을 배분할지, 언제 완전한 model replica를 늘리고 줄일지를 다룹니다.
request + SLO contract
→ estimate work, memory, and deadline slack
→ admit / defer / degrade / reject
→ fair and deadline-aware token scheduling
→ continuous batch on prefill / decode workers
→ observe goodput, queue work, KV pressure
→ scale warm capacity with delayed feedback
이 글에서 답하는 질문
- TTFT·ITL·E2E SLO와 goodput은 어떻게 정의하는가?
- Queue length와 GPU utilization만으로 overload를 알기 어려운 이유는 무엇인가?
- Admission 단계에서 memory와 deadline을 어떻게 검사하는가?
- 긴 prompt·긴 output·여러 tenant 사이의 공정성을 어떻게 계산하는가?
- Replica ready time이 긴 LLM에서 autoscaling 신호와 안전장치는 무엇인가?
- RAG Agent의 fan-out·tool wait·reasoning budget을 어떤 운영 계약으로 묶는가?
그림 1. SLO control plane은 router 앞의 rate limiter 하나가 아니다. Admission, queue discipline, token scheduler, worker pools와 delayed autoscaler가 같은 demand·capacity 단위를 공유해야 한다.
1. SLI, SLO, SLA를 구분한다
SLI
실제로 측정한 지표입니다. 예: TTFT p99 = 1.8s.
SLO
내부 운영 목표입니다. 예: interactive request의 99%가 TTFT 2s 이하.
SLA
고객과 맺은 계약과 보상 조건입니다. 모든 내부 SLO가 곧 SLA는 아닙니다.
SLO에는 대상 population, 측정 구간, percentile 또는 attainment, 제외 조건, model revision을 명시합니다.
population: interactive / model=v3 / region=kr
window: rolling 28 days
target: 99% requests TTFT ≤ 2 s
and: 99% output gaps ≤ 80 ms
exclude: client disconnect before admission only
2. LLM의 Latency를 분해한다
Request arrival부터 첫 token까지:
$$ TTFT=T_{route}+T_{queue}+T_{prefill}+T_{first\ decode} $$
전체 완료 시간은:
$$ T_{E2E}=TTFT+\sum_{j=2}^{O} ITL_j+T_{postprocess} $$
O: 생성된 output token 수ITL_j: output token 사이 간격TPOT: 구현에 따라 첫 token 이후 평균 time per output token
평균 TPOT만 보면 몇 초짜리 streaming stall 하나가 희석될 수 있습니다. User-facing SLO에는 token gap p99 또는 max stall도 둡니다.
3. SLO Class를 먼저 나눈다
모든 요청이 같은 deadline을 갖지 않습니다.
| Class | 예 | 주요 목표 | Overload 정책 |
|---|---|---|---|
| Interactive | Chat·tool call | Tight TTFT·ITL | Warm capacity·빠른 reject |
| Long reasoning | 분석·코딩 | ITL·완료 deadline | Output budget·별도 pool |
| Batch | 평가·요약 | Completion deadline | Queue·preempt 허용 |
| Best effort | 실험·재생성 | Cost·throughput | 남는 capacity 사용 |
Class별 queue·weight·deadline을 분리하되 idle capacity를 빌려 쓰는 work-conserving policy를 둡니다. 물리 GPU를 모두 고정 분리하면 한쪽은 idle이고 다른 쪽은 overload가 될 수 있습니다.
4. Goodput을 정의한다
Request goodput의 한 예:
$$ G_{req}=\frac{1}{\Delta t}\sum_i \mathbf{1}[TTFT_i\le D^{TTFT}_i\land TPOT_i\le D^{TPOT}_i\land success_i] $$
단순 attainment ratio도 함께 봅니다.
$$ A=\frac{\text{SLO를 만족한 요청 수}}{\text{admitted 요청 수}} $$
둘은 다릅니다. 10 RPS 중 100%를 만족하는 system과 100 RPS 중 80%를 만족하는 system은 attainment와 goodput 판단이 다릅니다. DistServe는 TTFT·TPOT constraint 안에서 처리되는 request rate라는 goodput 관점을 사용합니다.
5. Denominator를 숨기지 않는다
Admitted 요청만 denominator로 쓰면 입구에서 대량 reject해 100% attainment처럼 보일 수 있습니다.
운영 dashboard에는 함께 표시합니다.
- Offered requests·input tokens·예측 output tokens
- Admitted·deferred·degraded·rejected 수
- Reject reason과 tenant·class
- Admitted SLO attainment
- Offered load 대비 successful goodput
- Client cancel·timeout·retry amplification
Admission 정책 변경 전후에는 offered population이 같아야 비교가 가능합니다.
6. Request 수는 Demand 단위가 아니다
다음 두 요청은 1 request로 같지만 비용은 크게 다릅니다.
A: prompt 100 tokens, output 20 tokens
B: prompt 32K tokens, output 4K tokens, long-lived KV
Demand estimate에는 최소한 다음을 포함합니다.
- Input token·chunk와 prefill service time
- 예측 output token과 decode step
- KV bytes·residency time
- Model·adapter·quantization revision
- Speculative draft/verify cost
- Parallel Agent branch·best-of-N fan-out
Token 수를 선형 work로 쓰는 것은 첫 근사입니다. Attention, batch, prefix hit, hardware에 따라 달라지므로 profiled shape bucket의 service time으로 보정합니다.
7. Little의 법칙으로 Queue를 읽는다
안정된 장기 평균에서:
$$ L=\lambda W $$
L: system 안 평균 요청·workλ: 도착률W: 평균 체류 시간
예를 들어 queue에 평균 20 requests, 도착률 10 RPS라면 평균 queue·service 체류는 약 2초입니다. 그러나 LLM service time은 heavy-tailed이고 continuous batching으로 서로 결합되므로 평균식이 p99를 보장하지는 않습니다.
M/M/1의 W=1/(μ-λ)는 utilization이 1에 가까워질 때 지연이 급격히 증가한다는 직관만 줍니다. 실제 capacity curve는 open-loop replay로 측정합니다.
8. Queue Budget을 TTFT에서 역산한다
Interactive TTFT deadline D가 있을 때 허용 queue budget은 대략:
$$ B_{queue}=D-T_{route,p99}-T_{prefill,p99}-T_{first,p99}-margin $$
Queue age가 이 budget을 넘은 뒤 scale-out을 시작하면 이미 늦습니다. Admission과 autoscaler는 요청 수가 아니라 predicted wait와 deadline slack을 봅니다.
9. Deadline Slack
Request i의 TTFT slack을:
$$ slack_i=D_i-now-\widehat{T}_{queue+prefill+first,i}-U_i $$
로 둘 수 있습니다.
D_i: absolute first-token deadlineT̂: 현재 batch·queue에서의 예측U_i: prediction uncertainty·safety margin
slack_i < 0이면 정상 경로로 받아도 deadline을 놓칠 가능성이 높습니다. 단순 earliest-deadline-first는 긴 job이 주변 요청에 미치는 영향을 무시할 수 있으므로 expected work와 incumbent SLO impact도 함께 봅니다.
10. Admission Control의 네 Gate
Contract Gate
- 인증·tenant·model·adapter가 유효한가?
- Input·max output·context가 policy 안인가?
- Streaming·tool schema·priority가 지원되는가?
Memory Gate
- Prompt KV와 reserved output KV가 block pool에 들어가는가?
- Prefix hit를 과대평가하지 않았는가?
- Preemption·swap reserve를 남겼는가?
Deadline Gate
- Predicted TTFT와 TPOT가 SLO 안에 들어오는가?
- 새 요청이 active decode의 ITL을 깨뜨리는가?
Budget Gate
- Tenant token·GPU-time quota가 남았는가?
- Concurrent branch·session 한도를 넘지 않는가?
모든 gate가 같은 immutable request ID와 policy revision을 기록합니다.
11. Admit, Defer, Degrade, Reject
Admission 결과를 binary로만 두지 않습니다.
Admit
요청 contract 그대로 실행합니다.
Defer
Batch class나 deadline 여유가 있는 요청을 durable queue로 보냅니다.
Degrade
사용자가 동의한 policy 안에서 smaller model, shorter output cap, lower retrieval top-k, reduced reasoning budget으로 전환합니다.
Reject
지금 capacity로 안전하게 수행할 수 없음을 빠르게 알립니다. Rate limit이면 429, 일시적 service capacity이면 503 등 API 의미를 일관되게 하고 Retry-After·backoff hint를 제공합니다.
Streaming header나 첫 token을 보낸 뒤에는 깨끗한 retry가 어려우므로 admission을 먼저 확정합니다.
12. Overload에서 빠른 Reject가 나은 이유
회복 불가능한 요청을 queue에 계속 넣으면:
- Queue age가 늘어납니다.
- 기존 요청 TTFT가 deadline을 넘습니다.
- Client timeout과 retry가 증가합니다.
- 같은 논리 요청이 중복되어 load가 더 커집니다.
- Goodput이 collapse합니다.
Reject는 사용자 경험 비용이 있으므로 capacity 보호의 마지막 경계입니다. 그렇지만 “받고 늦게 실패”보다 deterministic한 retry·fallback이 가능한 경우가 많습니다.
13. Retry Storm을 통제한다
Client와 gateway 계약:
- Exponential backoff와 full jitter
- Server가 제공한
Retry-After - Idempotency key와 duplicate suppression
- Absolute deadline 전파
- 최대 retry count와 retry budget
- Region·model fallback의 circuit breaker
- Streaming partial response의 retry 금지 또는 resume protocol
Autoscaler로 capacity를 늘리는 동안 모든 client가 동시에 재시도하면 새 replica도 즉시 포화됩니다.
14. FIFO는 공정하지 않다
FIFO는 도착 순서를 지키지만 request cost를 모릅니다. 긴 prompt 하나가 short interactive request의 TTFT를 막고, 긴 generation 여러 개가 batch slot과 KV를 오래 점유할 수 있습니다.
반대로 shortest-job-first는 짧은 요청 throughput을 높여도 긴 요청을 굶길 수 있습니다. Deadline, tenant share, age와 unknown output length를 같이 다뤄야 합니다.
15. Token 기반 Fairness
VTC 논문의 기본 관점처럼 tenant가 받은 service를 weighted token으로 계산할 수 있습니다.
$$ service_i=w_p\cdot inputTokens_i+w_d\cdot outputTokens_i $$
- Prefill을 시작할 때 input token cost를 charge합니다.
- 매 decode iteration에서 생성된 token cost를 증가시킵니다.
- Virtual counter가 가장 작은 backlogged tenant를 우선합니다.
- Idle share는 다른 tenant가 빌려 쓰되 영구 credit으로 축적하지 않습니다.
Output 길이를 미리 몰라도 token마다 counter를 갱신할 수 있다는 장점이 있습니다. Weight는 실제 profiled GPU work와 product tier를 반영합니다.
16. Request Fairness, Token Fairness, GPU-time Fairness
어떤 cost function도 모든 목적을 만족하지 않습니다.
| 기준 | 장점 | 함정 |
|---|---|---|
| Request count | 단순 | 길이 차이를 무시 |
| Token count | Streaming과 잘 맞음 | Prefill·decode token 비용이 다름 |
| Predicted GPU time | 자원 비용에 가까움 | Model·batch별 predictor 필요 |
| KV byte-seconds | Memory 점유 반영 | Compute를 놓침 |
| Monetary cost | 제품 quota와 연결 | Hardware 상태와 시차 |
실무에서는 prefill work + decode work + KV byte-seconds의 근사와 weighted tenant share를 결합할 수 있습니다. Cost function revision을 metric label로 남깁니다.
17. Priority는 Fairness의 예외 계약이다
높은 priority는 무제한 선점권이 아닙니다.
- 예약된 minimum share
- Burst 가능한 maximum share
- Deadline이 가까운 request boost
- Queue age에 따른 aging
- Best-effort starvation bound
- Admin·safety request의 별도 lane
Tenant가 priority 값을 직접 임의 설정하지 못하게 하고 authorization policy에서 class를 부여합니다.
18. Deadline과 Fairness를 결합한다
Scheduler 후보 점수의 예:
eligible = memory_fit and not_expired
score =
+ deadline_urgency(slack)
+ starvation_age
- normalized_virtual_service / tenant_weight
- predicted_interference_on_active_decode
이는 일반 법칙이 아니라 설계 예입니다. SOLA처럼 request state와 iteration workload를 함께 조절하는 연구는 SLO attainment가 queue order뿐 아니라 매 iteration batch 선택에 달렸음을 보여 줍니다.
19. Prefill과 Decode를 따로 보호한다
긴 prefill을 한 번에 실행하면 active decode가 오래 기다릴 수 있습니다. 4편의 chunked prefill은 prefill을 작은 chunk로 나눠 decode 사이에 섞습니다.
SLO scheduler는 다음을 정합니다.
- Iteration당 decode token budget
- Prefill chunk token budget
- TTFT deadline이 가까운 prefill의 boost
- ITL stall을 막는 maximum iteration time
- Batch class가 빌리는 capacity
Sarathi-Serve는 chunked prefill과 stall-free scheduling으로 throughput·latency trade-off를 다룹니다.
20. Preemption의 비용
High-priority request 때문에 active generation을 멈추려면 state를 처리해야 합니다.
Keep KV on GPU
Compute slot만 양보합니다. Memory pressure는 줄지 않습니다.
Swap KV
GPU memory를 비우지만 host·network transfer latency가 생깁니다.
Recompute
KV를 버리고 나중에 prompt부터 다시 계산합니다. 긴 context에는 비쌉니다.
Migrate
다른 replica로 KV와 state를 옮깁니다. Llumnix는 live migration을 dynamic rescheduling에 사용합니다.
Preemption rate, pause duration, swapped byte, recompute token과 victim SLO를 관찰합니다.
21. Routing은 Queue Length보다 넓다
Replica 선택 점수에 다음을 포함합니다.
predicted queue work
+ active decode interference
+ KV memory pressure
+ model / adapter residency
- reusable prefix KV value
+ migration or cold-load cost
+ failure / rollout risk
Queue에 2건인 replica가 32K reasoning 요청을 처리 중이고, 10건인 replica가 짧은 tool call만 가진 경우 request count는 잘못된 선택을 합니다.
22. Session Stickiness와 Load Balance
같은 session을 같은 replica로 보내면 prefix·conversation KV를 재사용할 수 있지만 hot session이 imbalance를 만듭니다.
정책 선택:
- Hard stickiness: locality 우선, overload 위험
- Soft stickiness: slack 안에서 locality 우선
- Shared prefix store: transfer cost와 consistency 추가
- Migration: load balance와 state transfer 교환
- Recompute: short prefix일 때 단순
Router는 locality로 절약할 prefill time과 queue wait 증가를 같은 시간 단위로 비교합니다.
23. Autoscaling의 Control Loop
observe → estimate demand/capacity → decide → provision
→ load model → initialize ranks → warm kernels → ready
→ observe changed workload
Decision과 실제 capacity 사이에 긴 delay가 있습니다. 그동안 workload도 바뀝니다. 빠른 gain으로 queue 변동을 쫓으면 overshoot와 scale thrashing이 생깁니다.
24. GPU Utilization만으로 Scale하지 않는다
GPU utilization이 낮아도 다음 상태일 수 있습니다.
- KV cache가 꽉 차 새 request를 못 받음
- Small-batch decode가 memory bandwidth 또는 launch latency에 포화
- TP rank가 collective를 기다림
- Queue는 긴 prefill인데 CPU parsing이 막힘
- Prefix locality 때문에 특정 replica만 overload
반대로 큰 offline prefill로 utilization이 높아도 interactive queue는 비어 있을 수 있습니다. Utilization은 원인 진단용이지 단독 capacity signal이 아닙니다.
25. Queue를 Work-seconds로 바꾼다
Request i의 profiled remaining GPU work를 ŵ_i라 하면:
$$ Q_{work}=\sum_{i\in waiting+active}\hat{w}_i $$
Replica 하나의 target load에서 측정한 service rate가 C GPU-work/s라면 backlog drain time을 거칠게 Q_work/(R·C)로 볼 수 있습니다.
Predictor가 틀리므로 prompt bucket, output distribution, prefix hit, quantization·parallel plan별 error를 기록하고 p90 upper estimate를 admission에 사용할 수 있습니다.
26. 필요한 Replica 수의 시작식
Arrival work rate λ_w, replica당 sustainable work rate C, backlog Q, drain target T_d, safety factor s라면:
$$ R_{desired}=\left\lceil \frac{s\lambda_w+Q/T_d}{C} \right\rceil $$
이는 초기 controller 식입니다. C는 peak benchmark가 아니라 target TTFT·ITL을 만족하는 measured capacity envelope여야 합니다. Continuous batching 때문에 고정 상수가 아니므로 workload mix별 lookup table이나 model이 필요합니다.
27. Multi-signal Scale-out
Scale-out trigger 후보:
- Predicted queue wait가 TTFT budget 접근
- Earliest slack 또는 low-slack request 비율
- Arrival work rate의 상승 추세
- KV allocatable block headroom
- SLO goodput·attainment 하락
- Prefill·decode phase별 queue imbalance
- Replica failure·rollout로 effective capacity 감소
여러 metric 중 가장 큰 desired capacity를 선택하는 방식은 Kubernetes HPA의 multi-metric maximum과 유사하게 구성할 수 있습니다. 단, LLM-specific work estimator는 custom metric으로 제공해야 합니다.
28. Ready Time을 모두 더한다
새 replica가 capacity가 되는 시간:
$$ T_{ready}=T_{provision}+T_{image}+T_{weight}+T_{rank}+T_{compile}+T_{warm}+T_{register} $$
- GPU node 할당
- Container image·driver 준비
- Weight load·shard·quantized layout
- TP/PP communicator 초기화
- Kernel JIT·CUDA Graph capture
- Dummy prefill/decode warm-up
- Health·router registration
Readiness는 HTTP process가 떴다는 뜻이 아니라 target shape에서 정상 token을 생성하고 model revision·rank group이 일치하는 상태입니다.
29. Cold-start보다 짧은 Burst
Spike가 10초 안에 오는데 T_ready=120s라면 reactive autoscaling은 그 spike의 TTFT를 구할 수 없습니다.
가능한 조합:
- Minimum warm replicas
- Forecast에 따른 scheduled scale-out
- Preloaded weight·local checkpoint cache
- Standby rank group 또는 shared weight loading
- Admission·queue deadline protection
- Smaller fallback model
- Batch queue 전환
ServerlessLLM과 BlitzScale 같은 연구는 model loading·live scale 경로 자체를 줄이지만, 실제 환경의 weight locality와 network를 측정해야 합니다.
30. Scale-out을 완전한 Group으로 계산한다
TP=8 × PP=2 replica는 pod 하나가 아니라 16 GPU와 topology가 맞아야 ready입니다.
desired replicas = 4
ready complete groups = 2
partial groups = 1 ← capacity 0, resource already reserved
Gang scheduling, node topology, NCCL health, weight shard readiness를 group condition으로 묶습니다. Partial group을 capacity metric에 더하면 admission이 과도하게 열립니다.
31. Prefill과 Decode Pool을 따로 Scale한다
7편의 P/D 분리에서는 phase별 worker pool과 KV transfer를 다뤘습니다.
Prefill signal:
- Waiting input work·TTFT slack
- Chunk backlog·prefix hit
- Prefill GPU utilization·compute time
Decode signal:
- Active sequence·predicted remaining output
- ITL slack·KV byte-seconds
- Decode step time·batch occupancy
한 pool만 늘리면 KV transfer queue나 다른 pool이 bottleneck이 될 수 있습니다. Complete request goodput을 objective로 두고 phase ratio를 조정합니다.
32. Scale-in은 Drain Protocol이다
Replica를 즉시 종료하면 active stream과 KV를 잃습니다.
- Router에서 새 admission을 닫습니다.
- Prefix locality 손실과 migration 대상을 계산합니다.
- Active request가 끝나거나 deadline 안에 migrate합니다.
- Adapter·KV·trace를 flush합니다.
- Group 전체가 drain됐는지 확인합니다.
- Weight cache를 유지할지 eviction policy를 적용합니다.
- Capacity registry에서 제거한 뒤 자원을 반환합니다.
Scale-down stabilization window, minimum lifetime, maximum drain duration을 둬 flapping을 막습니다.
33. Hysteresis와 Rate Limit
Controller 안전장치:
- Scale-out threshold와 scale-in threshold를 다르게 둠
- Scale-down stabilization window
- 한 cycle의 최대 replica 증감
- 최소 warm replica·failure reserve
- Cooldown보다 readiness event를 우선 관찰
- Metric missing·stale 시 conservative policy
- Desired와 ready capacity를 분리
- Manual freeze·kill switch
Kubernetes HPA의 stabilization·scaling policy를 사용할 수 있지만 model group과 custom readiness semantics는 별도 controller가 보완해야 할 수 있습니다.
34. Failure와 Rollout도 Demand Event다
Traffic이 같아도 다음은 effective capacity를 줄입니다.
- GPU·NIC·rank failure
- Model revision canary가 GPU 일부 점유
- Quantized kernel fallback
- Prefix cache cold reset
- Region·zone evacuation
- Driver update와 graph recompile
Autoscaler input은 desired pod가 아니라 ready, healthy, benchmarked complete-group capacity입니다. N+1 reserve도 GPU 개수가 아니라 failure domain을 잃은 뒤 남는 SLO goodput으로 검증합니다.
35. RAG Agent의 Demand가 폭발하는 지점
한 user request가 한 generation이라는 가정이 깨집니다.
Retrieval Fan-out
Query rewrite·HyDE·multi-query가 여러 generation을 만듭니다.
Tool Parallelism
여러 tool result를 요약·검증하는 branch가 동시에 생깁니다.
Retry and Repair
JSON parse 실패나 insufficient evidence가 generation을 반복합니다.
Test-time Search
Best-of-N·verifier·tree search가 request 하나를 N개 candidate로 확장합니다.
Admission은 external request뿐 아니라 내부 branch 생성에도 적용합니다. Root request에 token·branch·wall-clock budget을 예약하고 child가 그 budget을 상속하게 합니다.
36. Tool Wait 동안 KV를 어떻게 할까
Agent가 외부 tool을 기다리는 동안 GPU KV를 유지하면 resume은 빠르지만 memory를 점유합니다.
정책 후보:
- 짧은 tool: GPU KV 유지
- 중간 wait: CPU·remote KV로 swap
- 긴 wait: state만 저장하고 recompute
- Deadline 종료: child tool과 KV를 함께 cancel
Tool latency distribution과 prefix recompute cost로 threshold를 정합니다. Waiting session도 KV byte-seconds fairness에 포함할 수 있습니다.
37. Degradation은 Quality Contract다
Overload 시 임의로 context를 자르거나 model을 바꾸면 조용한 품질 장애가 됩니다.
허용된 degrade ladder 예:
level 0: requested model + full retrieval + reasoning budget
level 1: same model + capped output
level 2: same model + reduced optional context
level 3: approved smaller model for non-critical class
level 4: asynchronous batch or explicit reject
Citation·ACL·safety evidence는 optional context와 구분합니다. Response에 applied policy와 model revision을 trace하되 내부 정보는 노출하지 않습니다.
38. Control-plane Decision Log
{
"request_id": "req_...",
"tenant_class": "interactive_standard",
"policy_revision": "slo-2026-07-16.3",
"slo_ms": {"ttft": 2000, "itl": 80},
"demand": {
"input_tokens": 8200,
"predicted_output_p90": 480,
"kv_mib_reserved": 1085,
"work_ms_p90": 960
},
"admission": {
"result": "admit",
"slack_ms": 430,
"reason": "within_deadline_and_memory"
},
"route": {
"replica_group": "rg-17",
"prefix_hit": true
}
}
Prompt 원문 없이도 decision을 재현할 수 있는 bucket·revision·estimate를 남깁니다.
39. 관찰할 Metric
Offered and Admission
- Offered request·input token·work rate
- Admit·defer·degrade·reject by reason
- Retry·duplicate·cancel rate
- Predicted slack와 actual error
Queue and Fairness
- Queue age·work-seconds·earliest slack
- Tenant별 virtual service와 share deviation
- Starvation age·priority inversion
- Prefill chunk·decode batch 구성
Workers
- TTFT·ITL·E2E p50·p95·p99
- SLO attainment·request/token goodput
- KV allocatable block·prefix hit
- Preemption·swap·recompute·migration
- Kernel·collective·rank health
Autoscaler
- Desired·provisioning·warming·ready group
- Ready time 단계별 breakdown
- Scale decision reason·forecast error
- Drain time·cache loss·thrash count
- Cost per SLO-attaining request
40. Alert는 행동과 연결한다
| Signal | 가능한 원인 | 즉시 행동 |
|---|---|---|
| TTFT 상승, ITL 정상 | Queue·prefill 부족 | Admission tighten·prefill scale |
| ITL 상승, TTFT 정상 | Decode batch·KV·collective | Prefill budget 축소·decode scale |
| Reject 급증, ready 증가 없음 | Provision·weight load 실패 | Warm pool·group event 조사 |
| Fair share deviation | Cost counter·priority 오류 | Scheduler policy rollback |
| KV pressure 상승 | Long output·tool wait | Output budget·swap·decode capacity |
| Utilization 낮고 queue 상승 | Rank/CPU/network bottleneck | Timeline·complete group health 확인 |
Alert가 “GPU utilization 90%”에서 끝나면 operator가 어떤 control을 바꿔야 할지 알 수 없습니다.
41. 운영 순서
- Class별 TTFT·ITL·completion SLO와 population을 정의합니다.
- Offered·admitted denominator와 goodput 식을 고정합니다.
- Production trace에서 input/output·KV·fan-out demand를 추정합니다.
- Open-loop benchmark로 replica별 SLO capacity envelope를 만듭니다.
- Queue wait budget과 prediction uncertainty margin을 정합니다.
- Contract·memory·deadline·budget admission gate를 구현합니다.
- Token/GPU-time cost 기반 tenant fairness와 aging을 검증합니다.
- Prefill chunk·decode budget이 TTFT·ITL을 함께 지키는지 봅니다.
- Queue work·slack·KV·goodput을 autoscaling custom metric으로 냅니다.
- Model group의 end-to-end ready time을 측정합니다.
- Warm floor·forecast·degrade·reject로 cold-start gap을 메웁니다.
- Scale-in drain, failure, rollout, retry storm을 chaos test합니다.
실전 체크리스트
- TTFT·ITL/TPOT·E2E·max stall을 구분했다.
- SLO의 population·window·percentile·제외 조건이 명확하다.
- Offered와 admitted denominator를 함께 본다.
- Request·token goodput 식과 deadline을 버전 관리한다.
- Request count를 profiled work·KV byte로 변환한다.
- Queue wait budget을 TTFT에서 역산했다.
- Admission에서 contract·memory·deadline·budget을 검사한다.
- Admit·defer·degrade·reject semantics가 API에 정의돼 있다.
- Retry-After·jitter·idempotency·retry budget을 적용했다.
- Tenant service를 input·output token 또는 GPU work로 charge한다.
- Priority maximum share와 starvation aging이 있다.
- Prefill chunk가 active decode ITL에 미치는 영향을 측정했다.
- Preemption의 KV keep·swap·recompute·migration 비용을 안다.
- Router가 queue work·KV·prefix locality를 함께 본다.
- GPU utilization을 단독 autoscaling signal로 쓰지 않는다.
- Desired와 complete-group ready capacity를 분리한다.
- Provision부터 warm-up까지 실제 ready time을 측정했다.
- Burst horizon이 ready time보다 짧을 때 warm floor가 있다.
- P/D pool의 phase별 queue와 complete goodput을 함께 본다.
- Scale-in이 drain·migration·cache policy를 따른다.
- Agent child branch와 tool wait에도 budget·cancel을 전파한다.
- Cost가 아니라 SLO-attaining request당 cost를 최적화한다.
스스로 확인하기
Q1. GPU utilization이 95%일 때만 scale-out하면 되는가?
아닙니다. KV memory가 먼저 포화되거나 small-batch decode·collective가 latency 병목일 수 있고, 반대로 best-effort prefill이 GPU를 채워도 interactive queue는 정상일 수 있습니다. Queue work, slack, KV pressure와 goodput을 함께 봅니다.
Q2. Admission reject를 늘리면 SLO가 좋아졌다고 볼 수 있는가?
Admitted 요청의 attainment는 좋아질 수 있지만 offered load 대비 goodput과 사용자 성공률은 나빠질 수 있습니다. Offered·admitted·rejected denominator와 reason을 함께 공개해야 합니다.
Q3. Tenant마다 같은 RPS 제한이면 공정한가?
아닙니다. 100-token chat과 32K prompt·4K output 요청은 GPU work와 KV 점유가 다릅니다. Input prefill, 생성 token, KV byte-seconds 같은 service cost를 weighted share에 반영합니다.
Q4. Queue가 길어진 뒤 replica를 추가하면 burst를 해결할 수 있는가?
Model provision·weight load·rank init·graph warm-up이 burst보다 길면 그 요청의 deadline에는 늦습니다. Warm capacity, forecast, admission, approved degradation이 cold-start interval을 보호해야 합니다.
Q5. Scale-in은 pod 수만 줄이면 되는가?
아닙니다. Active stream, KV, prefix cache와 multi-GPU rank group이 있습니다. 새 admission을 닫고 drain·migration한 뒤 complete group 단위로 registry에서 제거해야 합니다.
다음 글
이번 글은 SLO control loop의 정책과 신호를 설계했습니다. 마지막 글 LLM Serving 벤치마킹과 Capacity Planning: Trace·Goodput·비용·Release Gate에서는 이 controller가 믿을 수 있는 capacity envelope와 workload trace를 만들고, 몇 GPU가 필요한지 재현 가능하게 계산하는 전체 실험 절차를 다룹니다.
참고문헌
- Little, A Proof for the Queuing Formula: L = λW, Operations Research, 1961.
- Sheng et al., Fairness in Serving Large Language Models, OSDI 2024.
- Agrawal et al., Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve, OSDI 2024.
- Zhong et al., DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving, OSDI 2024.
- Sun et al., Llumnix: Dynamic Scheduling for Large Language Model Serving, OSDI 2024.
- Fu et al., ServerlessLLM: Low-Latency Serverless Inference for Large Language Models, OSDI 2024.
- Xu et al., SOLA: Optimizing SLO Attainment for Large Language Model Serving with State-Aware Scheduling, MLSys 2025.
- Patke et al., Hierarchical Autoscaling for Large Language Model Serving with Chiron, 2025.
- Zhang et al., BlitzScale: Fast and Live Large Model Autoscaling with O(1) Host Caching, OSDI 2025.
- Kubernetes, Horizontal Pod Autoscaling, accessed 2026-07-16.
검증 메모 — 개념과 문헌은 2026년 7월 16일 확인했습니다. SLO predictor·fairness cost·autoscaling threshold는 model, scheduler, GPU group, traffic와 product policy에 따라 달라집니다. 본문의 deadline·work·replica 식은 설계 예이며 실제 open-loop workload replay에서 TTFT·ITL goodput, reject·retry, ready time과 failure capacity를 다시 측정해야 합니다.