Prefix Caching은 반복되는 프롬프트의 앞부분(prefix)을 캐싱하여 재사용하는 최적화 기법입니다.
동일하거나 유사한 프롬프트가 반복될 때, 매번 처음부터 다시 계산하지 않고 공통 부분의 KV 캐시를 재사용합니다.
1. 시스템 프롬프트가 있는 챗봇
요청 1:
[시스템 프롬프트 1000토큰] + "Python으로 정렬 알고리즘 작성해줘"
→ 전체 계산
요청 2:
[시스템 프롬프트 1000토큰] + "JavaScript로 API 호출 예제 보여줘"
→ 시스템 프롬프트는 캐시 재사용! (1000토큰 prefill 생략)
2. RAG (Retrieval-Augmented Generation)
[긴 문서/컨텍스트 5000토큰] + "질문 1"
[긴 문서/컨텍스트 5000토큰] + "질문 2"
[긴 문서/컨텍스트 5000토큰] + "질문 3"
→ 문서는 한 번만 처리, 질문만 매번 추가
3. Few-shot 프롬프팅
[예제 1, 예제 2, 예제 3... 2000토큰] + "새로운 입력 1"
[예제 1, 예제 2, 예제 3... 2000토큰] + "새로운 입력 2"
→ 예제들은 캐시 재사용
첫 번째 요청:
입력: [A][B][C][D]
처리: Prefill 전체 → KV 캐시 생성 및 저장
캐시 키: hash([A][B][C])
두 번째 요청:
입력: [A][B][C][E]
처리:
- [A][B][C]: 캐시 HIT! → 재사용
- [E]: 새로 계산
- 전체 prefill 시간의 75% 절약!
완전 일치 방식 (Exact Match):
해시 기반:
# 의사 코드
def get_cache_key(tokens):
return hash(tuple(tokens))
# 캐시 조회
cache_key = get_cache_key(prefix_tokens)
if cache_key in kv_cache_store:
return kv_cache_store[cache_key]
레벨 1: [시스템 프롬프트]
레벨 2: [시스템 프롬프트] + [문서 컨텍스트]
레벨 3: [시스템 프롬프트] + [문서 컨텍스트] + [대화 기록]
각 레벨을 독립적으로 캐싱하여 유연성 향상
시간 절약:
시스템 프롬프트: 1000토큰 (prefill 시간: 100ms)
사용자 입력: 50토큰 (prefill 시간: 5ms)
캐싱 없이: 105ms
캐싱 있을 때: 5ms
→ 95% 시간 절약!
비용 절감:
1. 캐시 저장소
In-memory: 빠르지만 재시작 시 손실
Redis/Memcached: 영구 저장, 여러 서버 간 공유
로컬 디스크: 대용량, 느림
2. 캐시 만료 정책 (Eviction)
3. 캐시 키 설계
# 세밀한 캐시 키
cache_key = {
'model_id': 'gpt-4',
'tokens': tuple(tokens),
'temperature': 0.7, # 생성 파라미터도 포함할지?
}
PagedAttention + Prefix Caching = 최강 조합!
물리 블록 풀:
[1][2][3][4][5][6][7][8]...
요청 A (시스템 프롬프트 + 질문1):
논리: [prefix][query1]
물리: [1][2] + [5]
요청 B (동일 시스템 프롬프트 + 질문2):
논리: [prefix][query2]
물리: [1][2] + [7] ← prefix 블록 [1][2] 공유!
1. Anthropic Claude
2. vLLM
3. TGI (Text Generation Inference)
1. 프롬프트 구조화
❌ 나쁜 예:
"질문: {질문} 시스템: {시스템_프롬프트}"
✅ 좋은 예:
"{시스템_프롬프트} 질문: {질문}"
→ prefix가 앞에 있어야 캐싱 효과적!
2. 배치 처리
동일한 prefix를 가진 요청들을 묶어서 처리
→ 캐시 히트율 극대화
3. 캐시 워밍 (Warming)
자주 사용되는 prefix를 미리 캐싱
→ 첫 요청부터 빠른 응답
실제 벤치마크 (시스템 프롬프트 1000토큰 기준):
| 지표 | 개선도 |
|---|---|
| Prefill 시간 | 90% 감소 |
| 전체 지연시간 | 30-50% 감소 |
| 처리량 | 2-3배 향상 |
| 비용 (API) | 80-90% 절감 |
1. 메모리 오버헤드
2. 캐시 미스 패널티
3. 가변성 문제
프롬프트에 타임스탬프나 무작위 요소가 있으면:
"현재 시각은 {timestamp}입니다..."
→ 매번 다르므로 캐싱 불가
Prefix Caching은 특히 반복적인 패턴이 있는 워크로드(챗봇, RAG, 에이전트 등)에서 매우 효과적인 최적화 기법입니다!