← all posts
AI 2026.05.03 · 13 min read Advanced

LLM을 어떻게 배포할 것인가 — serving 스택의 네 층

KV cache 단편화 해소부터 mobile NPU 컴파일까지, LLM inference를 실용적으로 만드는 PagedAttention·Speculative Decoding·Continuous Batching·Edge Deployment의 설계 철학을 추적한다.


LLM 모델을 훈련하는 것과 실제로 서빙하는 것은 전혀 다른 문제다. 훈련은 GPU 수십 장과 며칠의 시간을 정당화할 수 있지만, inference는 사용자 요청마다 수백 ms 안에 응답해야 한다. 이 간극을 메우기 위해 시스템 연구자들이 내놓은 네 가지 핵심 아이디어 — PagedAttention, Speculative Decoding, Continuous Batching, Edge Deployment — 는 각각 독립적으로 보이지만, 하나의 공통 질문에 답한다: “어떻게 하면 모델의 품질을 손상시키지 않고 더 많은 요청을 더 빠르게 처리할 수 있는가?”

메모리 단편화라는 숨은 적 — PagedAttention

KV cache는 LLM inference에서 메모리의 가장 큰 소비자다. sequence length에 비례해서 커지고, 생성이 끝날 때까지 GPU에 남아 있어야 한다. 문제는 naive한 연속 할당 방식이다.

Sequence A: max 2048 예약, actual 100 → 95% 낭비 (internal fragmentation)
Sequence B: A가 끝난 후 남은 작은 hole들 → 새 큰 sequence가 들어갈 수 없음 (external fragmentation)

합산: 50-80% GPU 메모리가 실제로 사용되지 않는다

Kwon et al. (2023)의 PagedAttention은 OS의 가상 메모리에서 영감을 받는다. KV cache를 고정 크기 블록(예: 16 토큰)으로 나누고, 각 sequence마다 page table을 유지해 논리적 토큰 위치를 물리적 블록 ID로 매핑한다.

PageTable(s,t)(block_id, offset_within_block)\mathrm{PageTable}(s, t) \to (\text{block\_id},\ \text{offset\_within\_block})

블록 단위 할당은 internal fragmentation을 0으로 만들고, 어느 빈 블록이든 재사용할 수 있으므로 external fragmentation도 사라진다. 결과적으로 메모리 활용률이 50%에서 95% 이상으로 뛴다. 같은 prompt를 공유하는 여러 sample은 동일한 KV 블록을 reference count로 공유(prefix sharing)하며, Copy-on-Write로 isolation을 보장한다.

트레이드오프

블록 크기는 hyperparameter다. 너무 작으면 page table 조회 오버헤드가 커지고, 너무 크면 internal fragmentation이 다시 생긴다. 그리고 page table indirection 자체가 약 5-10%의 latency 비용을 추가한다 — 그러나 배치 크기 증가로 얻는 throughput 이득이 이를 압도한다.

병렬 추측으로 순차성을 우회 — Speculative Decoding

Autoregressive 디코딩의 근본적 병목은 순차성이다. 매 토큰마다 큰 target 모델의 full forward pass가 필요하다. Speculative Decoding(Leviathan et al., 2023)은 이 제약을 우회한다.

절차는 간단하다. 작고 빠른 draft 모델 MqM_qγ\gamma개 토큰을 먼저 추측한다. 그 다음 큰 target 모델 MpM_pprompt + draft tokens한 번의 forward pass로 처리해 모든 위치의 logit을 동시에 얻는다(causal mask 덕분에 가능). 각 draft 토큰은 rejection sampling으로 검증된다.

α(x)=min ⁣(1, p(xctx)q(xctx))\alpha(x) = \min\!\left(1,\ \frac{p(x \mid \mathrm{ctx})}{q(x \mid \mathrm{ctx})}\right)

핵심은 lossless라는 성질이다.

정리 2.1 · Speculative Decoding Lossless (Leviathan 2023)

Speculative decoding이 출력하는 토큰 시퀀스의 분포는 target 모델 pp로부터의 vanilla autoregressive sampling과 정확히 동일하다.

▷ 증명

임의의 토큰 xx에 대해 출력 확률을 계산한다. accept 경로에서의 기여는 min(q(x),p(x))\min(q(x), p(x))이고, reject 후 resampling 경로의 기여는 max(0,p(x)q(x))\max(0, p(x) - q(x))다. 두 항을 합치면 case analysis에 의해 정확히 p(x)p(x)가 된다. \square

β=0.7,γ=4,c=0.1\beta = 0.7, \gamma = 4, c = 0.1일 때 expected speedup을 계산하면 분자(expected accepted tokens) =1+0.7+0.49+0.343+0.24=2.77= 1 + 0.7 + 0.49 + 0.343 + 0.24 = 2.77, 분모(cost) =1+0.1×4=1.4= 1 + 0.1 \times 4 = 1.4로 약 2×가 된다. 실제 LLaMA-70B + 7B draft 조합에서 A100 기준 2-3×의 speedup이 보고된다.

GPU 공회전을 없애다 — Continuous Batching

PagedAttention이 메모리 문제를 풀었다면, Continuous Batching은 GPU utilization 문제를 푼다. Static batching의 낭비 구조는 직관적이다: 길이 50, 200, 100, 1000인 4개 sequence를 한 batch로 묶으면, 앞 세 sequence가 끝나도 1000짜리가 완료될 때까지 전체 배치가 기다린다. 평균 utilization이 30-50%에 그친다.

Continuous batching(Orca)의 해법은 매 generation step마다 batch 구성을 갱신하는 것이다.

Step t:    {A, B, C, D}
Step t+50: A 완료 → 제거, E 추가 → {B, C, D, E}
Step t+100: C 완료 → 제거, F 추가 → {B, D, E, F}
...

GPU는 거의 항상 실제 토큰을 처리 중이고, utilization은 90% 이상으로 올라간다. PagedAttention의 블록 단위 메모리 관리가 이 dynamic한 sequence 교체를 가능하게 한다. Static batching 대비 2-3×의 throughput 향상이 보고된다.

SLO(Service Level Objective)가 P99 latency 상한으로 정해진 상황이라면, 최적 배치 크기는 해당 latency 제약 안에서 throughput을 극대화하는 BB^*다. Priority queue와 weighted fair queuing으로 multi-tenant 환경에서 high-priority 요청에 GPU 시간을 우선 배분할 수 있다. 다만 low-priority 요청의 starvation 위험은 별도의 aging 메커니즘으로 관리해야 한다.

서버 최적화의 종착점 — Edge Deployment

서버 사이드의 모든 최적화(FlashAttention, PagedAttention, Speculative Decoding)는 cloud GPU를 전제한다. Mobile/embedded 환경은 제약이 다르다: 메모리 100MB-1GB, 배터리 예산, ARM CPU/Mali GPU/Apple Neural Engine 등 이기종 하드웨어.

실용적인 mobile 배포 파이프라인은 압축 → 변환 → 컴파일의 세 단계로 구성된다.

PyTorch FP32
  → Distillation (모델 크기 1/4)
  → Pruning 50% (effective 크기 1/2)
  → INT8 Quantization (크기 1/4)
  → ONNX export
  → Target compile (TFLite / CoreML / TVM)

Whisper-large(1.5GB)를 이 pipeline으로 통과시키면 최종 30MB 내외의 TFLite 모델이 되어 A14 Bionic에서 실시간 음성 인식이 가능해진다.

target compilation 도구의 선택은 배포 환경을 따른다. iOS는 CoreML(Apple Neural Engine 직접 활용), Android는 TFLite, 커스텀 NPU/FPGA에는 TVM의 AutoSchedule + LLVM backend가 적합하다. TVM은 수 시간의 search 비용이 들지만, 수동 튜닝 전문가가 없는 환경에서 custom hardware의 성능을 자동으로 끌어낸다.

정리

  • PagedAttention: KV cache를 OS paging 방식으로 관리해 메모리 단편화를 제거한다. 50%였던 GPU 메모리 활용률이 95% 이상으로 오른다.
  • Speculative Decoding: draft 모델의 병렬 추측 + target 모델의 한 번 verify로 2-3×의 throughput을 얻는다. rejection sampling 덕분에 출력 분포는 target과 정확히 동일하다.
  • Continuous Batching: 매 step마다 batch를 갱신해 GPU 공회전을 없앤다. PagedAttention과 결합하면 static batching 대비 2-3× throughput이 나온다.
  • Edge Deployment: 서버 압축 스택(distill → prune → quantize) + ONNX + target compile이 하나의 파이프라인을 이룬다. 최종 병목은 모델 크기가 아니라 hardware-specific kernel 최적화다.

LLM serving의 네 층은 결국 같은 원칙을 다른 레이어에서 구현한다 — 낭비되는 자원(메모리, 연산, GPU 대기, 모델 크기)을 체계적으로 0에 가깝게 만드는 것.

REF