𝗞𝗩 𝗖𝗮𝗰𝗵𝗲 𝗮𝗻𝗱 𝗣𝗮𝗴𝗲𝗱𝗔𝘁𝘁𝗲𝗻𝘁𝗶𝗼𝗻: LLM 서버가 느려지는 이유

LLM 서버가 느려지고 있습니다.

4개의 A100 GPU에 70B 모델을 배포했습니다. 오전 8시에는 모든 것이 정상입니다. 하지만 점심시간이 되면 지연 시간(latency)이 두 배로 늘어납니다. 메모리를 확인해 보니, 대부분이 "tensor buffers"로 채워져 있습니다. 이는 사실 이전 대화에서 생성된 캐시된 상태들입니다.

이것이 바로 KV 캐시 문제입니다. 이는 프로덕션 환경의 LLM 서빙에서 가장 큰 병목 현상입니다.

KV 캐시란 무엇인가요?

모든 트랜스포머(transformer) 모델은 토큰을 하나씩 생성합니다. 새로운 토큰을 생성하려면 모델은 이전의 모든 토큰으로부터 Key와 Value 텐서가 필요합니다. 매번 이를 다시 계산하는 것은 너무 느립니다. 대신 엔진은 이를 저장합니다. 이 저장 공간이 바로 KV 캐시입니다.

메모리 문제:

Llama 3.1 70B 모델의 경우, 단일 4096 토큰 시퀀스에 약 1.3GB의 메모리가 필요합니다.

만약 256명의 사용자가 동시에 접속한다면 336GB의 메모리가 필요합니다. 이는 A100 GPU 4개가 수용할 수 있는 용량보다 많습니다. KV 캐시는 매우 빠르게 증가하여 종종 모델 가중치(weights) 자체보다 더 많은 메모리를 사용하기도 합니다.

기존의 메모리 관리 방식이 실패하는 이유:

  • 내부 단편화(Internal fragmentation): 4096개의 토큰을 위한 공간을 할당했지만 실제로는 300개만 사용합니다. 이 경우 공간의 93%를 낭비하게 됩니다.
  • 공유 불가: 동일한 시스템 프롬프트를 사용하는 두 사용자가 각각 해당 프롬프트의 복사본을 별도로 저장합니다.
  • 전량 또는 전무 방식의 제거(All-or-nothing eviction): 메모리가 부족해지면 시퀀스 전체를 CPU로 옮겨야 합니다. 이 과정에서 GPU 작업이 중단됩니다.

PagedAttention이 이를 해결하는 방법:

PagedAttention은 운영체제(OS)와 유사하게 작동합니다. KV 캐시를 '페이지(page)'라고 불리는 작고 고정된 크기의 블록으로 나눕니다.

이는 세 가지 주요 문제를 해결합니다:

  • 온디맨드 할당(On-demand allocation): 시퀀스는 성장함에 따라 필요한 만큼만 페이지를 차지합니다. 사용하지 않는 용량에 메모리를 낭비하지 않습니다.
  • 공유 접두사(Shared prefix) 지원: 여러 사용자가 공통된 시스템 프롬프트에 대해 동일한 물리적 페이지를 공유할 수 있습니다. 이는 "copy-on-write" 로직을 사용하여 엄청난 양의 메모리를 절약합니다.
  • 세밀한 제거(Fine-grained eviction): 메모리가 가득 차면 시스템은 거대한 시퀀스 대신 작은 페이지들을 CPU로 이동시킵니다.

결과:

PagedAttention(vLLM에 적용된 기술)을 사용하면 기존 방식에 비해 처리량(throughput)을 2배에서 4배까지 높일 수 있습니다.

사용해야 할 때:

  • 높은 동시성(High concurrency)이 필요할 때.
  • 시퀀스 길이가 서로 다를 때.
  • 시작 부분이 동일한 프롬프트가 많을 때.

사용하지 않아도 될 때:

  • 단일 사용자 로컬 추론(inference).
  • 매우 작은 모델을 사용할 때.
  • 모든 시퀀스의 길이가 정확히 동일한 작업.

KV Cache와 PagedAttention: 역할과 중요성

거대 언어 모델(LLM)은 인공지능 분야에 혁신을 가져왔지만, 이를 실제로 서비스할 때는 상당한 기술적 도전 과제에 직면하게 됩니다. 특히 추론(Inference) 단계에서 발생하는 메모리 및 계산 효율성 문제는 모델의 성능과 운영 비용에 직접적인 영향을 미칩니다.

이 글에서는 LLM 추론의 핵심 기술인 KV Cache와 이를 혁신적으로 개선한 PagedAttention에 대해 알아보고, 왜 이 기술들이 중요한지 살펴보겠습니다.

KV Cache란 무엇인가?

LLM은 기본적으로 '어텐션(Attention)' 메커니즘을 기반으로 작동합니다. 문장에서 다음 토큰을 예측할 때, 모델은 이전의 모든 토큰과의 관계를 계산해야 합니다.

매번 새로운 토큰을 생성할 때마다 이전 토큰들에 대한 Key(K)와 Value(V) 벡터를 다시 계산하는 것은 매우 비효율적입니다. 이를 방지하기 위해, 한 번 계산된 K와 V 벡터를 메모리에 저장해 두었다가 다음 단계에서 재사용하는데, 이것이 바로 KV Cache입니다.

KV Cache의 작동 방식:

  1. 입력 단계: 프롬프트가 입력되면 각 토큰에 대한 K와 V 벡터를 계산합니다.
  2. 캐싱: 계산된 K와 V 벡터를 메모리에 저장합니다.
  3. 생성 단계: 새로운 토큰을 생성할 때, 새로 계산된 토큰의 K, V 값만 기존 캐시와 결합하여 어텐션 계산에 사용합니다.

결과적으로 KV Cache는 중복 계산을 줄여 추론 속도를 획기적으로 높여줍니다.

KV Cache의 문제점: 메모리 낭비와 단편화

KV Cache는 성능을 높여주지만, 동시에 심각한 메모리 문제를 야기합니다.

  1. 정적 메모리 할당 (Static Allocation): 대부분의 기존 시스템은 문장의 최대 길이를 미리 예측하여 그에 필요한 메모리를 미리 할당합니다. 하지만 실제 생성되는 문장이 예상보다 짧으면, 할당된 메모리의 상당 부분이 사용되지 않은 채 낭비됩니다.
  2. 메모리 단편화 (Memory Fragmentation):
    • 내부 단편화 (Internal Fragmentation): 할당된 블록 내에서 실제 데이터가 차지하지 않는 빈 공간.
    • 외부 단편화 (External Fragmentation): 사용 가능한 메모리 조각들이 흩어져 있어, 연속된 큰 메모리 공간을 확보하기 어려운 상태.

이러한 비효율성 때문에 시스템은 실제 처리할 수 있는 양보다 훨씬 적은 수의 요청(Request)만 처리할 수 있게 되며, 이는 곧 낮은 처리량(Throughput)으로 이어집니다.

PagedAttention: 해결책

이 문제를 해결하기 위해 등장한 것이 바로 PagedAttention입니다. PagedAttention은 운영체제(OS)의 가상 메모리(Virtual Memory)페이징(Paging) 개념에서 영감을 받았습니다.

PagedAttention은 KV 캐시를 연속적인 메모리 공간에 저장하는 대신, 작은 블록(Blocks) 단위로 나누어 관리합니다.

PagedAttention의 핵심 원리:

  • 블록 단위 관리: KV 캐시를 고정된 크기의 블록으로 나눕니다.
  • 비연속적 저장: 각 블록은 물리적 메모리의 서로 다른 위치에 흩어져 있을 수 있습니다.
  • 블록 테이블 (Block Table): 논리적인 순서와 실제 물리적 위치를 매핑하는 테이블을 사용하여, 모델이 마치 연속된 메모리를 사용하는 것처럼 느끼게 합니다.

이 방식을 통해 메모리를 필요한 만큼만, 그리고 필요한 위치에 동적으로 할당할 수 있습니다.

PagedAttention의 이점

PagedAttention을 도입하면 다음과 같은 강력한 이점을 얻을 수 있습니다.

  1. 메모리 효율성 극대화: 메모리 낭비를 거의 제로(0)에 가깝게 줄일 수 있습니다. 할당된 블록은 실제 데이터가 채워질 때만 의미를 갖기 때문입니다.
  2. 처리량(Throughput) 향상: 메모리 낭비가 줄어들면, 동일한 GPU 메모리 내에서 훨씬 더 많은 사용자 요청을 동시에 처리할 수 있습니다.
  3. 긴 문맥(Long Context) 지원: 메모리 관리가 효율적이므로, 더 긴 시퀀스 길이를 가진 모델을 더 안정적으로 실행할 수 있습니다.
  4. 효율적인 메모리 공유: 여러 요청이 동일한 프롬프트를 공유하는 경우(예: Few-shot prompting), PagedAttention은 동일한 KV 캐시 블록을 여러 요청이 참조하게 하여 메모리를 더욱 절약할 수 있습니다.

결론

KV Cache는 LLM 추론 속도를 높이는 필수적인 기술이지만, 메모리 관리 측면에서 큰 한계를 가지고 있었습니다. PagedAttention은 운영체제의 페이징 개념을 도입하여 이 문제를 해결했으며, 이는 현대적인 LLM 서빙 프레임워크(예: vLLM)의 핵심 기술이 되었습니다.

결과적으로 PagedAttention은 더 적은 자원으로 더 많은 사용자를 수용할 수 있게 함으로써, LLM 기술의 상용화와 확산에 결정적인 역할을 하고 있습니다.


Source: https://dev.to/tech_nuggets/kv-cache-and-pagedattention-what-they-do-and-why-they-matter-jce

Optional learning community: https://t.me/GyaanSetuAi