상태: 초안 (2026-10-13), 일부 실측. 실측은 같은 사이트의 「토스 ML/AI Infra 준비」 8편에서 8GB급 GPU 한 장, Qwen2.5-1.5B-Instruct, vLLM 0.29.0, LMCache 0.5.5(프로세스 내 모드)로 잰 값을 다시 인용했습니다. 논문과 공식 문서는 2026-10-13 에 직접 열어 확인했습니다. LMCache 의 현재 권장 방식(MP 모드)과 큰 모델의 값은 미실측입니다. 작성 규칙: 실측 데이터가 기본이고, 못 잰 것은 「미실측」, 확인하지 못한 것은 「미확인」으로 표시합니다.
LMCache: KV 캐시를 GPU 밖으로
목차
- 1. GPU 안의 캐시가 가진 두 가지 한계
- 2. LMCache 의 구조
- 3. 왜 TTFT 와 처리량이 좋아지나
- 4. 직접 잰 값: 576ms 에서 48.6ms
- 5. 손익 분기: 불러오기가 계산보다 쌀 때만
- 6. 앞부분이 아닌 조각도 다시 쓰기: CacheBlend, CacheGen
- 7. 프리필·디코드 분리에서의 KV 전송
- 8. 언제 이득이 없나
- 참고
1. GPU 안의 캐시가 가진 두 가지 한계
2편의 프리픽스 캐시는 강력하지만 GPU 메모리 안에서만 일합니다. 그래서 두 가지가 아쉽습니다.
- 자리가 모자라면 지워집니다. 지워진 앞부분이 다시 오면 처음부터 계산합니다.
- 인스턴스마다 따로입니다. 같은 모델을 GPU 여러 장에 띄우면, 옆 인스턴스가 방금 계산한 KV 를 쓰지 못합니다.
첫째가 얼마나 아픈지 잰 적이 있습니다. GPU 의 KV 자리(21,520토큰)보다 큰 문서 묶음(문서 10개, 문서당 약 5,000토큰, 합계 약 5만 토큰)을 순서대로 읽히고 같은 순서로 다시 읽혔습니다. vLLM 만 쓰면 두 번째 읽기의 첫 토큰이 576ms 로 처음(575ms)과 같았고, vLLM 이 센 프리픽스 캐시 적중은 0 이었습니다. 가장 오래된 것부터 지우는 캐시(LRU)에 순환하며 접근하면, 자리가 조금만 모자라도 다음 차례에 쓸 문서가 늘 방금 지워져 있기 때문입니다.
2. LMCache 의 구조
LMCache 는 서빙 엔진 옆에 붙는 KV 캐시 계층입니다. 기술 보고서(arXiv 2510.09665, 2025-12 개정판)와 공식 문서(2026-10-13 열람)에서 확인한 구조는 이렇습니다.
- 엔진과의 접점은 KV 커넥터입니다. vLLM 은 엔진 밖으로 KV 를 내보내고 들여오는 표준 인터페이스(KV connector)를 두고 있고, LMCache 가 그 구현 가운데 하나입니다. 스케줄러 쪽은 「이 요청의 앞부분 중 몇 토큰을 밖에서 찾았나」를 묻고, 모델 실행 쪽은 층마다 불러오기·저장을 시작하고 기다립니다.
- 단위는 청크입니다. 기본 256토큰을 한 덩어리로 다룹니다. vLLM 의 블록(16토큰)보다 크게 묶는 까닭은 저장소와 네트워크가 작은 조각을 많이 옮길 때 느리기 때문입니다. 보고서는 대역폭을 다 쓰려면 한 번에 옮기는 단위가 커야 한다는 근거로 다른 측정을 인용합니다.
- 저장 계층은 GPU → CPU 메모리 → 로컬 디스크 → 원격 저장소입니다. 보고서와 문서에는 Redis·Valkey, S3, Mooncake, NIXL, InfiniStore, 공유 파일 시스템, GPUDirect Storage 등이 백엔드로 올라 있습니다.
- 기다리지 않게 하는 장치들. 저장은 뒤에서 비동기로 합니다. 불러오기는 층 단위로 계산과 겹칩니다(이 층을 계산하는 동안 다음 층의 KV 를 가져옴). 요청이 대기열에 있는 동안 느린 계층의 KV 를 빠른 계층으로 미리 올려 두기도 합니다.
- **현재 권장 배치는 노드마다 하나 뜨는 별도 서버(MP 모드)**입니다. 여러 vLLM 이 한
lmcache server를 함께 씁니다. 처음의 「엔진 프로세스 안에서 도는 방식」은 문서에서 Legacy·deprecated 로 표시됩니다. 최신 정식판은 v0.5.5(2026-09-12)이고, v0.5.6 사전판이 나와 있습니다.
같은 앞부분을 열쇠로 쓰므로 인스턴스 1 이 저장한 KV 를 인스턴스 2 가 찾아 쓸 수 있습니다. 같은 노드라면 MP 서버의 CPU 메모리를, 노드가 다르면 공유 저장소나 RDMA 로 이웃의 메모리를 읽는 P2P 방식을 씁니다.
3. 왜 TTFT 와 처리량이 좋아지나
핵심은 한 줄입니다. 다시 하는 프리필을 저장소에서 불러오기로 바꿉니다.
- TTFT. 첫 토큰까지의 시간은 대부분 프리필입니다(1편). 앞부분 4,864토큰을 불러오면 남은 약 150토큰만 계산하면 됩니다.
- 처리량. 프리필은 GPU 의 계산을 가장 많이 먹는 단계입니다. 그것을 건너뛰면 같은 GPU 가 같은 시간에 더 많은 요청을 받습니다. 그래서 「같은 TTFT 를 지키면서 감당하는 요청률」이 오릅니다.
- 토큰 간격(ITL). 2편에서 본 것처럼 긴 프리필은 같은 GPU 의 디코드를 멈춥니다. 프리필이 줄면 끼어드는 일도 줄어 토큰 간격도 고르게 됩니다.
보고서의 수치(8×H100 서버, Llama-3.1-8B·70B, Qwen2.5-72B 등 여섯 모델, CPU 오프로드 상한 500GB):
| 실험 | 조건 | 결과(최강 기준선 대비) |
|---|---|---|
| 다회전 문서 질의응답, CPU 오프로드 (8.2절) | 질의 약 1만 토큰(문서 약 12쪽 + 질문), 출력 최대 100토큰, 기준선 vLLM 0.10.2(GPU 프리픽스 캐시)·vLLM CPU 오프로딩·상용 제품 둘 | 초당 1요청에서 TTFT 1.9~8.1배 작음, ITL 7~92% 작음, 같은 TTFT 에서 처리량 2.3~14배 |
| 실제 서비스 기록 재생 (8.3절) | 두 회사의 입출력 분포, CPU 500GB, 기준선 vLLM | TTFT 3.7~6.8배 작음, ITL 19~58% 작음 |
| 중앙 저장 서버 (8.4절) | 원격 서버와 15Gbps 링크 | 같은 TTFT 에서 처리량 1.3~3배 |
초록은 처리량 「최대 15배」라고 적지만, 결과 절에서 확인한 최대치는 8.2절의 14배였습니다. 원격 저장소 쪽 이득이 1.3~3배로 CPU 메모리보다 작은 것은 링크가 느리기 때문이고, 다음 절의 손익 분기와 같은 이야기입니다.
4. 직접 잰 값: 576ms 에서 48.6ms
1절의 실험에 LMCache 를 켰습니다(CPU 메모리 상한 1.5GB, 청크 256). 환경은 8GB급 노트북 GPU, Qwen2.5-1.5B-Instruct(fp16), vLLM 0.29.0, LMCache 0.5.5, 요청은 하나씩 보냈습니다.
| 설정 · 패스 | 첫 토큰 p50 | p95 | 패스 전체 |
|---|---|---|---|
| vLLM 만 · 처음 | 575.5ms | 637.3ms | 6.2초 |
| vLLM 만 · 다시 | 576.2ms | 577.9ms | 6.2초 |
| LMCache · 처음 | 597.8ms | 676.2ms | 6.5초 |
| LMCache · 다시 | 48.6ms | 59.6ms | 0.9초 |
「다시」는 같은 순서로 다시 읽은 두 번째 패스입니다.
- 다시 읽기의 첫 토큰이 약 12배 빨라졌습니다. LMCache 로그에는 요청마다 약 5,000토큰 가운데 4,864토큰(256 × 19)을 CPU 에서 불러왔고 엔진이 새로 계산한 토큰은 0 이라고 찍혔습니다. 청크 단위라 마지막 모자란 조각은 불러오지 못하고 다시 계산합니다.
- 불러온 KV 는 문서당 0.13GB 였습니다. 1편의 식으로 Qwen2.5-1.5B(28층, KV 헤드 2, 헤드 차원 128, 2바이트)는 토큰당 28,672바이트이고, 4,864토큰이면 0.1299GiB 로 로그와 같습니다.
- 처음 읽을 때는 약 4% 느렸습니다(575.5 → 597.8ms). 읽으면서 KV 를 CPU 로 내리는 비용입니다.
- GPU 메모리 사용은 두 설정이 같았습니다. LMCache 는 GPU 자리를 더 쓰지 않습니다.
길이를 바꿔 보면 이득이 문맥 길이에 따라 커집니다(CPU 2GB, GPU 에서 밀려난 문서를 다시 요청).
| 입력 토큰 | 다시 계산 | 불러옴 | 배율 |
|---|---|---|---|
| 554 | 66ms | 21ms | 3.1배 |
| 1,077 | 119ms | 24ms | 5.0배 |
| 2,144 | 231ms | 29ms | 8.0배 |
| 4,273 | 481ms | 45ms | 10.7배 |
| 6,414 | 768ms | 41ms | 약 19배 |
다시 계산하는 시간은 길이에 거의 비례하지만, 불러오는 시간은 GPU 에서 바로 적중할 때(20~32ms)보다 몇 ms 더 걸리는 수준으로 완만합니다.
용량은 절벽입니다. 같은 다시 읽기를 CPU 상한만 바꿔 쟀습니다(작업 집합의 KV 는 계산으로 약 1.49GB).
| CPU 상한 | 다시 읽기 첫 토큰 | 외부 적중 |
|---|---|---|
| 없음(vLLM 만) | 600ms | — |
| 0.5GB | 620ms | 0% |
| 1.0GB | 620ms | 0% |
| 1.5GB | 39ms | 98% |
| 2.0GB | 39ms | 98% |
작업 집합보다 조금이라도 작으면 이득이 0 이고 저장 비용만 남았습니다. 1절과 같은 LRU 순환 접근의 함정입니다. 실제처럼 일부 문서가 자주 읽히는 분포(지프 분포, 문서 60개)에서는 작은 캐시도 도움이 되어, 평균 첫 토큰이 vLLM 만 278ms 에서 CPU 1GB 174ms, 2GB 63ms 로 줄었습니다.
이 실험의 한계: 동시성 1, 1.5B 모델 하나, 난수 낱말로 만든 합성 문서, 한 번씩 잰 값이고, 지금 문서가 권하는 MP 모드가 아니라 프로세스 내 모드였습니다.
5. 손익 분기: 불러오기가 계산보다 쌀 때만
불러오기가 이득이려면 KV 를 옮기는 시간이 그 KV 를 다시 계산하는 시간보다 짧아야 합니다. 토큰 n개에 대해 적으면 다음과 같습니다.
- 다시 계산: n × (토큰당 프리필 시간)
- 불러오기: n × (토큰당 KV 바이트) ÷ 대역폭 + 고정 지연
n 이 양쪽에 있으니, 고정 지연을 빼면 손익 분기 대역폭 = 토큰당 KV 바이트 ÷ 토큰당 프리필 시간입니다. 위 실측(6,414토큰 768ms, 토큰당 약 0.12ms)에 넣으면 28,672바이트 ÷ 0.12ms ≈ 0.24GB/s 입니다(계산).
- CPU 메모리(이 GPU 의 PCIe 실측 13.4GB/s)는 분기보다 50배 넘게 빨라 확실한 이득입니다.
- 1GbE 급 링크(다른 실험에서 잰 실효 104MB/s)는 분기보다 느립니다. 6,414토큰의 KV(약 184MB)를 옮기는 데만 약 1.8초로, 다시 계산(0.77초)보다 오래 걸립니다(계산). 느린 네트워크 저장소에서 불러오는 것은 손해입니다.
- 보고서도 같은 결론입니다. B200 GPU 에서 32Gbps 링크는 입력이 256K 토큰을 넘을 때만 불러오기가 프리필보다 빨랐고, 64·128Gbps 는 시험한 모든 길이에서 빨랐습니다(8.7절, 모델은 미확인). 그래서 저자들은 불러올지 다시 계산할지를 상황에 따라 고르라고 권합니다.
모델과 GPU 가 분기를 옮깁니다. 프리필 계산량은 토큰당 대략 「2 × 파라미터 수」 FLOP 이고, KV 바이트는 1편의 식입니다. 둘의 비(KV 1바이트를 아끼면 아끼는 계산)를 공개 구성으로 계산하면 다음과 같습니다(어텐션 계산은 빼고 어림).
| 모델 | 토큰당 프리필 계산 | 토큰당 KV | KV 1바이트당 계산 |
|---|---|---|---|
| Qwen2.5-1.5B | 약 3.1 GFLOP | 28KiB | 약 11만 FLOP |
| Llama 3.1 8B | 약 16 GFLOP | 128KiB | 약 12만 FLOP |
| Qwen2.5-7B | 약 15 GFLOP | 56KiB | 약 27만 FLOP |
| Llama 3.1 70B | 약 140 GFLOP | 320KiB | 약 43만 FLOP |
KV 1바이트당 계산이 클수록 불러오기가 유리합니다. GQA 로 KV 를 줄인 큰 모델일수록 「불러올 가치」가 큽니다. 반대로 GPU 가 빠를수록 다시 계산이 빨라져 분기 대역폭이 올라갑니다. 같은 저장소라도 느린 GPU 에서는 이득, 빠른 GPU 에서는 손해일 수 있습니다.
적중률도 분기가 있습니다. 적중하면 527.6ms 를 벌고(576.2 − 48.6), 놓치면 저장 비용 22.3ms 를 냅니다(597.8 − 575.5). 적중 확률 p 에서 기대 이득이 0 이 되는 p 는 22.3 ÷ (22.3 + 527.6) ≈ 4% 입니다. 이 실험의 값이고 일반 상수가 아닙니다. 다른 공개 자료의 숫자를 넣으면 20% 안팎으로도 올라갑니다.
6. 앞부분이 아닌 조각도 다시 쓰기: CacheBlend, CacheGen
프리픽스 캐시는 맨 앞부터 똑같을 때만 씁니다. RAG 처럼 문서 조각 여러 개를 매번 다른 순서로 붙이면 첫 조각 말고는 적중하지 않습니다. 조각마다 따로 만든 KV 를 그냥 이어 붙이면, 조각 사이의 어텐션(뒤 조각이 앞 조각을 보는 것)이 빠져 답이 틀립니다.
CacheBlend(Yao 외, EuroSys 2025)는 이어 붙인 뒤 KV 가 가장 많이 어긋나는 토큰만 골라 다시 계산합니다. 층마다 그런 토큰은 10~15% 정도였고, 10~20% 만 다시 계산하면 충분했습니다. 다시 계산을 다음 층 불러오기와 겹쳐 숨깁니다. 결과는 전체 재계산 대비 TTFT 2.2~3.3배 감소, 처리량 2.8~5배 증가, 품질(F1·Rouge-L) 하락은 0.01~0.03 이하였습니다(Mistral-7B·Yi-34B·Llama-70B, A40 2장, NVMe 실측 4.8GB/s). LMCache 의 MP 서버는 --engine-type blend 로 이 방식을 켭니다.
CacheGen(Liu 외, SIGCOMM 2024)은 KV 를 옮기는 비용 자체를 줄입니다. 이웃 토큰끼리 KV 가 비슷하다는 점을 이용해 차이만 부호화하고, 앞쪽 층은 촘촘히·뒤쪽 층은 거칠게 양자화합니다. 일반 양자화보다 KV 가 3.5~4.3배 작아졌고, 3Gbps 링크에서 TTFT 가 양자화 기준선보다 3.2~3.7배 낮았으며 정확도 하락은 2% 이내였습니다(Mistral-7B·Llama-34B·70B, A40 4장). 대역폭이 떨어지면 청크마다 압축 수준을 낮추거나 텍스트를 보내 다시 계산하는 쪽으로 바꿉니다. 5절의 손익 분기를 청크마다 실시간으로 계산하는 셈입니다.
7. 프리필·디코드 분리에서의 KV 전송
KV 를 옮기는 능력은 다른 데에도 쓰입니다. 4편에서 볼 분리 서빙은 프리필 GPU 가 만든 KV 를 디코드 GPU 로 보내야 합니다. LMCache 문서의 분리 구성은 프리필→디코드 전송을 NIXL(vLLM 의 NixlConnector)에 맡기고, vLLM 의 MultiConnector 로 LMCache 커넥터를 함께 묶어 요청 사이 재사용을 더합니다. 보고서는 8K 입력·200 출력, NVLink 조건에서 vLLM 자체 분리 구성보다 평균 TTFT 가 1.53~1.84배, 평균 ITL 이 1.12~1.66배 낮았다고 보고합니다(8.5절, 모델 이름은 절 안에서 확인하지 못함).
8. 언제 이득이 없나
| 조건 | 왜 | 근거 |
|---|---|---|
| 프롬프트가 짧다 | 다시 계산이 이미 싸서 아낄 것이 적다. 고정 지연이 더 크다 | 실측: 554토큰에서 3.1배, 6,414토큰에서 19배 |
| 같은 앞부분이 다시 오지 않는다 | 적중이 없으면 저장 비용만 낸다 | 실측: 처음 읽기 +4% |
| 캐시 용량이 작업 집합보다 작다(순환 접근) | LRU 가 다음에 쓸 것을 늘 지운다 | 실측: 0.5·1.0GB 에서 적중 0% |
| 저장소·네트워크가 느리다 | 옮기는 시간이 다시 계산보다 길다 | 계산: 1GbE 는 이 모델의 분기 0.24GB/s 아래. 보고서 8.7절 |
| 작은 모델, 빠른 GPU | 다시 계산이 빨라 분기 대역폭이 올라간다 | 계산(5절 표) |
| GPU 프리픽스 캐시로 충분하다 | 작업 집합이 GPU 에 다 들어가면 vLLM 만으로 적중한다 | 실측: 청크 크기 시험에서 vLLM 만 쓴 값과 같았음 |
티티 한마디. 경기 영상을 다시 보려고 매번 경기를 새로 치를 필요는 없어요. 녹화해 둔 걸 틀면 되죠. 다만 녹화본이 먼 창고에 있고 길이 막히면, 그냥 한 판 더 치는 게 빠를 때도 있어요. 얼마나 먼지, 몇 번이나 다시 볼지를 먼저 재 봐야 해요.
참고
- Liu 외, LMCache: An Efficient KV Cache Layer for Enterprise-Scale LLM Inference: https://arxiv.org/abs/2510.09665 (v2, 2025-12-05. 5·6·8.2~8.7·9절)
- LMCache 문서: https://docs.lmcache.ai/ (
mp/index.html,mp/l2_storage/supported_storages.html,mp/disaggregated_prefill.html,mp/p2p.html,kv_cache_optimizations/cacheblend.html, 2026-10-13 열람), 릴리스: https://github.com/LMCache/LMCache/releases - Yao 외, CacheBlend (EuroSys 2025): https://arxiv.org/abs/2405.16444 (v3, 초록·4·5·7절)
- Liu 외, CacheGen (SIGCOMM 2024): https://arxiv.org/abs/2310.07240 (v6, 5·7절)
- vLLM 분리 프리필·KV 커넥터: https://docs.vllm.ai/en/latest/features/disagg_prefill/, LMCache 예제: https://docs.vllm.ai/en/latest/examples/disaggregated/lmcache/
- 실측 인용: 같은 사이트 「토스 ML/AI Infra 준비」 8편(KV 오프로드 실측), 24편(1GbE 실효 처리량)