본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 6장: Prefix Caching과 프롬프트 최적화
2026년 3월 26일·AI / ML·

6장: Prefix Caching과 프롬프트 최적화

시스템 프롬프트 캐싱, Prefix-aware 스케줄링, RadixAttention의 원리를 분석하고, 멀티턴 대화와 평가 워크플로우에서의 성능 개선을 다룹니다.

17분284자9개 섹션
llmaiperformancemlops
공유
llm-inference6 / 10
12345678910
이전5장: Speculative Decoding — 추측 기반 가속다음7장: 양자화 추론 — FP8, INT8, INT4

이 장에서 배우는 것

  • Prefix Caching의 기본 원리와 적용 시나리오
  • Prefix-aware 스케줄링과 캐시 인식 라우팅
  • SGLang의 RadixAttention 메커니즘
  • 멀티턴 대화에서의 KV 캐시 재활용
  • 평가 워크플로우에서 60%+ 시간 절감 달성 방법

반복되는 프롬프트의 비용

실제 LLM 서비스에서는 동일하거나 유사한 프롬프트가 반복적으로 등장합니다. 가장 대표적인 사례는 **시스템 프롬프트(System Prompt)**입니다.

전형적인 API 호출 패턴
text
요청 1: [시스템 프롬프트 800토큰] + [사용자: "오늘 날씨 알려줘"]
요청 2: [시스템 프롬프트 800토큰] + [사용자: "내일 일정 확인해줘"]
요청 3: [시스템 프롬프트 800토큰] + [사용자: "이메일 요약해줘"]
...수천 건의 요청...

매 요청마다 동일한 800토큰의 시스템 프롬프트를 Prefill하면, 이 800토큰에 대한 KV 캐시 연산이 매번 반복됩니다. 시간당 10,000건의 요청을 처리한다면, 시스템 프롬프트 Prefill만으로 800만 토큰의 중복 연산이 발생합니다.

Prefix Caching은 이 중복을 제거합니다. 한 번 계산한 접두사(Prefix)의 KV 캐시를 저장해 두고, 동일한 접두사를 가진 후속 요청에서 재활용합니다.

Info

Prefix Caching은 Prefill 단계의 중복 연산을 제거해 TTFT를 줄이는 기법입니다. 3장의 PagedAttention이 메모리 효율을, 4장의 Continuous Batching이 처리량을 최적화했다면, Prefix Caching은 반복 연산의 효율을 최적화합니다.

Prefix Caching의 동작 원리

기본 메커니즘

Prefix Caching은 다음과 같이 동작합니다.

  1. 첫 번째 요청: 시스템 프롬프트 + 사용자 입력 전체를 Prefill하고, 시스템 프롬프트 부분의 KV 캐시를 별도로 저장(태그)합니다
  2. 두 번째 요청: 시스템 프롬프트가 동일한지 확인하고, 동일하다면 저장된 KV 캐시를 재활용합니다. 사용자 입력 부분만 새로 Prefill합니다
  3. 후속 요청: 같은 시스템 프롬프트를 공유하는 모든 요청이 캐시를 재활용합니다
Prefix Caching 효과
text
캐시 없이:
  요청 1 Prefill: [시스템 800토큰 + 사용자 50토큰] = 850토큰 연산
  요청 2 Prefill: [시스템 800토큰 + 사용자 30토큰] = 830토큰 연산
  
Prefix Cache 적용:
  요청 1 Prefill: [시스템 800토큰 + 사용자 50토큰] = 850토큰 연산 (캐시 저장)
  요청 2 Prefill: [캐시 히트 + 사용자 30토큰] = 30토큰 연산 (96% 절감)

해시 기반 캐시 키

KV 캐시를 재활용하려면, 입력 토큰 시퀀스가 정확히 일치하는지 확인해야 합니다. 이를 위해 토큰 시퀀스의 **해시(Hash)**를 캐시 키로 사용합니다.

3장에서 다룬 vLLM의 APC(Automatic Prefix Caching)는 블록 단위로 해시를 계산합니다. 블록 크기가 16토큰이라면, 16토큰 단위로 해시를 비교해 일치하는 블록의 KV 캐시를 재활용합니다.

블록 단위 해시 매칭
text
요청 1 토큰: [A A A A | B B B B | C C C C | D D D D | E E ...]
              블록0     블록1     블록2     블록3     블록4
              hash=h0   hash=h1   hash=h2   hash=h3
 
요청 2 토큰: [A A A A | B B B B | C C C C | X X X X | Y Y ...]
              블록0     블록1     블록2     블록3'    블록4'
              hash=h0   hash=h1   hash=h2   hash=h3'
 
→ 블록0, 블록1, 블록2의 KV 캐시 재활용 (3블록 = 48토큰)
→ 블록3'부터 새로 Prefill

Prefix-aware 스케줄링

Prefix Caching의 효과를 극대화하려면, 스케줄러가 캐시 상태를 인식하고 이를 반영해야 합니다.

캐시 인식 라우팅 (Cache-aware Routing)

여러 GPU 레플리카(Replica)가 요청을 처리하는 분산 환경에서, 동일한 시스템 프롬프트를 사용하는 요청을 같은 레플리카로 라우팅하면 캐시 히트율이 극대화됩니다.

단순한 라운드 로빈이나 부하 기반 라우팅 대신, 접두사 해시를 기준으로 라우팅하면 캐시 히트율이 50-70%에서 90%+ 이상으로 향상될 수 있습니다.

우선순위 스케줄링

캐시 히트가 예상되는 요청을 우선 처리하면 전체 시스템의 효율이 높아집니다. 캐시 히트 요청은 Prefill이 빠르므로 GPU를 빠르게 비워 다음 요청을 처리할 수 있습니다.

RadixAttention (SGLang)

SGLang은 UC Berkeley에서 개발한 추론 프레임워크로, RadixAttention이라는 고급 Prefix Caching 메커니즘을 제공합니다.

Radix Tree 기반 캐시 관리

기존의 블록 해시 방식은 정확히 일치하는 접두사만 캐싱할 수 있습니다. RadixAttention은 **래딕스 트리(Radix Tree)**를 사용해 여러 요청의 접두사를 계층적으로 관리합니다.

RadixAttention의 Radix Tree
text
                    [시스템 프롬프트]
                   /                \
        [사용자 대화 A]         [사용자 대화 B]
         /         \                  |
  [턴3 질문]   [턴3 다른질문]    [턴2 질문]

래딕스 트리의 장점은 다음과 같습니다.

  1. 가변 길이 매칭: 블록 경계에 구애받지 않고 가장 긴 공통 접두사를 찾아 재활용합니다
  2. 계층적 공유: 여러 대화가 공통 시스템 프롬프트를 공유하면서, 각자의 대화 이력에 대한 캐시도 유지합니다
  3. LRU Eviction: 트리의 리프 노드부터 LRU(Least Recently Used) 정책으로 캐시를 제거합니다

SGLang의 프로그래밍 모델

SGLang은 Python DSL을 통해 복잡한 LLM 호출 패턴을 효율적으로 표현합니다. 프로그래머가 프롬프트 구조를 명시적으로 정의하면, SGLang이 자동으로 Prefix Caching을 최적화합니다.

sglang_example.py
python
import sglang as sgl
 
@sgl.function
def multi_turn_chat(s, system_prompt, messages):
    s += sgl.system(system_prompt)
    for msg in messages:
        s += sgl.user(msg["user"])
        s += sgl.assistant(sgl.gen("response", max_tokens=256))
    # SGLang이 자동으로 공통 접두사를 감지하고 캐싱

멀티턴 대화 최적화

멀티턴 대화는 Prefix Caching의 가장 자연스러운 적용 대상입니다. 각 턴이 이전 턴의 전체 이력을 포함하므로, 이전 턴의 KV 캐시를 그대로 재활용할 수 있습니다.

멀티턴 대화의 KV 캐시 재활용
text
턴 1: [시스템] + [사용자1] → Prefill 전체 + Decode
턴 2: [시스템] + [사용자1] + [응답1] + [사용자2] → 캐시 히트 + [응답1+사용자2] Prefill + Decode
턴 3: [시스템] + [사용자1] + [응답1] + [사용자2] + [응답2] + [사용자3]
      → 캐시 히트 + [응답2+사용자3]만 Prefill + Decode

각 턴에서 새로 Prefill해야 하는 토큰은 이전 응답과 새 사용자 입력뿐입니다. 대화가 길어질수록 캐시 히트 비율이 높아져 TTFT가 거의 일정하게 유지됩니다.

Warning

멀티턴 대화에서 Prefix Caching이 효과적이려면, 이전 턴의 KV 캐시가 아직 메모리에 남아 있어야 합니다. 대화 간격이 길거나 GPU 메모리가 부족해 캐시가 Evict되면, 전체 이력을 다시 Prefill해야 합니다.

평가 워크플로우에서의 60%+ 시간 절감

Prefix Caching이 가장 극적인 효과를 보이는 시나리오 중 하나가 평가(Evaluation) 워크플로우입니다.

LLM-as-a-Judge 패턴

LLM 품질 평가에서 흔히 사용되는 패턴은, 동일한 평가 기준 프롬프트에 서로 다른 응답을 붙여 점수를 매기는 것입니다.

LLM-as-a-Judge 워크플로우
text
공통 평가 프롬프트 (2000토큰):
  "다음 기준에 따라 응답을 1-5점으로 평가하세요:
   1. 정확성: ...
   2. 관련성: ...
   3. 유창성: ...
   [상세 루브릭 2000토큰]"
 
평가 대상 1000건:
  [공통 프롬프트 2000토큰] + [응답 1: 200토큰]
  [공통 프롬프트 2000토큰] + [응답 2: 350토큰]
  ...
  [공통 프롬프트 2000토큰] + [응답 1000: 150토큰]

Prefix Caching 없이는 2000토큰의 공통 프롬프트를 1000번 Prefill해야 합니다. Prefix Caching이 적용되면 공통 프롬프트는 한 번만 Prefill하고, 이후 999건은 개별 응답(평균 200토큰)만 Prefill합니다.

절감률=1−1×2000+1000×2001000×2200=1−202,0002,200,000≈90.8%\text{절감률} = 1 - \frac{1 \times 2000 + 1000 \times 200}{1000 \times 2200} = 1 - \frac{202,000}{2,200,000} \approx 90.8\%절감률=1−1000×22001×2000+1000×200​=1−2,200,000202,000​≈90.8%

실제로는 캐시 관리 오버헤드와 메모리 제약으로 이론적 최댓값에 도달하기는 어렵지만, 60-80%의 시간 절감은 충분히 달성 가능합니다.

벤치마크 평가

모델 벤치마크(MMLU, HumanEval 등)에서도 동일한 지시문이 수백 개의 테스트 케이스에 반복됩니다. 대규모 벤치마크 스위트를 실행할 때 Prefix Caching으로 평가 시간을 크게 단축할 수 있습니다.

프로덕션 적용 가이드

캐시 크기 관리

Prefix Cache는 추가 GPU 메모리를 소비합니다. 캐시 크기가 커지면 동시 처리 가능한 요청 수가 줄어들 수 있으므로, 적절한 상한을 설정해야 합니다.

캐시 크기 튜닝 고려사항
text
총 GPU 메모리 예산:
  모델 가중치 + 활성 KV 캐시 + Prefix Cache + 여유 공간
 
Prefix Cache 최대 크기 설정:
  - 고유 접두사 수가 적은 경우: 전체 KV 예산의 20-30%
  - 고유 접두사 수가 많은 경우: 전체 KV 예산의 10-15%
  - LRU eviction으로 자주 사용되지 않는 캐시 자동 정리

캐시 워밍 (Cache Warming)

서비스 시작 시 자주 사용되는 시스템 프롬프트의 KV 캐시를 미리 계산해 두는 캐시 워밍(Cache Warming) 전략이 효과적입니다. 콜드 스타트(Cold Start) 시 첫 번째 요청의 지연시간을 줄일 수 있습니다.

Tip

vLLM에서 Prefix Caching을 활성화하려면 서버 시작 시 --enable-prefix-caching 플래그를 사용합니다. SGLang은 RadixAttention이 기본 활성화되어 있습니다.


정리

이 장에서는 Prefix Caching의 원리와 적용 시나리오를 분석했습니다.

  • Prefix Caching은 공통 접두사의 KV 캐시를 재활용해 Prefill 중복 연산을 제거합니다
  • 캐시 인식 라우팅으로 분산 환경에서도 높은 캐시 히트율을 유지할 수 있습니다
  • SGLang의 RadixAttention은 래딕스 트리 기반의 유연한 접두사 매칭을 제공합니다
  • 멀티턴 대화와 평가 워크플로우에서 60-90%의 시간 절감이 가능합니다

다음 장에서는 모델 자체를 작게 만드는 양자화(Quantization) 기법을 다룹니다. FP8, INT8, INT4 등의 저정밀도 형식이 어떻게 메모리를 절반으로 줄이면서도 정확도를 유지하는지 알아보겠습니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#llm#ai#performance#mlops

관련 글

AI / ML

7장: 양자화 추론 — FP8, INT8, INT4

양자화의 기초 개념부터 FP8의 부상, W8A8/W4A16 전략, GPTQ/AWQ/SmoothQuant 기법, KV 캐시 양자화까지 정확도와 성능의 트레이드오프를 분석합니다.

2026년 3월 28일·16분
AI / ML

5장: Speculative Decoding — 추측 기반 가속

Draft-Verify 패러다임으로 자기회귀 디코딩을 가속하는 Speculative Decoding의 원리, 수학적 보장, 그리고 Medusa, Eagle 등 변형 기법을 분석합니다.

2026년 3월 24일·17분
AI / ML

8장: 모델 병렬화와 분산 추론

텐서 병렬화, 파이프라인 병렬화, 시퀀스 병렬화, Expert 병렬화의 원리를 분석하고, 멀티 GPU 추론 전략과 클러스터 수준 최적화를 다룹니다.

2026년 3월 30일·17분
이전 글5장: Speculative Decoding — 추측 기반 가속
다음 글7장: 양자화 추론 — FP8, INT8, INT4

댓글

목차

약 17분 남음
  • 이 장에서 배우는 것
  • 반복되는 프롬프트의 비용
  • Prefix Caching의 동작 원리
    • 기본 메커니즘
    • 해시 기반 캐시 키
  • Prefix-aware 스케줄링
    • 캐시 인식 라우팅 (Cache-aware Routing)
    • 우선순위 스케줄링
  • RadixAttention (SGLang)
    • Radix Tree 기반 캐시 관리
    • SGLang의 프로그래밍 모델
  • 멀티턴 대화 최적화
  • 평가 워크플로우에서의 60%+ 시간 절감
    • LLM-as-a-Judge 패턴
    • 벤치마크 평가
  • 프로덕션 적용 가이드
    • 캐시 크기 관리
    • 캐시 워밍 (Cache Warming)
  • 정리