推理服务评测指南#
本指南介绍如何使用 python -m sglang.bench_serving 评测在线服务的吞吐量和延迟。它通过兼容 OpenAI 的端点或原生端点支持多个推理后端,并生成控制台指标及可选的 JSONL 输出文件。
功能简介#
生成合成提示词或基于数据集的提示词,并提交至目标服务端点
测量吞吐量、首字延迟 (TTFT)、逐字延迟 (ITL)、单次请求端到端延迟等
支持流式或非流式模式、速率控制和并发限制
支持的后端与端点#
sglang/sglang-native:POST /generatesglang-oai,vllm,lmdeploy:POST /v1/completionssglang-oai-chat,vllm-chat,lmdeploy-chat:POST /v1/chat/completionstrt(TensorRT-LLM):POST /v2/models/ensemble/generate_streamgserver: 自定义服务器(此脚本暂未实现)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)
示例#
如需评测图片数据集,设置每个请求 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
如需评测随机数据集,设置 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(生成文本与错误)
端到端示例#
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
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
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
带聊天模板的图片 (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
生成共享前缀 (长系统提示词 + 短问题)
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
为了严格控制长度使用 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
性能分析与缓存刷新 (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
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
使用 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以报告投机采样的接受长度(如果可用)。