Bench Serving 使用指南#

本指南介绍如何使用 python -m sglang.bench_serving 对在线服务的吞吐量和延迟进行基准测试。它通过 OpenAI 兼容的本地端点支持多种推理后端,并提供控制台指标和可选的 JSONL 输出。

功能特点#

  • 生成合成数据集驱动的提示词并将其提交到目标服务端点

  • 测量吞吐量、首token时间(TTFT)、token间延迟(ITL)、每请求端到端延迟等指标

  • 支持流式或非流式模式、速率控制和并发限制

支持的后端和端点#

  • sglang / sglang-native: POST /generate

  • sglang-oai, vllm, lmdeploy: POST /v1/completions

  • sglang-oai-chat, vllm-chat, lmdeploy-chat: POST /v1/chat/completions

  • trt (TensorRT-LLM): POST /v2/models/ensemble/generate_stream

  • gserver: 自定义服务器(本脚本暂未实现)

  • truss: POST /v1/models/model:predict

如果提供了 --base-url,请求将发送到该地址。否则,使用 --host--port。当未提供 --model 时,脚本将尝试查询 GET /v1/models 以获取可用的模型 ID(OpenAI 兼容端点)。

先决条件#

  • Python 3.8+

  • 本脚本通常使用的依赖项:aiohttpnumpyrequeststqdmtransformers,以及某些数据集所需的 datasetspillowpybase64。按需安装。

  • 一个正在运行并通过上述端点可访问的推理服务器

  • 如果您的服务器需要身份验证,请设置环境变量 OPENAI_API_KEY(用作 Authorization: Bearer <key>

快速开始#

对暴露 /generate 端点的 sglang 服务器运行基本基准测试:

python3 -m sglang.launch_server --model-path meta-llama/Llama-3.1-8B-Instruct
python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --num-prompts 1000 \
  --model meta-llama/Llama-3.1-8B-Instruct

或者,使用 OpenAI 兼容端点(completions):

python3 -m sglang.bench_serving \
  --backend vllm \
  --base-url http://127.0.0.1:8000 \
  --num-prompts 1000 \
  --model meta-llama/Llama-3.1-8B-Instruct

数据集#

使用 --dataset-name 选择:

  • sharegpt(默认):加载 ShareGPT 样式的数据对;可选地使用 --sharegpt-context-len 限制长度,并用 --sharegpt-output-len 覆盖输出

  • random:随机文本长度;从 ShareGPT token 空间采样

  • random-ids:随机 token ID(可能导致乱码)

  • image:生成图像并将其包装在聊天消息中;支持自定义分辨率、多种格式和不同内容类型

  • generated-shared-prefix:合成数据集,具有共享的长系统提示和简短问题

  • mmmu:从 MMMU(数学部分)采样并包含图像

常见数据集标志:

  • --num-prompts N:请求数量

  • --random-input-len--random-output-len--random-range-ratio:适用于 random/random-ids/image 数据集

  • --image-count:每个请求的图像数量(适用于 image 数据集)

  • --apply-chat-template:在构建提示词时应用分词器聊天模板

  • --dataset-path PATH:ShareGPT json 文件路径;如果为空且缺失,将下载并缓存

生成共享前缀标志(适用于 generated-shared-prefix):

  • --gsp-num-groups

  • --gsp-prompts-per-group

  • --gsp-system-prompt-len

  • --gsp-question-len

  • --gsp-output-len

图像数据集标志(适用于 image):

  • --image-count:每个请求的图像数量

  • --image-resolution:图像分辨率;支持预设值(4k、1080p、720p、360p)或自定义 '高度x宽度' 格式(例如,1080x1920、512x768)

  • --image-format:图像格式(jpeg 或 png)

  • --image-content:图像内容类型(random 或 blank)

示例#

  1. 要对每个请求包含 3 张图像、500 个提示词、512 输入长度和 512 输出长度的图像数据集进行基准测试,可以运行:

python -m sglang.launch_server --model-path Qwen/Qwen2.5-VL-3B-Instruct --disable-radix-cache
python -m sglang.bench_serving \
    --backend sglang-oai-chat \
    --dataset-name image \
    --num-prompts 500 \
    --image-count 3 \
    --image-resolution 720p \
    --random-input-len 512 \
    --random-output-len 512
  1. 要对包含 3000 个提示词、1024 输入长度和 1024 输出长度的随机数据集进行基准测试,可以运行:

python -m sglang.launch_server --model-path Qwen/Qwen2.5-3B-Instruct
python3 -m sglang.bench_serving \
    --backend sglang \
    --dataset-name random \
    --num-prompts 3000 \
    --random-input 1024 \
    --random-output 1024 \
    --random-range-ratio 0.5

选择模型和分词器#

  • 除非后端暴露 GET /v1/models,否则需要 --model;在这种情况下,将自动选择第一个模型 ID。

  • --tokenizer 默认为 --model。两者都可以是 HF 模型 ID 或本地路径。

  • 对于 ModelScope 工作流,设置 SGLANG_USE_MODELSCOPE=true 可以通过 ModelScope 获取(为提高速度会跳过权重)。

  • 如果您的分词器缺少聊天模板,脚本会发出警告,因为对于乱码输出的分词计数可能不够健壮。

速率、并发和流式处理#

  • --request-rate:每秒请求数。inf 立即发送所有请求(突发)。非无限速率使用泊松过程确定到达时间。

  • --max-concurrency:限制飞行中的并发请求数,与到达速率无关。

  • --disable-stream:在支持时切换到非流式模式;对于聊天完成,TTFT 然后等于总延迟。

其他关键选项#

  • --output-file FILE.jsonl:将 JSONL 结果追加到文件;如果未指定则自动命名

  • --output-details:包含每个请求的数组(生成的文本、错误、ttfts、itls、输入/输出长度)

  • --extra-request-body '{"top_p":0.9,"temperature":0.6}':合并到负载中(采样参数等)

  • --disable-ignore-eos:传递 EOS 行为(因后端而异)

  • --warmup-requests N:首先运行具有短输出的预热请求(默认 1)

  • --flush-cache:在主运行前调用 /flush_cache(sglang)

  • --profile:调用 /start_profile/stop_profile(需要服务器启用分析,例如 SGLANG_TORCH_PROFILER_DIR

  • --lora-name name1 name2 ...:每个请求随机选择一个并传递给后端(例如,sglang 的 lora_path

  • --tokenize-prompt:发送整数 ID 而不是文本(当前仅支持 --backend sglang

身份验证#

如果您的目标端点需要 OpenAI 风格的身份验证,请设置:

export OPENAI_API_KEY=sk-...yourkey...

脚本将自动为 OpenAI 兼容的路由添加 Authorization: Bearer $OPENAI_API_KEY

指标说明#

每次运行后打印:

  • 请求吞吐量(req/s)

  • 输入 token 吞吐量(tok/s)- 包括文本和视觉 token

  • 输出 token 吞吐量(tok/s)

  • 总 token 吞吐量(tok/s)- 包括文本和视觉 token

  • 总输入文本 token 和总输入视觉 token - 按模态细分

  • 并发性:所有请求的总时间除以 wall 时间

  • 端到端延迟(ms):每请求总延迟的平均值/中位数/标准差/p99

  • 首个 token 时间(TTFT,ms):流式模式的平均值/中位数/标准差/p99

  • Token 间延迟(ITL,ms):token 之间的平均值/中位数/标准差/p95/p99/最大值

  • TPOT(ms):第一个 token 后的 token 处理时间,即 (延迟 - ttft)/(token数-1)

  • 接受长度(仅 sglang,如果可用):推测解码接受长度

脚本还会使用配置的分词器重新生成标记文本并报告"重新分词"计数。

JSONL 输出格式#

当设置 --output-file 时,每个运行追加一个 JSON 对象。基本字段包括:

  • 参数摘要:backend、dataset、request_rate、max_concurrency 等

  • 持续时间和总计:completed、total_input_tokens、total_output_tokens、重新分词总计

  • 控制台中打印的吞吐量和延迟统计信息

  • 可用时的 accept_length(sglang)

使用 --output-details 时,扩展对象还包含数组:

  • input_lensoutput_lens

  • ttftsitls(每个请求:ITL 数组)

  • generated_textserrors

端到端示例#

  1. sglang 原生 /generate(流式):

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --dataset-name random \
  --random-input-len 1024 --random-output-len 1024 --random-range-ratio 0.5 \
  --num-prompts 2000 \
  --request-rate 100 \
  --max-concurrency 512 \
  --output-file sglang_random.jsonl --output-details
  1. OpenAI 兼容 Completions(例如 vLLM):

python3 -m sglang.bench_serving \
  --backend vllm \
  --base-url http://127.0.0.1:8000 \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --dataset-name sharegpt \
  --num-prompts 1000 \
  --sharegpt-output-len 256
  1. OpenAI 兼容 Chat Completions(流式):

python3 -m sglang.bench_serving \
  --backend vllm-chat \
  --base-url http://127.0.0.1:8000 \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --dataset-name random \
  --num-prompts 500 \
  --apply-chat-template
  1. 图像(VLM)与聊天模板:

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model your-vlm-model \
  --dataset-name image \
  --image-count 2 \
  --image-resolution 720p \
  --random-input-len 128 --random-output-len 256 \
  --num-prompts 200 \
  --apply-chat-template

4a) 自定义分辨率的图像:

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model your-vlm-model \
  --dataset-name image \
  --image-count 1 \
  --image-resolution 512x768 \
  --random-input-len 64 --random-output-len 128 \
  --num-prompts 100 \
  --apply-chat-template

4b) 1080p 图像,PNG 格式和空白内容:

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model your-vlm-model \
  --dataset-name image \
  --image-count 1 \
  --image-resolution 1080p \
  --image-format png \
  --image-content blank \
  --random-input-len 64 --random-output-len 128 \
  --num-prompts 100 \
  --apply-chat-template
  1. 生成的共享前缀(长系统提示 + 短问题):

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --dataset-name generated-shared-prefix \
  --gsp-num-groups 64 --gsp-prompts-per-group 16 \
  --gsp-system-prompt-len 2048 --gsp-question-len 128 --gsp-output-len 256 \
  --num-prompts 1024
  1. 用于严格长度控制的标记提示词(ID)(仅 sglang):

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --dataset-name random \
  --tokenize-prompt \
  --random-input-len 2048 --random-output-len 256 --random-range-ratio 0.2
  1. 分析和缓存刷新(sglang):

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --profile \
  --flush-cache
  1. TensorRT-LLM 流式端点:

python3 -m sglang.bench_serving \
  --backend trt \
  --base-url http://127.0.0.1:8000 \
  --model your-trt-llm-model \
  --dataset-name random \
  --num-prompts 100 \
  --disable-ignore-eos
  1. 使用 mooncake trace 评估大规模 KVCache 共享(仅 sglang):

python3 -m sglang.bench_serving \
  --backend sglang \
  --host 127.0.0.1 --port 30000 \
  --model mode-name \
  --dataset-name mooncake \
  --mooncake-slowdown-factor 1.0 \
  --mooncake-num-rounds 1000 \
  --mooncake-workload conversation|mooncake|agent|synthetic
  --use-trace-timestamps true \
  --random-output-len 256

故障排除#

  • 所有请求失败:验证 --backend、服务器 URL/端口、--model 和身份验证。检查脚本打印的预热错误。

  • 吞吐量似乎太低:调整 --request-rate--max-concurrency;验证服务器批量大小/调度;确保在适当时启用流式处理。

  • Token 计数看起来异常:优先选择具有适当聊天模板的聊天/指令模型;否则乱码的分词可能不一致。

  • 图像/MMMU 数据集:确保您安装了额外的依赖项(pillowdatasetspybase64)。

  • 身份验证错误(401/403):设置 OPENAI_API_KEY 或在您的服务器上禁用身份验证。

注意事项#

  • 脚本提高文件描述符软限制(RLIMIT_NOFILE)以帮助处理许多并发连接。

  • 对于 sglang,运行后查询 /get_server_info 以报告可用的推测解码接受长度。