推理服务评测指南#

本指南介绍如何使用 python -m sglang.bench_serving 评测在线服务的吞吐量和延迟。它通过兼容 OpenAI 的端点或原生端点支持多个推理后端,并生成控制台指标及可选的 JSONL 输出文件。

功能简介#

  • 生成合成提示词或基于数据集的提示词,并提交至目标服务端点

  • 测量吞吐量、首字延迟 (TTFT)、逐字延迟 (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+

  • 此脚本通常使用的依赖项:aiohttp, numpy, requests, tqdm, transformers。对于某些数据集还需:datasets, pillow, pybase64。请根据需要安装。

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

  • 如果您的服务器需要身份验证,请设置环境变量 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 的端点(补全模式)

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 词表空间中采样

  • 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(此时会自动选择第一个模型 ID),否则必须提供 --model

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

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

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

速率、并发与流式传输#

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

  • --max-concurrency: 无论到达速率如何,限制同时进行的请求上限。

  • --disable-stream: 切换到非流式模式(如果支持);此时对于聊天补全,TTFT 等于总延迟。

其他关键选项#

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

  • --output-details: 包含逐个请求的详情数组(生成的文本、错误、TTFT、ITL、输入/输出长度)

  • --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(需要服务器启用 profiling,例如设置 SGLANG_TORCH_PROFILER_DIR

  • --lora-name name1 name2 ...: 为每个请求随机挑选一个 LoRA 并传给后端(例如 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 - 按模态划分

  • 并发度 (Concurrency):所有请求的总时长除以实际运行时间

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

  • 首字延迟 (TTFT, ms):流式模式下的 平均值/中位数/标准差/P99

  • 逐字延迟 (ITL, ms):Token 之间的 平均值/中位数/标准差/P95/P99/最大值

  • TPOT (ms):首字后的 token 处理时间,即 (latency - ttft)/(tokens-1)

  • 接受长度 (仅限 sglang,如果可用):投机采样接受长度

脚本还会使用配置的分词器对生成的文本重新分词,并报告“重新分词 (retokenized)”后的计数。

JSONL 输出格式#

设置 --output-file 后,每次运行会追加一个 JSON 对象。基础字段包括:

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

  • 时长与总量:已完成数、总输入 token 数、总输出 token 数、重新分词总量

  • 吞吐量和延迟统计数据(同控制台打印)

  • accept_length(如果可用,sglang)

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

  • input_lens, output_lens (输入/输出长度)

  • ttfts, itls (每个请求的 ITL 数组)

  • generated_texts, errors (生成文本与错误)

端到端示例#

  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 兼容补全 (例如 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 兼容聊天补全 (流式)

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) PNG 格式且内容为空的 1080p 图片

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. 为了严格控制长度使用 tokenized 提示词 (ids) (仅限 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;检查服务器 batch size/调度配置;确保在适当时启用了流式传输。

  • Token 计数异常:优先选用带有正确聊天模板的 chat/instruct 模型;否则乱码输出的分词结果可能不一致。

  • 图片/MMMU 数据集:确保安装了额外依赖 (pillow, datasets, pybase64)。

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

备注#

  • 脚本会自动调高文件描述符软限制 (RLIMIT_NOFILE) 以支持大量并发连接。

  • 对于 sglang,运行结束后会查询 /get_server_info 以报告投机采样的接受长度(如果可用)。