광고
~ / posts / developer

LLM 접두사 캐시 라우팅 고르기, 복제본 수별 적중률과 GPU 비용

서버가 여러 대면 라운드로빈이 프롬프트 캐시를 깨요. 복제본 8대 시뮬레이션에서 재계산 비율이 51%에서 세션 고정 3.7%로 줄고 프리필 GPU 비용은 13분의 1이 됐어요. API 병렬 요청 순서, 라우팅 방식별 비교, 체크리스트까지 정리했어요.

모델 서버를 늘렸는데 첫 토큰 지연이 그대로라면 라우팅부터 의심해 보세요. 접두사 캐시(prefix cache)는 GPU 마다 따로 있어서, 다음 턴이 다른 서버로 가면 지난 대화를 처음부터 다시 읽어요. 결론부터 말하면 앞부분이 시스템 프롬프트 하나뿐이면 라운드로빈으로 충분하고, 대화가 쌓이는 서비스는 세션 고정, 문서·에이전트처럼 앞부분이 여러 갈래면 캐시 인지 라우팅에 부하 균형을 켜는 게 기본값이에요. API 를 쓸 때도 같은 원리가 적용돼서, 병렬 요청을 보내는 순서 하나로 입력비가 7배 차이 나요.

캐싱의 단가와 TTL 은 프롬프트 캐싱 비용 계산 글에서 다뤘어요. 이 글은 그다음 단계, 요청을 어느 서버(또는 어느 캐시)로 보낼지를 숫자로 비교해요. 직접 서빙 쪽은 파이썬으로 라우팅을 시뮬레이션해 재계산 토큰과 GPU 비용을 냈고, API 쪽은 2026-11-04 에 연 공식 문서와 가격표로 계산했어요.

광고

왜 서버를 늘리면 캐시 적중률이 떨어지나

vLLM 의 자동 접두사 캐싱 설계 문서에 따르면 KV 블록은 앞 블록 해시와 블록 안 토큰으로 식별되고, 다 찬 블록만 캐시돼요. 이 해시 테이블과 블록은 엔진 프로세스 하나의 GPU 메모리 안에 있어요. 서버 A 가 계산해 둔 대화 앞부분을 서버 B 는 몰라요.

서버가 N 대인데 요청을 무작위로 나누면 직전 턴과 같은 서버로 갈 확률은 1/N 이에요. 같은 대화가 여러 서버에 조각조각 중복 저장돼 메모리도 낭비돼요.

복제본 4대에서 같은 대화 1~4턴이 라운드로빈이면 서버 1~4로 흩어져 모두 다시 계산되고, 세션 고정이면 서버 2에 모여 첫 턴만 계산되며, 캐시 인지 라우팅은 서버 2가 바쁠 때만 4턴을 서버 3으로 넘기는 비교
같은 서버로 돌아와야 지난 대화의 KV 를 다시 쓸 수 있어요

반대로 공통 앞부분이 시스템 프롬프트 하나뿐이면 문제가 거의 없어요. 서버마다 처음 한 번씩만 계산해 두면 그다음부터는 어느 서버로 가도 적중해요. 라우팅이 비용을 가르는 건 앞부분이 대화·문서·사용자마다 다른 경우예요.

계산 조건 — 이렇게 가정했어요

복제본 하나는 Qwen3-8B(bf16)를 올린 H100 80GB 한 장이에요.

시드를 바꿔 세 번 돌렸을 때 재계산 비율 차이는 1%p 안이었어요.

대화형 서비스 — 복제본 수별 재계산 비율

대화 200개가 끝날 때까지 쌓이는 토큰은 평균 약 120만 개로, 서버 한 대의 유휴 캐시(30만)를 넘어요. 그래서 서버가 한 대여도 48.6% 를 다시 계산해요. 대화마다 첫 턴은 어차피 계산해야 하니 이론상 바닥은 3.7% 예요.

대화형 서비스 프롬프트 토큰 재계산 비율 (동시 대화 200개 · 12턴)
라운드로빈세션 고정캐시 인지+부하 균형
01020304050601대 · 라운드로빈 48.6%1대 · 세션 고정 48.6%1대 · 캐시 인지+부하 균형 48.6%1대2대 · 라운드로빈 49%2대 · 세션 고정 34.7%2대 · 캐시 인지+부하 균형 34.7%2대4대 · 라운드로빈 49.7%4대 · 세션 고정 12.8%4대 · 캐시 인지+부하 균형 12.4%4대8대 · 라운드로빈 51%8대 · 세션 고정 3.7%8대 · 캐시 인지+부하 균형 4.3%8대

라운드로빈은 서버를 늘려도 재계산이 줄지 않고, 고정 계열은 서버 수만큼 캐시 총량이 늘어 바닥(3.7%)에 다가가요

단위: % · 자료: Qwen3-8B · 서버당 유휴 캐시 30만 토큰 · LRU 가정으로 직접 시뮬레이션
표로 보기
구분라운드로빈세션 고정캐시 인지+부하 균형
1대48.648.648.6
2대4934.734.7
4대49.712.812.4
8대513.74.3

라운드로빈은 서버를 늘려도 그대로예요. 캐시 용량을 무한대로 풀어 줘도 라운드로빈은 4대에서 25.8%, 8대에서 39.4% 를 다시 계산했어요. 용량이 문제가 아니라 다음 턴이 다른 서버로 가는 게 문제라서예요.

세션 고정은 서버 수만큼 캐시를 넓혀요. 대화가 서버별로 나뉘니 서버 8대면 각 서버가 대화 25개만 들고 있으면 돼요. 캐시 총량이 8배가 된 효과라 바닥에 거의 붙어요.

첫 토큰 지연으로 보면 12번째 턴(8,800토큰)의 프리필이 캐시 없이 약 338ms, 적중하면 약 9ms 예요(빈 GPU, 위 효율 가정). 시스템 프롬프트만 맞으면 269ms 라 대화형에서는 거의 안 줄어요.

라우팅 방식별 GPU 비용 — 요청 100만 건당

재계산한 토큰을 GPU 시간으로 바꿔 요청 100만 건당 프리필 비용을 냈어요. 디코드(답 생성) 비용은 라우팅과 상관없어서 뺐어요.

복제본 8대의 프리필 GPU 비용 (요청 100만 건당)
라운드로빈·무작위고정(세션·문서 해시)캐시 인지+부하 균형
0100200300400500대화형 · 라운드로빈·무작위 127달러대화형 · 고정(세션·문서 해시) 9.5달러대화형 · 캐시 인지+부하 균형 11달러대화형문서 Q&A · 라운드로빈·무작위 499달러문서 Q&A · 고정(세션·문서 해시) 144달러문서 Q&A · 캐시 인지+부하 균형 157달러문서 Q&A

대화형은 13분의 1, 문서 Q&A 는 3.5분의 1로 줄어요

단위: 달러 · 자료: H100 SXM 시간당 4.29달러(Lambda 2026-11-04) · BF16 989 TFLOPS의 50% 가정 · 직접 시뮬레이션
표로 보기
구분라운드로빈·무작위고정(세션·문서 해시)캐시 인지+부하 균형
대화형1279.511
문서 Q&A499144157

대화형에서 하루 요청 100만 건이면 라우팅 하나로 한 달 약 3,500달러 차이예요((127.4 − 9.5) × 30). H100 한 장 한 달(730시간 × 4.29 = 약 3,132달러)보다 커요.

llm-d 저장소는 Llama 3.1 70B 를 MI300X 4장에서 돌린 사례로, 접두사 캐시 인지 라우팅이 라운드로빈보다 출력 처리량 3배·TTFT 2배 빨랐다고 소개해요.

문서 질의응답에서 생기는 서버 쏠림

고정 라우팅의 약점은 쏠림이에요. 문서 해시로 서버를 정하면 인기 문서를 맡은 서버에 질문이 몰려요. 시뮬레이션에서 서버 8대 기준 가장 바쁜 서버는 평균보다 68% 많은 요청을 받았어요. 가장 바쁜 서버에 맞춰 용량을 잡아야 하니 아낀 GPU 를 쏠림에 다시 내주게 돼요.

방식 (8대)재계산 비율가장 바쁜 서버 ÷ 평균100만 건당 프리필
무작위60.9%1.01499달러
문서 해시 고정17.4%1.68144달러
캐시 인지 + 부하 균형19.1%1.04157달러

캐시 인지 + 부하 균형은 이 문서를 가진 서버를 먼저 고르되, 그 서버가 다른 후보보다 두 배 넘게(그리고 일정 개수 넘게) 밀려 있으면 덜 바쁜 서버로 넘기는 방식으로 시뮬레이션했어요. 재계산은 1.7%p 늘었지만 쏠림이 거의 사라졌어요. 대화형의 해시 고정 쏠림은 1.08 로 작았지만, 소수 고객이 트래픽 대부분을 내는 B2B 라면 꼭 재 보세요.

직접 서빙 라우터별 설정 비교

2026-11-04 기준 각 저장소 문서에서 확인한 내용이에요.

라우터고를 수 있는 정책캐시와 관련된 설정
SGLang sgl-routerpower_of_two(기본), cache_aware, session_aware최소 일치 토큰 기본 1,024, --affinity-mode prefer·balanced, 부하 배수 기본 2
vLLM production-stack 라우터roundrobin, session--session-key 로 세션 헤더 지정, 접두사 인지 라우팅은 개발 중
일반 L7 로드밸런서라운드로빈, 최소 연결, 헤더 해시헤더 해시를 세션 고정으로 쓸 수 있음

SGLang 라우터의 cache_aware 는 프롬프트의 가장 긴 캐시 접두사를 가진 엔진을 고르고, 선호 엔진이 없거나 입장 제한에 걸리면 power_of_two 로 내려가요. balanced 모드는 선호 엔진의 부하가 대안의 2배와 정해진 차이를 모두 넘을 때만 옮겨요.

라우터를 여러 대 띄울 때 함정이 있어요. 같은 문서에 따르면 라우터는 상태를 공유하지 않고 세션 바인딩은 라우터마다 메모리에 있어요. session_aware 를 쓰면서 라우터 앞에 라운드로빈 로드밸런서를 두면 세션이 라우터별로 갈라져요. 라우터 앞단도 세션 헤더 기준으로 고정해야 해요.

API 를 쓰는지, 복제본이 2대 이상인지, 앞부분이 시스템 프롬프트 하나뿐인지, 대화 단위로만 갈라지는지 차례로 물어 미리 데우기·라우터 없음·라운드로빈·세션 고정·캐시 인지 + 부하 균형 중 하나를 고르는 순서도
위에서부터 답하면 기본 라우팅이 정해져요
광고
광고

API 를 쓸 때도 라우팅은 있어요 — 병렬 요청과 캐시 키

Claude API — 병렬 요청은 하나를 먼저 보내요. Claude 프롬프트 캐싱 문서는 캐시 항목이 첫 응답이 시작된 뒤에야 쓸 수 있다고 적어요. 같은 앞부분으로 요청 10개를 한꺼번에 보내면 모두 캐시를 못 찾고 각자 쓰기를 해요. 문서는 max_tokens: 0 으로 출력 없이 캐시만 써 두는 미리 데우기 요청도 안내해요. 이때 thinking 과 effort 설정을 본 요청과 똑같이 맞춰야 같은 항목에 적중해요.

Claude 가격표의 Sonnet 5.5 단가(100만 토큰당 입력 2달러, 5분 캐시 쓰기 2.50달러, 읽기 0.10달러)로 2만 토큰 앞부분 요청 10개를 계산했어요.

2만 토큰 앞부분을 공유하는 요청 10개의 입력비 (Claude Sonnet 5.5)
캐시 없음캐시 없음 · 40센트40센트10개 동시 전송10개 동시 전송 · 50센트50센트1개 먼저 후 9개1개 먼저 후 9개 · 6.8센트6.8센트미리 데우기 후 10개미리 데우기 후 10개 · 7센트7센트

동시에 보내면 10개 모두 쓰기 요금(1.25배)이라 캐시를 안 쓸 때보다 비싸요

단위: 센트 · 자료: Claude 가격표 2026-11-04 (입력 2달러·5분 쓰기 2.50달러·읽기 0.10달러 / 100만 토큰)로 직접 계산
표로 보기
구분입력비
캐시 없음40
10개 동시 전송50
1개 먼저 후 9개6.8
미리 데우기 후 10개7

계산은 단순해요. 동시 전송은 2만 × 10 × 2.50달러 ÷ 100만 = 0.50달러, 먼저 하나를 보내면 쓰기 0.05달러 + 읽기 9번 0.018달러 = 0.068달러예요. 나머지 9개가 기다리는 게 싫으면 사용자가 몰리기 전에 미리 데워 두세요. Batches API 는 적중이 최선 노력(best-effort)이라, 문서는 1시간 캐시를 단 요청 하나짜리 배치를 먼저 끝낸 뒤 나머지를 넣으라고 권해요.

캐시는 워크스페이스 단위로 격리되니, 같은 트래픽을 여러 워크스페이스로 나누면 캐시도 갈라져요.

OpenAI API — 키당 분당 15건 안팎. OpenAI 프롬프트 캐싱 문서에 따르면 캐시는 개별 머신에 있고, 라우팅은 머신 부하·앞부분 토큰 해시(도구 정의 포함)·prompt_cache_key 로 정해져요. 분당 15건을 넘으면 다른 머신으로 넘칠 수 있어서, GPT-5.6 이전 모델은 고정 prompt_cache_key 를 주고 키당 분당 15건 안팎으로 맞추라고 해요. 분당 120건이면 키 8개로 나누는 식이에요. 나눌 때는 사용자 ID 해시를 8로 나눈 나머지처럼 같은 입력이면 늘 같은 키가 나오는 매핑을 써야 해요. 해시 생성기로 같은 ID 가 매번 같은 값이 나오는지 확인해 볼 수 있어요. 키는 라우팅에 영향만 줄 뿐 적중을 보장하지 않고, GPT-5.6 이후 모델은 라우팅을 알아서 해서 키가 고객별 캐시 회계 용도로만 쓰여요.

상황별 추천

상황추천이유
서버 1대, 또는 앞부분이 공통 시스템 프롬프트뿐엔진 접두사 캐싱만 켜고 라운드로빈·최소 부하서버마다 한 번씩만 쓰면 끝
챗봇·상담처럼 대화가 쌓임세션 고정(대화 ID 헤더)8대에서 재계산 51% → 3.7%
문서 Q&A·RAG 에서 문서 수가 서버 캐시보다 많음캐시 인지 + 부하 균형서버별로 문서를 나눠 캐시 총량을 늘림
에이전트·퓨샷처럼 앞부분이 나무 모양으로 갈라짐캐시 인지(가장 긴 접두사 일치)대화 ID 하나로 표현이 안 됨
API 에서 같은 앞부분으로 병렬 처리미리 데우기 후 병렬동시 전송은 캐시 없음보다 비쌈
OpenAI GPT-5.6 이전 모델, 분당 수백 건결정적 매핑으로 prompt_cache_key 분할키당 분당 15건 안팎 권장

어떤 방식이든 날짜·요청 ID 가 앞쪽에 있어 앞부분이 매번 바뀌면 소용없으니 그것부터 고쳐요.

도입 체크리스트

바꾸기 전

바꾼 뒤

API 라면

광고
광고

자주 묻는 질문

서버가 두 대뿐인데도 라우팅을 신경 써야 하나요?

대화가 쌓이는 서비스라면 그래요. 시뮬레이션에서 두 대만 돼도 세션 고정이 재계산을 49%에서 35%로 줄였어요. 앞부분이 시스템 프롬프트 하나뿐이면 두 대든 열 대든 라운드로빈으로 충분해요.

세션 고정을 하면 서버 하나가 죽었을 때 어떻게 되나요?

그 서버에 묶인 대화는 다른 서버로 옮겨지고 다음 한 턴만 처음부터 계산해요. 답이 틀려지지는 않아요. 서버 수가 바뀌면 해시가 재배치되니, 일관 해시(consistent hashing)를 쓰는 라우터면 옮겨지는 대화가 일부로 줄어요.

캐시 인지 라우팅은 라우터가 무거워지지 않나요?

라우터가 프롬프트를 토큰화하고 접두사 트리를 들고 있어야 해서 CPU 와 메모리를 더 써요. SGLang 라우터는 기본으로 1,024토큰 넘게 일치해야 그 엔진을 선호하고, 그보다 짧으면 부하 기준으로 골라요. 앞부분이 짧은 서비스는 캐시 인지의 이득이 작으니 세션 고정이 더 가벼워요.

GPU 캐시가 모자라면 CPU 나 디스크로 늘리면 되지 않나요?

KV 를 CPU 메모리나 디스크로 내려 GPU 밖에 더 오래 보관하는 계층형 캐시도 있어요. llm-d 는 이를 CPU·디스크 오프로딩과 KV 캐시 상태의 전역 인덱스로 소개해요. 다만 GPU 로 다시 올리는 시간이 들어서, 같은 GPU 에 이미 있는 캐시를 쓰는 것보다는 느려요. 라우팅으로 GPU 적중부터 올리는 게 먼저예요.

프리필 비용이 이렇게 차이 나면 출력 지연도 줄어드나요?

답을 한 토큰씩 만드는 시간은 그대로예요. 줄어드는 건 첫 토큰까지의 시간과 프리필에 쓰던 GPU 시간이에요. 다만 프리필이 덜 끼어들면 같은 배치에서 돌던 다른 요청의 토큰 간격도 덜 흔들려요. 이 관계는 LLM 서빙 배칭 방식 글에서 계산했어요.

정리

더 깊이 읽기

이 글은 실무에서 판단할 때 필요한 것 위주로 정리했어요. 같은 주제의 내부 동작 원리는 devboi 기술 블로그의 프롬프트 캐싱 원리 — 접두사 KV 캐시·블록 해시·RadixAttention에서 도식과 코드로 단계별로 풀었어요.

참고한 자료

#접두사 캐시 라우팅#prefix cache aware routing#세션 고정 라우팅#SGLang 라우터 cache_aware#vLLM 라우터#prompt_cache_key#프롬프트 캐시 적중률#LLM 서빙 복제본
← 이전 글NestJS durable 프로바이더 언제 쓰나, 테넌트 메모리와 점검표다음 글 →트랜잭션 격리 수준 고르는 법, MySQL·PostgreSQL 판단표와 재시도 비용
광고

더 둘러보기

💻 개발자 다른 도구

🔥 많이 찾는 도구

🔮 재미로 한 번 더

📝 읽어 볼 만한 글

글 전체 보기 →