<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kv 캐시 &#8211; 하루 한 AI</title>
	<atom:link href="https://jspulsar.dev/tag/kv-%ec%ba%90%ec%8b%9c/feed/" rel="self" type="application/rss+xml" />
	<link>https://jspulsar.dev</link>
	<description>매일 하나씩, AI로 똑똑해지기</description>
	<lastBuildDate>Wed, 03 Jun 2026 14:02:15 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://jspulsar.dev/wp-content/uploads/2026/02/favicon_512-150x150.png</url>
	<title>kv 캐시 &#8211; 하루 한 AI</title>
	<link>https://jspulsar.dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>KV 캐시가 뭐길래 — 긴 컨텍스트가 빠르게 비싸지는 이유</title>
		<link>https://jspulsar.dev/kv-cache-context-window-explained/</link>
					<comments>https://jspulsar.dev/kv-cache-context-window-explained/#respond</comments>
		
		<dc:creator><![CDATA[jshi2504]]></dc:creator>
		<pubDate>Wed, 03 Jun 2026 13:53:42 +0000</pubDate>
				<category><![CDATA[로컬AI]]></category>
		<category><![CDATA[학습]]></category>
		<category><![CDATA[claude api]]></category>
		<category><![CDATA[context window]]></category>
		<category><![CDATA[gemini api]]></category>
		<category><![CDATA[kv 캐시]]></category>
		<category><![CDATA[llm 추론]]></category>
		<category><![CDATA[로컬 ai]]></category>
		<guid isPermaLink="false">https://jspulsar.dev/?p=1350</guid>

					<description><![CDATA[Claude 200K, Gemini 1M이 왜 갑자기 비싸지는지 KV 캐시의 메모리 구조로 풀었다. 컨텍스트 윈도우와 KV 캐시 크기가 어떻게 연결되는지, GQA·PagedAttention·RadixAttention이 이 문제를 어떻게 다르게 푸는지 한국어로 정리한다.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Gemini 2.5 Pro 가격표를 보면 한 줄에 눈이 멈춘다. 200K 토큰을 넘는 순간 input 단가가 정확히 두 배가 된다. Claude도 2024 시점엔 비슷한 임계점이 있었다. &#8220;왜 갑자기 두 배지?&#8221;라는 질문에 한국어 인터넷은 &#8220;1M 컨텍스트는 1000배 비싸진다&#8221; 같은 단정으로 답하곤 한다. 원전을 찾으려고 한참 헤맸는데 못 찾았다. 대신 공식 자료들을 따라가며 진짜로 일어나는 일을 풀어봤다 — 답은 책상 위에 펼쳐둔 책 더미에 있다. 이 글은 그 KV 캐시와 컨텍스트 윈도우(context window)의 무게를 한국어 직관으로 정리한다.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="768" src="https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-formula-screenshot-1024x768.png" alt="" class="wp-image-1351" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-formula-screenshot-1024x768.png 1024w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-formula-screenshot-300x225.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-formula-screenshot-768x576.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-formula-screenshot-600x450.png 600w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-formula-screenshot.png 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 1. NVIDIA 공식 블로그의 KV 캐시 공식 설명</em></p>



<h2 class="wp-block-heading">TL;DR</h2>



<ul class="wp-block-list">
<li>KV 캐시는 트랜스포머가 매 토큰의 key·value 벡터를 보관하는 메모리다. 컨텍스트 윈도우가 길어질수록 무게가 늘어 GPU 메모리도 빠르게 차고 API 비용도 같이 올라간다.</li>



<li>Llama 3.1 8B(BF16) 기준 토큰 1개가 <strong>128 KB</strong>. 32K 컨텍스트 = <strong>4 GB</strong>, 128K = <strong>16 GB</strong>, 1M = <strong>128 GB</strong>. 모델 가중치(16GB)는 별도다.</li>



<li>Gemini 2.5 Pro는 200K 초과 시 input <strong>2배</strong>·output <strong>1.5배</strong>(Google AI 공식). Claude는 2024 시점엔 같은 임계점이었으나 2026 현재 <strong>Opus 4.8·4.7·4.6·Sonnet 4.6</strong>은 1M까지 standard pricing이다 — 뒤에서 시점 차로 따로 적었다.</li>



<li>PagedAttention(공간)·RadixAttention(상태)·GQA(원천) 셋은 같은 KV 캐시 문제를 다른 축에서 푸는 한 묶음이다.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">KV 캐시·Context Window가 뭔가</h2>



<p class="wp-block-paragraph">용어부터 간단히 정리한다. <strong>KV 캐시</strong>는 트랜스포머가 매 토큰의 key·value 벡터를 메모리에 저장해 다음 토큰을 만들 때 재사용하는 자료구조다. **컨텍스트 윈도우(context window)**는 한 번에 그 KV로 보관할 수 있는 토큰 수의 한도다. Anthropic 공식 문서는 컨텍스트 윈도우를 모델의 <a href="https://platform.claude.com/docs/en/build-with-claude/context-windows" target="_blank" rel="noopener">&#8220;working memory&#8221;</a>라고 부른다.</p>



<p class="wp-block-paragraph">이 글의 자리는 <a href="https://jspulsar.dev/vllm-pagedattention-explained/">vLLM이 PagedAttention으로 단편화를 푼 이야기</a>와 <a href="https://jspulsar.dev/sglang-radixattention-explained/">SGLang이 RadixAttention으로 prefix 재계산을 푼 이야기</a>의 <strong>뿌리</strong>다. 두 글이 KV 캐시의 증상(단편화·중복 계산)을 푼 약이었다면, 여기서는 그 진앙인 KV 캐시 자체를 본다. Yao Fu(2024)는 <a href="https://arxiv.org/abs/2405.08944" target="_blank" rel="noopener">긴 컨텍스트 배포의 어려움을 KV 캐시 단일 원인으로 환원</a>한다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">책상 비유로 KV 캐시 풀어보기</h2>



<p class="wp-block-paragraph">LLM은 토큰을 하나씩 생성한다. 다음 토큰을 만들려면 어텐션이 앞 토큰들의 key·value 벡터를 전부 봐야 하고, 매번 다시 계산하기엔 비싸니 메모리에 저장해둔다 — 그게 KV 캐시다. 토큰을 1개 더 생성할 때마다 <strong>새 K·V 한 묶음이 메모리에 더해진다.</strong> 1개씩, 선형으로.</p>



<p class="wp-block-paragraph"><a href="https://jspulsar.dev/sglang-radixattention-explained/">SGLang에서 RadixAttention을 도서관 책장으로 풀었듯</a>, KV 캐시 자체는 책상 위에 펼친 책 더미 비유로 풀린다.</p>



<p class="wp-block-paragraph">책상 한 장을 떠올려보자. <strong>책상의 크기</strong>가 컨텍스트 윈도우 한도다 — 8K, 128K, 1M. <strong>한 페이지</strong>는 토큰 1개고, 그 페이지에 그 토큰의 key·value 벡터가 적혀 있다. <strong>펼쳐둔 책 전체의 무게</strong>가 KV 캐시 메모리다. <strong>한 페이지의 무게</strong>는 모델 크기·정밀도·KV head 수에 따라 정해진다 — Llama 3.1 8B(BF16) 한 페이지가 128 KB인데, 정확 계산은 뒤에서 다시 본다.</p>



<p class="wp-block-paragraph">다음 토큰을 쓰려면 책상 위 모든 페이지를 한 번씩 훑어야 한다. 그게 어텐션 연산이다. 책상에 펼친 책이 1만 페이지면 새 한 페이지를 더 쓸 때 1만 페이지를 같이 본다.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="862" height="506" src="https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-context-window-diagram.png" alt="" class="wp-image-1352" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-context-window-diagram.png 862w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-context-window-diagram-300x176.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-context-window-diagram-768x451.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/kv-cache-context-window-diagram-600x352.png 600w" sizes="(max-width: 862px) 100vw, 862px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 2. 책상 = context window, 펼친 책의 무게 = KV 캐시 메모리, 한 페이지 = 토큰 1개</em></p>



<p class="wp-block-paragraph">비유는 여기까지가 깔끔하다. 다음은 이걸 토큰당 KB 단위 숫자로 옮겨보는 내용이다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">모델별 정확 수치 — Llama 3.1 8B/70B 컨텍스트별 표</h2>



<p class="wp-block-paragraph">KV 캐시 크기는 닫힌 공식으로 계산된다. NVIDIA Technical Blog·Lyceum·Morph가 동일하게 인용하는 <a href="https://developer.nvidia.com/blog/mastering-llm-techniques-inference-optimization/" target="_blank" rel="noopener">표준 공식</a>은 다음과 같다.</p>



<pre class="wp-block-code"><code>KV 캐시 (bytes) = 2 × num_layers × num_kv_heads × head_dim × seq_len × dtype_bytes
</code></pre>



<p class="wp-block-paragraph">여기서 2는 K와 V 두 텐서, <code>num_layers</code>는 트랜스포머 블록 수, <code>num_kv_heads</code>는 GQA 이후 KV head 수, <code>head_dim</code>은 헤드 차원, <code>seq_len</code>은 컨텍스트 토큰 수, <code>dtype_bytes</code>는 정밀도 바이트(BF16/FP16 = 2, FP8 = 1)다. Llama 3.1 8B는 <a href="https://huggingface.co/NousResearch/Meta-Llama-3.1-8B/raw/main/config.json" target="_blank" rel="noopener">HuggingFace config.json</a>에 <code>num_hidden_layers=32, num_key_value_heads=8, hidden_size=4096, num_attention_heads=32</code>로 박혀 있다. head_dim은 4096/32 = 128. 토큰 1개당 KV 캐시는 <code>2 × 32 × 8 × 128 × 2 = 131,072 bytes</code>, <strong>128 KB</strong>다.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="768" src="https://jspulsar.dev/wp-content/uploads/2026/06/llama-3-1-config-json-1024x768.png" alt="" class="wp-image-1353" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/llama-3-1-config-json-1024x768.png 1024w, https://jspulsar.dev/wp-content/uploads/2026/06/llama-3-1-config-json-300x225.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/llama-3-1-config-json-768x576.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/llama-3-1-config-json-600x450.png 600w, https://jspulsar.dev/wp-content/uploads/2026/06/llama-3-1-config-json.png 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 3. Llama 3.1 8B config.json — num_hidden_layers=32, num_key_value_heads=8</em></p>



<p class="wp-block-paragraph">여기에 컨텍스트 토큰 수를 곱하면 모델별 KV 캐시가 나온다. 단일 시퀀스(batch=1) 기준이다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Context</th><th>Llama 3.1 8B (128 KB/token)</th><th>Llama 3.1 70B (320 KB/token)</th></tr></thead><tbody><tr><td>8K</td><td><strong>1.0 GB</strong></td><td><strong>2.5 GB</strong></td></tr><tr><td>32K</td><td><strong>4.0 GB</strong></td><td><strong>10 GB</strong></td></tr><tr><td>128K</td><td><strong>16 GB</strong></td><td><strong>40 GB</strong></td></tr><tr><td>1M</td><td><strong>128 GB</strong></td><td><strong>320 GB</strong></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">표만 보면 &#8220;지수적으로 늘어난다&#8221;고 적고 싶어진다. 정확히는 그렇지 않다. <strong>단일 시퀀스의 KV 캐시 자체는 토큰 수에 선형으로 늘어난다.</strong> 다만 모델 크기(8B → 70B), 정밀도, 동시 사용자 수가 곱셈으로 붙으면서 GPU 한 장의 한계가 빠르게 닥친다. &#8220;기하급수적&#8221;보다는 &#8220;선형이지만 곱셈으로 부풀어 오른다&#8221;가 더 정확하다.</p>



<p class="wp-block-paragraph">숫자로 보면 분명하다. 70B를 1M로 돌리면 KV만 320 GB라 H100 80GB 한 장에 KV조차 못 들어가고, 가중치(BF16 약 140 GB)까지 합치면 H100 4~5장에 나눠 담아야 한다. 8B도 1M이면 KV 128 GB로 80GB 한계를 넘는다.</p>



<h3 class="wp-block-heading">GQA가 없었다면 더 무거웠다</h3>



<p class="wp-block-paragraph">표의 무게는 Llama 3.1이 GQA(grouped-query attention)를 쓴 결과다. <code>num_key_value_heads</code>가 query head 수(8B는 32, 70B는 64)보다 작아서(둘 다 8) KV 캐시가 줄어 있다. MHA였다면 8B는 토큰당 512 KB로 4배, 70B는 토큰당 2.5 MB로 8배 더 컸을 거다. 비교 대상을 빼고 &#8220;GQA는 8배 절약&#8221;이라고만 적으면 8B는 4배라 모순처럼 보이는데 둘 다 맞는 숫자다. GQA는 <a href="https://arxiv.org/abs/2305.13245" target="_blank" rel="noopener">Ainslie 외 EMNLP 2023</a>이 제안해 Llama 2 70B(2023-07)에서 처음 채택됐고 Llama 3부터 전 사이즈로 통일됐다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">API 가격 임계점 — Gemini 2.5 Pro와 Claude 시점 차</h2>



<p class="wp-block-paragraph">메모리 수치를 가격에 연결할 차례다. 가장 깨끗하게 임계점이 보이는 모델이 Gemini 2.5 Pro다. <a href="https://ai.google.dev/gemini-api/docs/pricing" target="_blank" rel="noopener">Google AI 공식 pricing</a>은 input을 ≤200K 구간 $1.25/MTok, &gt;200K 구간 <strong>$2.50/MTok</strong>(정확히 2배), output은 ≤200K $10/MTok, &gt;200K <strong>$15/MTok</strong>(1.5배)으로 적는다. 같은 모델인데 200K 라인 하나를 기준으로 단가가 갈린다.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>2024 vs 2026 — Claude 200K 임계점의 시점 차</strong></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>시점</th><th>상황</th></tr></thead><tbody><tr><td>2024-08 ~ 2025</td><td>Claude Sonnet 4·4.5, 200K 초과 시 input $3→$6 (2배), output $15→$22.50 (1.5배). 1M 베타·Tier 4+ 한정</td></tr><tr><td>2026-04 이후 (현재)</td><td><strong>Opus 4.8 · 4.7 · 4.6 · Sonnet 4.6</strong>은 <a href="https://platform.claude.com/docs/en/about-claude/pricing" target="_blank" rel="noopener">1M까지 standard pricing</a>. 임계점 사라짐. 공식 docs가 &#8220;900k-token 요청도 9k-token 요청과 같은 per-token rate로 청구된다&#8221;고 적는다 (Anthropic 모델 버전은 빈번하게 갱신되니 docs 직접 확인 권장)</td></tr><tr><td>차이</td><td>글이 인용되는 시점에 따라 다르다. 2024 시점에 적힌 글이 그대로 2026까지 돌아다니면서 &#8220;Claude 200K = 2배&#8221;가 굳어진 모양새다</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">그러니까 &#8220;Claude 200K부터 2배&#8221;를 검색에서 본 적이 있다면 그건 2024 시점의 사실이다. 2026 현재 Claude 신모델 라인에서는 그 임계점이 사라졌다. 임계점이 여전히 명시적으로 살아 있는 모델은 지금은 Gemini 2.5 Pro 쪽이다.</p>
</blockquote>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="https://jspulsar.dev/wp-content/uploads/2026/06/gemini-pricing-200k-threshold-1024x768.png" alt="" class="wp-image-1354" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/gemini-pricing-200k-threshold-1024x768.png 1024w, https://jspulsar.dev/wp-content/uploads/2026/06/gemini-pricing-200k-threshold-300x225.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/gemini-pricing-200k-threshold-768x576.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/gemini-pricing-200k-threshold-600x450.png 600w, https://jspulsar.dev/wp-content/uploads/2026/06/gemini-pricing-200k-threshold.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 4. Gemini 2.5 Pro의 200K 임계점 — input 2배, output 1.5배</em></p>



<p class="wp-block-paragraph">가격 얘기에서 자주 보이는 단정이 하나 더 있다. 인터넷에서 &#8220;1M 컨텍스트는 1000배 비싸진다&#8221; 같은 문장을 종종 본다. 원전을 못 찾았다. 한국어·영어 검색 어디에도, arxiv·공식 pricing 어디에도 1000배라는 단일 출처가 잡히지 않는다. 가장 가까운 정량 인용은 <a href="https://arxiv.org/abs/2405.08944" target="_blank" rel="noopener">Yao Fu(2024)</a>가 7B 모델 1M 토큰 KV가 100GB+ VRAM을 요구한다고 적는 정도다. 그래서 여기서는 1000배는 빼고 검증되는 숫자만 적었다 — Llama 3.1 8B 8K→1M KV가 1GB→128GB로 <strong>128배</strong>, Gemini 2.5 Pro 200K 초과 input <strong>2배</strong>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="https://jspulsar.dev/wp-content/uploads/2026/06/claude-pricing-1m-standard-1-1024x768.png" alt="" class="wp-image-1356" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/claude-pricing-1m-standard-1-1024x768.png 1024w, https://jspulsar.dev/wp-content/uploads/2026/06/claude-pricing-1m-standard-1-300x225.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/claude-pricing-1m-standard-1-768x576.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/claude-pricing-1m-standard-1-600x450.png 600w, https://jspulsar.dev/wp-content/uploads/2026/06/claude-pricing-1m-standard-1.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 5. Anthropic 공식 docs — Opus 4.8·4.7·4.6·Sonnet 4.6은 1M까지 standard pricing</em></p>



<p class="wp-block-paragraph">200K·1M 임계점은 마법이 아니라 H100 80GB 한 장이 KV를 더 들 수 없는 지점이 가격에 비친 모양새다. 그 너머는 GPU 여러 장과 더 복잡한 인프라가 붙어야 하니 단가가 갈린다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">세 길의 정리 — GQA · PagedAttention · RadixAttention</h2>



<p class="wp-block-paragraph">여기까지 보면 KV 캐시는 한 문제, 세 길이 있다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>길</th><th>차원</th><th>무엇을 줄이나</th><th>1차 출처</th></tr></thead><tbody><tr><td><strong>GQA / MQA</strong></td><td>원천 (KV head 수 자체)</td><td>KV head 수를 query head보다 줄여 한 페이지의 무게 자체 감소</td><td><a href="https://arxiv.org/abs/2305.13245" target="_blank" rel="noopener">Ainslie EMNLP 2023</a> / <a href="https://arxiv.org/abs/1911.02150" target="_blank" rel="noopener">Shazeer 2019</a></td></tr><tr><td><strong>PagedAttention</strong></td><td>공간 (메모리 단편화)</td><td>연속 메모리 예약을 block 단위로 흩어 담아 단편화 해소</td><td><a href="https://arxiv.org/abs/2309.06180" target="_blank" rel="noopener">Kwon SOSP 2023</a> · <a href="https://jspulsar.dev/vllm-pagedattention-explained/">vLLM 원리 글</a></td></tr><tr><td><strong>RadixAttention</strong></td><td>상태 (계산 중복)</td><td>같은 prefix는 KV 캐시 재사용 (radix tree)</td><td><a href="https://arxiv.org/abs/2312.07104" target="_blank" rel="noopener">Zheng NeurIPS 2024</a> · <a href="https://jspulsar.dev/sglang-radixattention-explained/">SGLang 원리 글</a></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">셋은 경쟁이 아니라 다른 축의 답이다. GQA는 한 페이지의 무게 자체를 줄이고, PagedAttention은 책상 위 책 배치의 빈틈을 줄이고, RadixAttention은 같은 첫 장을 두 번 펼치지 않는다. vLLM·SGLang 같은 서빙 엔진은 GQA 모델 위에서 두 기법을 같이 쓴다 — 같은 진앙에 세 약이 다른 축으로 붙는 구조다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">그래서 긴 컨텍스트는 어떻게 다루나</h2>



<p class="wp-block-paragraph">표를 다시 보면 &#8220;내 모델 + 내 컨텍스트 = KV 몇 GB&#8221;가 머릿속으로 계산된다. 로컬은 그 숫자가 가용 VRAM·통합 메모리를 안 넘어야 하고, API는 컨텍스트 임계점·prompt caching 단가가 곧 비용으로 이어진다. M3 Pro 36GB는 Llama 3.1 8B BF16(16GB) + 32K KV 4GB = 약 20GB로 여유가 있지만, 128K까지 가면 합 32GB로 빠듯해진다. RTX 2070 8GB는 8B BF16 자체가 VRAM을 넘어서 Q4 양자화 + 짧은 컨텍스트 조합만 현실적이다.</p>



<p class="wp-block-paragraph">API는 또 다른 절약 방법이 있다. Anthropic·Google의 prompt caching·context caching이 반복되는 prefix의 재청구를 일부 흡수한다 — <a href="https://jspulsar.dev/claude-api-%eb%b9%84%ec%9a%a9-%ec%99%84%eb%b2%bd-%ea%b0%80%ec%9d%b4%eb%93%9c-2026-%ed%86%a0%ed%81%b0-%eb%8b%a8%ea%b0%80%c2%b7%ec%ba%90%ec%8b%b1%c2%b7%eb%b0%b0%ec%b9%98-%ed%95%a0%ec%9d%b8-%ed%95%9c/">Claude API 비용 가이드</a>에서 캐시 단가와 배치 할인을 정리해뒀다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">자주 묻는 질문</h2>



<p class="wp-block-paragraph"><strong>Q1. KV 캐시가 정확히 뭔가요?</strong>
트랜스포머가 매 토큰의 key·value 벡터를 메모리에 저장해 다음 토큰을 만들 때 재사용하는 자료구조다. 비유로는 책상 위에 펼쳐둔 책 더미 — 한 페이지는 한 토큰, 책상 크기가 컨텍스트 윈도우다.</p>



<p class="wp-block-paragraph"><strong>Q2. 왜 긴 컨텍스트가 빠르게 비싸지나요?</strong>
KV 캐시가 토큰 수에 선형으로 늘고, 거기에 모델 크기·정밀도·동시 사용자 수가 곱셈으로 붙어 GPU 한 장의 메모리 한계가 빠르게 닥치기 때문이다. 200K·1M 임계점은 그 한계가 가격에 비친 자리다.</p>



<p class="wp-block-paragraph"><strong>Q3. Claude 200K랑 Gemini 1M, 가격은 똑같이 오르나요?</strong> 시점·모델마다 다르다. 2026 현재 명시적 임계점은 Gemini 2.5 Pro의 200K 초과 input 2배·output 1.5배. Claude는 2024~2025 시점엔 Sonnet 4·4.5 200K 초과 2배가 있었지만 2026 현재 Opus 4.8·4.7·4.6·Sonnet 4.6은 1M까지 standard pricing이다.</p>



<p class="wp-block-paragraph"><strong>Q4. GQA가 KV 캐시를 얼마나 아끼나요?</strong>
비교 대상을 명시해야 한다. Llama 3.1 8B 기준 4배, 70B 기준 8배 — MHA로 가정한 경우 대비다. MQA로 가면 한 단계 더 줄지만 품질이 같이 떨어지는 trade-off가 있어 Llama 라인은 GQA를 채택했다.</p>



<p class="wp-block-paragraph"><strong>Q5. &#8220;1M 컨텍스트는 1000배 비싸진다&#8221;는 사실인가요?</strong>
원전을 못 찾아 여기서는 다루지 않았다. 검증되는 가까운 정량 인용은 <a href="https://arxiv.org/abs/2405.08944" target="_blank" rel="noopener">Yao Fu 논문</a>이 짚는 &#8220;7B 모델 1M 토큰 KV가 100GB+ VRAM&#8221; 정도다.</p>



<p class="wp-block-paragraph"><strong>Q6. 8GB GPU(예: RTX 2070)에서 8K context를 돌릴 수 있나요?</strong>
8B 모델 BF16 자체가 16GB라 VRAM을 넘는다. Q4 양자화(4<del>5GB) + 짧은 컨텍스트(4K</del>8K)에선 가능하다. 긴 컨텍스트 자체는 8GB 단일 GPU에선 어렵다.</p>



<p class="wp-block-paragraph"><strong>Q7. PagedAttention·RadixAttention·GQA는 어떻게 다른가요?</strong>
같은 KV 캐시 문제를 다른 축에서 푼다. GQA는 한 토큰의 KV 크기 자체를 줄이고, PagedAttention은 메모리 단편화를 줄이고, RadixAttention은 같은 prefix를 두 번 계산하지 않는다. 셋은 같이 쓰는 약이다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">정리 — KV 캐시는 마법이 아니라 책상 위 무게다</h2>



<p class="wp-block-paragraph">KV 캐시는 마법이 아니라 책상 위에 펼쳐둔 책의 무게다. 한 토큰을 더할 때마다 무게가 선형으로 늘고, 모델 크기·정밀도·동시 사용자가 곱해지면 GPU 한 장의 한계가 빠르게 닥친다. Claude 200K·Gemini 1M에서 가격이 갑자기 오르는 임계점은 그 무게가 H100 80GB 한 장의 물리 한계를 넘는 지점이다. PagedAttention·RadixAttention·GQA는 그 무게를 줄이는 세 길이고 본 시리즈에서 한 글씩 다뤘다. 원리를 알면 &#8220;1M 1000배&#8221;라는 숫자에 휘둘리지 않게 된다 — 이 글에서 풀고 싶었던 한 줄이다.</p>



<h2 class="wp-block-heading">관련 글</h2>



<ul class="wp-block-list">
<li><a href="https://jspulsar.dev/vllm-pagedattention-explained/">vLLM은 왜 빠른가 — PagedAttention을 OS 페이징으로 이해하기</a> — <strong>이 글의 짝꿍</strong>. 공간 차원(메모리 단편화)으로 KV 캐시 문제를 푼 길.</li>



<li><a href="https://jspulsar.dev/sglang-radixattention-explained/">SGLang은 왜 빠른가 — RadixAttention과 prefix 공유의 직관</a> — <strong>이 글의 짝꿍</strong>. 상태 차원(prefix 재사용)으로 KV 캐시 문제를 푼 길.</li>



<li><a href="https://jspulsar.dev/claude-api-%eb%b9%84%ec%9a%a9-%ec%99%84%eb%b2%bd-%ea%b0%80%ec%9d%b4%eb%93%9c-2026-%ed%86%a0%ed%81%b0-%eb%8b%a8%ea%b0%80%c2%b7%ec%ba%90%ec%8b%b1%c2%b7%eb%b0%b0%ec%b9%98-%ed%95%a0%ec%9d%b8-%ed%95%9c/">Claude API 비용 완벽 가이드 2026</a> — 위 글이 짚은 가격 임계점의 실전 비용 가이드. 200K·prompt caching 맥락.</li>



<li><a href="https://jspulsar.dev/ollama%eb%a1%9c-m3-pro-%eb%a7%a5%eb%b6%81%ec%97%90-%eb%a1%9c%ec%bb%ac-llm-%eb%9d%84%ec%9a%b0%ea%b8%b0-30%eb%b6%84-%ec%8b%a4%ec%b8%a1-%ea%b0%80%ec%9d%b4%eb%93%9c/">Ollama로 M3 Pro 맥북에 로컬 LLM 띄우기 — 30분 실측 가이드</a> — 로컬 환경에서 KV 캐시 무게를 직접 느끼는 가장 단순한 출발점.</li>



<li><a href="https://jspulsar.dev/vllm-m3-pro-mac-guide/">M3 Pro에서 vLLM 돌려보기 — Mac 3경로와 솔직한 한계 (2026)</a> — 위 vLLM 짝꿍 글의 실측편. 책상 비유의 GB 숫자가 실제 Mac에서 어떻게 도는지.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">참고 자료</h2>



<ul class="wp-block-list">
<li><a href="https://arxiv.org/abs/1706.03762" target="_blank" rel="noopener">Attention is All You Need — Vaswani et al., arXiv:1706.03762</a> — Transformer·멀티헤드 어텐션 K·V 원전</li>



<li><a href="https://arxiv.org/abs/2405.08944" target="_blank" rel="noopener">Challenges in Deploying Long-Context Transformers — Yao Fu, arXiv:2405.08944</a> — &#8220;KV 캐시가 긴 컨텍스트 어려움의 단일 원인&#8221;이라는 학술 뼈대. 7B 모델 1M 토큰 KV 100GB+ 인용</li>



<li><a href="https://arxiv.org/abs/2305.13245" target="_blank" rel="noopener">GQA: Training Generalized Multi-Query Transformer Models — Ainslie et al., arXiv:2305.13245 (EMNLP 2023)</a> — GQA 원논문. 4·8배 절약 출처</li>



<li><a href="https://arxiv.org/abs/1911.02150" target="_blank" rel="noopener">Fast Transformer Decoding — Shazeer, arXiv:1911.02150</a> — MQA 원논문</li>



<li><a href="https://arxiv.org/abs/2407.21783" target="_blank" rel="noopener">The Llama 3 Herd of Models — arXiv:2407.21783</a> — Llama 3.1 공식 논문. 128K context·GQA 통일</li>



<li><a href="https://developer.nvidia.com/blog/mastering-llm-techniques-inference-optimization/" target="_blank" rel="noopener">Mastering LLM Techniques: Inference Optimization — NVIDIA Technical Blog</a> — KV 캐시 공식 1차 정리</li>



<li><a href="https://huggingface.co/NousResearch/Meta-Llama-3.1-8B/raw/main/config.json" target="_blank" rel="noopener">NousResearch/Meta-Llama-3.1-8B config.json</a> — num_layers·num_kv_heads·head_dim 직접 인용</li>



<li><a href="https://platform.claude.com/docs/en/about-claude/pricing" target="_blank" rel="noopener">Anthropic Pricing — platform.claude.com</a> — Opus 4.8·4.7·4.6·Sonnet 4.6 1M까지 standard pricing 공식 명시</li>



<li><a href="https://platform.claude.com/docs/en/build-with-claude/context-windows" target="_blank" rel="noopener">Anthropic Context Windows — platform.claude.com</a> — &#8220;working memory&#8221; 표현. 책상 비유 정합 근거</li>



<li><a href="https://ai.google.dev/gemini-api/docs/pricing" target="_blank" rel="noopener">Gemini API Pricing — Google AI</a> — Gemini 2.5 Pro 200K 임계점 정확 인용</li>



<li><a href="https://arxiv.org/abs/2309.06180" target="_blank" rel="noopener">PagedAttention — Kwon et al., arXiv:2309.06180 (SOSP 2023)</a> — vLLM PagedAttention 원논문</li>



<li><a href="https://arxiv.org/abs/2312.07104" target="_blank" rel="noopener">SGLang RadixAttention — Zheng et al., arXiv:2312.07104 (NeurIPS 2024)</a> — SGLang RadixAttention 원논문</li>
</ul>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jspulsar.dev/kv-cache-context-window-explained/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SGLang은 왜 빠른가 — RadixAttention과 prefix 공유의 직관</title>
		<link>https://jspulsar.dev/sglang-radixattention-explained/</link>
					<comments>https://jspulsar.dev/sglang-radixattention-explained/#respond</comments>
		
		<dc:creator><![CDATA[jshi2504]]></dc:creator>
		<pubDate>Sat, 30 May 2026 15:00:00 +0000</pubDate>
				<category><![CDATA[로컬AI]]></category>
		<category><![CDATA[학습]]></category>
		<category><![CDATA[kv 캐시]]></category>
		<category><![CDATA[llm 서빙]]></category>
		<category><![CDATA[prefix sharing]]></category>
		<category><![CDATA[radixattention]]></category>
		<category><![CDATA[sglang]]></category>
		<guid isPermaLink="false">https://jspulsar.dev/?p=1345</guid>

					<description><![CDATA[SGLang이 왜 vLLM 다음으로 주목받는지 RadixAttention 원리를 한국어 직관으로 풀었다. 접두사 트리로 KV를 공유해 CoT·multi-turn에서 prefix를 재계산하지 않는 구조와, PagedAttention과 어떻게 짝을 이루는지 — 6.4배의 비교 대상까지.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">로컬 LLM 처리량 얘기에서 vLLM을 만난 다음 줄에 SGLang이 있다. &#8220;최대 6.4배 빠르다&#8221;는 상투구가 됐는데, 정작 &#8220;왜 빠른가&#8221;를 한 문장으로 답해보라면 막힌다. 나도 그랬다. 그래서 공식 자료들을 따라가며 그 핵심을 도서관 책장 정리 비유로 다시 풀어봤다. <a href="https://jspulsar.dev/vllm-pagedattention-explained/">지난 글</a>에서 vLLM이 OS 페이징을 KV 캐시에 가져왔다는 이야기를 했는데, SGLang은 같은 문제를 다른 축에서 푼 한 쌍이다. 결론부터 말하면 SGLang의 빠름은 마법이 아니라 같은 prefix로 시작하는 책을 같은 책장에 모아두는, 잘 정리된 도서관의 아이디어다.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="https://jspulsar.dev/wp-content/uploads/2026/06/sglang-docs-home-1024x768.png" alt="" class="wp-image-1346" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/sglang-docs-home-1024x768.png 1024w, https://jspulsar.dev/wp-content/uploads/2026/06/sglang-docs-home-300x225.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/sglang-docs-home-768x576.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/sglang-docs-home-600x450.png 600w, https://jspulsar.dev/wp-content/uploads/2026/06/sglang-docs-home.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 1. SGLang 공식 문서 첫 화면</em></p>



<h2 class="wp-block-heading">TL;DR</h2>



<ul class="wp-block-list">
<li>SGLang은 LMSYS(UC 버클리 Zheng et al.)가 <strong>NeurIPS 2024</strong>에서 발표한 LLM 서빙 프레임워크. 핵심은 <strong>RadixAttention</strong> — 접두사 트리(radix tree)로 KV 캐시를 공유하는 알고리즘이다.</li>



<li>CoT·multi-turn 채팅·few-shot·RAG처럼 <strong>같은 prefix가 반복되는 워크로드</strong>에서 prefix를 재계산하지 않아 처리량을 끌어올린다. Chatbot Arena 실측 cache hit이 LLaVA-Next-34B 52.4%·Vicuna-33B 74.1%였다 (SGLang 논문).</li>



<li>논문 abstract 기준 <strong>최대 6.4배 throughput</strong> — vs Guidance·vLLM·LMQL·TGI 여러 워크로드의 최댓값(Llama-7B A10G·Mixtral-8x7B). LMSYS 블로그(좁은 범위)는 &#8220;최대 5배&#8221;로 적었는데 같은 연구를 다른 범위에서 본 수치라 서로 모순이 아니다.</li>



<li><strong>PagedAttention과는 다른 축의 최적화</strong>라 SGLang은 둘을 같이 쓴다. 2025~2026년 vLLM도 <strong>APC(Automatic Prefix Caching)</strong> 를 도입해 prefix 공유는 두 진영 공통 자산이 됐고, SGLang의 차별은 그 이상의 구조(CFSM·Frontend DSL)로 이동했다.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">SGLang이란? 왜 다들 SGLang을 말하나</h2>



<p class="wp-block-paragraph">SGLang은 LMSYS(UC 버클리, vLLM·Chatbot Arena와 같은 그룹)의 Lianmin Zheng 외가 <a href="https://arxiv.org/abs/2312.07104" target="_blank" rel="noopener">arXiv:2312.07104 — NeurIPS 2024</a>에서 발표한 LLM 서빙 프레임워크다. 2026년 5월 현재 <a href="https://github.com/sgl-project/sglang" target="_blank" rel="noopener">GitHub 28.7k stars</a>, xAI(Grok)·NVIDIA·AMD·LinkedIn·Cursor 등이 운영에 채택했다.</p>



<p class="wp-block-paragraph"><a href="https://jspulsar.dev/vllm-pagedattention-explained/">vLLM이 메모리 단편화를 줄여 더 많은 요청을 동시에 처리하는 길</a>이었다면, SGLang은 같은 prefix를 두 번 계산하지 않는 다른 길이다. 둘은 경쟁이 아니라 짝이고, SGLang은 두 기법을 같이 쓴다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">같은 prefix를 매번 다시 계산하는 낭비 — 무엇이 반복되나</h2>



<p class="wp-block-paragraph">KV 캐시를 짧게 짚으면 — LLM은 토큰을 하나씩 생성하면서 앞 토큰의 key/value 벡터를 재사용한다. 매번 다시 계산하면 느리니 메모리에 저장해둔다.</p>



<p class="wp-block-paragraph">운영 워크로드를 들여다보면 한 가지가 눈에 띈다. <strong>system prompt, few-shot 예시, 대화 이력, RAG 컨텍스트</strong>가 요청마다 반복된다. 기존 시스템은 이 반복되는 prefix를 매 요청마다 처음부터 다시 KV로 계산한다 — 캐시는 한 요청 안에서만 재사용되고 다음 요청이 오면 사라진다. SGLang 논문은 이 낭비가 특히 큰 4가지를 짚는다 — Few-shot learning, Self-consistency·CoT, Multi-turn chat, Tree-of-thought.</p>



<p class="wp-block-paragraph">처리량 한계가 메모리에 있다면 vLLM의 PagedAttention이 답이지만, 한계가 <strong>같은 prefix를 또 계산하는 데</strong> 있다면 다른 길이 필요하다. 그 길이 RadixAttention이다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">RadixAttention 직관 — 도서관 책장 정리 비유</h2>



<p class="wp-block-paragraph">여기가 글의 핵심이다. PagedAttention을 OS 페이징으로 풀었듯, RadixAttention은 도서관 책장 비유로 풀린다.</p>



<p class="wp-block-paragraph">일반 도서관을 떠올려보자. 책이 입고 순서대로 아무 책장에 꽂힌다. &#8220;김&#8221;으로 시작하는 책을 찾으려면 처음부터 뒤져야 한다. 기존 KV 캐시가 딱 이 모양이다 — 같은 prefix로 시작하는 시퀀스가 들어와도 이전 결과를 찾을 길이 없으니 처음부터 계산한다.</p>



<p class="wp-block-paragraph">이제 잘 정리된 도서관을 그려보자. 같은 첫 글자로 시작하는 책은 같은 책장에, 같은 두 글자는 같은 칸에, 같은 세 글자는 같은 선반에 둔다. <strong>트리처럼 가지치기로 분류되는 구조다.</strong> prefix가 같은 시퀀스가 들어오면 <strong>가장 긴 매칭 칸</strong>까지 그대로 재사용하고, 새 토큰만 그 가지 끝에 추가하면 된다.</p>



<p class="wp-block-paragraph">이 트리가 <strong>radix tree(접두사 트리)</strong> 다. 일반 trie와 다른 점은 간선에 단일 문자가 아니라 가변 길이 시퀀스가 라벨로 붙는다는 것 — 한 칸에 여러 글자 묶음이 들어간다고 생각하면 된다. KV 노드 메타는 CPU, 실제 KV 텐서는 GPU의 paged layout(토큰 1개당 1 page)에 둔다. PagedAttention의 메모리 구조 위에 RadixAttention의 prefix 공유 레이어가 얹히는 구조다.</p>



<p class="wp-block-paragraph">동작은 단순하다. 새 요청이 오면 스케줄러가 트리를 순회해 가장 긴 매칭 prefix까지 재사용하고, 신규 토큰만 계산해 가지 끝에 새 노드를 매단다. 자리가 부족하면 <strong>가장 오래 안 본 책부터</strong> 뺀다 — LRU 기반 eviction(리프 노드부터, reference count 0 우선). 트리 관리 패널티는 작다. <a href="https://www.lmsys.org/blog/2024-01-17-sglang/" target="_blank" rel="noopener">LMSYS 블로그</a>는 ShareGPT 측정 오버헤드 0.3% 미만이라고 적는다 — cache hit이 없어도 손해가 거의 없고, hit이 있으면 그만큼 이득이다.</p>



<p class="wp-block-paragraph">비유를 하나 더 보태면, 멀티턴 채팅은 &#8220;회사 양식 템플릿&#8221;에 가깝다 — 표지·머리말·정형 문구를 매번 새로 쓰지 않고 양식을 재사용한다.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="841" height="526" src="https://jspulsar.dev/wp-content/uploads/2026/06/radix-attention-mapping.png" alt="" class="wp-image-1347" srcset="https://jspulsar.dev/wp-content/uploads/2026/06/radix-attention-mapping.png 841w, https://jspulsar.dev/wp-content/uploads/2026/06/radix-attention-mapping-300x188.png 300w, https://jspulsar.dev/wp-content/uploads/2026/06/radix-attention-mapping-768x480.png 768w, https://jspulsar.dev/wp-content/uploads/2026/06/radix-attention-mapping-600x375.png 600w" sizes="auto, (max-width: 841px) 100vw, 841px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><em>그림 2. RadixAttention의 radix tree — 같은 prefix까지는 재사용, 새 토큰만 새 가지</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">PagedAttention과 RadixAttention — 공간 vs 상태</h2>



<p class="wp-block-paragraph"><a href="https://jspulsar.dev/vllm-pagedattention-explained/">vLLM 글</a>을 읽은 사람이 가장 궁금해할 질문에 답할 차례다.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>PagedAttention이 공간(메모리)을 아끼고, RadixAttention은 상태(계산)를 아낀다.</strong></p>
</blockquote>



<p class="wp-block-paragraph">두 기법은 서로 다른 영역을 건드리니 같이 쓸 수 있다. <a href="https://www.lmsys.org/blog/2024-01-17-sglang/" target="_blank" rel="noopener">LMSYS 블로그</a> 원문이 명시한다 — &#8220;RadixAttention is <strong>compatible with existing techniques like continuous batching and paged attention</strong>.&#8221; SGLang 런타임은 paged layout 위에 RadixAttention의 prefix 공유 레이어를 얹는다. 같이 쓴다.</p>



<p class="wp-block-paragraph">그래서 SGLang vs vLLM은 &#8220;어느 게 더 빠른가&#8221;가 아니라 &#8220;어느 워크로드냐&#8221;의 문제다. 그런데 여기서 한 가지 짚고 가야 한다.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>2024 vs 2026 — vLLM APC 도입의 진실</strong></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>시점</th><th>상황</th></tr></thead><tbody><tr><td>2024 초</td><td>SGLang의 RadixAttention 발표 직후. vLLM은 prefix caching 미보유. 워크로드에 따라 RadixAttention 우위 명확</td></tr><tr><td>2025~2026</td><td>vLLM이 <a href="https://docs.vllm.ai/en/latest/features/automatic_prefix_caching/" target="_blank" rel="noopener">APC(Automatic Prefix Caching)</a> 도입. <a href="https://docs.vllm.ai/en/v0.6.0/automatic_prefix_caching/details.html" target="_blank" rel="noopener">vLLM design docs</a>가 본인 입으로 &#8220;this eviction policy effectively implements the exact policy as in RadixAttention <strong>when applied to models with full attention</strong>&#8220;이라고 적는다 — RadixAttention의 정책과 사실상 동등 (full attention 모델 한정)</td></tr><tr><td>차이</td><td>SGLang은 token-level radix tree, vLLM APC는 block-level hash matching. 매칭 단위와 자료구조가 다르고, 워크로드에 따라 격차가 다르게 나타난다</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">정리하면, <strong>prefix 공유 자체는 두 진영의 공통 자산이 됐다.</strong> SGLang의 차별은 그 이상의 구조(아래에서 짧게 볼 Compressed FSM·Frontend DSL)로 이동했다. 이 시점 차를 모르면 &#8220;SGLang이 prefix caching의 유일한 답&#8221;이라는 인상을 받기 쉬운데, 그건 2024 시점에 적힌 글이 그대로 전해진 결과다.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">&#8220;최대 6.4배&#8221;의 정확한 비교 대상</h2>



<p class="wp-block-paragraph"><a href="https://arxiv.org/abs/2312.07104" target="_blank" rel="noopener">SGLang 논문 abstract</a>는 이렇게 적는다 — &#8220;SGLang achieves up to <strong>6.4× higher throughput</strong> compared to state-of-the-art inference systems on various large language and multi-modal models on tasks including agent control, logical reasoning, few-shot learning benchmarks, JSON decoding, retrieval-augmented generation pipelines, and multi-turn chat.&#8221; 한 문장에 <strong>비교 상대·모델·워크로드·&#8221;최댓값&#8221;</strong> 정보가 모두 들어 있다. 그래서 &#8220;6.4배 빠르다&#8221;만 따로 떼면 비교 상대·모델·워크로드가 사라진 숫자가 된다.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>수치 정직 박스 — 같은 SGLang의 여러 숫자</strong></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>수치</th><th>무엇 대비 무엇</th><th>조건 · 출처</th></tr></thead><tbody><tr><td><strong>최대 6.4배 throughput</strong></td><td>SGLang <strong>vs Guidance·vLLM·LMQL·HuggingFace TGI</strong></td><td>Llama-7B(A10G)·Mixtral-8x7B, 여러 워크로드의 최댓값 (<a href="https://arxiv.org/abs/2312.07104" target="_blank" rel="noopener">arXiv:2312.07104 abstract</a>)</td></tr><tr><td>최대 5배 throughput</td><td>SGLang <strong>vs Guidance v0.1.8, vLLM v0.2.5, TGI v1.3.0</strong></td><td>Llama-7B/Mixtral, A10G, MMLU·HellaSwag·ReAct·ToT (좁은 범위) (<a href="https://www.lmsys.org/blog/2024-01-17-sglang/" target="_blank" rel="noopener">LMSYS Blog 2024-01-17</a>)</td></tr><tr><td>최대 2.5배 throughput (구조화 출력)</td><td>SGLang <strong>compressed FSM (jump-forward)</strong> vs Outlines+vLLM v0.2.7, Guidance+llama.cpp v0.2.38</td><td>Llama-7B, 정보 추출·JSON 디코딩 (<a href="https://www.lmsys.org/blog/2024-02-05-compressed-fsm/" target="_blank" rel="noopener">LMSYS Blog 2024-02-05</a>)</td></tr><tr><td>cache hit 52.4% / 74.1%</td><td>RadixAttention 실측 (LLaVA-Next-34B / Vicuna-33B)</td><td>Chatbot Arena 프로덕션 (SGLang 논문)</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">같은 SGLang에 대한 다른 숫자가 모순이 아닌 이유는 <strong>비교 상대와 워크로드 범위가 다르기 때문</strong>이다. S4에서 본 vLLM의 &#8220;24배 vs 2~4배&#8221;와 같은 패턴.</p>
</blockquote>



<p class="wp-block-paragraph">참고로 &#8220;SGLang structured generation 최대 22배&#8221;라는 수치를 인터넷에서 종종 본다. 그런데 원전을 못 찾았다. SGLang 논문·LMSYS 블로그·GitHub README·NeurIPS Proceedings를 다 훑어봐도 22배가 어디서 나온 수치인지 짚을 수 없었다. 가장 가까운 검증 가능 수치는 위 표의 <strong>CFSM 2~2.5배</strong>(vs Outlines+vLLM·Guidance+llama.cpp)이고, xgrammar 통합 이후 JSON 디코딩 3~10배가 <a href="https://x.com/lmsysorg/status/1861880264567443958">LMSYS 트윗 2024-11</a>에서 확인된다. 그래서 본 글에서는 22배는 빼고 위 표의 수치만 적었다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Compressed FSM과 Frontend DSL — 한 줄로</h2>



<p class="wp-block-paragraph">SGLang의 차별이 RadixAttention &#8220;그 이상&#8221;으로 이동했다고 했으니, 그 위가 무엇인지 짧게 짚는다.</p>



<p class="wp-block-paragraph"><strong>Compressed FSM(CFSM)</strong> — JSON schema·정규식으로 출력을 강제하는 constrained decoding. schema → regex → FSM 변환 후 &#8220;토큰 선택지가 단 하나뿐&#8221;인 구간을 찾아 여러 토큰을 한 번에 prefill 처리한다(jump-forward). 구조화 출력이 자유 생성보다 빨라지는 경우가 생기는 이유다 — <a href="https://www.lmsys.org/blog/2024-02-05-compressed-fsm/" target="_blank" rel="noopener">LMSYS 블로그</a> 참조.</p>



<p class="wp-block-paragraph"><strong>Frontend DSL</strong> — Python 내장 DSL로 prompt 흐름을 함수처럼 표현한다(<code>gen()</code>·<code>select()</code>·<code>fork()</code>). prefix 공유 효과는 vanilla API에서도 자동으로 얻으니, DSL은 여러 단계 prompt 프로그램을 함수처럼 짜는 추가 도구로 보면 된다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Ollama·vLLM·SGLang — 어느 게 빠른가가 아니라 목적이 다르다</h2>



<p class="wp-block-paragraph">원리를 알고 나면 자주 나오는 질문이 &#8220;그럼 셋 중 뭐 쓰지&#8221;다. <a href="https://jspulsar.dev/ollama%eb%a1%9c-m3-pro-%eb%a7%a5%eb%b6%81%ec%97%90-%eb%a1%9c%ec%bb%ac-llm-%eb%9d%84%ec%9a%b0%ea%b8%b0-30%eb%b6%84-%ec%8b%a4%ec%b8%a1-%ea%b0%80%ec%9d%b4%eb%93%9c/">Ollama</a>는 단일 사용자 prototyping의 단순함, vLLM은 다중 요청 처리량의 메모리 효율, SGLang은 prefix가 반복되는 워크로드(챗봇·RAG·에이전트·CoT)의 계산 절약과 jump-forward — 어느 게 빠른가가 아니라 목적이 다르다. SGLang은 vLLM의 대체가 아니라 PagedAttention 위에 RadixAttention을 얹는 조합 관계고, 단일 사용자 로컬에선 Ollama가 더 실용적, 동시 요청이 많은 서버에서 SGLang 이득이 드러난다. 단일 기기 결정 트리는 후속 글(준비 중).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">자주 묻는 질문</h2>



<p class="wp-block-paragraph"><strong>Q1. SGLang이 vLLM보다 정말 6배 빠른가요?</strong>
6.4배는 SGLang 논문 abstract의 vs Guidance·vLLM·LMQL·TGI <strong>여러 워크로드 최댓값</strong>(Llama-7B A10G·Mixtral-8x7B)이다. LMSYS 블로그(좁은 범위)에선 5배, 일반 batch 워크로드에선 더 작을 수 있다.</p>



<p class="wp-block-paragraph"><strong>Q2. RadixAttention과 PagedAttention의 차이는 무엇인가요?</strong>
PagedAttention은 메모리 단편화를 줄여 공간을 아끼고, RadixAttention은 같은 prefix를 두 번 계산하지 않아 상태(계산)를 아낀다. 둘은 서로 다른 축의 최적화라 SGLang은 둘을 같이 쓰고, 2025~2026년 vLLM도 APC로 prefix caching을 흡수했다.</p>



<p class="wp-block-paragraph"><strong>Q3. SGLang은 vLLM을 대체하나요?</strong>
꼭 그렇진 않다. prefix 공유 효과가 큰 워크로드(챗봇·RAG·에이전트·CoT)는 SGLang이 강점, 일반 서빙은 vLLM도 충분. 둘 다 OpenAI 호환 API라 엔드포인트만 바꾸면 코드가 그대로 붙는다.</p>



<p class="wp-block-paragraph"><strong>Q4. RadixAttention은 어떤 워크로드에 가장 효과적인가요?</strong>
system prompt가 반복되는 챗봇, few-shot 예시를 공유하는 분류·추출, CoT 분기, multi-turn 대화처럼 <strong>prefix가 반복되는 패턴</strong>이다. Chatbot Arena 실측 cache hit이 LLaVA-Next-34B 52.4%·Vicuna-33B 74.1%(SGLang 논문 RadixAttention 실험)였다.</p>



<p class="wp-block-paragraph"><strong>Q5. SGLang의 Compressed FSM이 22배 빠르다는데 사실인가요?</strong>
논문·LMSYS·GitHub README를 다 훑어봐도 22배 수치는 못 찾았다. 검증되는 가까운 수치는 CFSM(jump-forward)의 <strong>최대 2.5배 throughput·2배 latency 감소</strong> — vs Outlines+vLLM v0.2.7·Guidance+llama.cpp v0.2.38(<a href="https://www.lmsys.org/blog/2024-02-05-compressed-fsm/" target="_blank" rel="noopener">LMSYS 2024-02-05</a>)이고, xgrammar 통합 후 JSON 디코딩 3~10배가 <a href="https://x.com/lmsysorg/status/1861880264567443958">LMSYS 트윗 2024-11</a>에 보고됐다. 그래서 본 글에서도 22배는 다루지 않았다.</p>



<p class="wp-block-paragraph"><strong>Q6. SGLang을 RTX 2070·M3 Pro 같은 소비자 GPU에서 돌릴 수 있나요?</strong>
가능하나 throughput 이득은 <strong>동시 요청이 많은 서버 시나리오</strong>에서 본격적으로 나타난다. 단일 사용자 로컬은 Ollama·llama.cpp가 더 실용적이고, 결정 트리는 후속 글에서 다룬다.</p>



<p class="wp-block-paragraph"><strong>Q7. SGLang은 Ollama와 어떻게 다른가요?</strong>
&#8220;단일 사용자 = Ollama, 다중 처리량 + prefix 반복 = SGLang&#8221;으로 정리하면 헷갈리지 않는다. 어느 게 빠른가가 아니라 목적이 다르다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">정리 — 빠름은 마법이 아니라 책장 정리다</h2>



<p class="wp-block-paragraph">SGLang의 빠름은 <strong>트리 한 그루</strong>에서 나온다. 같은 prefix로 시작하는 KV를 같은 가지에 모아두고, 새 요청이 오면 가장 긴 매칭 가지까지 재사용한 뒤 새 토큰만 가지를 친다 — 도서관이 잘 정리되면 같은 책을 두 번 찾으러 안 다니듯. PagedAttention과 짝이고, 공간을 아끼는 길과 상태를 아끼는 길은 다른 축이라 같이 쓸 수 있다. 2026년 vLLM도 APC로 같은 방향을 흡수했고, SGLang의 차별은 그 위(CFSM·Frontend DSL)로 옮겨갔다. 원리를 알면 &#8220;6.4배&#8221;라는 숫자에 휘둘리지 않게 된다. 이 글에서 풀고 싶었던 게 그 한 줄이다.</p>



<h2 class="wp-block-heading">관련 글</h2>



<ul class="wp-block-list">
<li><a href="https://jspulsar.dev/vllm-pagedattention-explained/">vLLM은 왜 빠른가 — PagedAttention을 OS 페이징으로 이해하기</a> — <strong>본 글의 짝꿍</strong>. RadixAttention과는 다른 축(공간 차원)의 원리. 본 글의 &#8220;PagedAttention vs RadixAttention&#8221; 박스가 직접 참조한 글이다.</li>



<li><a href="https://jspulsar.dev/vllm-m3-pro-mac-guide/">M3 Pro에서 vLLM 돌려보기 — Mac 3경로와 솔직한 한계 (2026)</a> — 짝꿍 글의 실측편. 원리를 알았으니 실제 맥에서 어떻게 도는지 보고 싶다면.</li>



<li><a href="https://jspulsar.dev/ollama%eb%a1%9c-m3-pro-%eb%a7%a5%eb%b6%81%ec%97%90-%eb%a1%9c%ec%bb%ac-llm-%eb%9d%84%ec%9a%b0%ea%b8%b0-30%eb%b6%84-%ec%8b%a4%ec%b8%a1-%ea%b0%80%ec%9d%b4%eb%93%9c/">Ollama로 M3 Pro 맥북에 로컬 LLM 띄우기 — 30분 실측 가이드</a> — &#8220;셋 중 뭐 쓰지&#8221;의 가장 단순한 출발점. &#8220;단일 사용자 = Ollama&#8221; 맥락.</li>



<li>(준비 중) Mac·RTX 2070에서 SGLang 결정 트리 — 본 글의 실측 짝으로 이어질 후속 글.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">참고 자료</h2>



<ul class="wp-block-list">
<li><a href="https://arxiv.org/abs/2312.07104" target="_blank" rel="noopener">SGLang: Efficient Execution of Structured Language Model Programs — arXiv:2312.07104 (NeurIPS 2024)</a> — RadixAttention·CFSM 원논문. 6.4배·cache hit 52.4%·74.1% 출처</li>



<li><a href="/kv-cache-context-window-explained">KV 캐시가 뭐길래 — 긴 컨텍스트가 빠르게 비싸지는 이유</a> — <strong>본 글이 다룬 RadixAttention의 진앙</strong>. PagedAttention(공간)·RadixAttention(상태)이 풀려고 한 KV 캐시 자체를 책상 비유로 푼 학습 시리즈 뿌리 글. Claude 200K·Gemini 1M 가격 임계점까지.</li>



<li><a href="https://www.lmsys.org/blog/2024-01-17-sglang/" target="_blank" rel="noopener">Fast and Expressive LLM Inference with RadixAttention and SGLang — LMSYS Blog (2024-01-17)</a> — RadixAttention 도입 글. 5배(좁은 범위) 출처, &#8220;compatible with paged attention&#8221; 인용</li>



<li><a href="https://www.lmsys.org/blog/2024-02-05-compressed-fsm/" target="_blank" rel="noopener">Fast JSON Decoding for Local LLMs with Compressed Finite State Machine — LMSYS Blog (2024-02-05)</a> — CFSM 도입 글. 2.5배·2배 출처</li>



<li><a href="https://docs.vllm.ai/en/v0.6.0/automatic_prefix_caching/details.html" target="_blank" rel="noopener">vLLM Automatic Prefix Caching — design docs</a> — vLLM이 RadixAttention 정책을 흡수했음을 본인 문서에 명시한 1차 근거 (&#8220;when applied to models with full attention&#8221;)</li>



<li><a href="https://docs.vllm.ai/en/latest/features/automatic_prefix_caching/" target="_blank" rel="noopener">vLLM Automatic Prefix Caching — 사용 문서(latest)</a> — APC 사용·설정 소개 페이지</li>



<li><a href="https://github.com/sgl-project/sglang" target="_blank" rel="noopener">SGLang GitHub Repository</a> — 최신 버전·운영 채택 현황(2026-05 기준 28.7k stars, xAI·NVIDIA·AMD·Cursor 등)</li>



<li><a href="https://arxiv.org/abs/2309.06180" target="_blank" rel="noopener">PagedAttention 원논문 — arXiv:2309.06180 (SOSP 2023)</a> — 짝꿍 글 S4의 1차 출처. 본 글에선 비교 컨텍스트로 1회 참조</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://jspulsar.dev/sglang-radixattention-explained/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
