벤치마크 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.jsonNote 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-name은 hf로 설정해야 해요. 로컬 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}'
모든 카테고리 실행:
# 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의 느슨한 스키마 방언(dict → object, float → number, tuple → array, any → string)을 정규화해서 현대 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-metrics에client_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 Planning과 SLA 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)
- 벤치마크 전체 개요: Benchmark Suites
- 파라미터 조합 자동 비교: Parameter Sweeps
- 커밋 단위 성능 대시보드: Performance Dashboard
- 운영 서버 벤치마킹은 GuideLLM 추천: https://github.com/vllm-project/guidellm