CAG (Context-Aware Generation) 기술 보고서
CAG (Context-Aware Generation) 기술 보고서
1. CAG란 무엇인가?
1.1 정의
Context-Aware Generation (CAG) 은 LLM 추론 시 동일한 문맥(Context)을 공유하는 여러 요청에서 KV 캐시를 재사용 하여 중복 연산을 제거하는 최적화 기술입니다.
1.2 기존 LLM 추론의 문제점
일반적인 LLM 추론은 두 단계로 구성됩니다:
[Prefill 단계] → [Decode 단계]
문맥 처리 토큰 생성
(느림) (빠름)
문제: 동일한 시스템 프롬프트나 문서를 사용하는 여러 요청에서 매번 Prefill을 반복 수행
요청 1: [시스템 프롬프트 + 문서 + 질문1] → Prefill (3초) → Decode
요청 2: [시스템 프롬프트 + 문서 + 질문2] → Prefill (3초) → Decode ← 중복!
요청 3: [시스템 프롬프트 + 문서 + 질문3] → Prefill (3초) → Decode ← 중복!
1.3 CAG의 해결 방식
SGLang의 RadixAttention 은 KV 캐시를 Radix Tree 구조로 관리하여 공통 접두사(prefix)를 자동으로 감지하고 재사용합니다:
요청 1: [시스템 프롬프트 + 문서 + 질문1] → Prefill (3초) → Decode → 캐시 저장
요청 2: [시스템 프롬프트 + 문서 + 질문2] → 캐시 히트! → Decode만 수행
요청 3: [시스템 프롬프트 + 문서 + 질문3] → 캐시 히트! → Decode만 수행
2. CAG의 핵심 장점
2.1 응답 속도 향상
장점
설명
Prefill 단계 생략
문맥 처리 시간을 완전히 제거
TTFT 단축
Time To First Token이 크게 감소
처리량 증가
동일 하드웨어로 더 많은 요청 처리 가능
2.2 비용 효율성
장점
설명
GPU 연산 절감
중복 행렬 연산 제거
전력 소비 감소
Prefill은 가장 연산 집약적인 단계
하드웨어 효율 극대화
동일 GPU로 더 높은 throughput 달성
2.3 사용자 경험 개선
장점
설명
일관된 응답 속도
첫 요청 이후 안정적인 latency
실시간 대화 가능
긴 문서 기반 대화에서도 빠른 응답
확장성
다수 사용자 동시 처리 효율 증가
3. 실측 테스트 결과
3.1 테스트 환경
GPU: NVIDIA H100 80GB HBM3
프레임워크: SGLang 0.5.8 (RadixAttention)
모델: Qwen2.5-Coder-7B-AWQ, Qwen2.5-Coder-32B-AWQ
3.2 문맥 크기별 CAG 효과
문맥 크기
모델
Prefill 시간
Cache Hit 시간
속도 향상
절감 시간
~500 토큰
7B
0.458초
0.192초
2.4x
0.27초
~800 토큰
7B
0.444초
0.234초
1.9x
0.21초
~20,000 토큰
32B
13.51초
10.96초
1.2x
2.55초
3.3 테스트 1: 기술 문서 기반 QA (500 토큰)
시나리오: 태양광 발전소 기술 문서를 문맥으로 5개의 서로 다른 질문
요청 1 (Cold): 0.458초 ████████████████████████
요청 2 (Warm): 0.272초 ██████████████
요청 3 (Warm): 0.264초 █████████████
요청 4 (Warm): 0.141초 ███████
요청 5 (Warm): 0.091초 ████
결과: 첫 요청 대비 평균 2.4배 속도 향상
3.4 테스트 2: 대규모 코드베이스 QA (20,000 토큰)
시나리오: Enterprise Solar Power Plant Management System 코드 (~80,000자)를 문맥으로 동일 질문 6회
요청 1 (Cold): 13.51초 ████████████████████████████████████████████████████
요청 2 (Warm): 10.96초 █████████████████████████████████████████
요청 3 (Warm): 10.96초 █████████████████████████████████████████
요청 4 (Warm): 10.96초 █████████████████████████████████████████
요청 5 (Warm): 10.96초 █████████████████████████████████████████
요청 6 (Warm): 10.96초 █████████████████████████████████████████
결과:
요청당 2.55초 절감
5개 후속 요청 기준 총 12.75초 절감
100개 요청 시 255초 (4분 15초) 절감
4. CAG가 효과적인 사용 사례
4.1 RAG (Retrieval-Augmented Generation)
┌─────────────────────────────────────────────────────┐
│ [시스템 프롬프트] + [검색된 문서들] + [사용자 질문] │
│ ───────────────────────────────── ─────────────── │
│ 공통 접두사 (캐시됨) 변하는 부분 │
└─────────────────────────────────────────────────────┘
동일 문서에 대한 다양한 질문에서 효과 극대화
문서가 길수록 절감 효과 증가
4.2 코드 어시스턴트
┌─────────────────────────────────────────────────────┐
│ [시스템 프롬프트] + [프로젝트 코드] + [개발자 질문] │
│ ───────────────────────────────── ─────────────── │
│ 공통 접두사 (캐시됨) 변하는 부분 │
└─────────────────────────────────────────────────────┘
대규모 코드베이스 분석 시 특히 유용
연속적인 코드 리뷰, 디버깅 질문에 효과적
4.3 고객 서비스 챗봇
┌─────────────────────────────────────────────────────┐
│ [시스템 프롬프트] + [FAQ/매뉴얼] + [고객 질문] │
│ ───────────────────────────────── ─────────────── │
│ 공통 접두사 (캐시됨) 변하는 부분 │
└─────────────────────────────────────────────────────┘
모든 고객이 동일한 FAQ/매뉴얼 문맥 공유
대규모 동시 접속 시 비용 절감 효과 극대화
5. CAG 효과 극대화 전략
5.1 프롬프트 설계
# ✓ 좋은 예: 공유 문맥을 앞에 배치
messages = [
{"role": "system", "content": f"Context:\n{shared_document}\n\nAnswer questions."},
{"role": "user", "content": user_question} # 이 부분만 변경
]
# ✗ 나쁜 예: 질문이 앞에 오면 캐시 히트 불가
messages = [
{"role": "user", "content": f"Question: {user_question}\nDocument: {shared_document}"}
]
5.2 서버 설정 최적화
python -m sglang.launch_server \
--model-path Qwen/Qwen2.5-Coder-32B-Instruct-AWQ \
--mem-fraction-static 0.9 \ # KV 캐시 공간 최대화
--chunked-prefill-size 4096 \ # 청크 단위 처리
--context-length 32768 # 충분한 컨텍스트 길이
6. 성능 비교 요약
6.1 CAG 적용 전후 비교
┌────────────────────────────────────────────────────────────────┐
│ 20K 토큰 문맥 기준 │
├────────────────────────────────────────────────────────────────┤
│ CAG 미적용 (매번 Prefill) │
│ ───────────────────────────────────────────────────────────── │
│ 요청 10개: 13.51초 × 10 = 135.1초 │
│ 요청 100개: 13.51초 × 100 = 1,351초 (22분 31초) │
├────────────────────────────────────────────────────────────────┤
│ CAG 적용 (RadixAttention) │
│ ───────────────────────────────────────────────────────────── │
│ 요청 10개: 13.51초 + (10.96초 × 9) = 112.15초 │
│ 요청 100개: 13.51초 + (10.96초 × 99) = 1,098.55초 (18분 19초) │
├────────────────────────────────────────────────────────────────┤
│ 절감 효과 │
│ ───────────────────────────────────────────────────────────── │
│ 요청 10개: 22.95초 절감 (17% 감소) │
│ 요청 100개: 252.45초 절감 (4분 12초, 19% 감소) │
└────────────────────────────────────────────────────────────────┘
6.2 핵심 인사이트
발견
의미
속도 배율 vs 절대 시간
소규모 문맥은 배율↑, 대규모 문맥은 절대 시간 절감↑
문맥이 클수록 효과↑
20K 토큰에서 요청당 2.55초 절감
요청이 많을수록 효과↑
첫 요청 이후 모든 요청에서 혜택
실시간 서비스에 필수
긴 문서 기반 대화에서 UX 크게 개선
7. 결론
7.1 CAG의 핵심 가치
비용 절감: GPU 연산 중복 제거로 인프라 비용 감소
속도 향상: Prefill 생략으로 응답 latency 단축
확장성: 동일 하드웨어로 더 많은 동시 요청 처리
사용자 경험: 긴 문맥에서도 빠른 응답으로 실시간 대화 가능
부록: 테스트 코드
from openai import OpenAI
client = OpenAI(base_url="http://localhost:30000/v1", api_key="not-needed")
SHARED_CONTEXT = """[긴 문서 내용]"""
questions = ["질문1", "질문2", "질문3"]
for question in questions:
response = client.chat.completions.create(
model="default",
messages=[
{"role": "system", "content": f"Context:\n{SHARED_CONTEXT}"},
{"role": "user", "content": question}
]
)
print(response.choices[0].message.content)
*본 보고서는 SGLang RadixAttention 기반 CAG 실측 테스트 결과를 바탕으로 작성되었습니다.*