본문으로 건너뛰기

vLLM의 PagedAttention

[!tldr] 업무 관점 takeaway PagedAttention은 GPU 메모리 효율을 위해 [[KV-Cache]]를 16~64KB 작은 페이지 단위로 쪼개 흩뿌린다. GPU 안에선 효율적이지만, GPU 밖으로 내보낼 땐 PCIe 대역폭 활용률이 박살난다 (64KB 전송 ≈ 4 GB/s vs 16MB ≈ 49 GB/s). 이게 [[LMCache-개요|LMCache의 256 토큰 chunk batching]]이 존재하는 이유 = 우리 NVMe 입장에서는 작은 페이지가 아니라 chunk 단위 I/O가 떨어진다는 사실이 결정적.


무엇인가

vLLM의 핵심 메모리 관리 기법. KV Cache를 연속된 큰 메모리 블록 대신 작은 페이지 (16 토큰 ≈ 수십 KB) 단위로 저장.

OS 가상 메모리 페이징과 같은 아이디어. 페이지 테이블이 논리 ↔ 물리 매핑을 관리.


장점 — 메모리 효율

기존 방식의 문제:

  • 연속 메모리 할당 → fragmentation 심함
  • 가변 길이 시퀀스에서 메모리 낭비

PagedAttention:

  • 작은 page 단위로 필요한 만큼만 할당
  • 시퀀스가 짧아도 큰 블록 잡지 않음
  • → 동시 처리 가능한 요청 수 ↑

부작용 1 — 페이지가 흩어짐 (scatter)

GPU 메모리 내:
[Page A] ... [Page B] ... [Page C] (불연속)

GPU 안에서는 페이지 테이블로 접근 → 문제 없음. GPU 밖으로 보낼 땐 → 흩어진 페이지를 다시 모으는(gather) 추가 작업 필요.

부작용 2 — 페이지 단위가 너무 작다 (PCIe 비효율)

페이지 1개 ≈ 16 토큰 ≈ 수십 KB.

이걸 페이지 하나씩 PCIe로 보내면:

64KB 전송 → 4 GB/s ← 페이지 그대로 보낼 때
1MB 전송 → 30 GB/s
16MB 전송 → 49 GB/s ← LMCache가 chunk로 묶을 때

12× 대역폭 차이가 묶기 한 번으로 발생.


LMCache가 푸는 방식

[[LMCache-개요|LMCache]]는 256 토큰 = 1 chunk 로 페이지들을 묶어서:

  • 저장 시: gather → chunk 단위 write
  • 로딩 시: chunk 단위 read → 페이지로 distribute

이 chunk 단위가 우리 NVMe에서 보는 I/O 사이즈를 결정한다 ([[LMCache-Local-Disk-Backend]], [[기여-포인트-맵|기여 포인트 [3]]]).


Storage Stack 함의

[!note] 의외의 연결 "PagedAttention 페이지 사이즈" ↔ "NVMe block size / FDP RU size" AI 추론 엔진이 결정한 페이지 단위가 chunk batching을 거쳐 결국 SSD의 erase unit 크기와 정렬 여부를 결정. 두 세계가 chunk size 한 변수로 연결된다.


관련 페이지

  • [[KV-Cache]] — 페이징되는 대상
  • [[LMCache-개요]] — chunk batching으로 페이지 비효율을 푸는 SW
  • [[LMCache-아키텍처]] — Cache Index가 chunk 단위로 운영되는 곳