앞의 일곱 편에 나온 절감률 — 41~80%, 7%→84%, 히트율 25% — 은 전부 남의 트래픽 숫자다. CTO의 진짜 질문은 "우리 트래픽에서는 얼마나 나오나, 엔지니어 몇 주를 쓰기 전에 알 수 있나"다. 답은 있다. 프로덕션 로그를 리플레이해서 히트율의 상한을 재고, 벤치 도구로 타임스탬프까지 재현하고, API의 usage 필드로 실제 절감액을 검증하는 세 층이다. 이 글은 그 방법과 함정, 그리고 추정치와 실측치가 왜 벌어지는지를 다룬다.
상한(ceiling)은 예측이 아니다
무한 캐시를 가정하고 모든 요청을 prefix tree에 넣으면 "공유되는 토큰 비율"이 나온다. Preble의 측정은 도구 사용 85%, 임바디드 에이전트 97%, 프로그램 생성 97%, 장문 QA 91%. TraceLab(코딩 에이전트 4,265세션, 357,161스텝)은 사용자 프롬프트와 도구 결과만 "새 토큰"이라 전체 prefill의 약 81%가 원리상 캐시 가능하고, 실현 히트율은 95.7%였다. 반면 Mooncake(Kimi) 실트레이스는 무한 저장소여도 이론 상한이 ~50%, LRU 1K 블록에서 30%, 50K 블록에서야 50%였고 블록의 절반 이상은 두 번 다시 쓰이지 않았다. TraceLab에서 미스는 5분 유휴부터 시작해 1시간이면 거의 전부였고, 사람이 생각하는 동안의 공백이 비용의 12.8%였다. 상한과 실측을 벌리는 최대 변수는 TTL이다.
로그 분석 3종 — 프리픽스 상한, 정확일치 중복률, 근사중복률
토큰 가중 프리픽스 상한은 이렇게 잰다. 요청을 시간순으로 정렬하고, 실제로 보낸 그대로(tools+system+messages) 렌더링해 로컬 토크나이저로 토큰화하고, 스트림(테넌트·prompt_cache_key)별 radix trie에 넣되 노드마다 마지막 사용 시각을 기록한다. 새 요청은 블록 단위로 trie를 따라가다 (a) 자식이 없거나 (b) 마지막 사용이 TTL 밖이면 멈추고, 그때까지의 토큰 수가 히트다. 함정 둘: 부분 블록은 히트가 아니다(vLLM 16토큰, Mooncake 512토큰 단위로 내림 — vLLM의 오프라인 분석기 RFC가 실제 해시 체인을 그대로 재현한다), 그리고 API 최소 프리픽스(Claude 512~4,096, GPT-5.6+ 1,024) 미만이면 0이다 — OpenAI 쿡북의 예시로 900토큰 프롬프트는 절감 0, 1,100토큰은 히트 70%에서 −55%. TTL ∈ {5분, 30분, 1시간}, 블록 ∈ {16, 512}, 스트림 ∈ {테넌트, 키, 전역}으로 스윕하면 그 퍼짐이 곧 예상 오차다. 정확일치는 정규화 프롬프트의 SHA-256을 TTL 창 안에서 세고, 근사중복은 마지막 사용자 턴을 임베딩해 임계값 이상을 센다 — 단 뒤에서 보듯 이 마지막 숫자는 라벨 없이 믿으면 안 된다.
재현 테스트 — 타임스탬프까지 재생하기
- vllm bench serve:
--dataset-name prefix_repetition(프리픽스·접미사 길이, 프리픽스 수),custom(내 JSONL),timed_trace(Mooncake 형식,--timed-trace-sec-multiplier 0.001로 원속도 재생),--request-rate·--burstiness(1 미만이면 버스트). - SGLang bench_serving:
generated-shared-prefix의--gsp-group-distribution zipf가 "몇 테넌트가 트래픽을 지배"하는 현실을 모델링하고,--mooncake-workload conversation|agent는 한 줄 리플레이다. - inference-perf(llm-d): OTel GenAI 스팬에서 에이전트 DAG를 복원해 기록된 대기 시간을
wait_ms로 보존한다 — 사람 공백을 재현하는 유일한 도구. NVIDIA GenAI-Perf는 세션delay로 "사용자 멈춤 길이 vs TTL"을 스윕한다. - 클러스터 단위 추정은 틀린다: llm-d에서 같은 코드 생성 워크로드가 동시성 20에서 48%로 정점을 찍고 레플리카 KV가 차면 무너졌지만, 150테넌트×6K 프리픽스 B2B는 90~95%를 유지했다. 레플리카·라우팅 키 단위로 추정할 것.
API 쪽 검증 — usage 필드와 캐시 진단
절감액 = Σ캐시 토큰 × (정가 − 읽기 단가) − Σ쓰기 토큰 × (쓰기 단가 − 정가). ProjectDiscovery의 방법이 표준이다: 실제 지출 vs "같은 볼륨을 전액으로 냈을 가상 비용"을 스트림별·주별로 — 집계는 오도한다(고정 스트림 84% vs 집계 69%). 작업 길이별 캐시율은 1스텝 35.5%, 20스텝 이상 74%, 1,225스텝 91.8%. 미스 원인은 Anthropic의 cache-diagnosis 베타가 system_changed | tools_changed | messages_changed와 cache_missed_input_tokens로 알려주고, OpenAI는 prompt_cache_key를 붙이는 것만으로 한 고객이 60%→87%가 됐다(키당 ~15 RPM 초과 시 콜드 레플리카). count_tokens는 무료(2,000~8,000 RPM)라 로그 토큰 가중치를 매기는 데 쓰면 된다.
시맨틱 캐시는 라벨 없이는 숫자를 믿지 말 것
2026년 8월 연구가 결정적이다: LMSYS-Chat·Quora·MOSS 각 10만 질의에서 임계값 0.90의 원시 히트율 50.7~57.0%가, Llama-3.1-8B 심판으로 "답을 대체해도 되는가"를 검사하자 1.6~2.2%로 줄었다. 임베딩 기반 추정은 10배 이상 부풀 수 있다(⑥편의 vCache가 보인 임계값 딜레마와 같은 이야기). 방어 가능한 프로토콜은 유사도 0.80~0.99 구간에서 5,000쌍 샘플, 라벨러 3명, 의도 클래스별 임계값(FAQ 0.94·지원 0.92·거래 0.97), 매주 히트의 1~5% 블라인드 감사 — 이 절차로 18%→67% 히트, 오탐 0.8%, −73%가 나왔다. 한국어는 KLUE-STS(≥4.0을 양성), KorSTS, PAWS-X ko(어휘는 겹치지만 뜻이 다른 적대적 음성 — 임베딩 캐시의 정확한 함정)로 시드를 만들고 자사 로그 쌍으로 교체한다. 평가 비용은 작다: vLLM 분석기는 CPU만, Mooncake 대화 리플레이(12K 요청, 1시간)는 GPU 한 대, 국내 SK 데보션의 부하테스트 글처럼 하루면 돌린다 — 비싼 줄은 라벨링뿐이다. 다음 글은 이렇게 얻은 히트율이 운영 중에 무너지는 순간들이다.
— LLM 서빙 캐싱 시리즈 ⑧ / 다음 글: 캐시 수명주기 운영 — 워밍, 콜드 캐시, 오토스케일링
댓글 없음:
댓글 쓰기
국정원의 댓글 공작을 지탄합니다.