vLLM 퀵스타트: 2026 년 고성능 LLM 서비스

OpenAI API 를 활용한 고속 LLM 추론

Page content

vLLM는 UC 버클리 Sky Computing Lab 에서 개발한 대규모 언어 모델 (LLM) 을 위한 고속 처리 및 메모리 효율적인 추론 및 서비스 엔진입니다.

혁신적인 PagedAttention 알고리즘을 통해 vLLM 은 기존 서비스 방식 대비 14~24 배 높은 처리량을 달성하여 생산 환경의 LLM 배포를 위한 최적의 선택지가 되었습니다. vLLM 이 Ollama, Docker Model Runner, LocalAI 및 클라우드 제공업체 (비용 및 인프라 절충안 포함) 와 비교하여 어디에 위치하는지 확인하려면 LLM 호스팅: 로컬, 자체 호스팅 및 클라우드 인프라 비교를 참조하세요.

vllm 로고

vLLM 이란 무엇인가요?

vLLM(가상 LLM) 은 빠르고 효율적인 LLM 추론 및 서비스를 위한 오픈소스 라이브러리로, 생산 환경 배포를 위한 업계 표준으로 빠르게 자리 잡았습니다. 2023 년에 출시된 vLLM 은 서비스 효율성을 극적으로 향상시키는 획기적인 메모리 관리 기법인 PagedAttention를 도입했습니다.

주요 기능

높은 처리량 성능: vLLM 은 동일한 하드웨어 환경에서 HuggingFace Transformers 대비 14~24 배 높은 처리량을 제공합니다. 이 막대한 성능 향상은 연속 배치 (continuous batching), 최적화된 CUDA 커널, 그리고 메모리 조각화를 제거하는 PagedAttention 알고리즘에서 비롯됩니다.

OpenAI API 호환성: vLLM 은 OpenAI 형식과 완전히 호환되는 내장 API 서버를 제공합니다. 이를 통해 애플리케이션 코드를 변경하지 않고 OpenAI 에서 자체 호스팅 인프라로 원활하게 마이그레이션할 수 있습니다. 단순히 API 클라이언트의 엔드포인트를 vLLM 으로만 변경하면 투명하게 작동합니다.

PagedAttention 알고리즘: vLLM 의 성능 뒤에는 PagedAttention 이라는 핵심 혁신이 있습니다. 이는 가상 메모리 페이지링 개념을 어텐션 메커니즘에 적용한 것입니다. KV 캐시를 위해 연속된 메모리 블록을 할당하면 메모리 조각화가 발생하는 대신, PagedAttention 은 메모리를 고정 크기의 블록으로 나누어 필요할 때 할당합니다. 이를 통해 메모리 낭비를 최대 4 배 줄이고 훨씬 더 큰 배치 크기를 가능하게 합니다.

연속 배치 (Continuous Batching): 모든 시퀀스가 완료될 때까지 기다리는 고정 배치와 달리 vLLM 은 연속 (롤링) 배치를 사용합니다. 하나의 시퀀스가 완료되는 즉시 새로운 시퀀스가 배치에 추가될 수 있어 GPU 활용도를 극대화하고 incoming 요청에 대한 지연 시간을 최소화합니다.

멀티 GPU 지원: vLLM 은 텐서 병렬 처리 및 파이프라인 병렬 처리를 지원하여 대규모 모델을 여러 GPU 에 분산시킬 수 있습니다. 단일 GPU 메모리에 맞지 않는 모델도 효율적으로 서비스하며 2 개에서 8 개 이상의 GPU 에 이르는 구성을 지원합니다.

광범위한 모델 지원: LLaMA, Mistral, Mixtral, Qwen, Phi, Gemma 등 인기 있는 모델 아키텍처와 호환되며 HuggingFace Hub 의 인struction 튜닝 모델 및 기본 모델 모두를 지원합니다.

vLLM 사용 시기

vLLM 은 다음과 같은 특정 시나리오에서 그 강점을 발휘합니다:

생산 환경 API 서비스: API 를 통해 많은 동시 사용자에게 LLM 을 제공해야 할 때, vLLM 의 높은 처리량과 효율적인 배치 기능은 최고의 선택입니다. 챗봇, 코드 어시스턴트 또는 콘텐츠 생성 서비스를 운영하는 기업은 초당 수백 건의 요청을 처리할 수 있는 능력으로 혜택을 봅니다.

고동시성 워크로드: 애플리케이션에 많은 동시 사용자가 요청을 보내는 경우, vLLM 의 연속 배치 및 PagedAttention 을 사용하면 동일한 하드웨어로 대체재보다 더 많은 사용자를 서비스할 수 있습니다.

비용 최적화: GPU 비용이 우려되는 경우 vLLM 의 우수한 처리량으로 적은 수의 GPU 로도 동일한 트래픽을 처리할 수 있어 인프라 비용을 직접적으로 절감할 수 있습니다. PagedAttention 의 4 배 메모리 효율성은 더 작고 저렴한 GPU 인스턴스 사용도 가능하게 합니다.

Kubernetes 배포: vLLM 의 상태 없는 (stateless) 디자인과 컨테이너 친화적 아키텍처는 Kubernetes 클러스터에 이상적입니다. 부하 하에서도 일관된 성능과 직관적인 리소스 관리는 클라우드 네이티브 인프라와 잘 통합됩니다.

vLLM 을 사용하지 않는 경우: 로컬 개발, 실험, 또는 단일 사용자 시나리오의 경우 Ollama 나 llama.cpp와 같은 도구가 더 간단한 설정으로 더 나은 사용자 경험을 제공합니다. vLLM 의 복잡성은 생산 워크로드에서 성능 이점을 활용해야 할 때 정당화됩니다.

vLLM 설치 방법

사전 요구사항

vLLM 을 설치하기 전에 시스템이 다음 요구사항을 충족하는지 확인하세요:

  • GPU: 계산 능력 7.0+ 를 갖춘 NVIDIA GPU(V100, T4, A10, A100, H100, RTX 20/30/40 시리즈)
  • CUDA: 버전 11.8 이상
  • Python: 3.8 ~ 3.11
  • VRAM: 7B 모델 최소 16GB, 13B 모델 24GB 이상, 대형 모델 40GB 이상
  • 드라이버: NVIDIA 드라이버 450.80.02 이상

pip 를 통한 설치

가장 간단한 설치 방법은 pip 를 사용하는 것입니다. CUDA 11.8 이상 시스템에서 작동합니다:

# 가상 환경 생성 (권장)
python3 -m venv vllm-env
source vllm-env/bin/activate

# vLLM 설치
pip install vllm

# 설치 확인
python -c "import vllm; print(vllm.__version__)"

다른 CUDA 버전을 사용하는 시스템의 경우 적절한 휠을 설치하세요:

# CUDA 12.1용
pip install vllm==0.4.2+cu121 -f https://github.com/vllm-project/vllm/releases

# CUDA 11.8용
pip install vllm==0.4.2+cu118 -f https://github.com/vllm-project/vllm/releases

Docker 를 통한 설치

Docker 는 특히 생산 환경에서 가장 안정적인 배포 방법을 제공합니다:

# 공식 vLLM 이미지 가져오기
docker pull vllm/vllm-openai:latest

# GPU 지원으로 vLLM 실행
docker run --runtime nvidia --gpus all \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    -p 8000:8000 \
    --ipc=host \
    vllm/vllm-openai:latest \
    --model mistralai/Mistral-7B-Instruct-v0.2

--ipc=host 플래그는 멀티 GPU 설정에서 올바른 프로세스 간 통신을 가능하게 하므로 중요합니다.

소스 빌드

최신 기능이나 커스텀 수정을 위해 소스에서 빌드하세요:

git clone https://github.com/vllm-project/vllm.git
cd vllm
pip install -e .

vLLM 빠른 시작 가이드

첫 모델 실행

명령줄 인터페이스를 사용하여 모델로 vLLM 을 시작하세요:

# OpenAI 호환 API 로 Mistral-7B 다운로드 및 서비스
python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2 \
    --port 8000

vLLM 은 HuggingFace Hub 에서 모델을 자동으로 다운로드 (캐시되지 않은 경우) 하고 서버를 시작합니다. 서버 준비가 완료되었다는 출력을 볼 수 있습니다:

INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000

API 요청 보내기

서버가 실행되면 OpenAI Python 클라이언트 또는 curl 을 사용하여 요청을 보낼 수 있습니다:

curl 사용:

curl http://localhost:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "mistralai/Mistral-7B-Instruct-v0.2",
        "prompt": "vLLM 이 무엇인지 한 문장으로 설명해주세요:",
        "max_tokens": 100,
        "temperature": 0.7
    }'

OpenAI Python 클라이언트 사용:

from openai import OpenAI

# vLLM 서버로 연결
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"  # vLLM 은 기본적으로 인증이 필요하지 않습니다
)

response = client.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    prompt="vLLM 이 무엇인지 한 문장으로 설명해주세요:",
    max_tokens=100,
    temperature=0.7
)

print(response.choices[0].text)

채팅 완료 API:

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[
        {"role": "system", "content": "도움이 되는 어시스턴트입니다."},
        {"role": "user", "content": "PagedAttention 이 무엇인가요?"}
    ],
    max_tokens=200
)

print(response.choices[0].message.content)

고급 설정

vLLM 은 성능을 최적화하기 위한 수많은 매개변수를 제공합니다:

python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2 \
    --port 8000 \
    --gpu-memory-utilization 0.95 \  # GPU 메모리의 95% 사용
    --max-model-len 8192 \            # 최대 시퀀스 길이
    --tensor-parallel-size 2 \        # 텐서 병렬 처리로 GPU 2 개 사용
    --dtype float16 \                 # FP16 정밀도 사용
    --max-num-seqs 256                # 최대 배치 크기

주요 매개변수 설명:

  • --gpu-memory-utilization: GPU 메모리 사용 비율 (0.90 = 90%). 더 높은 값은 더 큰 배치를 허용하지만 메모리 급증에 대한 여유를 덜 둡니다.
  • --max-model-len: 최대 컨텍스트 길이. 이를 줄이면 더 큰 배치에 메모리를 절약할 수 있습니다.
  • --tensor-parallel-size: 모델을 분산시킬 GPU 수입니다.
  • --dtype: 가중치 데이터 유형 (float16, bfloat16, float32). FP16 이 일반적으로 최적입니다.
  • --max-num-seqs: 배치에서 처리할 최대 시퀀스 수입니다.

vLLM 대 Ollama 비교

vLLM 과 Ollama 모두 로컬 LLM 호스팅을 위한 인기 있는 선택지이지만, 서로 다른 사용 사례를 목표로 합니다. 각 도구를 언제 사용해야 하는지 이해하는 것은 프로젝트 성공에 큰 영향을 미칩니다.

성능 및 처리량

vLLM은 다중 사용자 시나리오에서 최대 처리량을 위해 설계되었습니다. PagedAttention 과 연속 배치를 통해 동시 요청 수백 건을 효율적으로 처리할 수 있습니다. 벤치마크에 따르면 vLLM 은 표준 구현 대비 1424 배, 고도 동시성 환경에서 Ollama 대비 24 배 더 높은 처리량을 달성합니다.

Ollama는 단일 사용자 인터랙티브 사용에 최적화되어 개별 요청에 대한 낮은 지연 시간을 강조합니다. vLLM 의 다중 사용자 처리량에는 미치지 못하지만, 빠른 콜드 스타트 시간과 낮은 유휴 리소스 소비로 개발 및 개인 사용에 탁월한 성능을 제공합니다.

사용 편의성

Ollama는 단순성에서 압도적으로 앞서 있습니다. 설치란 단일 명령어 (curl | sh) 로 끝나며, 모델 실행도 ollama run llama2만큼 간단합니다. 다양한 하드웨어 프로필에 최적화된 양자화된 버전이 포함된 모델 라이브러리를 제공합니다. 사용자 경험은 Docker 를 연상시킵니다. - 가져오고, 실행하고, 시작합니다.

vLLM은 더 많은 설정이 필요합니다: Python 환경 관리, CUDA 설치, 서비스 매개변수 이해, 수동 모델 지정 등. 학습 곡선이 가파르지만 성능 최적화에 대한 세밀한 제어를 얻습니다. 이 복잡성은 하드웨어에서 최대 성능을 끌어내야 하는 생산 배포를 위해 정당화됩니다.

API 및 통합

vLLM은 바로 사용할 수 있는 OpenAI 호환 REST API 를 제공하여 기존 애플리케이션에서 OpenAI API 를 대체할 수 있습니다. 이는 애플리케이션 코드 변경 없이 클라우드 제공업체에서 자체 호스팅 인프라로 생산 서비스를 마이그레이션하는 데 중요합니다.

Ollama는 간단한 REST API 와 전용 Python/JavaScript 라이브러리를 제공합니다. 기능은 있지만 OpenAI 호환이 아니므로 OpenAI 형식을 기대하는 애플리케이션 통합 시 코드 변경이 필요합니다. 다만, Ollama-OpenAI 어댑터와 같은 커뮤니티 프로젝트가 이 격차를 메꿉니다.

메모리 관리

vLLM의 PagedAttention 알고리즘은 동시 요청을 위해 우수한 메모리 효율성을 제공합니다. 동일한 VRAM 으로 순환한 구현 대비 2~4 배 더 많은 동시 사용자를 서비스할 수 있습니다. 이는 생산 배포에서 비용 절감으로 직접적으로 이어집니다.

Ollama는 단일 사용자 시나리오에 적합한 단순한 메모리 관리를 사용합니다. 활동에 따라 모델 로딩/언로딩을 자동으로 관리하여 개발에는 편리하지만, 고도 동시성 생산 사용에는 최적이지 않습니다.

멀티 GPU 지원

vLLM은 네이티브 텐서 병렬 처리 및 파이프라인 병렬 처리로 2~8 개 이상의 GPU 에 걸쳐 모델을 효율적으로 분산합니다. 이는 단일 GPU 에 fitting 하지 않은 70B 파라미터 LLM 과 같은 대형 모델을 서비스하는 데 필수적입니다.

Ollama는 현재 멀티 GPU 지원이 제한적이며, 주로 단일 GPU 에서 가장 잘 작동합니다. 이는 분산 추론이 필요한 매우 대형 모델에는 덜 적합합니다.

사용 사례 권장 사항

vLLM 을 선택할 때:

  • 많은 동시 사용자를 위한 생산 API 서비스 제공
  • 클라우드 배포에서 요청당 비용 최적화
  • Kubernetes 또는 컨테이너 오케스트레이션 플랫폼 실행
  • 기존 애플리케이션을 위한 OpenAI API 호환성 필요
  • 멀티 GPU 지원이 필요한 대형 모델 서비스
  • 성능 및 처리량이 핵심 요구사항

Ollama 를 선택할 때:

  • 로컬 개발 및 실험
  • 단일 사용자 인터랙티브 사용 (개인 어시스턴트, 챗봇)
  • 빠른 프로토타이핑 및 모델 평가
  • 인프라 복잡성 없이 LLM 학습
  • 개인 워크스테이션 또는 노트북 실행
  • 단순성과 사용 편의성이 우선시될 때

많은 팀이 둘 다 사용합니다: 개발 및 실험에는 Ollama 를, 생산 배포에는 vLLM 을 사용합니다. 이 조합은 개발자 생산성을 유지하면서 생산 성능을 보장합니다.

vLLM 대 Docker Model Runner 비교

Docker 는 최근 로컬 AI 모델 배포를 위한 공식 솔루션인 Model Runner(구 GenAI Stack) 를 도입했습니다. 이것이 vLLM 과 어떻게 비교되나요?

아키텍처 철학

Docker Model Runner는 “AI 를 위한 Docker"가 되는 것을 목표로 합니다. 컨테이너 실행만큼이나 쉬운 방식으로 로컬에서 AI 모델을 실행하는 단순하고 표준화된 방법입니다. 복잡성을 추상화하고 다양한 모델 및 프레임워크에 걸쳐 일관된 인터페이스를 제공합니다.

vLLM은 최대 성능을 위한 LLM 서비스에만 특화된 특수 추론 엔진입니다. Docker 로 컨테이너화하는 저수준 도구이지, 완전한 플랫폼이 아닙니다.

설정 및 시작

Docker Model Runner 설치는 Docker 사용자에게 간단합니다:

docker model pull llama3:8b
docker model run llama3:8b

이것은 Docker 이미지 워크플로우와 유사하여 이미 컨테이너를 사용하는 개발자에게 즉시 익숙합니다.

vLLM은 더 많은 초기 설정 (Python, CUDA, 의존성) 이 필요하거나 사전 빌드 Docker 이미지를 사용할 수 있습니다:

docker pull vllm/vllm-openai:latest
docker run --runtime nvidia --gpus all vllm/vllm-openai:latest --model <model-name>

성능 특징

vLLM은 PagedAttention 과 연속 배치로 인해 다중 사용자 시나리오에서 우수한 처리량을 제공합니다. 초당 수백 건의 요청을 처리하는 생산 API 서비스의 경우, vLLM 의 최적화는 범용 서비스 접근법 대비 2~5 배 더 나은 처리량을 제공합니다.

Docker Model Runner는 최대 성능보다 사용 편의성에 중점을 둡니다. 로컬 개발, 테스트 및 중간 워크로드에 적합하지만, vLLM 이 규모에서 뛰어날 수 있게 하는 고급 최적화를 구현하지는 않습니다.

모델 지원

Docker Model Runner는 인기 있는 모델에 대한 원클릭 액세스가 포함된 선별된 모델 라이브러리를 제공합니다. Stable Diffusion, Whisper 및 기타 AI 모델을 포함한 여러 프레임워크 (LLM 만 아님) 를 지원하여 다른 AI 워크로드에 대해 더 다재다능합니다.

vLLM은 트랜스포머 기반 언어 모델에 대한 깊은 지원으로 LLM 추론에 특화되어 있습니다. HuggingFace 호환 LLM 은 모두 지원하지만 이미지 생성이나 음성 인식과 같은 다른 AI 모델 유형으로 확장되지 않습니다.

생산 배포

vLLM은 Anthropic, Replicate 및 수십억 토큰을 매일 서비스하는 많은 다른 회사에서 생산 환경에서 테스트되었습니다. 성능 특징과 무거운 부하 하에서의 안정성은 생산 LLM 서비스의 사실상 표준입니다.

Docker Model Runner는 신규이며 개발 및 로컬 테스트 시나리오에 더 중점을 둡니다. 생산 트래픽을 처리할 수 있지만, 생산 배포가 요구하는 검증된 성과 기록 및 성능 최적화는 부족합니다.

통합 생태계

vLLM은 Kubernetes 연산자, Prometheus 메트릭, 분산 서비스를 위한 Ray 및 기존 애플리케이션을 위한 광범위한 OpenAI API 호환성 등 생산 인프라 도구와 통합됩니다.

Docker Model Runner는 Docker 생태계 및 Docker Desktop 과 자연스럽게 통합됩니다. Docker 에 이미 표준화된 팀에게는 일관된 경험을 제공하지만, 특수화된 LLM 서비스 기능은 적습니다.

각각 사용 시기

vLLM 을 사용할 때:

  • 생산 LLM API 서비스
  • 고처리량, 다중 사용자 배포
  • 최대 효율성이 필요한 비용 민감 클라우드 배포
  • Kubernetes 및 클라우드 네이티브 환경
  • 검증된 확장성 및 성능이 필요할 때

Docker Model Runner 를 사용할 때:

  • 로컬 개발 및 테스트
  • 다양한 AI 모델 유형 실행 (LLM 만 아님)
  • Docker 생태계에 깊이 투자된 팀
  • 인프라 설정 없이 빠른 실험
  • 학습 및 교육 목적

하이브리드 접근법: 많은 팀이 편의를 위해 로컬에서 Docker Model Runner 로 개발한 후, 성능을 위해 생산에서 vLLM 으로 배포합니다. Docker Model Runner 이미지를 사용하여 vLLM 컨테이너를 실행할 수도 있어 두 가지 접근법을 결합할 수 있습니다.

생산 배포 모범 사례

Docker 배포

생산 준비된 Docker Compose 구성을 만드세요:

version: '3.8'

services:
  vllm:
    image: vllm/vllm-openai:latest
    runtime: nvidia
    environment:
      - CUDA_VISIBLE_DEVICES=0,1
    volumes:
      - ~/.cache/huggingface:/root/.cache/huggingface
      - ./logs:/logs
    ports:
      - "8000:8000"
    command: >
      --model mistralai/Mistral-7B-Instruct-v0.2
      --tensor-parallel-size 2
      --gpu-memory-utilization 0.90
      --max-num-seqs 256
      --max-model-len 8192      
    restart: unless-stopped
    shm_size: '16gb'
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 2
              capabilities: [gpu]

Kubernetes 배포

생산 규모를 위해 Kubernetes 에 vLLM 을 배포하세요:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        args:
          - --model
          - mistralai/Mistral-7B-Instruct-v0.2
          - --tensor-parallel-size
          - "2"
          - --gpu-memory-utilization
          - "0.90"
        resources:
          limits:
            nvidia.com/gpu: 2
        ports:
        - containerPort: 8000
        volumeMounts:
        - name: cache
          mountPath: /root/.cache/huggingface
      volumes:
      - name: cache
        hostPath:
          path: /mnt/huggingface-cache
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm
  ports:
  - port: 80
    targetPort: 8000
  type: LoadBalancer

모니터링 및 관측성

vLLM 은 모니터링을 위해 Prometheus 메트릭을 노출합니다:

import requests

# 메트릭 가져오기
metrics = requests.get("http://localhost:8000/metrics").text
print(metrics)

모니터링할 주요 메트릭:

  • vllm:num_requests_running - 활성화된 요청
  • vllm:gpu_cache_usage_perc - KV 캐시 활용도
  • vllm:time_to_first_token - 지연 시간 메트릭
  • vllm:time_per_output_token - 생성 속도

성능 튜닝

GPU 메모리 활용 최적화: --gpu-memory-utilization 0.90으로 시작하여 관찰된 동작에 따라 조정하세요. 더 높은 값은 더 큰 배치를 허용하지만 트래픽 급증 중 OOM 오류 위험이 있습니다.

최대 시퀀스 길이 튜닝: 사용 사례에서 전체 컨텍스트 길이가 필요하지 않은 경우 --max-model-len을 줄이세요. 이는 더 큰 배치에 메모리를 확보합니다. 예를 들어, 4K 컨텍스트만 필요한 경우 모델의 최대 (보통 8K-32K) 대신 --max-model-len 4096로 설정하세요.

적절한 양자화 선택: 모델을 지원하는 경우 메모리를 줄이고 처리량을 늘리기 위해 양자화된 버전 (8-bit, 4-bit) 을 사용하세요:

--quantization awq  # AWQ 양자화 모델용
--quantization gptq # GPTQ 양자화 모델용

접두어 캐싱 활성화: 반복되는 프롬프트 (시스템 메시지가 있는 챗봇 등) 가 있는 애플리케이션의 경우 접두어 캐싱을 활성화하세요:

--enable-prefix-caching

이는 공통 프롬프트의 KV 값을 캐시하여 동일한 프롬프트 접두사를 공유하는 요청에 대한 계산을 줄입니다.

일반적인 문제 해결

메모리 부족 오류

증상: CUDA 메모리 부족 오류로 서버가 충돌합니다.

해결 방법:

  • --gpu-memory-utilization을 0.85 또는 0.80 으로 줄이기
  • 사용 사례가 허용하는 경우 --max-model-len 감소
  • 배치 크기를 줄이기 위해 --max-num-seqs 낮추기
  • 양자화된 모델 버전 사용
  • 더 많은 GPU 에 분산하기 위해 텐서 병렬 처리 활성화

낮은 처리량

증상: 서버가 예상보다 적은 요청을 처리합니다.

해결 방법:

  • 더 큰 배치를 허용하도록 --max-num-seqs 증가
  • 여유 공간이 있는 경우 --gpu-memory-utilization 올리기
  • htop로 CPU 병목 현상 확인 – 더 빠른 CPU 고려
  • nvidia-smi로 GPU 활용도 확인 – 95%+ 이어야 함
  • FP32 를 사용하는 경우 FP16 활성화: --dtype float16

첫 토큰 시간 느림

증상: 생성 시작 전 높은 지연 시간.

해결 방법:

  • 지연 시간 임계 애플리케이션에 작은 모델 사용
  • 반복된 프롬프트에 대해 접두어 캐싱 활성화
  • 처리량보다 지연 시간을 우선시하도록 --max-num-seqs 감소
  • 지원 모델에 대해 추측 디코딩 고려
  • 텐서 병렬 처리 구성 최적화

모델 로딩 실패

증상: 서버가 시작되지 않거나 모델을 로드할 수 없음.

해결 방법:

  • 모델 이름이 HuggingFace 형식과 정확히 일치하는지 확인
  • HuggingFace Hub 에 대한 네트워크 연결 확인
  • ~/.cache/huggingface에 충분한 디스크 공간 확보
  • 게이트드 모델의 경우 HF_TOKEN 환경 변수 설정
  • huggingface-cli download <model>로 수동 다운로드 시도

고급 기능

추측 디코딩 (Speculative Decoding)

vLLM 은 작은 드래프트 모델이 큰 타겟 모델이 검증할 토큰을 제안하는 추측 디코딩을 지원합니다. 이는 생성을 1.5~2 배 가속화할 수 있습니다:

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-70b-chat-hf \
    --speculative-model meta-llama/Llama-2-7b-chat-hf \
    --num-speculative-tokens 5

LoRA 어댑터

여러 전체 모델을 로드하지 않고 기본 모델 위에 여러 LoRA 어댑터 서비스:

python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-hf \
    --enable-lora \
    --lora-modules sql-lora=./path/to/sql-adapter \
                   code-lora=./path/to/code-adapter

그런데 각 요청별로 사용할 어댑터를 지정하세요:

response = client.completions.create(
    model="sql-lora",  # SQL 어댑터 사용
    prompt="이것을 SQL 로 변환하세요: 이번 달에 생성된 모든 사용자를 보여주세요"
)

멀티 LoRA 서비스

vLLM 의 멀티 LoRA 서비스는 최소한의 메모리 오버헤드로 수십 개의 파인튜닝 어댑터를 호스팅할 수 있습니다. 이는 고객별 또는 작업별 모델 변형을 서비스하는 데 이상적입니다:

# 특정 LoRA 어댑터로 요청
response = client.chat.completions.create(
    model="meta-llama/Llama-2-7b-hf",
    messages=[{"role": "user", "content": "SQL 쿼리 작성"}],
    extra_body={"lora_name": "sql-lora"}
)

접두어 캐싱 (Prefix Caching)

반복되는 프롬프트 접두사에 대한 KV 캐시 재계산을 피하기 위해 자동 접두어 캐싱 활성화:

--enable-prefix-caching

이는 특히 다음에 효과적입니다:

  • 고정 시스템 프롬프트가 있는 챗봇
  • 일관된 컨텍스트 템플릿이 있는 RAG 애플리케이션
  • 요청 간 반복되는 퓨샷 학습 프롬프트

접두어 캐싱은 프롬프트 접두사를 공유하는 요청의 첫 토큰 시간을 50~80% 줄일 수 있습니다.

통합 예제

LangChain 통합

from langchain.llms import VLLMOpenAI

llm = VLLMOpenAI(
    openai_api_key="EMPTY",
    openai_api_base="http://localhost:8000/v1",
    model_name="mistralai/Mistral-7B-Instruct-v0.2",
    max_tokens=512,
    temperature=0.7,
)

response = llm("PagedAttention 을 간단한 용어로 설명해주세요")
print(response)

LlamaIndex 통합

from llama_index.llms import VLLMServer

llm = VLLMServer(
    api_url="http://localhost:8000/v1",
    model="mistralai/Mistral-7B-Instruct-v0.2",
    temperature=0.7,
    max_tokens=512
)

response = llm.complete("vLLM 이 무엇인가요?")
print(response)

FastAPI 애플리케이션

from fastapi import FastAPI
from openai import AsyncOpenAI

app = FastAPI()
client = AsyncOpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

@app.post("/generate")
async def generate(prompt: str):
    response = await client.completions.create(
        model="mistralai/Mistral-7B-Instruct-v0.2",
        prompt=prompt,
        max_tokens=200
    )
    return {"result": response.choices[0].text}

성능 벤치마크

실제 성능 데이터는 vLLM 의 장점을 보여줍니다:

처리량 비교 (A100 GPU 의 Mistral-7B):

  • vLLM: 동시 사용자 64 명 기준 초당 약 3,500 토큰
  • HuggingFace Transformers: 동일한 동시성 기준 초당 약 250 토큰
  • Ollama: 동일한 동시성 기준 초당 약 1,200 토큰
  • 결과: vLLM 은 기본 구현 대비 14 배 향상 제공

메모리 효율성 (LLaMA-2-13B):

  • 표준 구현: 24GB VRAM, 동시 시퀀스 32 개
  • PagedAttention 사용 vLLM: 24GB VRAM, 동시 시퀀스 128 개
  • 결과: 동일한 메모리로 동시 요청 4 배 더 많음

부하 하의 지연 시간 (2xA100 의 Mixtral-8x7B):

  • vLLM: 100 req/s 기준 P50 지연 시간 180ms, P99 지연 시간 420ms
  • 표준 서비스: 100 req/s 기준 P50 지연 시간 650ms, P99 지연 시간 3,200ms
  • 결과: vLLM 은 높은 부하 하에서도 일관된 지연 시간 유지

이러한 벤치마크는 성능이 중요한 생산 LLM 서비스를 위해 vLLM 이 사실상 표준이 된 이유를 보여줍니다.

비용 분석

vLLM 선택의 비용 함의를 이해하세요:

시나리오: 일일 100 만 건 요청 제공

표준 서비스 사용 시:

  • 필요: 8 대 A100 GPU(80GB)
  • AWS 비용: 시간당 약 $32 × 24 × 30 = 월 $23,040
  • 토큰 100 만 건당 비용: 약 $0.75

vLLM 사용 시:

  • 필요: 2 대 A100 GPU(80GB)
  • AWS 비용: 시간당 약 $8 × 24 × 30 = 월 $5,760
  • 토큰 100 만 건당 비용: 약 $0.19
  • 절감: 월 $17,280(75% 감소)

이 비용 이점은 규모가 커질수록 커집니다. 월간 수십억 토큰을 서비스하는 조직은 순환한 구현 대신 vLLM 의 최적화된 서비스를 사용하여 수십만 달러를 절약합니다.

보안 고려사항

인증

vLLM 은 기본적으로 인증을 포함하지 않습니다. 생산 환경에서는 역방향 프록시 수준에서 인증을 구현하세요:

# Nginx 설정
location /v1/ {
    auth_request /auth;
    proxy_pass http://vllm-backend:8000;
}

location /auth {
    proxy_pass http://auth-service:8080/verify;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

또는 Kong, Traefik 또는 AWS API Gateway와 같은 API 게이트웨이를 사용하여 엔터프라이즈급 인증 및 속도 제한을 사용하세요.

네트워크 격리

vLLM 은 사내 네트워크에서 실행하고 인터넷에 직접 노출되지 않도록 하세요:

# Kubernetes NetworkPolicy 예제
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: vllm-access
spec:
  podSelector:
    matchLabels:
      app: vllm
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: api-gateway
    ports:
    - protocol: TCP
      port: 8000

속도 제한

남용을 방지하기 위해 속도 제한을 구현하세요:

# 속도 제한을 위해 Redis 사용 예제
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import redis
from datetime import datetime, timedelta

app = FastAPI()
redis_client = redis.Redis(host='localhost', port=6379)

@app.middleware("http")
async def rate_limit_middleware(request, call_next):
    client_ip = request.client.host
    key = f"rate_limit:{client_ip}"
    
    requests = redis_client.incr(key)
    if requests == 1:
        redis_client.expire(key, 60)  # 60 초 윈도우
    
    if requests > 60:  # 분당 60 건
        raise HTTPException(status_code=429, detail="속도 제한 초과")
    
    return await call_next(request)

모델 접근 제어

멀티 테넌트 배포의 경우, 사용자가 어떤 모델에 액세스할 수 있는지 제어하세요:

ALLOWED_MODELS = {
    "user_tier_1": ["mistralai/Mistral-7B-Instruct-v0.2"],
    "user_tier_2": ["mistralai/Mistral-7B-Instruct-v0.2", "meta-llama/Llama-2-13b-chat-hf"],
    "admin": ["*"]  # 모든 모델
}

def verify_model_access(user_tier: str, model: str) -> bool:
    allowed = ALLOWED_MODELS.get(user_tier, [])
    return "*" in allowed or model in allowed

마이그레이션 가이드

OpenAI 에서 vLLM 으로

API 호환성 덕분에 OpenAI 에서 자체 호스팅 vLLM 으로 마이그레이션은 간단합니다:

이전 (OpenAI):

from openai import OpenAI

client = OpenAI(api_key="sk-...")
response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "안녕하세요"}]
)

이후 (vLLM):

from openai import OpenAI

client = OpenAI(
    base_url="https://your-vllm-server.com/v1",
    api_key="your-internal-key"  # 인증을 추가한 경우
)
response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "안녕하세요"}]
)

base_urlmodel 이름만 업데이트하면 됩니다. 나머지 코드는 동일하게 유지됩니다.

Ollama 에서 vLLM 으로

Ollama 는 다른 API 형식을 사용합니다. 변환 방법은 다음과 같습니다:

Ollama API:

import requests

response = requests.post('http://localhost:11434/api/generate',
    json={
        'model': 'llama2',
        'prompt': '하늘은 왜 파란가요?'
    })

vLLM 동일:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
response = client.completions.create(
    model="meta-llama/Llama-2-7b-chat-hf",
    prompt="하늘은 왜 파란가요?"
)

코드베이스 전체에서 API 호출을 업데이트해야 하지만, OpenAI 클라이언트 라이브러리는 더 나은 오류 처리 및 기능을 제공합니다.

HuggingFace Transformers 에서 vLLM 으로

직접 Python 사용 마이그레이션:

HuggingFace:

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2")
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2")

inputs = tokenizer("Hello", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=100)
result = tokenizer.decode(outputs[0])

vLLM:

from vllm import LLM, SamplingParams

llm = LLM(model="mistralai/Mistral-7B-Instruct-v0.2")
sampling_params = SamplingParams(max_tokens=100)

outputs = llm.generate("Hello", sampling_params)
result = outputs[0].outputs[0].text

vLLM 의 Python API 는 배치 추론을 위해 더 간단하고 훨씬 빠릅니다.

vLLM 의 미래

vLLM 은 로드맵에 흥미로운 기능과 함께 빠른 개발을 계속하고 있습니다:

분리된 서비스 (Disaggregated Serving): 사전 처리 (프롬프트 처리) 와 디코딩 (토큰 생성) 을 다른 GPU 로 분리하여 리소스 활용을 최적화합니다. 사전 처리는 계산 제한적이지만 디코딩은 메모리 제한적이므로, 전용 하드웨어에서 실행하면 효율성이 향상됩니다.

멀티 노드 추론: 매우 대형 모델 (100B+ 파라미터) 을 여러 머신에 분산시켜 단일 노드 설정에 너무 큰 모델 서비스 가능.

향상된 양자화: GGUF(llama.cpp 에서 사용됨) 및 향상된 AWQ/GPTQ 통합과 같은 새로운 양자화 형식 지원으로 양자화된 모델의 성능이 향상됩니다.

추측 디코딩 개선: 더 효율적인 드래프트 모델 및 정확도 손실 없이 더 높은 속도 향상을 달성하는 적응형 추측 전략.

어텐션 최적화: FlashAttention 3, 극도로 긴 컨텍스트 (100K+ 토큰) 를 위한 링 어텐션 및 기타 최첨단 어텐션 메커니즘.

더 나은 모델 커버리지: 멀티모달 모델 (비전-언어 모델), 오디오 모델 및 특수 아키텍처의 지원을 확장합니다.

vLLM 프로젝트는 UC 버클리, Anyscale 및 더 넓은 오픈소스 커뮤니티의 기여로 활발한 개발을 유지하고 있습니다. LLM 배포가 생산 시스템에 점점 더 중요해짐에 따라 vLLM 은 성능 표준으로서의 역할이 계속 성장하고 있습니다.

vLLM 과 기타 로컬 및 클라우드 LLM 인프라의 더 넓은 비교를 원하시면, LLM 호스팅: 로컬, 자체 호스팅 및 클라우드 인프라 비교를 확인하세요.

유용한 링크

이 사이트의 관련 기사

외부 리소스 및 문서

  • vLLM GitHub 저장소 - 소스 코드, 포괄적 문서, 설치 가이드 및 활발한 커뮤니티 토론이 포함된 공식 vLLM 저장소. 최신 기능 및 문제 해결을 유지하는 데 필수적인 리소스입니다.

  • vLLM 문서 - 기본 설정부터 고급 구성까지 vLLM 의 모든 측면을 다루는 공식 문서. API 참조, 성능 튜닝 가이드 및 배포 모범 사례를 포함합니다.

  • PagedAttention 논문 - vLLM 의 효율성을 powering 하는 PagedAttention 알고리즘을 소개한 학술 논문입니다. vLLM 의 성능 이점 뒤의 기술 혁신을 이해하는 데 필수적인 독서입니다.

  • vLLM 블로그 - 출시 발표, 성능 벤치마크, 기술 심층 분석 및 생산 배포의 커뮤니티 사례 연구를 특징으로 하는 공식 vLLM 블로그입니다.

  • HuggingFace 모델 허브 - vLLM 과 작동하는 오픈소스 LLM 의 포괄적 저장소. 크기, 작업, 라이선스 및 성능 특징으로 모델을 검색하여 사용 사례에 맞는 올바른 모델을 찾습니다.

  • Ray Serve 문서 - 확장 가능하고 분산된 vLLM 배포를 구축하기 위한 Ray Serve 프레임워크 문서입니다. Ray 는 자동 확장, 멀티 모델 서비스 및 생산 시스템을 위한 리소스 관리와 같은 고급 기능을 제공합니다.

  • NVIDIA TensorRT-LLM - NVIDIA GPU 를 위한 NVIDIA 의 TensorRT-LLM 입니다. 다른 최적화 전략을 가진 vLLM 의 대안으로, 추론 최적화 환경을 이해하고 비교하는 데 유용합니다.

  • OpenAI API 참조 - vLLM 의 API 가 호환되는 공식 OpenAI API 문서입니다. OpenAI 와 자체 호스팅 vLLM 엔드포인트를 번갈아 사용할 애플리케이션을 구축할 때 참조하세요.