SGLang RadixAttention: KV 캐시를 트리로 공유하는 LLM 추론 아키텍처
같은 prompt를 매번 새로 계산하는 비용
RAG 파이프라인을 프로덕션에서 운영하면 금방 눈치채는 패턴이 있다. 수백만 개의 요청이 같은 시스템 프롬프트와 같은 문서 청크를 앞에 달고 들어온다. few-shot 분류기는 매 요청마다 동일한 예제 10개를 prefill한다. 멀티턴 에이전트는 대화가 길어질수록 앞부분을 반복한다.
GPU에서 prefill은 비싸다. transformer의 attention은 모든 token에 대해 key·value를 계산해 KV 캐시에 올려야 한다. 이 캐시가 요청 단위로 격리되면, 공통 prefix의 KV는 동일한 연산을 반복한다. 이론적으로는 낭비고, 프로덕션에서는 비용이다.
vLLM의 PagedAttention은 KV 캐시를 메모리 page 단위로 나눠 fragmentation을 줄였다. 하지만 기본적으로는 요청 단위 격리다. 공통 prefix의 공유는 separate feature로 구현되어 있고, 그 범위는 여전히 정적이다.
SGLang은 이 문제를 정면으로 겨냥한다. RadixAttention은 KV 캐시를 radix tree 구조로 유지하고, 들어오는 모든 요청에서 공통 prefix를 찾아 계산을 재사용한다. 이 장에서는 RadixAttention의 작동 원리, MLA 지원 아키텍처, 구조화된 출력(structured output) 최적화, 그리고 프로덕션 배포 시 고려사항을 살펴본다.
이 장은 SGLang 공식 문서, GitHub 리포지토리, 관련 기술 분석 자료를 기준으로 한다. vLLM과의 성능 비교 수치는 공개된 벤치마크를 인용하며, 워크로드와 하드웨어에 따라 다를 수 있다.
RadixAttention: KV 캐시를 트리로 보는 관점
PagedAttention의 page는 물리적 메모리 단편화를 해결한다. 하지만 서로 다른 요청이 같은 prefix를 가지고 있다는 의미적 사실을 활용하지 않는다.
RadixAttention의 핵심 아이디어는 단순하다. KV 캐시를 token sequence의 공통 prefix를 노드로 갖는 radix tree(압축 트라이)에 저장하고, 새 요청이 올 때 이 트리에서 longest prefix match를 찾아 기존 KV를 그대로 사용한다.
요청 A: [시스템 프롬프트 | 문서 1 | 질문 A]
요청 B: [시스템 프롬프트 | 문서 1 | 질문 B]
요청 C: [시스템 프롬프트 | 문서 2 | 질문 C]
트리 구조:
root
└─ [시스템 프롬프트] ─ 공유 ─
├─ [문서 1] ─ 공유 ─
│ ├─ [질문 A] ← 요청 A 고유
│ └─ [질문 B] ← 요청 B 고유
└─ [문서 2] ─ [질문 C] ← 요청 C 고유요청 B가 들어오면 [시스템 프롬프트 + 문서 1]에 해당하는 KV는 이미 트리에 있다. SGLang은 이 부분의 prefill을 건너뛰고 [질문 B]만 새로 계산한다.
트리 구조와 메모리 관리
RadixAttention은 GPU 메모리 위에서 동작하며, 트리 노드의 KV 데이터는 연속 메모리 블록을 사용한다. 각 노드는 token 범위, 해당 KV 포인터, 참조 카운트, 마지막 접근 시각을 관리한다.
메모리가 부족해지면 LRU(Least Recently Used) 정책으로 리프 노드부터 eviction한다. 참조 카운트가 0인(현재 활성 요청이 사용하지 않는) 노드만 제거 대상이 된다. 이 설계는 진행 중인 요청의 KV를 건드리지 않으면서 캐시 적중률을 유지한다.
PagedAttention과 무엇이 다른가
vLLM의 PagedAttention은 KV 캐시를 고정 크기 page로 나눈다. 목적은 메모리 단편화 제거다. 서로 다른 요청의 page는 물리적으로 불연속 메모리에 흩어져 있어도 논리적으로 이어진다.
공통 prefix 공유를 위해 vLLM도 prefix caching 기능을 별도로 제공한다. 하지만 두 접근의 근본적 차이는 설계의 우선순위다.
| 관점 | PagedAttention (vLLM) | RadixAttention (SGLang) |
|---|---|---|
| KV 캐시 구조 | 고정 크기 page, 요청별 논리 주소 | radix tree, token sequence 기반 |
| prefix 공유 | 별도 캐싱 레이어로 구현 | 트리 구조가 공유를 기본값으로 만든다 |
| 재사용 탐색 | 정적 prefix 비교 | longest match를 트리에서 탐색 |
| eviction | page 단위 LRU | leaf 노드부터 refcount 기반 LRU |
| 동적 공유 | 제한적 | 요청 도착 순서에 관계없이 공유 |
중요한 것은 어느 구현이 항상 낫다는 게 아니라, 워크로드가 prefix 공유를 얼마나 많이 가지느냐다. 고정 시스템 프롬프트 없는 단발성 요청이 대부분이라면 RadixAttention의 트리 탐색 overhead가 이득보다 클 수 있다. prefix 공유가 60% 이상인 워크로드에서야 RadixAttention의 가속이 드러난다.
MLA: DeepSeek V3에서 3.1× 빠른 이유
DeepSeek V3는 MLA(Multi-head Latent Attention)를 사용한다. 일반 MHA(Multi-head Attention)가 각 head마다 전체 KV를 저장하는 것과 달리, MLA는 low-rank 투영으로 KV를 압축한 잠재 벡터(latent vector)를 저장한다. KV 캐시 크기가 크게 줄고, 그만큼 더 긴 context를 같은 메모리로 처리할 수 있다.
그런데 이 구조는 기존 attention 커널이 그대로 최적화하기 어렵다. 잠재 벡터를 실제 K·V로 복원하는 단계가 추가되기 때문이다.
SGLang은 MLA를 위한 복수의 backend를 통합했다.
| backend | 특징 |
|---|---|
| FlashAttention3 | 현재 기본값 MLA backend. H100 Hopper 아키텍처의 WGMMA·TMA 명령을 활용 |
| FlashInfer | 페이지 단위 KV 처리에 최적화. 짧은 decode 단계에서 강점 |
| FlashMLA | DeepSeek이 MLA를 위해 직접 공개한 커널. CudaCore GEMMs 대신 Tensor Core를 사용 |
| CutlassMLA | NVIDIA CUTLASS 기반. 커스터마이징 가능성이 높음 |
같은 모델을 처리하는데 SGLang이 vLLM보다 DeepSeek V3에서 3.1× 빠른 이유는 RadixAttention의 prefix 공유와 MLA 최적화 커널의 조합이다. 단순한 추론 엔진 차이가 아니라 모델 아키텍처에 맞는 backend를 적극적으로 지원한 결과다.
Structured Output: 압축 FSM으로 JSON 디코딩을 3× 빠르게
LLM에서 구조화된 출력(JSON 스키마, 함수 호출)은 두 가지 방식으로 구현된다. 하나는 후처리 검증, 다른 하나는 디코딩 단계에서 유효하지 않은 토큰을 직접 차단하는 방식이다.
후자가 더 강력하지만 비용이 있다. 토큰마다 현재 FSM(Finite State Machine) 상태에서 허용되는 다음 토큰 집합을 계산해야 한다. vocabulary가 128,000개라면 매 step마다 128,000개 중 허용 여부를 판단해야 한다.
SGLang은 압축 FSM(Compressed Finite State Machine)을 사용한다. 핵심은 JSON 스키마에서 파생된 FSM을 사전에 분석하고, vocabulary를 토큰 단위가 아니라 FSM transition 단위로 미리 인덱싱하는 것이다. 런타임에는 현재 상태에서 유효한 토큰 집합을 미리 계산된 마스크에서 O(1)으로 읽어온다.
일반 FSM 압축 FSM
매 step: O(vocab_size) 매 step: O(1) 마스크 조회
예: 128k token 검사 예: 미리 인덱싱된 비트마스크SGLang 기준 JSON 디코딩이 나이브 구현 대비 약 3× 빠르다. 복잡한 중첩 JSON 스키마일수록 이 차이가 커진다.
이 기능은 도구 호출(tool calling), 함수 시그니처 추출, 데이터 추출 파이프라인에서 특히 중요하다. structured output을 검증 단계에서 디코딩 단계로 끌어들이면 재생성 재시도 비용도 줄어든다.
배포 아키텍처와 스케일링
SGLang은 단일 서버 배포부터 분산 클러스터까지 지원한다.
핵심 구성 요소
Zero-overhead CPU 스케줄러: 모든 요청 배치 결정을 Python GIL 밖에서 C++로 처리한다. 스케줄러가 GPU와 asyncronous하게 돌기 때문에 배치 구성 지연이 추론 throughput에 영향을 덜 준다.
Prefill-Decode 분리(Disaggregation): prefill(prompt 처리)과 decode(토큰 생성)를 별도 worker로 분리한다. prefill은 compute-bound, decode는 memory-bandwidth-bound이므로 분리하면 각자 최적 하드웨어를 쓸 수 있다. 멀티턴 에이전트에서 긴 context prefill이 decode throughput을 막는 문제를 줄인다.
Cache-aware 로드밸런서: 새 요청을 라우팅할 때 어떤 worker의 RadixAttention 트리에 해당 prefix가 이미 있는지를 고려한다. 캐시 히트가 높은 worker로 보내 cross-worker KV 재계산을 줄인다.
병렬 전략
Tensor Parallel → 한 모델을 여러 GPU에 나눠 실행 (큰 모델)
Pipeline Parallel → 레이어를 나눠 GPU 간 파이프라인 (긴 모델)
Expert Parallel → MoE 모델의 expert를 분산 (DeepSeek 등)
Data Parallel → 요청을 여러 인스턴스에 분산 (수평 확장)SGLang은 이 네 가지를 조합해 설정할 수 있다. DeepSeek V3처럼 MoE + MLA를 결합한 모델에서는 Expert Parallel과 MLA 커널 최적화를 같이 쓰는 것이 일반적이다.
SGLang이 적합한 워크로드와 그렇지 않은 워크로드
RadixAttention의 이점은 prefix 공유 비율과 직결된다. 이 비율이 낮으면 트리 탐색과 관리 overhead가 순이익을 상쇄한다.
| 워크로드 | SGLang이 유리한 이유 |
|---|---|
| RAG 파이프라인 | 같은 문서 청크가 여러 쿼리에 반복됨. prefix 히트율 높음 |
| few-shot 분류기 | 고정 예제가 모든 요청에 붙음. 예제 부분 KV 완전 공유 |
| 멀티턴 에이전트 | 대화 앞부분이 누적됨. 긴 context일수록 공유 비율 높아짐 |
| code completion | 코드베이스 prefix가 반복됨. 파일 단위 공유 가능 |
| structured output | 압축 FSM으로 JSON 디코딩 가속 |
| DeepSeek MoE 모델 | MLA 특화 커널로 vLLM 대비 현저한 속도 차이 |
| 워크로드 | 주의할 점 |
|---|---|
| 완전히 무작위 요청 | prefix 공유 없음. 트리 탐색만 overhead |
| 단발성 긴 prompt | cache hit 없고 eviction만 발생 |
| 짧은 문서 요약 반복 | prefix가 없으면 vLLM과 차이 없음 |
| 안정성이 최우선 | SGLang은 vLLM보다 ecosystem이 작아 provider 지원이 제한적일 수 있음 |
프로덕션 도입 체크리스트
--mem-fraction-static)을 먼저 측정하고 설정한다.정리
SGLang의 RadixAttention은 "KV 캐시를 요청 단위로 격리한다"는 기본 가정을 바꾼다. radix tree로 공통 prefix를 공유하면 RAG, few-shot, 멀티턴 워크로드에서 prefill 비용이 실질적으로 줄어든다.
MLA 특화 backend(FlashAttention3, FlashMLA 등)는 DeepSeek 계열처럼 attention 아키텍처가 다른 모델에서 기존 엔진 대비 눈에 띄는 성능 차이를 만든다. 압축 FSM structured output은 도구 호출과 JSON 추출이 많은 에이전트 파이프라인에서 디코딩 단계 자체를 빠르게 한다.
운영자가 기억할 것은 세 가지다. 첫째, 이득의 크기는 prefix 공유 비율에 달려 있다. 측정 없이 도입하면 overhead만 추가된다. 둘째, DeepSeek처럼 MLA를 쓰는 모델이라면 backend 선택이 latency·throughput에 결정적이다. 셋째, OpenAI-compatible API를 공유하므로 vLLM과 전환 비용이 낮다. 워크로드를 측정한 뒤 둘을 비교하고 선택하면 된다.
References
- SGLang GitHub Repository — sgl-project/sglang
- RadixAttention Documentation — SGLang
- SGLang vs vLLM in 2026: Benchmarks, Architecture, and When to Use Each
- SGLang Production Deployment Guide: RadixAttention and Multi-Turn Inference
- SGLang: How RadixAttention and Prefix Caching Are Reshaping LLM Serving at Scale
- Deploy FlashInfer on GPU Cloud: LLM Inference Kernels for vLLM and SGLang (2026)
- SGLang Learning Series — Part 1: Shared Prefix, KV Cache, and RadixAttention
- Irminsul: MLA-Native Position-Independent Caching for Agentic LLM Serving (arXiv)