벤치마크 CLI

벤치마크 CLI (Benchmark CLI)

이 섹션은 vLLM이 지원하는 다양한 데이터셋으로 벤치마크 테스트를 실행하는 방법을 안내해요. 새 기능과 데이터셋이 생길 때마다 함께 갱신되는 살아있는 문서예요.

!!! tip 이 페이지의 벤치마크는 주로 vLLM 특정 기능을 평가하고 회귀 테스트를 하는 데 목적이 있어요.

운영 중인 vLLM 서버를 벤치마킹할 때는 [GuideLLM](https://github.com/vllm-project/guidellm)을 추천해요. 라이브 진행 표시와 자동 리포트 생성을 갖춘 검증된 성능 벤치마킹 프레임워크거든요. 데이터셋 로딩, 요청 포맷, 워크로드 패턴 면에서도 `vllm bench serve`보다 더 유연해요.

데이터셋 개요 (Dataset Overview)

지원되는 데이터셋은 아래 표와 같아요. 온라인(online) 벤치마크와 오프라인(offline) 벤치마크 양쪽에서 쓸 수 있는지가 표시돼요.

Dataset Online Offline Data Path
ShareGPT wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
ShareGPT4V (Image) wget https://huggingface.co/datasets/Lin-Chen/ShareGPT4V/resolve/main/sharegpt4v_instruct_gpt4-vision_cap100k.json
Note that the images need to be downloaded separately. For example, to download COCO's 2017 Train images:
wget http://images.cocodataset.org/zips/train2017.zip
ShareGPT4Video (Video) git clone https://huggingface.co/datasets/ShareGPT4Video/ShareGPT4Video
BurstGPT wget https://github.com/HPMLL/BurstGPT/releases/download/v1.1/BurstGPT_without_fails_2.csv
Sonnet (deprecated) Local file: benchmarks/sonnet.txt
Random synthetic
RandomMultiModal (Image/Video) synthetic
RandomForReranking synthetic
Prefix Repetition synthetic
HuggingFace-VisionArena lmarena-ai/VisionArena-Chat
HuggingFace-MMVU yale-nlp/MMVU
HuggingFace-InstructCoder likaixin/InstructCoder
HuggingFace-AIMO AI-MO/aimo-validation-aime, AI-MO/NuminaMath-1.5, AI-MO/NuminaMath-CoT
HuggingFace-Other lmms-lab/LLaVA-OneVision-Data, Aeala/ShareGPT_Vicuna_unfiltered
HuggingFace-MTBench philschmid/mt-bench
HuggingFace-HumanEval openai/openai_humaneval
HuggingFace-GSM8K openai/gsm8k
HuggingFace-Blazedit vdaita/edit_5k_char, vdaita/edit_10k_char
HuggingFace-ASR openslr/librispeech_asr, facebook/voxpopuli, LIUM/tedlium, edinburghcstr/ami, speechcolab/gigaspeech, kensho/spgispeech, ArtificialAnalysis/Earnings22-Cleaned-AA, D4nt3/esb-datasets-earnings22-validation-tiny-filtered
Spec Bench wget https://raw.githubusercontent.com/hemingkx/Spec-Bench/refs/heads/main/data/spec_bench/question.jsonl
SPEED-Bench curl -LsSf https://raw.githubusercontent.com/NVIDIA-NeMo/Skills/refs/heads/main/nemo_skills/dataset/speed-bench/prepare.py | python3 -
Custom Local file: data.jsonl
Custom Audio Local file: audio_data.jsonl
Custom Image Local file: image_data.jsonl

범례:

  • ✅ - 지원
  • 🟡 - 부분 지원
  • 🚧 - 지원 예정

!!! note HuggingFace 데이터셋의 dataset-namehf로 설정해야 해요. 로컬 dataset-path를 쓸 때는 hf-name을 그 Hugging Face ID로 설정하세요:

```bash
--dataset-path /datasets/VisionArena-Chat/ --hf-name lmarena-ai/VisionArena-Chat
```

예시 (Examples)

🚀 온라인 벤치마크 (Online Benchmark)

Show more

먼저 모델을 서빙하는 것으로 시작해요:

vllm serve NousResearch/Hermes-3-Llama-3.1-8B

그 다음 벤치마킹 스크립트를 실행해요:

# download dataset
# wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
vllm bench serve \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --endpoint /v1/completions \
  --dataset-name sharegpt \
  --dataset-path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json \
  --num-prompts 10

성공하면 다음과 같은 결과가 나와요:

============ Serving Benchmark Result ============
Successful requests:                     10
Benchmark duration (s):                  5.78
Total input tokens:                      1369
Total generated tokens:                  2212
Request throughput (req/s):              1.73
Output token throughput (tok/s):         382.89
Total token throughput (tok/s):          619.85
---------------Time to First Token----------------
Mean TTFT (ms):                          71.54
Median TTFT (ms):                        73.88
P99 TTFT (ms):                           79.49
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          7.91
Median TPOT (ms):                        7.96
P99 TPOT (ms):                           8.03
---------------Inter-token Latency----------------
Mean ITL (ms):                           7.74
Median ITL (ms):                         7.70
P99 ITL (ms):                            8.39
==================================================

!!! warning 같은 서버에 vllm bench serve를 반복하면 prefix cache에 남은 프롬프트를 재사용해서 처리량이 부풀려질 수 있어요. 이는 재현 가능한 어떤 데이터셋에도 영향을 줄 수 있어요. 합성 랜덤 데이터셋은 고정 --seed(기본값 0)에 대해 재현 가능해요. prefix cache 히트는 한 실행 안에서 공유 프리픽스 때문에도 생길 수 있으니, 캐시 지표를 워크로드 맥락에서 해석해야 해요. 캐시 재사용을 원하지 않으면 --seed를 바꾸거나 서버를 리셋·재시작하거나, 실행 사이에 서버 캐시를 리셋하는 vllm bench sweep serve를 쓰세요.

지연 메트릭 이해하기 (Understanding the Latency Metrics)

vllm bench serve는 벤치마크 클라이언트에서 지연을 측정해요:

!!! note 메트릭 용어는 벤치마킹 도구마다 표준화되어 있지 않아요. 결과를 비교할 때는 메트릭 이름만이 아니라 측정 지점과 공식을 기준으로 하세요. 이 섹션은 vLLM에서 그 메트릭들을 어떻게 부르는지 설명해요.

  • Time to first token (TTFT) 는 요청을 보낸 시점부터 첫 번째 스트리밍 출력을 받을 때까지의 시간이에요.

  • Inter-token latency (ITL) 는 연속된 스트리밍 출력 사이의 시간을 기록해요. 보고되는 ITL 통계는 모든 성공 요청에서 이 개별 간격들을 집계한 것이에요.

  • Time per output token (TPOT) 은 요청마다 첫 토큰을 제외하고 한 번 계산한 뒤 요청 간에 집계돼요:

    $$ \text{TPOT} = \frac{\text{end-to-end latency} - \text{TTFT}} {\text{number of output tokens} - 1} $$

표준 디코딩에서는 각 스트리밍 출력이 보통 토큰 하나를 담으므로 ITL과 TPOT는 대체로 비슷해요.

추측 디코딩(speculative decoding)에서는 스트리밍 출력 하나에 여러 토큰이 들어갈 수 있어요. 예를 들어 한 엔진 tstep 안에서 여러 개의 허용된 draft 토큰이 담길 수 있죠. ITL은 스트리밍 출력 사이의 간격만 기록하고, 같은 출력 안의 토큰에 대해 0-지속시간 간격을 추가하지 않아요. 반면 TPOT은 요청의 디코딩 시간을 모든 출력 토큰에 걸쳐 분산시켜요.

이 예시에서 벤치마크는 두 개의 40ms ITL 샘플을 관찰해요. 두 번째 스트리밍 출력의 세 토큰은 추가 ITL 샘플을 만들지 않으므로 mean ITL은 40ms예요. TPOT은 (180 ms - 100 ms) / (5 - 1) = 20 ms/token이에요.

결과 시각화 (Results Visualization)

--plot-timeline--plot-dataset-stats는 각각 요청 완료 타임라인과 데이터셋 프롬프트·출력 토큰 통계를 생성해요. 디버깅이나 더 깊은 분석에 유용해요.

vllm bench serve \
    --backend vllm \
    --model meta-llama/Llama-3.1-8B-Instruct \
    --endpoint /v1/completions \
    --dataset-name sharegpt \
    --dataset-path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json \
    --num-prompts 100 \
    --plot-timeline \
    --timeline-itl-thresholds 2,5 \
    --plot-dataset-stats \
    --save-result
대화형 타임라인 (Interactive Timeline)

생성된 타임라인은 대부분의 브라우저에서 렌더링할 수 있는 HTML 형식의 대화형 시각화예요. ITL 색상 임계값을 커스터마이즈하려면 --timeline-itl-thresholds 플래그(기본값 25ms, 50ms)를 쓰면 돼요.

데이터셋 통계 (Dataset statistics)

생성된 그림은 입력 프롬프트와 출력 토큰 분포를 보여줘요.

커스텀 데이터셋 (Custom Dataset)

벤치마킹할 데이터셋이 vLLM에 아직 지원되지 않아도 CustomDataset로 벤치마킹할 수 있어요. 추론 시 --dataset-name custom 옵션을 쓰세요. 데이터는 .jsonl 형식이어야 하고 항목마다 "prompt" 필드가 있어야 해요. 예를 들어 data.jsonl은 이렇게 생겼어요:

{"prompt": "What is the capital of India?"}
{"prompt": "What is the capital of Iran?"}
{"prompt": "What is the capital of China?"}
# start server
vllm serve meta-llama/Llama-3.1-8B-Instruct
# run benchmarking script
vllm bench serve --port 9001 --save-result --save-detailed \
  --backend vllm \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --endpoint /v1/completions \
  --dataset-name custom \
  --dataset-path <path-to-your-data-jsonl> \
  --skip-chat-template \
  --num-prompts 80 \
  --max-concurrency 1 \
  --temperature=0.3 \
  --top-p=0.75 \
  --result-dir "./log/"

데이터에 chat template이 이미 적용되어 있다면 --skip-chat-template로 적용을 건너뛸 수 있어요.

커스텀 오디오 데이터셋 (Custom Audio Dataset)

지원되지 않는 오디오 데이터셋은 CustomAudioDataset로 벤치마킹할 수 있어요. 추론 시 --dataset-name custom_audio 옵션을 쓰세요. 데이터는 .jsonl 형식이고 항목마다 "prompt"와 "audio" 필드가 있어야 해요. 예를 들어 audio_data.jsonl:

{"prompt": "What does this audio say?", "audio": "/path/to/audio_1.wav"}
{"prompt": "Transcribe the audio.", "audio": "/path/to/audio_2.wav"}
  • 지원 모델: CustomAudioDataset는 두 유형의 오디오 모델을 지원해요. "prompt" 필드가 필요 없는 ASR 모델(예: Whisper), 그리고 멀티모달 오디오-텍스트 채팅 모델(예: Qwen2-Audio). 이 두 모델 유형은 추론 시 다른 인자가 필요하므로 예시를 두 개 보여줄게요.

  • 예시 1: Whisper

Whisper는 전용 ASR 인코더-디코더 모델이므로 --backend openai-audio--endpoint /v1/audio/transcriptions를 사용해요.

# start server
vllm serve openai/whisper-tiny
vllm bench serve \
  --model openai/whisper-tiny \
  --backend openai-audio \
  --endpoint /v1/audio/transcriptions \
  --dataset-name custom_audio \
  --dataset-path audio_data.jsonl \
  --no-oversample \
  --custom-output-len 256 \
  --save-result \
  --save-detailed \
  --result-filename whisper_bench.json
  • 예시 2: Qwen2-Audio

Qwen2-Audio는 ASR과 음성 분석을 할 수 있는 멀티모달 채팅 모델이라 --backend openai-chat--endpoint /v1/chat/completions를 사용해요. 멀티모달 채팅 변환을 켜려면 --enable-multimodal-chat도 필요해요.

vllm bench serve \
  --model Qwen/Qwen2-Audio-7B-Instruct \
  --backend openai-chat \
  --endpoint /v1/chat/completions \
  --dataset-name custom_audio \
  --dataset-path audio_data.jsonl \
  --no-oversample \
  --custom-output-len 256 \
  --enable-multimodal-chat \
  --save-result \
  --save-detailed \
  --result-filename qwen_bench.json

커스텀 이미지 데이터셋 (Custom Image Dataset)

지원되지 않는 이미지 데이터셋은 CustomImageDataset으로 벤치마킹할 수 있어요. 추론 시 --dataset-name custom_image 옵션을 쓰세요. 데이터는 .jsonl 형식이고 항목마다 "prompt"와 "image_files" 필드를 쓸 수 있어요. 예를 들어 image_data.jsonl:

{"prompt": "How many animals are present in the given image?", "image_files": ["/path/to/image/folder/horsepony.jpg"]}
{"prompt": "What colour is the bird shown in the image?", "image_files": ["/path/to/image/folder/flycatcher.jpeg"]}

"image_files"에 나열된 각 이미지는 프롬프트 텍스트 뒤에 나열된 순서대로 요청에 추가돼요. 텍스트와 이미지를 번갈아 넣는 순서를 유지하려면 OpenAI 호환 content 부분으로 "content" 필드를 쓰세요:

{"content": [{"type": "text", "text": "Compare "}, {"type": "image", "image": "/path/to/image/folder/chart_a.png"}, {"type": "text", "text": " with "}, {"type": "image_url", "image_url": {"url": "/path/to/image/folder/chart_b.png"}}]}

"image" 약칭은 "image_files"와 같은 값을 받아요. "image_url" 필드는 "url" 필드가 있는 OpenAI 스타일 객체 또는 URL 문자열을 받아요.

기본적으로 이미지 참조는 제공된 대로 서빙 엔드포인트로 보내지고, 로컬 이미지 경로는 file:// URL로 변환돼요.

벤치마크 클라이언트가 로컬·HTTP(S) 이미지를 요청 전에 로드해야 한다면 --custom-ensure-client-side-data를 넘겨 클라이언트 쪽에서 base64 data URL로 인코딩하세요.

기존 data:image/... URL은 이미 자체 포함이라 그대로 유지돼요.

# need a model with vision capability here
vllm serve Qwen/Qwen2-VL-7B-Instruct
# run benchmarking script
vllm bench serve --save-result --save-detailed \
  --backend openai-chat \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --endpoint /v1/chat/completions \
  --dataset-name custom_image \
  --dataset-path <path-to-your-image-data-jsonl> \
  --custom-ensure-client-side-data

멀티모달 입력에는 openai-chat 백엔드와 /v1/chat/completions 엔드포인트를 써야 한다는 점을 기억하세요.

비전 언어 모델용 VisionArena 벤치마크

# need a model with vision capability here
vllm serve Qwen/Qwen2-VL-7B-Instruct
vllm bench serve \
  --backend openai-chat \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --endpoint /v1/chat/completions \
  --dataset-name hf \
  --dataset-path lmarena-ai/VisionArena-Chat \
  --hf-split train \
  --num-prompts 1000

추측 디코딩을 사용한 InstructCoder 벤치마크

vllm serve meta-llama/Meta-Llama-3-8B-Instruct \
    --speculative-config $'{"method": "ngram",
    "num_speculative_tokens": 5, "prompt_lookup_max": 5,
    "prompt_lookup_min": 2}'
vllm bench serve \
    --model meta-llama/Meta-Llama-3-8B-Instruct \
    --dataset-name hf \
    --dataset-path likaixin/InstructCoder \
    --num-prompts 2048

추측 디코딩을 사용한 Spec Bench 벤치마크

vllm serve meta-llama/Meta-Llama-3-8B-Instruct \
    --speculative-config $'{"method": "ngram",
    "num_speculative_tokens": 5, "prompt_lookup_max": 5,
    "prompt_lookup_min": 2}'

SpecBench 데이터셋

모든 카테고리 실행:

# Download the dataset using:
# wget https://raw.githubusercontent.com/hemingkx/Spec-Bench/refs/heads/main/data/spec_bench/question.jsonl

vllm bench serve \
    --model meta-llama/Meta-Llama-3-8B-Instruct \
    --dataset-name spec_bench \
    --dataset-path "<YOUR_DOWNLOADED_PATH>/data/spec_bench/question.jsonl" \
    --num-prompts -1

사용 가능한 카테고리는 [writing, roleplay, reasoning, math, coding, extraction, stem, humanities, translation, summarization, qa, math_reasoning, rag]예요.

"summarization" 같이 특정 카테고리만 실행:

vllm bench serve \
    --model meta-llama/Meta-Llama-3-8B-Instruct \
    --dataset-name spec_bench \
    --dataset-path "<YOUR_DOWNLOADED_PATH>/data/spec_bench/question.jsonl" \
    --num-prompts -1 \
    --spec-bench-category "summarization"

추측 디코딩을 사용한 SPEED-Bench 벤치마크

SPEED-Bench는 추측 디코딩을 위한 통합·다양한 데이터셋이에요. Qualitative split으로 acceptance rate·length를, 5가지 입력 시퀀스 길이(1k, 2k, 8k, 16k, 32k) 구성의 Throughput split으로 처리량을 측정해요.

!!! note 이 데이터셋은 NVIDIA Evaluation Dataset License Agreement를 따릅니다. 사용자가 선택한 각 데이터셋에 대해, 해당 데이터셋 라이선스가 의도한 목적에 맞는지 확인할 책임은 사용자에게 있어요. prepare.py 스크립트는 모든 원본 데이터셋에서 자동으로 데이터를 가져와요.

먼저 이 원라이너로 데이터셋을 폴더에 내려받아요:

curl -LsSf https://raw.githubusercontent.com/NVIDIA-NeMo/Skills/refs/heads/main/nemo_skills/dataset/speed-bench/prepare.py | python3 -

이 명령은 다음 인자도 지원해요:

  • --config: 데이터셋 일부만 내려받기: qualitative, throughput_1k, throughput_2k, throughput_8k, throughput_16k, throughput_32k. 기본값은 모든 하위 집합을 내려받아요.
  • --output_dir: 지정한 폴더로 내려받기. 기본값은 현재 디렉터리예요.

추측 디코딩으로 서버를 시작해요:

vllm serve meta-llama/Llama-3.3-70B-Instruct \
    --speculative-config $'{"method": "eagle3",
    "num_speculative_tokens": 3,
    "model": "nvidia/Llama-3.3-70B-Instruct-Eagle3"}'

Qualitative split의 모든 카테고리 실행:

vllm bench serve \
    --model meta-llama/Llama-3.3-70B-Instruct \
    --dataset-name speed_bench \
    --dataset-path "<YOUR_DOWNLOADED_PATH>/data/speed_bench" \
    --num-prompts -1

사용 가능한 카테고리는 [writing, roleplay, reasoning, math, coding, stem, humanities, multilingual, summarization, qa, rag]예요.

"multilingual" 같이 특정 카테고리만 실행:

vllm bench serve \
    --model meta-llama/Llama-3.3-70B-Instruct \
    --dataset-name speed_bench \
    --dataset-path "<YOUR_DOWNLOADED_PATH>/data/speed_bench" \
    --num-prompts -1 \
    --speed-bench-category "multilingual"

Throughput split (2k ISL)의 모든 카테고리 실행:

vllm bench serve \
    --model meta-llama/Llama-3.3-70B-Instruct \
    --dataset-name speed_bench \
    --speed-bench-dataset-subset throughput_2k \
    --dataset-path "<YOUR_DOWNLOADED_PATH>/data/speed_bench/" \
    --num-prompts -1

사용 가능한 카테고리는 [high_entropy, mixed, low_entropy]예요. high entropy 데이터는 창작 글쓰기 같은 비정형 데이터를, low entropy 데이터는 코딩 같은 더 구조화된 데이터를 담아요. 자세한 내용은 데이터셋 카드를 참고하세요.

BFCL(도구 호출) 벤치마크

Berkeley Function Calling Leaderboard(BFCL) 데이터셋은 현실적인 도구 호출 트래픽에서 서빙 지연·처리량을 측정해요. 각 요청은 샘플별 tools 스키마와 채팅 히스토리를 담으므로, 서버는 auto-tool-choice 파서를 켠 /v1/chat/completions를 노출해야 해요. 벤치마크 클라이언트는 항상 openai-chat 백엔드를 사용해요.

도구 파서가 켜진 서버를 시작한 뒤 벤치를 실행해요. 예를 들어 gpt-oss-20b로:

# Server
vllm serve openai/gpt-oss-20b \
    --enable-auto-tool-choice \
    --tool-call-parser openai \
    --reasoning-parser openai_gptoss

# Client
vllm bench serve \
    --backend openai-chat \
    --endpoint /v1/chat/completions \
    --model openai/gpt-oss-20b \
    --dataset-name hf \
    --dataset-path gorilla-llm/Berkeley-Function-Calling-Leaderboard \
    --bfcl-categories simple,live_simple,multiple \
    --num-prompts 200

--bfcl-categories는 쉼표로 구분된 BFCL v3 카테고리 이름 목록이에요(BFCL_v3_ 프리픽스나 .json 접미사 없이). 기본값은 simple,live_simple,multiple이에요. 지원되는 다른 비멀티턴 카테고리로는 parallel, live_parallel, parallel_multiple, live_parallel_multiple, irrelevance, live_irrelevance, live_relevance, java, javascript, rest가 있어요. 멀티턴 카테고리는 아직 지원되지 않아요.

데이터셋 클래스는 BFCL의 느슨한 스키마 방언(dictobject, floatnumber, tuplearray, anystring)을 정규화해서 현대 grammar 백엔드가 번역된 도구 정의를 받아들이게 해요.

기타 HuggingFaceDataset 예시들

vllm serve Qwen/Qwen2-VL-7B-Instruct

lmms-lab/LLaVA-OneVision-Data:

vllm bench serve \
  --backend openai-chat \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --endpoint /v1/chat/completions \
  --dataset-name hf \
  --dataset-path lmms-lab/LLaVA-OneVision-Data \
  --hf-split train \
  --hf-subset "chart2text(cauldron)" \
  --num-prompts 10

Aeala/ShareGPT_Vicuna_unfiltered:

vllm bench serve \
  --backend openai-chat \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --endpoint /v1/chat/completions \
  --dataset-name hf \
  --dataset-path Aeala/ShareGPT_Vicuna_unfiltered \
  --hf-split train \
  --num-prompts 10

AI-MO/aimo-validation-aime:

vllm bench serve \
    --model Qwen/QwQ-32B \
    --dataset-name hf \
    --dataset-path AI-MO/aimo-validation-aime \
    --num-prompts 10 \
    --seed 42

philschmid/mt-bench:

vllm bench serve \
    --model Qwen/QwQ-32B \
    --dataset-name hf \
    --dataset-path philschmid/mt-bench \
    --num-prompts 80

openai/openai_humaneval:

vllm bench serve \
    --model NousResearch/Hermes-3-Llama-3.1-8B \
    --dataset-name hf \
    --dataset-path openai/openai_humaneval \
    --num-prompts 80

openai/gsm8k:

vllm bench serve \
    --model NousResearch/Hermes-3-Llama-3.1-8B \
    --dataset-name hf \
    --dataset-path openai/gsm8k \
    --num-prompts 80

vdaita/edit_5k_char 또는 vdaita/edit_10k_char:

vllm bench serve \
    --model Qwen/QwQ-32B \
    --dataset-name hf \
    --dataset-path vdaita/edit_5k_char \
    --num-prompts 90 \
    --blazedit-min-distance 0.01 \
    --blazedit-max-distance 0.99

openslr/librispeech_asr, facebook/voxpopuli, LIUM/tedlium, edinburghcstr/ami, speechcolab/gigaspeech, kensho/spgispeech, ArtificialAnalysis/Earnings22-Cleaned-AA, D4nt3/esb-datasets-earnings22-validation-tiny-filtered

vllm bench serve \
    --model openai/whisper-large-v3-turbo \
    --backend openai-audio \
    --dataset-name hf \
    --dataset-path facebook/voxpopuli --hf-subset en --hf-split test --no-stream --trust-remote-code \
    --num-prompts 99999999 \
    --no-oversample \
    --endpoint /v1/audio/transcriptions \
    --ready-check-timeout-sec 600 \
    --save-result \
    --max-concurrency 512

샘플링 파라미터로 실행하기

vllm 같은 OpenAI 호환 백엔드를 쓸 때는 선택적 샘플링 파라미터를 지정할 수 있어요. 클라이언트 명령 예시:

vllm bench serve \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --endpoint /v1/completions \
  --dataset-name sharegpt \
  --dataset-path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json \
  --top-k 10 \
  --top-p 0.9 \
  --temperature 0.5 \
  --num-prompts 10

램프업 요청률로 실행하기

벤치마크 도구는 벤치마크 실행 시간 동안 요청률을 점진적으로 높이는 것도 지원해요. 이는 서버를 스트레스 테스트하거나, 주어진 지연 예산 안에서 서버가 처리할 수 있는 최대 처리량을 찾는 데 유용해요.

두 가지 램프업 전략이 지원돼요:

  • linear: 시작값에서 끝값으로 요청률을 선형으로 높여요.
  • exponential: 요청률을 지수적으로 높여요.

램프업을 제어하는 인자는 다음과 같아요:

  • --ramp-up-strategy: 사용할 램프업 전략(linear 또는 exponential).
  • --ramp-up-start-rps: 벤치마크 시작 시의 요청률.
  • --ramp-up-end-rps: 벤치마크 종료 시의 요청률.

프로브 요청 (Probe Requests)

벤치마크 도구는 메인 워크로드와 함께 프로브 요청을 보내는 것도 지원해요. 이는 메인 워크로드가 서버를 공유하는 무관한 트래픽에 어떻게 영향을 주는지 측정할 때 유용해요. 예를 들어 큰 이미지를 가진 몇 개의 요청이 멀티모달 전처리가 프론트엔드를 점유하는 동안 동시에 가벼운 요청을 지연시키는 상황 같은 거죠.

--probe-request-rate를 양수로 설정하면 단일 토큰 텍스트 전용 프로브 요청을 그 비율(초당 요청 수)로 메인 워크로드와 함께 보내요. 프로브는 --max-concurrency를 우회하고 그 지연은 별도로 보고되므로, 프로브 백분위는 메인 워크로드가 무관한 요청에 주는 간섭을 직접 측정해요.

vllm bench serve \
    --model Qwen/Qwen2.5-VL-3B-Instruct \
    --backend openai-chat \
    --endpoint /v1/chat/completions \
    --dataset-name random-mm \
    --random-mm-bucket-config '{(2048, 2048, 1): 1.0}' \
    --request-rate 4 \
    --probe-request-rate 20

로드 패턴 구성 (Load Pattern Configuration)

vLLM의 벤치마크 서빙 스크립트는 요청 생성·동시성 동작을 제어하는 세 가지 핵심 파라미터로 정교한 로드 패턴 시뮬레이션을 제공해요:

로드 패턴 제어 파라미터
  • --request-rate: 요청 생성률(초당 요청 수)을 제어해요. 최대 처리량 테스트에는 inf로, 제어된 로드 시뮬레이션에는 유한값으로 설정해요.
  • --burstiness: Gamma 분포로 트래픽 변동성을 제어해요(범위: > 0). 낮은 값은 버스트한 트래픽을, 높은 값은 균일한 트래픽을 만들어요.
  • --max-concurrency: 동시에 진행 중인 미해결 요청 수를 제한해요. 인자가 없으면 동시성은 무제한이에요. 백프레셔를 시뮬레이션하려면 값을 설정하세요. 설정 시 벤치마크 클라이언트의 동시성 제한을 기다리는 시간을 보고하려면 --percentile-metricsclient_queue_time을 포함하세요. 유한한 --request-rate에서는 e2el_including_client_queue가 스케줄 상대 종료 대기 시간을 보고하고, 모든 요청이 벤치마크 시작에 도착하는 --request-rate=inf에서는 생략돼요.

이 파라미터들은 신중히 선택된 기본값과 함께 현실적인 로드 패턴을 만들기 위해 함께 작동해요. --request-rate는 기본값이 inf(무제한)라 모든 요청을 즉시 보내 최대 처리량 테스트를 해요. 유한값으로 설정하면 기본 --burstiness=1.0의 Poisson 프로세스 또는 Gamma 분포로 현실적인 요청 타이밍을 만들어요. --burstiness--request-rate가 무제한이 아닐 때만 효과가 있어요. 1.0은 자연스러운 Poisson 트래픽, 낮은 값(0.1-0.5)은 버스트 패턴, 높은 값(2.0-5.0)은 균일한 간격을 만들어요. --max-concurrency는 기본값이 None(무제한)이지만, 로드밸런서나 API 게이트웨이가 동시 연결을 제한하는 현실 세계의 제약을 시뮬레이션하도록 설정할 수 있어요. 결합하면 제한 없는 스트레스 테스트(--request-rate=inf)부터 현실적인 도착 패턴·자원 제약이 있는 프로덕션 유사 시나리오까지 모든 것을 시뮬레이션할 수 있어요.

--burstiness는 Gamma 분포로 요청 도착 패턴을 수학적으로 제어해요:

  • Shape 파라미터: burstiness
  • 변동계수(CV): $\frac{1}{\sqrt{burstiness}}$
  • 트래픽 특성:
    • burstiness = 0.1: 높은 버스트 트래픽 (CV ≈ 3.16) - 스트레스 테스트
    • burstiness = 1.0: 자연스러운 Poisson 트래픽 (CV = 1.0) - 현실적 시뮬레이션
    • burstiness = 5.0: 균일 트래픽 (CV ≈ 0.45) - 제어된 로드 테스트

사용 사례별 로드 패턴 권장:

Use Case Burstiness Request Rate Max Concurrency Description
Maximum Throughput N/A Infinite Limited Most common: Simulates load balancer/gateway limits with unlimited user demand
Realistic Testing 1.0 Moderate (5-20) Infinite Natural Poisson traffic patterns for baseline performance
Stress Testing 0.1-0.5 High (20-100) Infinite Challenging burst patterns to test resilience
Latency Profiling 2.0-5.0 Low (1-10) Infinite Uniform load for consistent timing analysis
Capacity Planning 1.0 Variable Limited Test resource limits with realistic constraints
SLA Validation 1.0 Target rate SLA limit Production-like constraints for compliance testing

이 로드 패턴은 기본 성능 특성부터 까다로운 트래픽 조건에서의 복원력까지 vLLM 배포의 다양한 측면을 평가하는 데 도움을 줘요.

Maximum Throughput 패턴(--request-rate=inf --max-concurrency=<limit>)은 프로덕션 벤치마킹에서 가장 흔히 쓰는 구성이에요.

로드 패턴을 효과적으로 구성하려면, 특히 Capacity PlanningSLA Validation에서는 시스템의 자원 한계를 이해해야 해요. 시작 시 vLLM은 로드 테스트 파라미터에 직접 영향을 주는 KV 캐시 구성을 보고해요:

GPU KV cache size: 15,728,640 tokens
Maximum concurrency for 8,192 tokens per request: 1920

여기서:

  • GPU KV 캐시 크기: 모든 동시 요청에서 캐시할 수 있는 총 토큰 수
  • 최대 동시성: 주어진 max_model_len에 대한 이론적 최대 동시 요청 수
  • 계산: max_concurrency = kv_cache_size / max_model_len

KV 캐시 지표로 로드 패턴을 구성하는 방법:

  • Capacity Planning: 보고된 최대값의 80-90%로 --max-concurrency를 설정해 현실적인 자원 제약을 테스트
  • SLA Validation: 보고된 최대값을 SLA 한도로 사용해 준수 테스트가 프로덕션 용량과 맞게
  • Realistic Testing: 이론적 한도에 가까워질 때 메모리 사용량을 모니터링해 지속 가능한 요청률 이해
  • 요청률 가이드: 특정 워크로드와 시퀀스 길이에 대한 지속 가능한 요청률을 추정하려면 KV 캐시 크기 사용

📈 오프라인 처리량 벤치마크 (Offline Throughput Benchmark)

Show more
vllm bench throughput \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --dataset-name sonnet \
  --dataset-path vllm/benchmarks/sonnet.txt \
  --num-prompts 10

성공하면 다음과 같은 결과가 나와요:

Throughput: 7.15 requests/s, 4656.00 total tokens/s, 1072.15 output tokens/s
Total num prompt tokens:  5014
Total num output tokens:  1500

비전 언어 모델용 VisionArena 벤치마크

vllm bench throughput \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --backend vllm-chat \
  --dataset-name hf \
  --dataset-path lmarena-ai/VisionArena-Chat \
  --num-prompts 1000 \
  --hf-split train

이제 num prompt tokens에 이미지 토큰 수가 포함돼요.

Throughput: 2.55 requests/s, 4036.92 total tokens/s, 326.90 output tokens/s
Total num prompt tokens:  14527
Total num output tokens:  1280

추측 디코딩을 사용한 InstructCoder 벤치마크

VLLM_WORKER_MULTIPROC_METHOD=spawn \
vllm bench throughput \
    --dataset-name=hf \
    --dataset-path=likaixin/InstructCoder \
    --model=meta-llama/Meta-Llama-3-8B-Instruct \
    --input-len=1000 \
    --output-len=100 \
    --num-prompts=2048 \
    --async-engine \
    --speculative-config $'{"method": "ngram",
    "num_speculative_tokens": 5, "prompt_lookup_max": 5,
    "prompt_lookup_min": 2}'
Throughput: 104.77 requests/s, 23836.22 total tokens/s, 10477.10 output tokens/s
Total num prompt tokens:  261136
Total num output tokens:  204800

기타 HuggingFaceDataset 예시들

lmms-lab/LLaVA-OneVision-Data:

vllm bench throughput \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --backend vllm-chat \
  --dataset-name hf \
  --dataset-path lmms-lab/LLaVA-OneVision-Data \
  --hf-split train \
  --hf-subset "chart2text(cauldron)" \
  --num-prompts 10

Aeala/ShareGPT_Vicuna_unfiltered:

vllm bench throughput \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --backend vllm-chat \
  --dataset-name hf \
  --dataset-path Aeala/ShareGPT_Vicuna_unfiltered \
  --hf-split train \
  --num-prompts 10

AI-MO/aimo-validation-aime:

vllm bench throughput \
  --model Qwen/QwQ-32B \
  --backend vllm \
  --dataset-name hf \
  --dataset-path AI-MO/aimo-validation-aime \
  --hf-split train \
  --num-prompts 10

LoRA 어댑터로 벤치마크:

# download dataset
# wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
vllm bench throughput \
  --model meta-llama/Llama-2-7b-hf \
  --backend vllm \
  --dataset_path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json \
  --dataset_name sharegpt \
  --num-prompts 10 \
  --max-loras 2 \
  --max-lora-rank 8 \
  --enable-lora \
  --lora-path yard1/llama-2-7b-sql-lora-test

합성 랜덤 멀티모달 (random-mm)

외부 데이터셋 없이 오프라인 처리량 테스트용 합성 멀티모달 입력을 생성해요. 이미지 토큰이 올바르게 계산되도록 --backend vllm-chat을 쓰세요.

vllm bench throughput \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --backend vllm-chat \
  --dataset-name random-mm \
  --num-prompts 100 \
  --random-input-len 300 \
  --random-output-len 40 \
  --random-mm-base-items-per-request 2 \
  --random-mm-limit-mm-per-prompt '{"image": 3, "video": 0}' \
  --random-mm-bucket-config '{(256, 256, 1): 0.7, (720, 1280, 1): 0.3}'

🛠️ 구조화 출력 벤치마크 (Structured Output Benchmark)

Show more

구조화 출력 생성(JSON, grammar, regex)의 성능을 벤치마킹해요.

서버 설정 (Server Setup)

vllm serve NousResearch/Hermes-3-Llama-3.1-8B

JSON 스키마 벤치마크

python3 benchmarks/benchmark_serving_structured_output.py \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --dataset json \
  --structured-output-ratio 1.0 \
  --request-rate 10 \
  --num-prompts 1000

Grammar 기반 생성 벤치마크

python3 benchmarks/benchmark_serving_structured_output.py \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --dataset grammar \
  --structure-type grammar \
  --request-rate 10 \
  --num-prompts 1000

Regex 기반 생성 벤치마크

python3 benchmarks/benchmark_serving_structured_output.py \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --dataset regex \
  --request-rate 10 \
  --num-prompts 1000

Choice 기반 생성 벤치마크

python3 benchmarks/benchmark_serving_structured_output.py \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --dataset choice \
  --request-rate 10 \
  --num-prompts 1000

XGrammar 벤치마크 데이터셋

python3 benchmarks/benchmark_serving_structured_output.py \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --dataset xgrammar_bench \
  --request-rate 10 \
  --num-prompts 1000

📚 긴 문서 QA 벤치마크 (Long Document QA Benchmark)

Show more

prefix 캐싱을 사용한 긴 문서 질의응답의 성능을 벤치마킹해요.

기본 긴 문서 QA 테스트

python3 benchmarks/benchmark_long_document_qa_throughput.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --enable-prefix-caching \
  --num-documents 16 \
  --document-length 2000 \
  --output-len 50 \
  --repeat-count 5

다양한 반복 모드

# Random mode (default) - shuffle prompts randomly
python3 benchmarks/benchmark_long_document_qa_throughput.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --enable-prefix-caching \
  --num-documents 8 \
  --document-length 3000 \
  --repeat-count 3 \
  --repeat-mode random

# Tile mode - repeat entire prompt list in sequence
python3 benchmarks/benchmark_long_document_qa_throughput.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --enable-prefix-caching \
  --num-documents 8 \
  --document-length 3000 \
  --repeat-count 3 \
  --repeat-mode tile

# Interleave mode - repeat each prompt consecutively
python3 benchmarks/benchmark_long_document_qa_throughput.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --enable-prefix-caching \
  --num-documents 8 \
  --document-length 3000 \
  --repeat-count 3 \
  --repeat-mode interleave

🗂️ Prefix 캐싱 벤치마크 (Prefix Caching Benchmark)

Show more

자동 prefix 캐싱의 효율을 벤치마킹해요.

고정 프롬프트 + prefix 캐싱

python3 benchmarks/benchmark_prefix_caching.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --enable-prefix-caching \
  --num-prompts 1 \
  --repeat-count 100 \
  --input-length-range 128:256

ShareGPT 데이터셋 + prefix 캐싱

# download dataset
# wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json

python3 benchmarks/benchmark_prefix_caching.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --dataset-path /path/ShareGPT_V3_unfiltered_cleaned_split.json \
  --enable-prefix-caching \
  --num-prompts 20 \
  --repeat-count 5 \
  --input-length-range 128:256
Prefix 반복 데이터셋
vllm bench serve \
  --backend openai \
  --model meta-llama/Llama-2-7b-chat-hf \
  --dataset-name prefix_repetition \
  --num-prompts 100 \
  --prefix-repetition-prefix-len 512 \
  --prefix-repetition-suffix-len 128 \
  --prefix-repetition-num-prefixes 5 \
  --prefix-repetition-output-len 128

Replay Timed Traces (타임드 트레이스 재생)

Show more

타이밍 정보가 있는 트레이스를 실행하는 예시예요.

MoonshotAI 트레이스 실행하기

서버를 시작해요:

vllm serve Qwen/Qwen3.5-2B \
--host 127.0.0.1 --port 8000

벤치마크를 실행해요:

# Download an example trace 
# curl -L -o conversation_trace.jsonl \
#https://raw.githubusercontent.com/kvcache-ai/Mooncake/main/FAST25-release/traces/conversation_trace.jsonl 

vllm bench serve --model Qwen/Qwen3.5-2B \  
--dataset-name=timed_trace --num-prompts 100 --host 127.0.0.1 \
--port 8000 --dataset-path ./conversation_trace.jsonl \
--ignore-eos  --self-timed --timed-trace-chunk-hash-size 512 \
--timed-trace-sec-multiplier 0.001 

이렇게 하면 트레이스 파일 conversation.jsonl의 처음 100줄을 재생해요.

🧪 해싱 벤치마크 (Hashing Benchmarks)

Show more

benchmarks/에는 prefix 캐싱과 관련 유틸리티가 쓰는 해싱 옵션을 비교하는 두 개의 헬퍼 스크립트가 있어요. 서버가 필요 없는 독립 실행형으로, 프로덕션에서 prefix 캐싱을 켜기 전에 해시 알고리즘을 고르는 데 도움을 줘요.

  • benchmarks/benchmark_hash.py: 대표적인 (bytes, tuple[int]) 페이로드에서 세 구현의 호출당 지연을 측정하는 마이크로 벤치마크예요.
python benchmarks/benchmark_hash.py --iterations 20000 --seed 42
  • benchmarks/benchmark_prefix_block_hash.py: 많은 가짜 블록에서 전체 prefix-cache 해시 파이프라인(hash_block_tokens)을 실행하고 처리량을 보고하는 엔드투엔드 블록 해싱 벤치마크예요.
python benchmarks/benchmark_prefix_block_hash.py --num-blocks 20000 --block-size 32 --trials 5

지원 알고리즘: sha256, sha256_cbor, xxhash, xxhash_cbor. 모든 변형을 시험하려면 선택적 의존성을 설치하세요:

uv pip install xxhash cbor2

알고리즘의 의존성이 없으면 스크립트는 그 알고리즘을 건너뛰고 계속해요.

⚡ 요청 우선순위 벤치마크 (Request Prioritization Benchmark)

Show more

vLLM의 요청 우선순위 지정 성능을 벤치마킹해요.

기본 우선순위 테스트

python3 benchmarks/benchmark_prioritization.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --input-len 128 \
  --output-len 64 \
  --num-prompts 100 \
  --scheduling-policy priority

프롬프트당 여러 시퀀스

python3 benchmarks/benchmark_prioritization.py \
  --model meta-llama/Llama-2-7b-chat-hf \
  --input-len 128 \
  --output-len 64 \
  --num-prompts 100 \
  --scheduling-policy priority \
  --n 2

👁️ 멀티모달 벤치마크 (Multi-Modal Benchmark)

Show more

vLLM의 멀티모달 요청 성능을 벤치마킹해요.

이미지 (ShareGPT4V)

vLLM을 시작해요:

vllm serve Qwen/Qwen2.5-VL-7B-Instruct \
  --dtype bfloat16 \
  --limit-mm-per-prompt '{"image": 1}' \
  --allowed-local-media-path /path/to/sharegpt4v/images

이미지가 있는 요청을 보내요:

vllm bench serve \
  --backend openai-chat \
  --model Qwen/Qwen2.5-VL-7B-Instruct \
  --dataset-name sharegpt \
  --dataset-path /path/to/ShareGPT4V/sharegpt4v_instruct_gpt4-vision_cap100k.json \
  --num-prompts 100 \
  --save-result \
  --result-dir ~/vllm_benchmark_results \
  --save-detailed \
  --endpoint /v1/chat/completions

비디오 (ShareGPT4Video)

vLLM을 시작해요:

vllm serve Qwen/Qwen2.5-VL-7B-Instruct \
  --dtype bfloat16 \
  --limit-mm-per-prompt '{"video": 1}' \
  --allowed-local-media-path /path/to/sharegpt4video/videos

비디오가 있는 요청을 보내요:

vllm bench serve \
  --backend openai-chat \
  --model Qwen/Qwen2.5-VL-7B-Instruct \
  --dataset-name sharegpt \
  --dataset-path /path/to/ShareGPT4Video/llava_v1_5_mix665k_with_video_chatgpt72k_share4video28k.json \
  --num-prompts 100 \
  --save-result \
  --result-dir ~/vllm_benchmark_results \
  --save-detailed \
  --endpoint /v1/chat/completions

합성 랜덤 이미지 (random-mm)

외부 데이터셋 없이 랜덤 텍스트 프롬프트와 함께 합성 이미지 입력을 생성해 비전 모델을 스트레스 테스트해요.

참고:

  • 온라인 벤치마크에는 --backend openai-chat과 엔드포인트 /v1/chat/completions를 쓰세요.
  • 오프라인 벤치마크에는 --backend vllm-chat를 쓰세요(오프라인 처리량 벤치마크의 예시 참고).

서버를 시작해요(예시):

vllm serve Qwen/Qwen2.5-VL-3B-Instruct \
  --dtype bfloat16 \
  --max-model-len 16384 \
  --limit-mm-per-prompt '{"image": 3, "video": 0}' \
  --mm-processor-kwargs max_pixels=1003520

벤치마크. 실제 응답을 시뮬레이션하려면 --ignore-eos 플래그를 쓰는 것이 좋아요. 출력 크기는 random-output-len 인자로 설정할 수 있어요.

Ex.1: 고정된 항목 수·단일 이미지 해상도, 약 40 토큰 생성 강제:

vllm bench serve \
  --backend openai-chat \
  --model Qwen/Qwen2.5-VL-3B-Instruct \
  --endpoint /v1/chat/completions \
  --dataset-name random-mm \
  --num-prompts 100 \
  --max-concurrency 10 \
  --random-prefix-len 25 \
  --random-input-len 300 \
  --random-output-len 40 \
  --random-range-ratio 0.2 \
  --random-mm-base-items-per-request 2 \
  --random-mm-limit-mm-per-prompt '{"image": 3, "video": 0}' \
  --random-mm-bucket-config '{(224, 224, 1): 1.0}' \
  --request-rate inf \
  --ignore-eos \
  --seed 42

요청당 항목 수는 여러 이미지 버킷을 넘겨 제어할 수 있어요:

  --random-mm-base-items-per-request 2 \
  --random-mm-num-mm-items-range-ratio 0.5 \
  --random-mm-limit-mm-per-prompt '{"image": 4, "video": 0}' \
  --random-mm-bucket-config '{(256, 256, 1): 0.7, (720, 1280, 1): 0.3}'

random-mm 전용 플래그:

  • --random-mm-base-items-per-request: 요청당 멀티모달 항목의 기본 수.
  • --random-mm-num-mm-items-range-ratio: 닫힌 정수 범위 [floor(n·(1−r)), ceil(n·(1+r))]에서 항목 수를 균일하게 변경. r=0이면 고정, r=1이면 0개 허용.
  • --random-mm-limit-mm-per-prompt: 모달리티별 하드 캡. 예: '{"image": 3, "video": 0}'.
  • --random-mm-bucket-config: (H, W, T) → 확률 매핑 dict. 확률 0 항목은 제거되고 나머지 확률은 합이 1이 되도록 재정규화됨. 이미지에는 T=1 사용. T>1은 비디오용(비디오 샘플링은 아직 미지원).

동작 참고:

  • 요청된 기본 항목 수를 프롬프트별 한도 아래에서 만족시킬 수 없으면 도구는 조용히 조정하지 않고 오류를 발생시켜요.

샘플링 작동 방식:

  • --random-mm-base-items-per-request--random-mm-num-mm-items-range-ratio로 정의된 정수 범위에서 요청별 항목 수 k를 균일하게 샘플링하고, k를 모달리티별 한도의 합 이하로 clamp해요.
  • k개 항목 각각에 대해 추가된 각 모달리티 항목 수를 추적하며 --random-mm-bucket-config의 정규화된 확률에 따라 버킷 (H, W, T)을 샘플링해요.
  • 어떤 모달리티(예: 이미지)가 --random-mm-limit-mm-per-prompt의 한도에 도달하면 그 모달리티의 모든 버킷이 제외되고 나머지 버킷 확률이 계속하기 전에 재정규화돼요. 이는 엣지 케이스로 봐야 하며, --random-mm-limit-mm-per-prompt를 큰 값으로 설정해 피할 수 있어요. 다만 이것이 엔진 구성 --limit-mm-per-prompt 때문에 오류를 일으킬 수 있음을 유의하세요.
  • 결과 요청은 multi_modal_data에 합성 이미지 데이터를 담아요(OpenAI Chat 형식). random-mm을 OpenAI Chat 백엔드와 함께 쓰면 프롬프트는 텍스트로 남고 MM 콘텐츠는 multi_modal_data로 첨부돼요.

🔬 멀티모달 프로세서 벤치마크 (Multimodal Processor Benchmark)

멀티모달(MM) 입력 프로세서 파이프라인의 단계별 지연(인코더 forward pass 포함)을 벤치마킹해요. 비전-언어 모델의 전처리 병목을 프로파일링할 때 유용해요.

Show more

벤치마크는 요청마다 다음 단계를 측정해요:

Stage Description
get_mm_hashes_secs Time spent hashing multimodal inputs
get_cache_missing_items_secs Time spent looking up the processor cache
apply_hf_processor_secs Time spent in the HuggingFace processor
merge_mm_kwargs_secs Time spent merging multimodal kwargs
apply_prompt_updates_secs Time spent updating prompt tokens
preprocessor_total_secs Total preprocessing time
encoder_forward_secs Time spent in the encoder model forward pass
num_encoder_calls Number of encoder invocations per request

벤치마크는 요청별 엔드투엔드 지연(TTFT + 디코드 시간)도 보고해요. 보고할 백분위는 --metric-percentiles(기본값: p99)로, 결과 저장은 --output-json으로 선택해요.

합성 데이터로 하는 기본 예시 (random-mm)

vllm bench mm-processor \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --dataset-name random-mm \
  --num-prompts 50 \
  --random-input-len 300 \
  --random-output-len 40 \
  --random-mm-base-items-per-request 2 \
  --random-mm-limit-mm-per-prompt '{"image": 3, "video": 0}' \
  --random-mm-bucket-config '{(256, 256, 1): 0.7, (720, 1280, 1): 0.3}'

HuggingFace 데이터셋 사용

vllm bench mm-processor \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --dataset-name hf \
  --dataset-path lmarena-ai/VisionArena-Chat \
  --hf-split train \
  --num-prompts 100

워밍업, 커스텀 백분위, JSON 출력

vllm bench mm-processor \
  --model Qwen/Qwen2-VL-7B-Instruct \
  --dataset-name random-mm \
  --num-prompts 200 \
  --num-warmups 5 \
  --random-input-len 300 \
  --random-output-len 40 \
  --random-mm-base-items-per-request 1 \
  --metric-percentiles 50,90,95,99 \
  --output-json results.json

전체 인자 참조는 vllm bench mm-processor를 보세요.

임베딩 벤치마크 (Embedding Benchmark)

vLLM의 임베딩 요청 성능을 벤치마킹해요.

Show more

텍스트 임베딩

생성 모델이 Completions API나 Chat Completions API를 쓰는 것과 달리, Embeddings API를 쓰려면 --backend openai-embeddings--endpoint /v1/embeddings를 설정해야 해요.

ShareGPT 같은 어떤 텍스트 데이터셋으로도 모델을 벤치마킹할 수 있어요.

서버를 시작해요:

vllm serve jinaai/jina-embeddings-v3 --trust-remote-code

벤치마크를 실행해요:

# download dataset
# wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
vllm bench serve \
  --model jinaai/jina-embeddings-v3 \
  --backend openai-embeddings \
  --endpoint /v1/embeddings \
  --dataset-name sharegpt \
  --dataset-path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json

멀티모달 임베딩

생성 모델과 달리 Embeddings API를 쓰려면 --endpoint /v1/embeddings를 설정해야 해요. 백엔드는 모델에 따라 달라요:

  • CLIP: --backend openai-embeddings-clip
  • VLM2Vec: --backend openai-embeddings-vlm2vec

다른 모델은 vllm/benchmarks/lib/endpoint_request_func.py 안에 기대되는 인스트럭션 형식에 맞는 직접 구현을 추가하세요.

모델이 지원하기만 하면 어떤 텍스트·멀티모달 데이터셋으로도 벤치마킹할 수 있어요. 예를 들어 ShareGPT와 VisionArena로 비전-언어 임베딩을 벤치마킹할 수 있어요.

CLIP 서빙·벤치마킹:

# Run this in another process
vllm serve openai/clip-vit-base-patch32

# Run these one by one after the server is up
# download dataset
# wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
vllm bench serve \
  --model openai/clip-vit-base-patch32 \
  --backend openai-embeddings-clip \
  --endpoint /v1/embeddings \
  --dataset-name sharegpt \
  --dataset-path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json

vllm bench serve \
  --model openai/clip-vit-base-patch32 \
  --backend openai-embeddings-clip \
  --endpoint /v1/embeddings \
  --dataset-name hf \
  --dataset-path lmarena-ai/VisionArena-Chat

VLM2Vec 서빙·벤치마킹:

# Run this in another process
vllm serve TIGER-Lab/VLM2Vec-Full --runner pooling \
  --trust-remote-code \
  --chat-template examples/pooling/embed/template/vlm2vec_phi3v.jinja

# Run these one by one after the server is up
# download dataset
# wget https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/resolve/main/ShareGPT_V3_unfiltered_cleaned_split.json
vllm bench serve \
  --model TIGER-Lab/VLM2Vec-Full \
  --backend openai-embeddings-vlm2vec \
  --endpoint /v1/embeddings \
  --dataset-name sharegpt \
  --dataset-path <your data path>/ShareGPT_V3_unfiltered_cleaned_split.json

vllm bench serve \
  --model TIGER-Lab/VLM2Vec-Full \
  --backend openai-embeddings-vlm2vec \
  --endpoint /v1/embeddings \
  --dataset-name hf \
  --dataset-path lmarena-ai/VisionArena-Chat

Reranker 벤치마크 (Reranker Benchmark)

vLLM의 rerank 요청 성능을 벤치마킹해요.

Show more

생성 모델과 달리 Reranker API를 쓰려면 --backend vllm-rerank--endpoint /v1/rerank을 설정해야 해요.

reranking에서 지원되는 유일한 데이터셋은 --dataset-name random-rerank이에요.

서버를 시작해요:

vllm serve BAAI/bge-reranker-v2-m3

벤치마크를 실행해요:

vllm bench serve \
  --model BAAI/bge-reranker-v2-m3 \
  --backend vllm-rerank \
  --endpoint /v1/rerank \
  --dataset-name random-rerank \
  --tokenizer BAAI/bge-reranker-v2-m3 \
  --random-input-len 512 \
  --num-prompts 10 \
  --random-batch-size 5

reranker 모델의 경우, 이 명령은 각각 random_input_len 토큰에 가까운 random_batch_size개의 "문서"를 가진 num_prompts / random_batch_size개의 요청을 만들어요. 위 예시에서는 각각 약 512 토큰의 "문서" 5개를 가진 rerank 요청 2개가 생성돼요.

/v1/rerank는 임베딩 모델도 지원한다는 점을 기억하세요. 임베딩 모델로 실행 중이라면 --no_reranker도 설정하세요. 이 경우 쿼리가 서버에서 개별 프롬프트로 취급되므로, 쿼리라는 추가 프롬프트를 고려해 random_batch_size - 1개의 문서를 보내요. 처리량 수치를 올바르게 보고하기 위한 토큰 계산도 그에 맞게 조정돼요.

출처: 공식문서

더 알아보기 (Learn more)