본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2026. 2. 3. · 3 Views
vLLM 통합 완벽 가이드
대규모 언어 모델 추론을 획기적으로 가속화하는 vLLM의 설치부터 실전 서비스 구축까지 다룹니다. PagedAttention과 연속 배칭 기술로 GPU 메모리를 효율적으로 활용하는 방법을 배웁니다.
목차
1. vLLM의 강력함
김개발 씨는 스타트업에서 AI 서비스를 개발하는 주니어 개발자입니다. 회사에서 LLM 기반 챗봇 서비스를 런칭했는데, 사용자가 늘어날수록 응답 속도가 느려지고 GPU 비용은 천정부지로 치솟았습니다.
"이대로는 서비스를 유지할 수 없어요." 팀장님의 한숨 섞인 말에 김개발 씨는 해결책을 찾아 나섭니다.
vLLM은 대규모 언어 모델의 추론 속도를 극대화하는 오픈소스 라이브러리입니다. 마치 고속도로에서 여러 차량이 동시에 달리듯, 여러 요청을 효율적으로 처리합니다.
PagedAttention이라는 혁신적인 메모리 관리 기법으로 기존 대비 최대 24배 빠른 처리량을 달성할 수 있습니다.
다음 코드를 살펴봅시다.
# vLLM의 핵심 개념: 기존 방식 vs vLLM 비교
# 기존 방식 - 요청마다 개별 처리
def traditional_inference(prompts):
results = []
for prompt in prompts: # 순차 처리로 느림
result = model.generate(prompt)
results.append(result)
return results
# vLLM 방식 - 연속 배칭으로 동시 처리
from vllm import LLM
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct")
# 여러 요청을 한 번에 처리 (최대 24배 빠름)
outputs = llm.generate(prompts) # 내부적으로 PagedAttention 적용
김개발 씨는 늦은 밤까지 사무실에 남아 LLM 성능 최적화 방법을 검색했습니다. HuggingFace Transformers, TensorRT-LLM, DeepSpeed 등 다양한 도구들이 있었지만, 문서를 읽으면 읽을수록 머리가 복잡해졌습니다.
그때 선배 개발자 박시니어 씨가 커피를 건네며 다가왔습니다. "뭘 그렇게 고민해요?" 김개발 씨가 상황을 설명하자, 박시니어 씨는 미소를 지었습니다.
"vLLM 써봤어요? 우리 팀도 예전에 같은 문제로 고생했는데, vLLM으로 해결했거든요." 그렇다면 vLLM이란 정확히 무엇일까요?
쉽게 비유하자면, vLLM은 마치 효율적인 식당 주방장과 같습니다. 일반적인 식당에서는 손님이 주문할 때마다 요리사가 한 명씩 붙어서 처리합니다.
하지만 효율적인 주방장은 비슷한 요리들을 묶어서 동시에 조리하고, 불판 위의 공간을 낭비 없이 활용합니다. vLLM도 마찬가지로 여러 요청을 묶어서 처리하고, GPU 메모리를 알뜰하게 사용합니다.
기존 LLM 추론 방식에는 두 가지 큰 문제가 있었습니다. 첫 번째는 메모리 낭비 문제였습니다.
LLM이 텍스트를 생성할 때는 KV Cache라는 것을 저장해야 하는데, 기존 방식은 최대 길이만큼 메모리를 미리 할당했습니다. 실제로는 그 절반도 사용하지 않는 경우가 많았지만요.
마치 10명이 앉을 수 있는 테이블에 2명만 앉아있는 것과 같았습니다. 두 번째는 처리량 한계 문제였습니다.
요청이 들어올 때마다 개별적으로 처리하다 보니, GPU가 쉬는 시간이 많았습니다. 비싼 GPU를 사놓고 제대로 활용하지 못하는 셈이었습니다.
바로 이런 문제를 해결하기 위해 UC Berkeley의 연구팀이 vLLM을 개발했습니다. vLLM의 핵심 기술은 PagedAttention입니다.
이 기술은 운영체제의 가상 메모리 개념을 LLM에 적용한 것입니다. KV Cache를 고정된 크기의 블록으로 나누어 필요한 만큼만 할당하고, 실제 사용량에 따라 동적으로 관리합니다.
덕분에 메모리 낭비를 최소화할 수 있습니다. 또 다른 핵심 기술은 **연속 배칭(Continuous Batching)**입니다.
기존에는 배치 내 모든 요청이 끝날 때까지 기다려야 했지만, vLLM은 완료된 요청 자리에 새 요청을 즉시 채워 넣습니다. GPU가 쉬는 틈 없이 계속 일하게 만드는 것입니다.
위의 코드를 살펴보면 vLLM의 사용법이 얼마나 간단한지 알 수 있습니다. 단 두 줄로 모델을 로드하고, generate 메서드 하나로 여러 요청을 동시에 처리합니다.
내부적으로는 복잡한 최적화가 일어나지만, 개발자는 그 복잡함을 전혀 신경 쓸 필요가 없습니다. 실제로 vLLM을 도입한 기업들의 사례를 보면 놀라운 결과가 나옵니다.
처리량은 최대 24배 증가하고, 같은 수의 요청을 처리하는 데 필요한 GPU 수는 절반 이하로 줄어듭니다. 비용 절감 효과가 어마어마한 것입니다.
박시니어 씨의 조언을 들은 김개발 씨의 눈이 반짝였습니다. "그렇게 좋은 게 있었군요!
당장 적용해볼게요." 이제 vLLM의 세계로 본격적으로 들어가 봅시다.
실전 팁
💡 - vLLM은 NVIDIA GPU에서 가장 잘 동작하며, A100, H100에서 최적의 성능을 발휘합니다
- 처음 시작한다면 공식 문서의 quickstart 예제부터 따라해 보세요
2. vLLM 설치 및 설정
김개발 씨는 vLLM을 설치하기 위해 터미널을 열었습니다. "pip install vllm 하면 되겠지?"라고 생각했지만, 현실은 그리 간단하지 않았습니다.
CUDA 버전 충돌, 의존성 오류 등 여러 문제에 부딪혔습니다. 개발 환경 설정은 언제나 가장 까다로운 첫 번째 관문입니다.
vLLM 설치는 CUDA 버전과 Python 환경 설정이 핵심입니다. pip로 간단히 설치할 수 있지만, GPU 드라이버와 CUDA 툴킷이 올바르게 설정되어 있어야 합니다.
Docker를 사용하면 환경 설정의 복잡함을 크게 줄일 수 있습니다.
다음 코드를 살펴봅시다.
# 1. 시스템 요구사항 확인
nvidia-smi # CUDA 버전 확인 (11.8 이상 필요)
# 2. 가상환경 생성 및 활성화
python -m venv vllm-env
source vllm-env/bin/activate
# 3. vLLM 설치 (CUDA 12.1 기준)
pip install vllm
# 4. 설치 확인 스크립트
from vllm import LLM, SamplingParams
# 간단한 테스트
llm = LLM(model="facebook/opt-125m") # 작은 모델로 테스트
params = SamplingParams(temperature=0.8, max_tokens=50)
outputs = llm.generate(["Hello, my name is"], params)
print(outputs[0].outputs[0].text)
김개발 씨는 먼저 자신의 개발 서버 환경을 확인했습니다. nvidia-smi 명령어를 입력하자 GPU 정보와 함께 CUDA 버전이 표시되었습니다.
다행히 CUDA 12.1이 설치되어 있었습니다. "좋아, 일단 환경은 괜찮네." 김개발 씨는 안도의 한숨을 쉬었습니다.
vLLM을 설치하기 전에 반드시 확인해야 할 것들이 있습니다. 마치 요리를 시작하기 전에 재료와 도구를 확인하는 것처럼, 개발 환경도 미리 점검해야 합니다.
첫 번째로 확인할 것은 GPU입니다. vLLM은 NVIDIA GPU에서만 동작하며, Compute Capability 7.0 이상이 필요합니다.
V100, T4, A10, A100, H100 등 비교적 최신 GPU가 해당됩니다. RTX 30 시리즈, 40 시리즈도 사용 가능합니다.
두 번째는 CUDA 버전입니다. vLLM 0.4.0 이상은 CUDA 11.8 또는 12.1을 지원합니다.
nvidia-smi 명령어로 현재 설치된 CUDA 버전을 확인할 수 있습니다. 세 번째는 Python 버전입니다.
Python 3.8 이상이 필요하며, 3.10 또는 3.11을 권장합니다. 가상환경을 사용하여 다른 프로젝트와 의존성 충돌을 방지하는 것이 좋습니다.
설치 자체는 놀라울 정도로 간단합니다. pip install vllm 한 줄이면 됩니다.
하지만 여기서 문제가 발생하는 경우가 종종 있습니다. 김개발 씨도 처음에는 오류를 만났습니다.
"CUDA version mismatch"라는 메시지가 떴습니다. 이럴 때는 PyTorch와 CUDA 버전을 맞춰주어야 합니다.
박시니어 씨가 조언했습니다. "가장 확실한 방법은 Docker를 쓰는 거예요.
환경 설정 때문에 시간 낭비하지 말고요." 실제로 vLLM 공식 Docker 이미지를 사용하면 모든 의존성이 미리 설정되어 있어 훨씬 편리합니다. Docker 명령어는 이렇습니다.
docker run --gpus all -p 8000:8000 vllm/vllm-openai:latest 한 줄로 OpenAI 호환 API 서버를 바로 띄울 수 있습니다. 설치가 완료되면 간단한 테스트 코드를 실행해 봅니다.
위의 코드에서 facebook/opt-125m은 매우 작은 모델로, 테스트 용도로 적합합니다. 모델 다운로드에 시간이 걸리지만, 한 번 다운로드하면 캐시에 저장됩니다.
실무에서는 몇 가지 추가 설정을 고려해야 합니다. tensor-parallel-size 옵션으로 여러 GPU를 활용할 수 있고, gpu-memory-utilization 옵션으로 GPU 메모리 사용량을 조절할 수 있습니다.
기본값은 0.9로, GPU 메모리의 90%를 사용합니다. 김개발 씨는 테스트 코드를 실행했습니다.
잠시 후 "Hello, my name is John and I"라는 출력이 나타났습니다. "설치 성공이다!" 김개발 씨는 주먹을 불끈 쥐었습니다.
실전 팁
💡 - 설치 오류가 발생하면 pip install vllm --no-build-isolation 옵션을 시도해 보세요
- 프로덕션 환경에서는 반드시 Docker를 사용하여 환경 일관성을 유지하세요
3. Qwen3 TTS와 vLLM 통합
설치를 마친 김개발 씨는 본격적으로 회사의 챗봇 모델을 vLLM에 올리기로 했습니다. 회사에서는 Qwen 시리즈 모델을 사용하고 있었는데, 최근 출시된 Qwen3-TTS 모델의 음성 합성 기능이 필요했습니다.
"vLLM이 이 모델도 지원할까?" 김개발 씨는 문서를 뒤지기 시작했습니다.
Qwen3 시리즈는 Alibaba에서 개발한 강력한 오픈소스 LLM입니다. vLLM은 Qwen 모델을 공식 지원하며, 특히 Qwen2.5와 Qwen3의 다양한 변형 모델들을 효율적으로 서빙할 수 있습니다.
TTS 기능 통합 시에는 텍스트 생성과 음성 합성 파이프라인을 분리하여 구성합니다.
다음 코드를 살펴봅시다.
from vllm import LLM, SamplingParams
# Qwen3 모델 로드 (8B 파라미터 버전)
llm = LLM(
model="Qwen/Qwen2.5-7B-Instruct",
trust_remote_code=True, # Qwen 모델에 필요
max_model_len=8192, # 컨텍스트 길이 설정
gpu_memory_utilization=0.85,
)
# 채팅 형식의 프롬프트 구성
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "vLLM의 장점을 설명해주세요."}
]
# Qwen 토크나이저로 채팅 템플릿 적용
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
prompt = tokenizer.apply_chat_template(messages, tokenize=False)
# 추론 실행
params = SamplingParams(temperature=0.7, max_tokens=512)
outputs = llm.generate([prompt], params)
김개발 씨는 Qwen 모델을 vLLM에 로드하는 방법을 찾아보았습니다. 다행히 vLLM은 Qwen 시리즈를 공식 지원하고 있었습니다.
HuggingFace Hub에서 모델 이름만 지정하면 자동으로 다운로드됩니다. 하지만 처음 실행했을 때 오류가 발생했습니다.
"trust_remote_code must be True for Qwen models." 김개발 씨는 오류 메시지를 읽고 옵션을 추가했습니다. trust_remote_code 옵션은 Qwen처럼 커스텀 코드가 포함된 모델에 필요합니다.
HuggingFace 모델 중에는 표준 Transformers 아키텍처가 아닌 자체 구현을 사용하는 경우가 있는데, 이 코드를 신뢰하고 실행하겠다는 의미입니다. Qwen 모델의 강점은 다국어 지원입니다.
한국어, 중국어, 영어 등 여러 언어를 유창하게 처리합니다. 김개발 씨의 회사 서비스가 한국 사용자를 대상으로 하기 때문에 이 점이 특히 매력적이었습니다.
모델을 로드할 때 max_model_len 파라미터도 중요합니다. 이것은 모델이 처리할 수 있는 최대 토큰 길이를 지정합니다.
Qwen2.5-7B는 기본적으로 32K 토큰까지 지원하지만, GPU 메모리가 부족하면 이 값을 줄여야 합니다. 김개발 씨는 8192로 설정했습니다.
회사 챗봇의 평균 대화 길이가 이 정도면 충분했기 때문입니다. 메모리 여유가 생기니 더 많은 동시 요청을 처리할 수 있게 되었습니다.
채팅 형식의 모델을 사용할 때는 채팅 템플릿을 적용해야 합니다. Qwen 모델은 특정 형식의 프롬프트를 기대하는데, 토크나이저의 apply_chat_template 메서드가 이를 자동으로 처리해줍니다.
TTS 기능과의 통합은 별도의 파이프라인으로 구성합니다. vLLM이 텍스트를 생성하면, 그 결과를 TTS 모델에 전달하여 음성으로 변환하는 방식입니다.
두 모델을 하나의 vLLM 인스턴스에서 동시에 서빙하면 리소스 관리가 복잡해지므로, 마이크로서비스 아키텍처로 분리하는 것이 일반적입니다. 박시니어 씨가 조언했습니다.
"TTS는 별도 서비스로 분리하는 게 좋아요. 텍스트 생성과 음성 합성의 처리 특성이 다르거든요.
텍스트 생성은 GPU 집약적이고, TTS는 상대적으로 가벼워요." 김개발 씨는 고개를 끄덕였습니다. 마치 주방에서 요리사와 플레이팅 담당을 분리하는 것과 같은 원리였습니다.
각자 전문 분야에 집중하면 전체 효율이 높아집니다. 실제 코드를 실행하자 Qwen 모델이 vLLM에서 빠르게 응답을 생성했습니다.
기존 HuggingFace Transformers로 실행했을 때보다 체감상 훨씬 빨랐습니다.
실전 팁
💡 - Qwen 모델은 AWQ, GPTQ 양자화 버전도 지원하여 메모리가 부족할 때 활용할 수 있습니다
- 채팅 템플릿은 모델마다 다르므로, 반드시 해당 모델의 토크나이저를 사용하세요
4. 추론 속도 벤치마크
Qwen 모델이 잘 동작하는 것을 확인한 김개발 씨는 이제 궁금해졌습니다. "정말 그렇게 빠른 걸까?" 숫자로 직접 확인해보고 싶었습니다.
팀장님께 보고할 때도 구체적인 수치가 있어야 설득력이 있을 테니까요.
vLLM의 성능은 **처리량(Throughput)**과 **지연시간(Latency)**으로 측정합니다. 처리량은 초당 생성 토큰 수, 지연시간은 첫 토큰까지의 시간(TTFT)과 토큰 간 시간(ITL)으로 나뉩니다.
실제 벤치마크에서 vLLM은 HuggingFace 대비 10-24배 높은 처리량을 보여줍니다.
다음 코드를 살펴봅시다.
import time
from vllm import LLM, SamplingParams
# 벤치마크 설정
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct", trust_remote_code=True)
params = SamplingParams(temperature=0.8, max_tokens=256)
# 테스트 프롬프트 준비 (동시 요청 시뮬레이션)
prompts = ["인공지능의 미래에 대해 설명해주세요."] * 32
# 벤치마크 실행
start_time = time.time()
outputs = llm.generate(prompts, params)
elapsed = time.time() - start_time
# 결과 계산
total_tokens = sum(len(o.outputs[0].token_ids) for o in outputs)
throughput = total_tokens / elapsed
print(f"처리량: {throughput:.2f} tokens/sec")
print(f"총 소요 시간: {elapsed:.2f}초")
print(f"요청당 평균 시간: {elapsed/len(prompts)*1000:.2f}ms")
김개발 씨는 벤치마크 코드를 작성하기 시작했습니다. 성능 측정에서 가장 중요한 것은 공정한 비교 조건을 만드는 것입니다.
같은 모델, 같은 프롬프트, 같은 생성 길이로 테스트해야 의미 있는 결과를 얻을 수 있습니다. LLM 서빙 성능을 측정하는 지표는 크게 두 가지입니다.
첫 번째는 **처리량(Throughput)**입니다. 초당 몇 개의 토큰을 생성할 수 있는지를 나타냅니다.
서버 입장에서 보면 같은 시간에 더 많은 사용자 요청을 처리할 수 있다는 의미입니다. 마치 식당에서 시간당 몇 테이블을 회전시킬 수 있는지와 비슷합니다.
두 번째는 **지연시간(Latency)**입니다. 이것은 다시 두 가지로 나뉩니다.
**TTFT(Time To First Token)**는 요청 후 첫 번째 토큰이 나올 때까지의 시간이고, **ITL(Inter-Token Latency)**는 토큰과 토큰 사이의 간격입니다. 사용자 체감 속도에 직접적인 영향을 미칩니다.
김개발 씨는 32개의 동시 요청으로 테스트했습니다. 실제 서비스 환경에서는 여러 사용자가 동시에 요청을 보내기 때문입니다.
순차 처리만 테스트하면 실제 상황을 제대로 반영하지 못합니다. 결과는 놀라웠습니다.
A100 GPU 한 장에서 초당 약 2,000개의 토큰을 생성했습니다. 기존 HuggingFace Transformers로 같은 테스트를 했을 때는 초당 200개 정도였으니, 약 10배의 성능 향상입니다.
박시니어 씨가 설명했습니다. "이게 바로 연속 배칭의 힘이에요.
32개 요청이 들어와도 GPU가 효율적으로 처리하니까 처리량이 선형에 가깝게 늘어나요." 더 인상적인 것은 메모리 효율성이었습니다. 기존 방식은 32개 요청을 처리하려면 KV Cache 메모리가 부족해서 배치 크기를 8 정도로 제한해야 했습니다.
하지만 vLLM은 PagedAttention 덕분에 32개 요청을 한 번에 처리할 수 있었습니다. 실무에서 벤치마크를 할 때는 몇 가지를 주의해야 합니다.
첫째, 워밍업을 해야 합니다. 첫 실행은 모델 컴파일 등으로 느릴 수 있으므로, 몇 번 실행한 후 측정합니다.
둘째, 여러 번 반복 측정하여 평균을 내야 합니다. 시스템 상태에 따라 결과가 달라질 수 있기 때문입니다.
김개발 씨는 결과를 정리하여 팀장님께 보고했습니다. "vLLM 도입으로 같은 GPU에서 10배 더 많은 요청을 처리할 수 있습니다.
GPU 비용을 90% 절감할 수 있다는 의미입니다." 팀장님의 얼굴에 미소가 번졌습니다. "잘했어요, 김개발 씨.
바로 적용합시다."
실전 팁
💡 - 벤치마크 시 반드시 GPU 온도와 전력 상태를 확인하세요. 스로틀링이 발생하면 결과가 왜곡됩니다
- vLLM 공식 벤치마크 스크립트를 활용하면 더 정확한 측정이 가능합니다
5. 메모리 사용량 최적화
벤치마크 결과에 고무된 김개발 씨는 프로덕션 배포를 준비했습니다. 하지만 문제가 하나 있었습니다.
회사의 GPU는 VRAM이 24GB인 RTX 4090이었는데, 7B 모델을 올리니 메모리가 빡빡했습니다. "어떻게 하면 더 효율적으로 메모리를 쓸 수 있을까?"
vLLM의 메모리 최적화는 **양자화(Quantization)**와 KV Cache 설정이 핵심입니다. AWQ, GPTQ 양자화로 모델 크기를 절반 이하로 줄이고, gpu_memory_utilization과 max_model_len 조절로 KV Cache를 최적화합니다.
적절한 설정으로 같은 GPU에서 2-3배 더 많은 동시 요청을 처리할 수 있습니다.
다음 코드를 살펴봅시다.
from vllm import LLM, SamplingParams
# 메모리 최적화 설정
llm = LLM(
model="Qwen/Qwen2.5-7B-Instruct-AWQ", # AWQ 양자화 모델
quantization="awq", # 양자화 방식 명시
gpu_memory_utilization=0.90, # GPU 메모리 90% 사용
max_model_len=4096, # 컨텍스트 길이 제한
max_num_seqs=64, # 최대 동시 시퀀스 수
enforce_eager=False, # CUDA Graph 활성화
)
# 메모리 사용량 확인
import torch
allocated = torch.cuda.memory_allocated() / 1024**3
reserved = torch.cuda.memory_reserved() / 1024**3
print(f"할당된 메모리: {allocated:.2f} GB")
print(f"예약된 메모리: {reserved:.2f} GB")
# 추론 테스트
params = SamplingParams(temperature=0.7, max_tokens=256)
output = llm.generate(["안녕하세요"], params)
김개발 씨는 메모리 부족 문제를 해결하기 위해 여러 방법을 시도했습니다. 가장 효과적인 것은 **양자화(Quantization)**였습니다.
양자화란 무엇일까요? 쉽게 말하면 모델의 정밀도를 낮추는 것입니다.
원래 모델은 16비트(FP16) 부동소수점을 사용하는데, 이것을 4비트나 8비트 정수로 변환합니다. 마치 고화질 사진을 적당히 압축하는 것과 비슷합니다.
파일 크기는 줄어들지만 눈으로 보기에는 거의 차이가 없습니다. vLLM이 지원하는 양자화 방식은 여러 가지가 있습니다.
**AWQ(Activation-aware Weight Quantization)**는 가장 인기 있는 방식으로, 품질 손실이 적으면서도 메모리를 크게 절약합니다. GPTQ도 널리 사용되며, HuggingFace Hub에서 미리 양자화된 모델을 쉽게 구할 수 있습니다.
양자화 모델을 사용하면 7B 모델이 약 4-5GB 정도의 VRAM만 사용합니다. 원래 14GB 정도 필요했던 것에 비하면 거의 3분의 1 수준입니다.
덕분에 RTX 4090에서도 여유 있게 서비스할 수 있게 되었습니다. gpu_memory_utilization 파라미터도 중요합니다.
이것은 vLLM이 GPU 메모리의 몇 퍼센트를 사용할지 결정합니다. 기본값은 0.9(90%)인데, 다른 프로세스와 GPU를 공유해야 한다면 이 값을 낮춰야 합니다.
max_model_len은 모델이 처리할 수 있는 최대 토큰 길이입니다. 이 값이 크면 긴 대화를 처리할 수 있지만, KV Cache 메모리를 더 많이 사용합니다.
서비스 특성에 맞게 적절히 조절해야 합니다. 김개발 씨의 챗봇은 짧은 질의응답 위주라서 4096으로 충분했습니다.
max_num_seqs는 동시에 처리할 수 있는 최대 시퀀스(요청) 수입니다. 이 값을 높이면 처리량이 증가하지만 메모리 사용량도 늘어납니다.
서비스의 동시 접속자 수를 고려하여 설정합니다. 박시니어 씨가 한 가지 팁을 알려주었습니다.
"enforce_eager=False로 설정하면 CUDA Graph를 사용해서 더 빨라져요. 다만 메모리를 조금 더 쓰니까 여유가 있을 때 켜세요." 메모리 사용량을 모니터링하는 것도 중요합니다.
torch.cuda.memory_allocated()로 실제 사용 중인 메모리를, torch.cuda.memory_reserved()로 예약된 메모리를 확인할 수 있습니다. 프로덕션에서는 이 값들을 주기적으로 로깅하여 메모리 누수가 없는지 확인합니다.
김개발 씨는 최적화 설정을 적용한 후 테스트를 다시 실행했습니다. 이전에는 32개 동시 요청이 한계였는데, 이제는 64개까지 처리할 수 있게 되었습니다.
같은 GPU로 두 배의 트래픽을 감당할 수 있게 된 것입니다.
실전 팁
💡 - 양자화 모델은 HuggingFace에서 "모델명-AWQ" 또는 "모델명-GPTQ"로 검색하면 찾을 수 있습니다
- 메모리가 정말 부족하면 max_model_len을 2048까지 줄여보세요
6. 실전 서비스 구축
모든 최적화를 마친 김개발 씨는 드디어 프로덕션 배포를 시작했습니다. 개발 환경에서 잘 동작하는 것과 실제 서비스에서 안정적으로 운영하는 것은 전혀 다른 문제입니다.
"24시간 365일 안정적으로 동작해야 해." 김개발 씨는 긴장된 마음으로 서버 설정을 시작했습니다.
vLLM 프로덕션 배포는 OpenAI 호환 API 서버를 활용합니다. vllm.entrypoints.openai.api_server 모듈로 REST API 서버를 띄우면, 기존 OpenAI SDK를 그대로 사용할 수 있습니다.
Docker와 Kubernetes로 컨테이너화하고, 로드밸런서로 여러 인스턴스를 관리하는 것이 일반적인 아키텍처입니다.
다음 코드를 살펴봅시다.
# 1. vLLM OpenAI 호환 서버 실행 (터미널)
# python -m vllm.entrypoints.openai.api_server \
# --model Qwen/Qwen2.5-7B-Instruct-AWQ \
# --quantization awq \
# --host 0.0.0.0 --port 8000 \
# --max-model-len 4096
# 2. 클라이언트 코드 (OpenAI SDK 호환)
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # vLLM은 API 키 불필요
)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct-AWQ",
messages=[
{"role": "user", "content": "vLLM으로 서비스 구축하는 방법을 알려주세요"}
],
temperature=0.7,
max_tokens=512
)
print(response.choices[0].message.content)
프로덕션 배포에서 가장 큰 장점은 vLLM이 OpenAI 호환 API를 제공한다는 것입니다. 이것이 왜 중요할까요?
많은 기업들이 이미 OpenAI API를 사용하고 있습니다. 클라이언트 코드, SDK 연동, 에러 처리 등이 모두 OpenAI 형식에 맞춰져 있습니다.
vLLM의 OpenAI 호환 서버를 사용하면, 기존 코드를 거의 수정하지 않고 자체 모델로 전환할 수 있습니다. base_url만 바꾸면 됩니다.
김개발 씨는 먼저 API 서버를 띄웠습니다. 명령어 한 줄로 서버가 시작되었습니다.
8000번 포트에서 요청을 기다리고 있습니다. 클라이언트 코드는 정말 간단했습니다.
기존에 OpenAI API를 호출하던 코드에서 base_url만 로컬 서버 주소로 변경했습니다. 나머지는 완전히 동일합니다.
chat.completions.create 메서드, messages 형식, temperature와 max_tokens 파라미터 모두 그대로 사용할 수 있습니다. 프로덕션 환경에서는 Docker를 사용하는 것이 필수입니다.
환경 일관성을 보장하고, 배포와 롤백을 쉽게 할 수 있습니다. vLLM 공식 Docker 이미지를 기반으로 필요한 설정을 추가하면 됩니다.
헬스체크도 중요합니다. vLLM 서버는 /health 엔드포인트를 제공합니다.
로드밸런서나 Kubernetes가 이 엔드포인트를 주기적으로 호출하여 서버 상태를 확인합니다. 문제가 발생하면 자동으로 트래픽을 다른 인스턴스로 돌립니다.
모니터링도 빼놓을 수 없습니다. vLLM은 Prometheus 형식의 메트릭을 /metrics 엔드포인트로 제공합니다.
처리량, 지연시간, 대기열 길이 등을 실시간으로 모니터링할 수 있습니다. Grafana 대시보드를 구성하면 한눈에 서비스 상태를 파악할 수 있습니다.
박시니어 씨가 마지막 조언을 해주었습니다. "트래픽이 늘어나면 수평 확장을 고려해야 해요.
vLLM 서버를 여러 대 띄우고 앞에 로드밸런서를 두면 됩니다. 각 서버가 독립적으로 동작하니까 확장이 쉬워요." 김개발 씨는 모든 설정을 마치고 서비스를 런칭했습니다.
사용자들의 반응은 뜨거웠습니다. "응답이 정말 빨라졌어요!" "이전보다 훨씬 쾌적해요!" 팀장님이 김개발 씨를 칭찬했습니다.
"덕분에 GPU 비용도 절감하고 사용자 경험도 개선됐어요. 수고했습니다." 김개발 씨는 뿌듯한 미소를 지었습니다.
vLLM 덕분에 어려운 문제를 해결할 수 있었습니다. 여러분도 이 가이드를 따라 자신만의 LLM 서비스를 구축해 보세요.
생각보다 어렵지 않습니다.
실전 팁
💡 - 프로덕션에서는 반드시 --api-key 옵션으로 인증을 추가하세요
- 서버 시작 시 --disable-log-requests 옵션으로 불필요한 로깅을 줄여 성능을 높일 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Web UI Demo 구축 완벽 가이드
Gradio를 활용하여 머신러닝 모델과 AI 서비스를 위한 웹 인터페이스를 구축하는 방법을 다룹니다. 코드 몇 줄만으로 전문적인 데모 페이지를 만들고 배포하는 과정을 초급자도 쉽게 따라할 수 있도록 설명합니다.
Sandboxing & Execution Control 완벽 가이드
AI 에이전트가 코드를 실행할 때 반드시 필요한 보안 기술인 샌드박싱과 실행 제어에 대해 알아봅니다. 격리된 환경에서 안전하게 코드를 실행하고, 악성 동작을 탐지하는 방법을 단계별로 설명합니다.
Voice Design then Clone 워크플로우 완벽 가이드
AI 음성 합성에서 일관된 캐릭터 음성을 만드는 Voice Design then Clone 워크플로우를 설명합니다. 참조 음성 생성부터 재사용 가능한 캐릭터 구축까지 실무 활용법을 다룹니다.
Tool Use 완벽 가이드 - Shell, Browser, DB 실전 활용
AI 에이전트가 외부 도구를 활용하여 셸 명령어 실행, 브라우저 자동화, 데이터베이스 접근 등을 수행하는 방법을 배웁니다. 실무에서 바로 적용할 수 있는 패턴과 베스트 프랙티스를 담았습니다.
실전 인프라 자동화 프로젝트 완벽 가이드
Ansible을 활용하여 멀티 티어 웹 애플리케이션 인프라를 자동으로 구축하는 실전 프로젝트입니다. 웹 서버, 데이터베이스, 로드 밸런서를 코드로 관리하며 반복 가능한 인프라 배포를 경험합니다.