AI 캐시 최적화, 왜 오래된 LRU가 만만치 않을까
핵심 요약
- KV 캐시는 모델이 앞선 토큰을 처리하며 만든 계산 결과 일부를 보관합니다.
- 프리픽스 캐싱은 요청의 앞부분이 일치할 때 저장된 KV 캐시를 재사용합니다.
- 최근 사용한 문맥을 곧 다시 사용하는 작업에서는 LRU의 단순한 규칙이 효과적일 수 있습니다.
- 캐시 정책의 성능은 적중률뿐 아니라 응답 지연과 정책 실행 비용까지 함께 비교해야 합니다.
코딩 에이전트는 파일을 읽어 코드를 고친 뒤 테스트 결과를 확인합니다. 이런 작업을 하는 동안 모델을 여러 번 호출합니다. 호출할 때마다 반복되는 긴 문맥을 재사용하면 계산 부담을 줄일 수 있습니다. 어떤 캐시를 남겨둘지 정하는 정책을 비교할 때는 오래전부터 써 온 캐시 교체 알고리즘인 LRU가 기준이 됩니다.
긴 문맥을 다시 계산하지 않는 방법
언어 모델은 문장을 토큰이라는 단위로 나눠 처리합니다. 이때 어텐션 계산에 쓰는 키와 값이라는 내부 데이터를 만듭니다. 이 데이터를 저장해 두는 공간이 KV 캐시입니다.
요청 사이에서 이 데이터를 다시 쓰는 방법 중 하나가 프리픽스 캐싱입니다. 프리픽스는 입력의 앞부분을 뜻합니다. 같은 지시문과 대화 기록으로 시작하는 요청이라면, 그 부분을 처리할 때 만든 KV 데이터를 다시 쓸 수 있습니다.
예를 들어 이전에 처리한 8,000토큰의 문맥 뒤에 새로운 내용 1,000토큰을 붙여 요청했다고 해보겠습니다. 앞의 8,000토큰에 해당하는 캐시가 남아 있고 재사용 조건도 맞는다면, 그 구간의 KV를 새로 만드는 계산을 줄일 수 있습니다.
그렇다고 전체 처리 시간이 곧바로 9분의 1이 되지는 않습니다. 새 입력을 처리하고 답변을 생성하는 데도 시간이 걸립니다. 새 토큰이 이전 문맥을 참조하는 계산도 여전히 필요합니다.
캐시를 다시 쓰려면 입력이 일치하는지도 중요합니다. 뜻이 비슷하다는 것만으로 같은 캐시를 쓸 수는 없습니다. 요청 앞쪽에 매번 바뀌는 시각 정보를 넣거나 문서 순서를 바꾸면, 그 지점 이후의 프리픽스는 재사용하기 어려워질 수 있습니다.
따라서 캐시 정책을 고르기에 앞서 반복되는 입력이 실제로 같은 형태로 유지되는지부터 확인해야 합니다.
LRU가 에이전트 작업과 잘 맞는 순간
캐시를 무한정 보관할 수는 없습니다. 메모리가 차면 일부 데이터를 지워야 합니다. 이렇게 공간이 부족할 때 무엇을 내보낼지 정하는 규칙을 퇴출 정책이라고 합니다.
LRU는 Least Recently Used의 약자입니다. 가장 오래 사용하지 않은 항목부터 내보냅니다. 기준은 단순합니다. 최근에 쓴 항목이라면 조만간 다시 쓸 가능성이 있다고 보는 것입니다.
이 가정이 잘 들어맞는 상황을 시간 지역성이 높다고 말합니다. 방금 펼쳐 본 문서를 책상 가까이에 두면 편한 것과 비슷합니다.
에이전트가 하나의 작업을 이어서 수행할 때도 이런 패턴이 나타날 수 있습니다. 저장소 설명을 읽은 뒤 코드를 수정하고, 테스트 결과를 받아 다시 수정합니다. 다음 요청에도 직전 대화의 상당 부분이 그대로 들어갈 수 있습니다.
이런 흐름에서는 최근 사용한 캐시를 남겨두는 규칙이 유용합니다. 복잡한 예측을 하지 않아도 곧 다시 필요한 문맥을 보관할 수 있기 때문입니다.
다만 모든 에이전트 작업이 이 패턴을 따르지는 않습니다. 도구 실행이 오래 걸리는 사이 다른 세션의 요청이 몰리면, 다시 필요한 문맥이 이미 밀려나 있을 수 있습니다. LRU가 잘 맞는지는 에이전트라는 이름만으로 알 수 없고, 요청이 실제로 들어오는 순서를 봐야 합니다.
복잡한 정책은 관리 비용까지 따져야 합니다
정책을 설계할 때 더 많은 정보를 참고할 수도 있습니다. 사용 빈도를 세거나 다시 계산하는 비용을 추정해 판단에 쓸 수 있습니다. 다음 접근을 예측하는 모델을 붙이는 방법도 있습니다.
하지만 판단을 정교하게 하려면 그만큼 일이 늘어납니다. 통계를 갱신하면서 후보를 비교해야 하고, 예측 모델을 쓴다면 이를 실행하는 데도 비용이 듭니다. 캐시를 잘 남겨둬서 아낀 시간보다 관리에 쓴 시간이 더 길다면 응답은 빨라지지 않습니다.
그래서 저는 캐시 정책의 성능을 볼 때 절약한 계산과 판단에 든 비용의 차이를 살핍니다. 다시 쓸 항목을 잘 맞혔다는 설명만으로는 실제로 얼마나 이득인지 알기 어렵습니다.
물론 LRU에도 약점이 있습니다. 한 번만 사용할 긴 입력이 연달아 들어오면, 나중에 다시 필요한 캐시가 밀려날 수 있습니다. 최근에 사용했다는 사실만으로 다시 쓸 가치가 얼마나 큰지까지 판단할 수는 없기 때문입니다.
캐시를 언제 다시 쓸지와 함께, 다시 쓰면 계산을 얼마나 아낄 수 있는지도 따져야 합니다. 여러 요청이 긴 공통 문맥을 공유할 때와 짧은 개별 문맥을 반복해서 쓸 때는 유리한 정책이 달라질 수 있습니다.
LRU보다 나은 정책인지 평가하려면 어떤 작업 패턴에서 성능이 좋아졌는지 함께 봐야 합니다. 특정 조건에서 앞섰다고 해서 모든 에이전트 서비스에서도 더 낫다고 보기는 어렵습니다.
실제 에이전트 기록으로 시험할 때 봐야 할 것
실제 작업 기록을 재생하는 벤치마크에서는 요청의 길이와 반복 패턴을 반영해 정책을 평가할 수 있습니다. 다만 실제 기록을 썼다는 것만으로 서비스 환경까지 그대로 재현했다고 볼 수는 없습니다.
비교할 때는 우선 메모리 예산을 같게 맞춰야 합니다. 같은 개수의 요청을 저장하더라도 요청마다 길이가 다르면 메모리 사용량은 달라집니다. 정책이 통계를 관리하는 데 쓰는 메모리도 비교 결과에 영향을 줍니다.
요청 순서와 시간 간격도 살펴야 합니다. 한 세션을 끝까지 실행하고 다음 세션으로 넘어가는 실험은 문맥을 재사용하기에 유리할 수 있습니다. 여러 세션의 요청이 섞여 들어오면 서로의 캐시를 밀어냅니다. 도구 실행을 기다리는 시간도 요청 순서를 바꿉니다.
적중률을 어떻게 계산했는지도 확인해야 합니다. 요청 앞부분의 짧은 구간만 다시 쓴 경우와 긴 문맥 대부분을 다시 쓴 경우를 똑같이 한 번의 적중으로 세면 둘의 차이가 드러나지 않습니다. 적중 횟수와 함께 재사용한 토큰의 양을 봐야 합니다.
사용자가 실제로 얼마나 기다리는지도 확인해야 합니다. 첫 응답 토큰이 나오기까지 걸리는 시간과 전체 작업을 마치는 데 걸리는 시간은 서로 다른 지표입니다. 평균 시간이 줄어도 일부 요청은 더 오래 기다릴 수 있으므로 느린 요청의 지연도 살펴야 합니다.
작업 기록으로 캐시 적중만 계산하는 실험도 유용합니다. 다만 실제로 속도가 빨라졌다고 하려면, 추론 서버에서 정책을 실행할 때 드는 비용까지 측정해야 합니다.
LRU는 규칙이 단순해도 반복 작업의 특성과 잘 맞을 수 있어 성능을 넘어서기가 만만치 않습니다. 새로운 최적화가 얼마나 쓸모 있는지는 같은 메모리와 요청 조건에서 사용자의 대기 시간을 얼마나 줄였는지로 판단해야 합니다. 에이전트가 방금 쓴 문맥을 곧 다시 읽는지, 한참 뒤에야 돌아오는지를 살피면 어떤 조건에서 비교해야 할지 잡을 수 있습니다.
댓글
댓글을 불러오는 중...