엔지니어링
Jun 16, 2026
엔지니어링
Agent 코딩과 긴 컨텍스트: VAST Data와 Backend.AI에서 KV 캐시 오프로딩이 실제로 주는 효과

허진호
테크니컬 라이터

조규진
소프트웨어 엔지니어

Anat Heilper
AI 아키텍트 디렉터 @VAST Data
Jun 16, 2026
엔지니어링
Agent 코딩과 긴 컨텍스트: VAST Data와 Backend.AI에서 KV 캐시 오프로딩이 실제로 주는 효과

허진호
테크니컬 라이터

조규진
소프트웨어 엔지니어

Anat Heilper
AI 아키텍트 디렉터 @VAST Data
에이전트 기반 코딩 환경에서는 여러 턴에 걸쳐 동작하는 코딩 어시스턴트가 동일한 긴 베이스 컨텍스트를 반복해서 사용합니다. 이때 사용자가 체감하는 성능은 time-to-first-token, 즉 TTFT에 크게 좌우됩니다. 문제는 이 베이스 컨텍스트가 수십만 토큰 수준으로 커지면, 같은 prefix를 반복해서 쓰는 상황에서도 매번 prefill 비용을 거의 그대로 다시 치르게 된다는 점입니다. GPU의 KV 캐시 용량이 한계에 다다르면 이전 턴에서 쓰던 블록이 계속 밀려나고, 밀려난 만큼 다시 계산해야 하는 소요가 생기기 때문입니다. 그 결과 반복적이기 때문에 더 빨라져야만 할 것 같은 작업의 TTFT가 좀처럼 낮아지지 않고 일정한 수준에 머물게 됩니다.
긴 컨텍스트를 가진 워크로드에 대응하는 방법
문제를 해결하는 방법에는 몇 가지 선택지가 있습니다. 하나는 GPU의 메모리 용량을 늘리는 것입니다. 애초부터 더 큰 메모리를 탑재하여 KV 캐시가 밀려나지 않도록 만든다면 그만큼 재연산을 해야 하는 상황이 줄어드니 TTFT가 감소하고, 작업도 더 빨리 끝나게 됩니다. 그러나 이 방법은 더 큰 메모리 용량을 가진 GPU들의 대당 가격이 매우 높고, 물리적으로 확장 가능한 용량에도 한계가 있기 때문에 대부분의 기업에게 선택지가 되기 어렵습니다.
두 번째는 KV 캐시 블록을 외부 스토리지로 옮겨두고, 필요할 때 다시 불러오는 KV 캐시 오프로딩 방식을 선택하는 것입니다. KV 캐시 오프로딩은 용량이 모자라 블록이 밀려나는 것을 방치하고, 이 밀려난 블록들을 매번 처음부터 계산하는 방식 대신 저장된 결과를 재사용할 수 있도록 만드는 것입니다. 첫 번째 방식보다 매우 현실적이지만, 일반적인 NFS 스토리지의 경우는 속도가 느리기 때문에 데이터를 오프로딩한 후 불러오는 비용이 데이터를 GPU 내부에서 다시 계산하는 비용보다 더 커질 수 있다는 검토사항이 생깁니다. 따라서 KV 캐시 오프로딩을 효과적으로 사용하려면 RDMA, GPUDirect Storage, 그리고 고성능 데이터 플랫폼을 적절히 조합해야 합니다. 이러한 구성을 어떻게 만드느냐에 따라 테일 레이턴시의 개선 여부가 달라지게 됩니다.
에이전트 코딩에서 GPU 내부에만 머무르는 KV 캐시의 한계
일반적인 챗봇은 사용자 간에 프롬프트를 거의 공유하지 않습니다. 반면 엔터프라이즈 RAG 서비스는 대부분의 요청이 하나의 긴 공통 프리픽스를 공유합니다. 에이전트 코딩은 이 두 패턴 어디에도 속하지 않습니다. 각 에이전트 세션은 서로 다른 긴 prefix를 붙들고 있고, 오래 이어지는 세션은 그 prefix를 두고 여러 턴을 진행합니다. 이 지점에서 GPU 메모리에만 의존하는 KV 캐시의 한계가 드러납니다.
KV 캐시를 오프로딩하지 않는 경우에는 GPU 메모리에 두 방향의 압박이 가해집니다. 먼저, 긴 컨텍스트 하나만으로도 KV 캐시는 모델 가중치 위에 추가로 쌓이게 되면서 메모리의 상당 부분을 차지하게 됩니다. 이런 세션이 몇 번만 더 반복되어 실행되면 캐시가 밀려나 축출되는 현상을 피할 수 없습니다. 특정 에이전트가 다음 턴을 수행하려고 돌아왔을 때, 해당 KV 블록은 이미 다른 에이전트의 컨텍스트에 밀려 사라졌고, 때문에 추론 엔진은 프리필을 처음부터 다시 수행해야 하는 것입니다.
따라서 이런 일이 발생하기 전에 KV캐시를 다른 곳으로 옮겨두는 KV 캐시 오프로딩의 효과는 하나의 추론 서버에서 긴 컨텍스트를 가진 작업을 반복적으로 처리하는, 이른바 무거운 에이전트 코딩 루프에서 대표적으로 확인할 수 있습니다. 이런 환경에서는 전체 처리 시간이 거의 절반 수준으로 줄고, 평균 TTFT도 절반 이상 감소합니다. 더 중요한 지표는 단순 평균이 아니라 TTFT 분포의 형태인데, 사용자 체감 성능은 이 분포에 더 크게 영향을 받기 때문입니다. 래블업과 VAST Data가 공동 수행한 아래 벤치마크를 통해 수치와 함께 살펴보겠습니다.
벤치마크 설정
Lablup과 VAST Data는 Backend.AI 26.4 환경에서 VAST AI OS v5.4의 KV Cache VFolder를 추론 세션에 마운트하여 KV 캐시 오프로딩의 효과를 검증했습니다.
벤치마크는 Backend.AI 세션에서 8개의 H100 GPU를 사용해 수행되었습니다. 추론 엔진은 vLLM 0.20.0과 KV 캐시 오프로딩을 담당하는 LMCache를 사용했으며, vllm-openai:0.20.0-cuda12.9-ubuntu22.04 컨테이너 이미지로 구성했습니다. 모델은 Mistral Medium 3.5 128B를 사용했습니다. 모든 워크로드는 Backend.AI 소스 코드에서 추출한 140K 토큰 길이의 단일 컨텍스트를 기반으로 합니다.
KV 캐시 백엔드는 Backend.AI의 스토리지 프록시를 통해 세션에 마운트된 VAST KV Cache VFolder입니다. LMCache의 gds_path는 이 VAST 마운트를 가리키며, NVIDIA GPUDirect Storage 기반 cuFile 버퍼(LMCACHE_CUFILE_BUFFER_SIZE)는 GPU당 24 GiB로 설정했습니다. 이 크기는 최대 컨텍스트에 해당하는 KV 캐시를 한 번에 처리할 수 있으면서도 vLLM의 HBM 할당 범위를 넘지 않도록 맞춘 값입니다. 실제 데이터 이동은 GDS가 담당하며, 호스트 메모리를 거치지 않고 GPU 메모리와 VAST 클러스터 사이를 100Gbps 네트워크로 직접 연결합니다. 스토리지 측 추가 설정은 필요 없으며, VAST의 어떤 폴더 타입이든 캐시 대상으로 사용할 수 있습니다.
워크로드 디자인
벤치마크는 하나의 추론 서버에서 서로 다른 10개의 에이전트 컨텍스트를 순환 처리하는 방식으로 구성했습니다. 각 컨텍스트는 5번의 턴을 수행합니다. 먼저 모든 컨텍스트의 첫 번째 턴을 순서대로 실행한 뒤, 다시 돌아와 두 번째 턴을 수행하는 식으로 반복합니다. 이 구조에서는 특정 컨텍스트가 다음 턴을 수행하기 전에 다른 9개의 긴 컨텍스트가 GPU를 거치게 되며, 이는 GPU 상주 KV 캐시에 가장 불리한 순서입니다.
벤치마크 결과
| 메트릭 | 오프로딩 미사용 | 오프로딩 사용 | 효과 |
|---|---|---|---|
| 전체 wall-clock | 1177.97s | 601.41s | 1.96배 빠름 |
| 평균 TTFT | 22,104 ms | 10,573 ms | 2.09배 빠름 |
| TPOT (토큰별 디코딩) | 14.5 ms | 14.5 ms | 동일 |
오프로딩을 사용하지 않은 경우와 비교하면 전체 처리 시간과 평균 TTFT는 모두 약 2배 수준으로 개선되었습니다. 반면 토큰당 디코딩 시간(TPOT)은 14.5 ms로 동일하게 유지되었습니다. 즉, 성능 개선은 전적으로 첫 토큰을 생성하기까지의 구간에서 발생하며, 생성이 시작된 이후의 속도는 동일합니다. 이를 통해 KV 캐시 오프로딩이 보여주는 개선점은 디코딩 단계가 아닌 프리필 단계에서의 최적화 효과라는 점을 이해할 수 있습니다.
다만 평균 TTFT만으로는 중요한 차이를 충분히 설명하기 어렵습니다. 컨텍스트별 첫 번째 요청과 이후 재사용 요청을 나누어 보면 효과를 명확하게 볼 수 있습니다.
| 턴 유형별 TTFT | 오프로딩 미사용 | 오프로딩 사용 | 효과 |
|---|---|---|---|
| 컨텍스트별 첫 번째 턴 (Cold) | ~22.3s | ~26.3s | ~4초 오프로드 패널티 |
| 컨텍스트별 후속 턴 (Warm reuse) | ~22.0s | ~6.6s | ~3.3배 빠름 |
각 컨텍스트의 첫 번째 턴에서는 오히려 약 4초 정도의 추가 지연이 발생합니다. 프리필을 수행하면서 동시에 KV 블록을 VAST에 기록하기 때문입니다. 그러나 한 번 저장된 이후에는 상황이 완전히 달라집니다. 동일한 컨텍스트에 대한 이후 턴에서는 KV 블록을 다시 계산하지 않고 스토리지에서 읽어오기 때문에, TTFT가 약 6.6초 수준으로 떨어집니다. 이는 GPU 단독 KV 캐시 대비 약 3.3배 빠른 수치입니다. 사용자 입장에서는 첫 토큰 생성까지 걸리는 시간이 약 22초에서 6초 수준으로 줄어드는 효과를 체감하게 됩니다.
배포 전에 반드시 고려해야 할 값은 LMCache의 cuFile 버퍼 크기 (LMCACHE_CUFILE_BUFFER_SIZE)입니다. Mistral Medium 3.5 기준으로 GPU당 24 GiB가 필요합니다. 이 버퍼는 GDS가 GPU 메모리와 스토리지 사이에서 데이터를 주고받기 위한 고정 영역으로, vLLM의 메모리 할당과 함께 메모리를 점유합니다. 예를 들어 80GB VRAM를 가진 H100에서 모델 가중치 약 16GB와 기타 오버헤드 약 3GB를 제외하면 약 19GB가 이미 사용된 상태입니다. vLLM을 0.9 수준으로 설정하면 약 53GB 정도가 KV 캐시에 할당되며, 이 중 24 GB는 버퍼로 사용됩니다. 중요한 점은 이 값이 캐시 용량이 아니라 전송을 위한 staging 공간이라는 점입니다. 실제 KV 캐시는 메모리에 머무를 필요 없이 스토리지에 저장되고 필요할 때 스트리밍됩니다. 이 버퍼는 메모리 기반 캐시를 스토리지 기반 캐시로 전환하기 위한 비용이며, 그 대가로 훨씬 많은 세션을 동시에 유지할 수 있습니다. 앞서 본 전체 처리 시간 개선은 바로 이 트레이드오프의 결과로 해석할 수 있습니다.
참고: KV 캐시 오프로딩을 활성화하면 vLLM 세션의 첫 턴에서 수 초 수준의 추가 지연이 발생합니다. 이 현상은 스토리지 종류와 무관하게 일관되게 나타나며, LMCache 구현에 기인한 것으로 보입니다. 현재로서는 알려진 제약 사항으로 보이며, 향후 업데이트를 확인할 필요가 있습니다.
VAST와 Backend.AI에서 라인 레이트에 근접한 읽기 성능
100Gbps 네트워크 환경에서 이론적 최대 대역폭은 약 12.5 GB/s입니다. 실측 결과 VAST 마운트는 최대 10,693 MB/s의 처리량과 초당 10,441건의 읽기 요청을 기록했으며, 이는 물리적 한계에 근접한 수준입니다. 측정 과정에서의 평균 읽기 왕복 지연 시간은 8.265 ms로 유지되었습니다. 해당 시나리오에서는 스토리지 경로가 병목으로 작용하지 않고, KV 캐시 오프로딩이 재계산보다 빠르기 위한 핵심 조건을 충족합니다. 일반적인 TCP 기반 NFS에서는 이 조건을 만족하기 어렵습니다. 여기서는 100Gbps 네트워크, GPUDirect Storage, 그리고 VAST의 DASE(Disaggregated Shared-Everything) 아키텍처가 스토리지 측 성능을 담당합니다. 여기에 Backend.AI가 추론 환경과 연결되면서 KV 캐시 오프로딩이 실제로 더 빠른 경로로 동작하는 것입니다.
KV 캐시 오프로딩이 효과를 내는 시나리오
VAST 기반 KV 캐시 오프로딩은 서로 다른 긴 프리픽스가 하나의 추론 서버에서 반복적으로 순환하는 코딩 워크로드에서 가장 큰 효과를 발휘합니다. 각 에이전트는 고유한 시스템 프롬프트와 도구, 그리고 작업 중인 코드 상태를 유지하며, 이러한 컨텍스트가 여러 요청에 걸쳐 반복적으로 사용됩니다. 이 환경에서는 매번 캐시를 재계산하는 대신 스토리지에서 불러오는 방식이 TTFT를 크게 줄입니다.
이외에도 요청마다 참조 문서가 바뀌는 장문 컨텍스트 기반 RAG 시스템이나, 사용자 또는 팀별로 서로 다른 컨텍스트를 유지하는 멀티테넌트 코딩 어시스턴트 서비스에도 잘 맞습니다. 반대로 대부분 단발성 요청으로 이루어진 일반 챗봇에는 효과가 거의 없습니다. 하나의 긴 공통 프리픽스를 계속 재사용하는 RAG 시스템 역시 vLLM의 기본 프리픽스 캐시만으로 충분하기 때문입니다.
위 구성은 컴퓨트 오케스트레이션 계층에 Backend.AI를, 스토리지 계층에 VAST Data의 스토리지를 사용해 구축되었습니다. 본 성능 결과는 두 솔루션을 함께 적용했을 때의 효과를 반영합니다. 동일한 벤치마크를 재현하거나, 자체적인 에이전트 워크로드에 적용, 평가해보고 싶다면 래블업에 문의하시기 바랍니다.
Reproduction summary
- 추론 엔진: vLLM 0.20.0 + LMCache
- 컨테이너 이미지:
vllm-openai:0.20.0-cuda12.9-ubuntu22.04 - 모델: Mistral Medium 3.5 128B
- GPU: NVIDIA H100 8장
- 베이스 컨텍스트: 140K-token chunk of the Backend.AI source repository
- 캐시 백엔드: Backend.AI를 통한 VAST KV 캐시 VFolder 마운트. LMCache gds_path는 VAST 마운트 경로로 설정. GDS cuFile 버퍼(LMCACHE_CUFILE_BUFFER_SIZE)는 GPU당 24GiB, vLLM의 메모리 할당량보다 작으면서 최대 컨텍스트 KV 캐시 하나에 맞도록 크기 조정.
- 네트워크: GPU 노드와 VAST 클러스터 간 100Gbps 패브릭
- 워크로드: 하나의 추론 서버에서 10개의 에이전트 컨텍스트를 순환, 각 컨텍스트당 5턴