공부하고 기록하는, 경제학과 출신 개발자의 노트

학습일지/AI

Ray Summit 2023 - Fast LLM Serving with vLLM and PagedAttention

inspirit941 2024. 2. 5. 18:12
반응형

Fast LLM Serving with vLLM and PagedAttention

https://youtu.be/5ZlavKF_98U?si=sjZ31eHwRAClmx7a

 

권우석(woosuk.kwon). Berkley Ph.D Student

스크린샷 2024-02-02 오후 4 38 05

 

LLM 기반 Application이 많이 등장함. Chat, Programming, CopyWriting...

  • 도메인은 다양하지만 결국 LLM Serving이 핵심인 서비스들. LLM Speed / Cost 영향을 크게 받는다.
  • 따라서 Serve Fast / Cost effcient 가 중요한 과제가 되었음

스크린샷 2024-02-02 오후 5 11 51

 

지금 LLM은 굉장히 비싼 몸.

  • High-End GPU를 '많이' 필요함.
  • 각각의 GPU가 handling할 수 있는 request는 매우 적음
    • NVidia A100 1개가 TPS 1도 안 됨.

KV Cache in LLM Inference Process

스크린샷 2024-02-02 오후 5 15 37

 

Inference Process를 되짚어보자.

  • 사용자가 prompt 포함된 query를 하면, Possible Next Token 결과를 받아서 계속 모델에 입력으로 넣는 식.
    • Max Token 제한에 걸리거나, <|end of sentense|> 같은 문장 종결토큰이 모델 결과로 등장할 때까지 반복됨

스크린샷 2024-02-02 오후 5 18 40스크린샷 2024-02-02 오후 5 19 13

 

Inference Process의 unique component로 KV Cache라는 게 있다.

  • 'Next token Prediction'을 수행할 때, 단순히 '직전 토큰'만 쓰는 게 아니라 All Previous Token 정보가 필요함.
  • Previous Token 정보를 저장하는 공간이 KV Cache.

따라서 KV Cache는 Sequence가 길어질수록 많은 공간을 차지하고, 연산이 끝나면 줄어든다.

vLLM: Efficiently Managing KV Cache

스크린샷 2024-02-02 오후 5 25 26

 

즉, KV Cache를 효과적으로 관리하는 것이 LLM Serving Throughput의 핵심이다.

  • 예컨대 A100 40GB 메모리에 LLM을 올린다고 가정하면
    • 파라미터가 26GB, KV Cache에 12GB를 쓴다.
  • KV Cache를 효율적으로 쓰지 못하는 LLM 모델이 많았음. 그래서 request가 증가할 때 Memeory Usage 상승률이 높았다.

vLLM은 KV Cache 사용량을 최적화해서, GPU의 메모리를 보다 효율적으로 사용할 수 있게끔 고안되었다.

  • 더 높은 Throughput을 지원한다.

KV Cache에서 정확히 뭐가 문제였나

스크린샷 2024-02-02 오후 5 28 58

 

기존 LLM serving에서 메모리 효율성을 떨어뜨리는 세 가지 영역

  • Internal fragmentation: sequence 연산 때문에 할당되었지만, 실제로는 안 쓰인 메모리 공간.
    • 모델이 token을 얼마나 생성할지 알 수 없기 때문에 발생함
  • Reservation: 지금은 sequence 연산에 안쓰이지만, 곧 쓰이게 될 메모리 공간
  • External fragmentation: 요청마다 들어오는 sequence 길이가 달라서 발생하는 메모리 공간

프로파일링 해본 바로는, 20~40% 정도의 KV Cache가 실제로 token state 저장을 위해 쓰임.

vLLM은 어떻게 했나: PagedAttention

스크린샷 2024-02-02 오후 5 32 51

 

OS에서 쓰이는 virtual Memory + paging 개념을 KV Cache에 적용

  • OS는 fragmentation을 낮추기 위해 paging 기법을 쓰고 있고
  • Process 간 efficient / elegant space multplexing을 위해 virtual memory 개념을 사용함

이걸 가능하게 한 것이 PagedAttention

스크린샷 2024-02-02 오후 5 35 30

 

KV Cache 공간을 paging한 것처럼, KV block으로 구분한다.

  • KV Block: fized-size contiguous chunk of memory that stores KV cache from left to right.
    • block size: 하나의 Block에 얼마나 많은 토큰이 들어갈 수 있는지 결정하는 값

스크린샷 2024-02-05 오후 2 32 28

 

즉, KV Cache를 쓰기 위해 'contiguous space'가 필요했던 구조적 한계를 개선하는 것.

  • input과 output이 static할 경우 contiguous space가 효율적이지만, LLM은 그렇지 않다.
  • KV Cache는 block 단위로 나뉘어서 임의의 메모리 공간에 저장하고, 필요할 때 가져오는 방식.

스크린샷 2024-02-05 오후 3 06 39

 

Virtualize KV Cache into logical / physical KB Block도 가능하다.

예컨대 사용자가 input으로 'Alan Turing is a computer scientist" 라고 넣으면

  • logical KV Block: order 정보를 포함하는 consecutive block
  • physical KV Block: adjacent할 필요 없이, KB Block 특정 공간에 저장됨

consecutive 정보는 일종의 Block Table에서 관리한다. physical block number 정보를 저장한 mapping table을 관리하는 식.

스크린샷 2024-02-05 오후 3 22 16

 

logical block에 new token이 생성되면 physical block에도 저장되고

block 공간이 차면, 다른 physical block을 매핑해서 진행하는 식.

  • 즉, 기존 방식과 달리 "On-demand" 로 메모리 공간을 할당한다.

스크린샷 2024-02-05 오후 3 23 16

 

serving multiple request도 똑같다. os가 메모리 관리하는 것과 근본적으로는 똑같기 때문

How much Efficient?

스크린샷 2024-02-05 오후 4 11 36

 

Minimal Internal Fragmentation

  • last block of sequence에서만 발생. wasted token 개수는 block size를 넘지 않는다.
    • 보통 token 개수는 100 ~ 1000까지 다양한데, block size는 16 or 32 정도로 설정함.
  • waste space를 4% 수준으로 낮춤 -> increase throughput.

vLLM: Enables input prompt sharing

스크린샷 2024-02-05 오후 5 03 42

 

위 예시는 Parallel Sampling. multiple output을 응답하는 형태.

  • input으로 들어온 문장은 여러 Output process가 공유해서 쓸 수 있다.
  • Chat보다는 github copilot처럼 여러 개의 웅답 후보군을 준비해야 하는 경우에 유용함

스크린샷 2024-02-05 오후 5 10 35스크린샷 2024-02-05 오후 5 10 54

 

구체적인 동작 방식

  • physical block은, 본인은 reference하는 logical block 개수를 저장한다.
  • new token을 입력할 때, physical block의 reference count를 보고
    • 1보다 클 경우, copy-on-write 방식으로 다른 physical block에 복사한 후 new token 정보를 추가한다. ref count는 1 줄어든다.
    • 1일 경우, physical block에 직접 쓴다.

vLLM: complicated decoding like beam search

스크린샷 2024-02-05 오후 5 20 17

 

beam search: 가장 정확도 높은 machine translation을 찾아주는 기능.

  • 동작 방식이 parallel sharing과 똑같다. 가장 나은 translation 문장을 생성하는 방식이 똑같기 때문.
  • OS에서 process tree (fork / kill) 하는 것과 비슷함.

Summarize

스크린샷 2024-02-05 오후 5 21 18

PagedAttention 기능을 사용해서 메모리 사용량을 효율화

  • Memory Fragmentation 비율을 낮췄옴.
  • Memory Sharing 활성화.

스크린샷 2024-02-05 오후 5 42 36

 

huggingface.generate 방식으로 모델 가져와서 쓴 것보다 성능이 월등히 낫다.

  • PagedAttention 없던 시절의 TGI (text generation inference)보다도 나음.

스크린샷 2024-02-05 오후 5 43 58스크린샷 2024-02-05 오후 5 44 09

 

우린 지원되는 모델도 많고, 주목받는 오픈소스 중 하나다

스크린샷 2024-02-05 오후 5 52 30

 

System Architecture / Implementation

스크린샷 2024-02-05 오후 5 27 24

 

  • Centralized vLLM Engine: deals with Block table.
    • iteration마다 GPU workers에 memory command 전달.
  • gpu block allocator가 physical block 관리

vLLM 자체는 python project이고, PagedAttention 로직 일부는 cuda code.

  • Megatron-LM for distributed Execution
  • huggingface / pytorch
  • Ray for cluster management (control plane communication)

Powering Vicuna & Chatbot Arena

스크린샷 2024-02-05 오후 5 44 34

 

오픈소스 공개 이전 시점에서 진행했던 것

  • LLaMA-based Model 사용한 Serving
    • 40K conversation per Day
    • GPU 개수 50% 줄이고도 서빙 가능
    • serving 속도는 2x ~ 3x 빠름

Adopters

스크린샷 2024-02-05 오후 5 47 32스크린샷 2024-02-05 오후 5 48 05스크린샷 2024-02-05 오후 5 48 54

 

많은 곳에서 쓰고 있다.

PagedAttention 자체가 업계 표준이 되고 있는 추세.

How to use?

스크린샷 2024-02-05 오후 5 50 02

 

offlien batch inference 예시

  • prompt list를 넣어주면, 알아서 batching process 진행한다.

스크린샷 2024-02-05 오후 5 50 59

 

for online serving 예시: with FastAPI

  • openAI의 api format과 동일한 interface 지원

Q. recurrent 방식의 Neural Network도 PagedAttention 쓸 수 있는가?

  • 된다고 생각함. 결국 memory management는 필요하고, output length를 생성 시점에서 알 수 없는 건 똑같기 때문.
  • 물론, Attention 방식을 안 쓴 모델은 적용 안 된다 ㅎㅎ

Q. memory problem을 어떻게 인지했나 (원문: How do you identify the memory problem)

  • 오픈소스 활성화가 덜 된 시점에서 LLM Serving 시스템 직접 만들어야 했고, Reduce latency보다는 high throughput을 목표로 했었다. (그게 더 비용효율적이었음) batch size를 늘려야 했고, 그러다보니 문제를 발견했다.
  • 그 당시의 memory management 방식은 전부 비효율적이었다.
  • Hands-on experience였음 ㅎㅎ

Q. Cache misses 같은 버그? 가 존재하는가?

  • 불가능하다. Attention 동작방식 자체가 'all previous words'를 받아서 computation 하는 구조. 연산 중 특정 구간의 missing이 발생하지 않는다

Q. PagedAttention 기법이 TGI 같은 기존 serving platform에도 적용되거나 그럴 예정인 듯한데, 그럼에도 vLLM을 써야 하는 이유가 있다면?

  • 우리는 Memory Sharing도 있다 (TGI에서는 아직 이게 없다)
  • Optimization 잘되어 있다 (TGI 대비 성능표)
  • 우리 Apache2 라이센스다 ㅎㅎ

Q. Sharing Prefix across different request 같은, 다른 기능을 테스트하거나 계획중인 게 있는지?

  • sharing prefix는 된다. 가능하다. experiment in paper에 있음.
  • 아직 engineering issue 때문에 branch merge는 안 되어 있지만, 될 거다

Q. Throughput에 집중했는데, Latency는?

  • Throughput을 늘리는 게 비용 효율적이어서 우선순위가 높았고
  • Latency의 경우 크게 두 가지 카테고리로 개선점을 잡을 수 있는데
    • Pure Optimization. i.e. Kernel Fusion? 같은 거... 언젠간 반영될 거다.
    • Tradeoff btwn Latency / Throughput. -> 조심스럽게 접근할 이슈라고 본다
      • speculative decoding 같은 거.
  • 일단 우리는 첫 번째 step에 집중하고 있다.
반응형