vLLM PagedAttention으로 오픈소스 LLM 추론 GPU VRAM 효율 3배 높이기

오픈소스 LLM(Llama 3, Mistral 등)을 실제 서비스에 도입할 때 가장 큰 걸림돌은 GPU 메모리 관리입니다. 고가의 H100이나 A100을 사용하더라도 동시 접속자가 늘어나면 금세 'Out of Memory(OOM)' 에러가 발생하거나, 요청 대기 시간이 기하급수적으로 늘어납니다. 이는 모델 파라미터 자체보다 추론 과정에서 생성되는 KV(Key-Value) 캐시가 메모리를 비효율적으로 점유하기 때문입니다.

vLLM은 운영체제의 가상 메모리 관리 기법에서 영감을 얻은 PagedAttention 알고리즘을 통해 이 문제를 해결했습니다. 메모리를 물리적으로 연속되게 할당하지 않고 필요한 만큼만 블록 단위로 할당하여, 낭비되는 메모리(Internal Fragmentation)를 0%에 가깝게 줄여줍니다. 이를 통해 동일한 GPU 자원에서 기존 HuggingFace Transformers 대비 최대 24배, 일반적인 최적화 엔진 대비 3~4배 높은 처리량(Throughput)을 확보할 수 있습니다.

TL;DR — vLLM의 PagedAttention은 KV 캐시를 불연속적인 메모리 블록에 할당하여 파편화를 방지합니다. 이를 통해 GPU VRAM 활용도를 90% 이상으로 끌어올리고 서비스 처리량을 비약적으로 향상시킬 수 있습니다.

목차

PagedAttention의 핵심 원리와 메모리 혁신

기존 LLM 추론 방식은 한 문장을 생성할 때 필요한 KV 캐시를 메모리에 미리 '연속적인 공간'으로 할당해야 했습니다. 하지만 문장의 길이는 매번 다르기 때문에, 최악의 경우(최대 토큰 길이)를 대비해 큰 공간을 예약해두어야 했습니다. 이 과정에서 실제로 사용되지 않는 메모리가 60~80%에 달하는 심각한 낭비가 발생했습니다.

vLLM은 이를 해결하기 위해 PagedAttention을 도입했습니다. 이는 메모리를 고정된 크기의 '페이지(Page)'로 나누고, 필요할 때마다 동적으로 할당하는 방식입니다. 물리적으로는 떨어져 있는 메모리 블록들을 논리적으로 연결하여 마치 연속된 공간인 것처럼 사용합니다. 결과적으로 메모리 파편화가 거의 사라지며, 남는 공간에 더 많은 요청(Batch)을 동시에 태울 수 있게 됩니다.

💡 비유로 이해하기:
기존 방식이 100명이 올지 1명이 올지 모르는 예약 손님을 위해 무조건 100인석 테이블을 비워두는 것이라면, PagedAttention은 손님이 오는 대로 빈 의자를 하나씩 붙여서 자리를 만들어주는 효율적인 식당 운영 방식과 같습니다.

vLLM 도입이 반드시 필요한 시나리오

첫째, 온프레미스 환경에서 한정된 GPU 자원을 운영할 때입니다. 클라우드와 달리 자원 확장이 즉각적이지 않은 상황에서 vLLM은 기존 장비의 한계를 돌파하게 해줍니다. 특히 Llama 3 70B와 같은 대형 모델을 다수의 유저에게 서빙해야 한다면 vLLM은 선택이 아닌 필수입니다.

둘째, 실시간 스트리밍 응답과 높은 처리량이 동시에 요구될 때입니다. 챗봇 서비스나 실시간 요약 서비스처럼 지연 시간(Latency)이 짧으면서도 수백 명의 동시 접속을 처리해야 하는 경우, vLLM의 'Continuous Batching' 기술은 개별 요청이 끝날 때까지 기다리지 않고 새로운 요청을 즉시 처리 프로세스에 끼워 넣어 GPU의 유휴 시간을 제거합니다.

vLLM 서버 구축 및 실전 최적화 방법

vLLM은 Python 환경에서 간편하게 설치하고 OpenAI 호환 API 서버를 띄울 수 있습니다. CUDA 12.1 이상 환경을 권장하며, 다음 명령어로 설치를 시작합니다.

pip install vllm

설치가 완료되면 Python 코드로 직접 모델을 로드하거나, 아래와 같이 CLI를 통해 즉시 API 서버를 구동할 수 있습니다. --gpu-memory-utilization 옵션은 vLLM이 점유할 VRAM 비율을 결정하는 핵심 파라미터입니다.

# Llama-3 8B 모델을 사용하여 API 서버 실행
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Meta-Llama-3-8B-Instruct \
    --max-model-len 4096 \
    --gpu-memory-utilization 0.9 \
    --port 8000

이제 http://localhost:8000/v1/completions 엔드포인트를 통해 OpenAI SDK와 호환되는 방식으로 추론 요청을 보낼 수 있습니다. vLLM은 내부적으로 PagedAttention을 통해 인입되는 요청들을 최적으로 배치 처리합니다.

실전 운영 시 주의사항 및 트러블슈팅

가장 자주 접하는 문제는 '최대 문맥 길이(Max Model Len) 설정 오류'입니다. vLLM은 실행 시점에 지정된 max_model_len에 맞춰 미리 KV 캐시 블록을 예약합니다. 이 값이 너무 크면 정작 모델 파라미터를 올릴 메모리가 부족해져 RuntimeError: Out of memory가 발생합니다. 반대로 너무 작으면 긴 문장 입력 시 잘림 현상이 발생하므로, 서비스 특성에 맞는 적절한 합의점을 찾아야 합니다.

또한, 여러 개의 프로세스가 GPU를 공유하는 환경에서는 주의가 필요합니다. vLLM은 기본적으로 사용 가능한 VRAM의 90%를 선점하려고 시도합니다. 만약 다른 프로세스(예: 모니터링 툴, 다른 모델 서버)가 같은 GPU를 쓰고 있다면 충돌이 발생합니다. 이럴 때는 아래와 같이 비율을 조정해야 합니다.

⚠️ 가장 자주 하는 실수:
멀티 GPU 환경에서 tensor_parallel_size를 설정하지 않으면 모델이 하나의 GPU에만 올라가 OOM이 발생할 수 있습니다. 70B 모델의 경우 최소 2~4개의 GPU로 분산해야 합니다.
# 2개의 GPU를 사용하여 분산 추론 실행
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Meta-Llama-3-70B \
    --tensor-parallel-size 2

성능 극대화를 위한 하이퍼파라미터 팁

성능을 쥐어짜기 위해서는 block_size 옵션을 조정해 볼 수 있습니다. 기본값은 16이지만, 메모리 효율을 더 극대화하려면 8이나 32로 변경하며 테스트하십시오. 또한 max_num_seqs(동시 처리 시퀀스 수)를 늘리면 처리량은 증가하지만 개별 요청의 응답 속도(Latency)는 소폭 느려질 수 있으므로 서비스의 우선순위에 따라 튜닝해야 합니다.

📌 핵심 요약
  • PagedAttention은 KV 캐시 메모리 낭비를 제거하여 GPU 효율을 극대화함.
  • 동일 GPU에서 Transformers 대비 처리량 3~4배 이상 향상 가능.
  • --gpu-memory-utilization으로 메모리 점유율을 정밀하게 제어할 것.
  • 대형 모델은 --tensor-parallel-size를 통해 여러 GPU에 분산 로드.

Frequently Asked Questions

Q. vLLM은 모든 오픈소스 모델을 지원하나요?

A. Llama, Mistral, Falcon, Mixtral 등 대부분의 인기 있는 아키텍처를 지원합니다. 최신 모델은 릴리즈 노트에서 지원 여부를 확인하세요.

Q. PagedAttention을 쓰면 답변의 정확도가 떨어지나요?

A. 아니요. PagedAttention은 메모리 관리 알고리즘일 뿐, 모델의 연산 결과(Attention Score) 자체를 변경하지 않으므로 정확도는 동일합니다.

Q. NVIDIA GPU 외에 다른 가속기에서도 동작하나요?

A. 현재 ROCm(AMD GPU)과 AWS Inferentia 등에 대한 지원이 확장되고 있지만, NVIDIA CUDA 환경에서 가장 안정적이고 빠릅니다.

Post a Comment