LLM 엔지니어링16장 · vLLM 서빙 벤치마킹과 RAG 최적화9 / 22← 이전목차다음 →MetaContents

16장. vLLM 서빙 벤치마킹과 RAG 최적화

vLLM 띄우고 재기

새 주방 설비는 매장이 아니라 설비를 받쳐 줄 전기와 배관이 있는 곳에 놓아야 합니다. vLLM 도 Linux 와 NVIDIA GPU 를 바탕으로 만들어져, Windows 에서는 바로 설치되지 않습니다. Linux 서버나 Windows 의 WSL2(윈도 안의 리눅스)에서 띄웁니다.

Linux 나 WSL2 에 설치하고, 서버를 띄우고, OpenAI 꼴로 부르고, 벤치마크 명령으로 재는 네 단계 흐름도

1번은 Linux(또는 WSL2)의 파이썬 환경에 vLLM 을 설치합니다. 2번은 vllm serve 로 모델을 올려 OpenAI 호환 서버를 띄웁니다. 3번은 지금까지의 openai 코드에서 주소만 바꿔 부릅니다. 4번은 vLLM 에 들어 있는 벤치마크 명령으로 TTFT, TPOT, 처리량을 잽니다. 전기와 배관이 Linux 와 GPU 드라이버, 새 설비가 vLLM 입니다.

띄울 때 쓰는 옵션

옵션뜻4GB GPU 에서
--max-model-len요청 하나의 최대 토큰 수줄여야 KV 캐시 자리가 남는다(예: 4096)
--gpu-memory-utilizationvLLM 이 잡을 GPU 메모리의 몫0.85 안팎
--dtype계산 정밀도GTX 1650 은 bf16 이 없어 half(fp16)
--max-num-seqs연속 배치에 함께 넣을 최대 요청 수메모리에 맞춰 줄인다
--enable-prefix-caching앞부분이 같은 프롬프트의 KV 캐시를 다시 쓴다켜 둔다

서버 띄우기

아래는 이 PC 에서 실행하지 않은 안내 코드입니다. vLLM 은 GPU 의 계산 능력(compute capability)이 7.0 이상이어야 하는데 GTX 1650 은 7.5 라서 조건은 맞지만, 4GB 에서는 0.5B 급 모델만 넉넉히 올라갑니다.

출력
# Linux 나 WSL2 의 우분투 터미널에서
python -m venv vllm-env && source vllm-env/bin/activate
pip install vllm
vllm serve Qwen/Qwen2.5-0.5B-Instruct --dtype half --max-model-len 4096 \
    --gpu-memory-utilization 0.85 --enable-prefix-caching --port 8000

예상 출력(실행하지 않고 유추한 예시)입니다. 판과 GPU 에 따라 글귀와 숫자가 다릅니다.

출력
INFO  ... Loading model weights took 약 1GB
INFO  ... GPU KV cache size: 약 수만 tokens
INFO  ... Maximum concurrency for 4,096 tokens per request: 약 10배 안팎
INFO  ... Starting vLLM API server on http://0.0.0.0:8000

벤치마크 명령

같은 서버를 vLLM 의 벤치마크 명령으로 잽니다. 이것도 이 PC 에서 실행하지 않은 안내 코드입니다.

출력
vllm bench serve --model Qwen/Qwen2.5-0.5B-Instruct --base-url http://127.0.0.1:8000 \
    --dataset-name random --random-input-len 256 --random-output-len 128 \
    --num-prompts 200 --max-concurrency 16

예상 출력(실행하지 않고 유추한 예시)입니다. 실제 숫자는 GPU 에 따라 몇 배씩 달라집니다.

출력
============ Serving Benchmark Result ============
Successful requests:            200
Request throughput (req/s):     약 수 개
Output token throughput (tok/s): 약 수백~1천
Mean TTFT (ms):                 약 수십~수백
Mean TPOT (ms):                 약 10~30
P99 TTFT (ms):                  평균보다 몇 배 크다
==================================================

부르는 코드 꼴

서버가 뜨면 Ollama 를 부르던 코드에서 주소와 모델 이름만 바꿉니다. 아래 코드는 요청 본문을 만들어 보기만 하고 서버에 보내지는 않습니다.

Python
import json

base_url = "http://127.0.0.1:8000/v1"      # vLLM 서버 주소(Ollama 는 11434 포트)
request = {
    "model": "Qwen/Qwen2.5-0.5B-Instruct",
    "messages": [{"role": "system", "content": "규정 도우미입니다."},
                 {"role": "user", "content": "재택 근무는 며칠까지 되나요?"}],
    "max_tokens": 80, "temperature": 0, "stream": True,   # stream 이면 TTFT 를 잴 수 있다
}
print("POST", base_url + "/chat/completions")
print(json.dumps(request, ensure_ascii=False)[:120], "...")

코드에 나오는 함수

코드쉬운 뜻
"role": "system"system(시스템)은 모델이 지킬 역할과 규칙을 주는 말이다. "user" 는 사용자의 질문이다
"stream": Truestream(시냇물, 흐름)처럼 답을 다 만들기 전에 토큰이 생기는 대로 조금씩 보내게 한다. 첫 조각이 오는 때로 TTFT 를 잰다
json.dumps(request, ...)JSON(JavaScript Object Notation) 글자로 바꾼다. dumps 는 dump string(글자로 쏟아 내기)의 줄임말이다
ensure_ascii=FalseASCII(American Standard Code for Information Interchange, 영문 위주의 기본 글자표) 밖의 글자도 그대로 둔다. 한글이 연 같은 꼴로 바뀌지 않는다
[:120]글자가 길어 앞의 120자만 보여 준다

이 코드가 뜻하는 것

우체국에 가기 전에 봉투에 받는 곳 주소를 쓰고 편지를 넣어 보기만 하는 일과 같습니다. 아직 부치지는 않습니다. 여기서 봉투의 주소가 base_url + "/chat/completions", 편지가 request 본문입니다.

줄하는 일쉽게 말하면
base_url = ...vLLM 서버 주소를 적는다받는 곳 주소
request = {...}모델 이름, 대화, 길이, 온도, 스트리밍을 담는다편지 내용
print("POST", ...)보낼 주소를 찍는다. POST 는 "부치다"라는 뜻의 HTTP 방식이다봉투의 주소를 확인한다
print(json.dumps(...)[:120], "...")본문을 JSON 글자로 바꿔 앞부분만 찍는다편지의 첫 줄을 훑어본다

출력은 주소 한 줄과, 한글이 그대로 보이는 JSON 앞부분 한 줄입니다. 서버에 보내지 않으므로 vLLM 이 없어도 돌아갑니다.

작게 줄여서 눈으로 보기

ensure_ascii 를 주고 안 주고의 차이를 봅니다.

Python
import json

body = {"질문": "연차"}
print(json.dumps(body))                       # 기본값: 한글을 \u 꼴로 바꾼다
print(json.dumps(body, ensure_ascii=False))   # 한글을 그대로 둔다
print(json.dumps(body, ensure_ascii=False)[:5], "...")   # 앞 다섯 글자만
출력
{"\uc9c8\ubb38": "\uc5f0\ucc28"}
{"질문": "연차"}
{"질문" ...
결과읽는 법
{"질문": "연차"}기본값에서는 한글을 \u 뒤 번호로 바꿔 적는다. 서버는 읽을 수 있지만 사람은 읽기 어렵다
{"질문": "연차"}ensure_ascii=False 를 주면 한글이 그대로 나온다
{"질문" ...글자 자르기 [:5] 로 앞 다섯 글자만 남겼다

주의할 점

  • vLLM 은 시작할 때 GPU 메모리를 크게 잡아 두므로, 같은 GPU 에서 Ollama 나 다른 모델을 함께 돌리기 어렵습니다.
  • 공개 벤치마크의 숫자는 큰 GPU 에서 잰 것이 많습니다. 우리 GPU 와 우리 질문 길이로 다시 재야 계획을 세울 수 있습니다.
← 이전 절16장 · 벤치마크를 바르게 재기다음 절 →16장 · RAG 파이프라인의 병목