大模型API性能评测先测什么:延迟、吞吐与稳定性指标拆解
大模型API性能评测最容易犯的错,是只发一次请求记下总耗时,然后拿这个数字对比不同模型或服务商。
单次总耗时混合了网络、排队、输入处理、输出生成和重试等多个环节,既不稳定也不足以说明问题。
真正可比的评测需要先拆指标,再固定输入输出条件,最后记录失败率和波动。
先拆开你要测的四个指标
大模型API的响应过程不是一步完成的。
一次调用通常包括:建立连接、发送请求(含输入tokens)、服务端排队与预填充、返回第一个输出token、持续生成后续token直到结束。
对应可以拆成四个独立指标:
- 首字延迟(TTFT):从发出请求到收到第一个输出token的时间,反映服务端排队和预填充速度。
- 端到端延迟:从发出请求到流式响应结束的总时间,受输出长度影响很大。
- 输出速度(tokens/s):输出token数除以生成阶段耗时,反映持续生成能力。
- 并发吞吐:多个请求同时发起时,单位时间内完成的请求数或总输出token数。
如果只测端到端延迟,输出长度一变结果就不可比。
比如A模型输出200个token用了4秒,B模型输出80个token用了2秒,不能直接说A比B慢,因为输出量不同。
评测时至少要把输入长度、输出上限和采样参数固定下来。
准备一个可重复的测试脚本
手工点网页测试很难保证条件一致。
建议用脚本发起请求,并记录每次调用的时间戳。
以下Python示例假设使用OpenAI兼容的流式接口,你需要替换base_url、api_key和model为实际值。
import time, json, requests
url = "https://your-api-host/v1/chat/completions"
headers = {"Authorization": "Bearer YOUR_KEY", "Content-Type": "application/json"}
payload = {
"model": "your-model",
"messages": [{"role": "user", "content": "用三句话解释什么是TCP三次握手"}],
"max_tokens": 200,
"temperature": 0,
"stream": True
}
start = time.perf_counter()
first_token_time = None
token_count = 0
with requests.post(url, headers=headers, json=payload, stream=True, timeout=60) as r:
r.raise_for_status()
for line in r.iter_lines():
if not line:
continue
if line.startswith(b"data: "):
data = line[6:]
if data == b"[DONE]":
break
chunk = json.loads(data)
delta = chunk["choices"][0].get("delta", {})
if delta.get("content"):
if first_token_time is None:
first_token_time = time.perf_counter()
token_count += 1
end = time.perf_counter()
print("TTFT:", round(first_token_time - start, 3), "s")
print("总耗时:", round(end - start, 3), "s")
print("输出块数:", token_count)
注意:流式接口返回的delta.content块不一定严格等于token数,不同服务商的分块策略不同。
如果要做精确tokens/s,优先使用响应中的usage字段(若接口返回),或改用非流式请求读取usage.completion_tokens。
脚本的作用是保证每次请求的输入、参数和计时方式一致,而不是追求绝对精确。
固定条件,别让变量混进来
同一批测试里,以下条件应保持一致:
- 输入文本:使用同一段固定长度的提示词,避免每次即兴提问。输入长度差异会直接影响预填充耗时。
- 输出上限:设置相同的
max_tokens,并尽量让模型输出长度接近。可以要求“用大约150字回答”来减少波动。 - 采样参数:
temperature设为0或固定值,减少输出长度随机波动。 - 网络环境:在同一台机器、同一网络出口下测试。跨地区网络差异可能比模型本身差异还大。
- 重试策略:记录是否发生重试,失败请求不能悄悄算进成功耗时里。
如果对比不同服务商,还要注意API网关、鉴权方式和限流策略不同。
有些平台对免费额度或低并发账号有额外排队,这类信息应在结果中注明,不能直接归因于模型推理慢。
并发测试要单独做
单请求延迟低,不代表并发时仍然稳定。
并发吞吐测试可以用简单工具或脚本同时发起N个请求,记录成功数、失败数、平均延迟和P95延迟。
例如用hey或wrk对非流式接口做压测时,需要把请求体放在文件中,并注意不要超过服务商的速率限制。
更稳妥的方式是写一个小的并发脚本,控制并发数从1逐步增加到5、10、20,观察:
- 平均首字延迟是否明显上升;
- 失败率(HTTP 429、5xx、超时)是否出现;
- P95延迟与平均延迟的差距是否拉大。
如果并发到10时开始出现大量429,说明瓶颈可能在限流而不是推理。
此时应记录限流阈值,而不是继续加大并发得出“性能差”的结论。
结果记录与判断
每次测试至少记录:时间、模型名、输入长度、输出tokens、TTFT、总耗时、tokens/s、HTTP状态码。
建议每个条件重复5次以上,取中位数和P95,而不是只看最好的一次。
判断时注意边界:TTFT低但输出速度慢,适合短问答不适合长文生成;
输出速度快但并发失败率高,适合低并发个人使用不适合生产批量任务。
没有一种指标能单独代表“性能好”,需要根据你的实际场景选择权重。
最后提醒,评测结果只对测试时的接口版本、网络环境和账号等级有效。
服务商调整路由或限流策略后,旧数据不能直接沿用。
保留测试脚本和原始记录,比记住一个结论更有用。