大语言模型参数指标详解:TTFT、TPOT、E2E Latency与吞吐量如何影响推理体验
1. 为什么你调用的模型“感觉慢”四个指标的真实分工很多人第一次做 AI 应用选型时判断标准只有一句“这个模型快不快”。但真正上线后你会发现用户抱怨的“慢”其实分好几种有人是点了发送后半天不吐字有人是第一个字很快但后面像挤牙膏还有人是一次性批量跑几千条数据时总耗时长得离谱。这背后对应的是四个完全不同的指标——TTFT、TPOT、E2E Latency 和吞吐量。TTFTTime to First Token首 Token 时延衡量的是从你发出请求到收到第一个 token 的时间它决定了用户“等待感”的强弱。TPOTTime Per Output Token单 token 输出耗时衡量的是首 token 之后每多生成一个 token 平均要花多久它决定了流式输出“顺不顺”。E2E Latency端到端时延是整条请求从发出到最后一个 token 落地的总时间。吞吐量则是单位时间内系统能处理多少 token 或多少请求它决定了你的服务能扛多少并发。这四个指标不是孤立的它们之间存在明显的相互制约。你把 batch size 调大吞吐量上去了但 TTFT 和 TPOT 往往会被拖慢你为了压低 TTFT 而减少批处理吞吐量又会掉下来。所以选型和调优的本质是在你的业务场景里找到这四者的平衡点。这篇文章会先讲清楚每个指标的定义和测量方式然后结合 TaoToken 统一 API 通道给你一套可复制的压测脚本和指标采集配置让你能亲手验证这些指标随并发变化的趋势。2. TaoToken 统一 API 通道为指标采集准备一个稳定入口要做推理性能测量第一步是有一个稳定的、可编程调用的模型入口。TaoToken 提供统一 API 通道把不同模型的调用方式收敛成一套兼容接口这样你在写压测脚本时不用为每个模型改一遍代码。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。在开始采集指标之前你需要先拿到 API Key。进入控制台的 API Keys 页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 创建一个新的 Key。创建时建议给它起一个能区分用途的名字比如perf-test-ttft这样后面你同时跑多组压测时不会搞混。Key 只在创建时完整显示一次复制后先存到本地环境变量里不要直接写进脚本明文。拿到 Key 之后你需要确认两件事Base URL 和 Model ID。Base URL 就是https://taotoken.net/apiModel ID 则取决于你要测哪个模型。你可以在模型对话页面https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 先手动发一条消息确认模型能正常返回然后在接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里找到对应的模型标识。这里有一个容易被忽略的点指标采集对网络稳定性很敏感。如果你在本地用不稳定的网络去测 TTFT测出来的数字里混了大量网络抖动根本没法用来做模型选型。所以压测脚本最好跑在一台网络环境相对干净的机器上或者至少保证压测期间没有其他大流量任务在抢带宽。我试过在同一台机器上一边下载大文件一边跑 TTFT 测试结果首 token 时延直接从 400ms 飙到 2s 以上完全是噪声。另外TaoToken 的 API 兼容 OpenAI 风格的调用方式这意味着你可以直接用 OpenAI SDK 或者任何兼容的 HTTP 客户端来发请求。对于指标采集来说这一点很关键因为流式响应的解析逻辑可以复用现成的库你只需要在解析过程中打时间戳就行。下面一节我会给出完整的可复制配置和脚本。3. 可复制配置压测脚本与指标采集参数这一节给你一套可以直接跑的配置。核心思路是用 Python 写一个压测脚本通过流式接口发请求在收到第一个 token、每个后续 token、以及最后一个 token 时分别打时间戳最后算出 TTFT、TPOT、E2E Latency 和吞吐量。先准备一个配置文件把 Base URL、Key 和 Model ID 集中管理。你可以用 JSON 格式路径放在项目根目录的perf_config.json{ base_url: https://taotoken.net/api, api_key: sk-your-key-here, model_id: your-model-id, max_tokens: 256, temperature: 0.7, stream: true }注意api_key这里只是占位实际运行时建议从环境变量读取避免把 Key 提交到代码仓库。你可以在脚本里用os.environ.get(TAOTOKEN_API_KEY)来取。接下来是压测脚本bench_llm.py。它用requests库发流式请求逐行解析 SSE 数据记录关键时间点import json import time import os import requests from concurrent.futures import ThreadPoolExecutor, as_completed with open(perf_config.json, r) as f: cfg json.load(f) API_KEY os.environ.get(TAOTOKEN_API_KEY, cfg[api_key]) BASE_URL cfg[base_url].rstrip(/) MODEL_ID cfg[model_id] def one_request(prompt, max_tokens256): url f{BASE_URL}/v1/chat/completions headers { Authorization: fBearer {API_KEY}, Content-Type: application/json } payload { model: MODEL_ID, messages: [{role: user, content: prompt}], max_tokens: max_tokens, temperature: cfg[temperature], stream: True } t_start time.perf_counter() t_first None t_last None token_count 0 with requests.post(url, headersheaders, jsonpayload, streamTrue, timeout120) as resp: resp.raise_for_status() for line in resp.iter_lines(decode_unicodeTrue): if not line or not line.startswith(data:): continue data line[5:].strip() if data [DONE]: break try: chunk json.loads(data) except json.JSONDecodeError: continue delta chunk.get(choices, [{}])[0].get(delta, {}) if delta.get(content): now time.perf_counter() if t_first is None: t_first now t_last now token_count 1 t_end time.perf_counter() ttft (t_first - t_start) if t_first else None e2e t_end - t_start tpot ((t_last - t_first) / (token_count - 1)) if token_count 1 else None return { ttft: ttft, tpot: tpot, e2e: e2e, tokens: token_count } def run_batch(prompt, concurrency): results [] with ThreadPoolExecutor(max_workersconcurrency) as ex: futures [ex.submit(one_request, prompt) for _ in range(concurrency)] for fut in as_completed(futures): results.append(fut.result()) return results if __name__ __main__: prompt 请用大约200字解释什么是大语言模型的推理时延。 for conc in [1, 2, 4, 8]: res run_batch(prompt, conc) ttfts [r[ttft] for r in res if r[ttft]] tpots [r[tpot] for r in res if r[tpot]] e2es [r[e2e] for r in res] total_tokens sum(r[tokens] for r in res) wall max(e2es) print(f并发{conc} | TTFT均值{sum(ttfts)/len(ttfts)*1000:.0f}ms | fTPOT均值{sum(tpots)/len(tpots)*1000:.1f}ms | fE2E均值{sum(e2es)/len(e2es)*1000:.0f}ms | f吞吐{total_tokens/wall:.1f} tok/s)这个脚本的关键点在于t_start在发请求前记录t_first在收到第一个带 content 的 delta 时记录t_last在最后一个 content 时记录t_end在流结束后记录。TTFT 就是t_first - t_startTPOT 是首 token 之后到最后一个 token 之间的时间除以 token 数减一E2E 是t_end - t_start。吞吐量用总 token 数除以整批请求的墙钟时间。运行前先装依赖pip install requests。然后设置环境变量export TAOTOKEN_API_KEY你的key再执行python bench_llm.py。脚本会依次用并发 1、2、4、8 跑四组打印每组的指标均值。这样你就能直观看到并发上升时TTFT 和 TPOT 怎么变吞吐量又怎么变。如果你用的是 Claude Code 这类编码工具做长期压测可以在 Coding Plan 页面https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 了解适合持续调用的方案。对于需要反复跑压测、对比不同模型参数的场景统一通道能省掉大量切换成本。4. 验证请求观察指标随并发变化的真实趋势配置好脚本后你需要实际跑一遍确认每个指标都能被正确采集并且观察它们随并发变化的趋势。这一节我带你走一遍验证流程包括单请求验证和多并发对比。先做单请求验证。把脚本里的并发列表改成[1]跑一次看输出是否合理。正常情况下TTFT 应该在几百毫秒量级TPOT 在几十毫秒量级E2E 在几秒量级吞吐量在几十 tok/s 量级。具体数字取决于你选的模型和当时的服务负载。如果 TTFT 显示为None说明整个流式响应里没有解析到 content可能是模型返回格式不同或者请求被拒绝了需要先检查响应体。单请求验证通过后跑完整的并发梯度。你会看到类似这样的趋势并发从 1 升到 8 时TTFT 均值从 400ms 升到 900msTPOT 从 30ms 升到 55msE2E 从 3s 升到 6s但吞吐量从 40 tok/s 升到 120 tok/s。这就是典型的“时延换吞吐”曲线。如果你看到吞吐量不升反降说明并发已经超过了服务端的处理能力请求开始排队甚至超时。这里有一个测量细节要注意TPOT 的计算依赖 token 计数。如果你的 prompt 让模型输出很短比如只生成 5 个 token那 TPOT 的样本太少波动会很大。建议压测时把max_tokens设到 128 以上并且用固定 prompt保证每次生成的 token 数量接近这样指标才有可比性。另外流式和非流式的测量方式不同。非流式请求你只能拿到总时间没法拆出 TTFT 和 TPOT。所以做指标采集一定要用stream: true。如果你在脚本里忘了开流式会发现t_first和t_last几乎同时出现TTFT 约等于 E2ETPOT 接近 0这显然是错的。验证成功后你可以把结果整理成表格方便对比不同模型或不同参数。比如固定并发为 4分别测max_tokens128和max_tokens512看 TPOT 和 E2E 怎么变。通常输出越长E2E 线性增长TPOT 相对稳定但如果服务端有 KV Cache 优化TPOT 可能随长度增加而略微上升。如果你在验证过程中想快速确认某个模型当前是否可用可以直接在模型对话页面https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 手动发一条流式消息观察首字出现的时间和后续吐字速度作为脚本测量的交叉验证。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth压测过程中最容易遇到的几个报错我按出现频率排一下并给出排查路径。401 Unauthorized这是最常见的问题基本是 Key 不对或没带上。检查三件事环境变量TAOTOKEN_API_KEY是否真的设置成功用echo $TAOTOKEN_API_KEY确认请求头里Authorization是否是Bearer加 Key注意 Bearer 后面有一个空格Key 是否已经过期或被删除。如果你在脚本里同时用了配置文件的 Key 和环境变量确认脚本读的是哪一个。另外Key 复制时容易带上首尾空格建议在脚本里做一次strip()。local proxy failed / connection refused这个报错通常出现在你本地设置了网络代理但代理没有正常工作时。压测脚本发请求时如果走了系统代理而代理不可用就会报这个。排查方式是检查环境变量HTTP_PROXY和HTTPS_PROXY如果不需要代理就清掉如果确实需要确认代理地址和端口正确。在 Python 里你也可以显式传proxies{http: None, https: None}来绕过系统代理。reading choices 相关报错这类报错通常出现在解析响应时choices字段为空或者结构不符合预期。常见原因是请求被服务端拒绝返回的是一个错误对象而不是正常的 completion 结构。你可以在脚本里先打印原始响应体确认返回内容。如果返回的是{error: {...}}那就按错误信息排查而不是继续解析 choices。另一个原因是流式响应里混入了非 data 行比如空行或注释行脚本里已经用startswith(data:)过滤了但如果你自己改了解析逻辑要注意保留这个过滤。OAuth / 认证方式不匹配如果你用的是某些编码工具比如 Claude Code 或 Codex 风格的客户端它们可能默认走 OAuth 而不是 API Key。这时候你需要确认客户端的认证配置。以 Claude Code 为例它需要设置 Base URL、API Key 和 Model ID 三件套。Base URL 填https://taotoken.net/apiAPI Key 填你创建的那个Model ID 填对应模型标识。如果只填了 Key 没填 Base URL客户端可能仍然往默认地址发请求导致认证失败。Codex 的auth.json也是类似需要确保里面的 base_url 和 api_key 都指向 TaoToken 的通道。排查时有一个通用方法先用curl发一个最小请求确认通道本身是通的。命令如下curl -s -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:your-model-id,messages:[{role:user,content:hi}],max_tokens:8,stream:true}如果 curl 能正常返回流式数据说明 Key 和通道没问题问题在脚本或客户端配置。如果 curl 也报 401那就回到 Key 本身排查。这个方法能帮你快速定位问题是在通道层还是在应用层。6. 把指标用起来选型与调优的下一步跑完压测、拿到四组并发下的指标后你手里就有了一张决策表。如果你的应用是实时对话优先看 TTFT尽量控制在 500ms 以内同时关注 TPOT 是否稳定避免吐字忽快忽慢。如果是批量文档摘要优先看吞吐量TTFT 可以放宽到几秒因为用户不会盯着屏幕等。如果是 Agent 类应用需要多轮调用E2E Latency 的累积效应更关键每一轮都要尽量压低。调优时记住那个制约关系提高并发或 batch size 能提升吞吐但会牺牲 TTFT 和 TPOT。你可以通过压测脚本快速验证不同参数组合找到你业务能接受的最优平衡点。比如把并发从 4 降到 2TTFT 可能从 900ms 回到 500ms而吞吐只从 120 tok/s 降到 80 tok/s这对实时场景就是划算的。如果你需要长期跑这类压测或者把指标采集集成到 CI 流程里可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 它更适合持续性的编码和 Agent 调用场景。接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里有完整的接口说明方便你把采集逻辑固化下来。API Keys 管理页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 可以给不同压测任务分配不同的 Key方便按用途追踪用量。最后提醒一个实操细节压测时尽量固定 prompt 和 max_tokens每次只改一个变量否则指标波动你分不清是参数影响还是输入差异。把每次压测的配置和结果记下来几轮之后你就能摸清所选模型在你业务场景下的性能边界。

相关新闻

AutoNet实战:自动化神经架构搜索与超参数调优指南

AutoNet实战:自动化神经架构搜索与超参数调优指南

过去几个月,我一直在帮一个做工业视觉检测的团队收拾他们的建模流程。问题倒不复杂:样本量不算少,特征也够,但每次换一批新产品,三位工程师就要重新做一轮特征筛选、网络结构选择、超参数调参。两周起步,做…

2026/10/18 20:18:55 阅读更多 →
CSS Sprites精灵图实战:从合并请求到高清屏适配的完整指南

CSS Sprites精灵图实战:从合并请求到高清屏适配的完整指南

去年年底,我接手了一个后台管理系统的性能优化,最直接的问题不是接口慢,而是首页一次性拉了40多张小图标。每张图标几KB到十几KB不等,F12打开Network面板,几十个请求排着队往下跑。当时我第一个念头就是:把…

2026/10/18 20:17:54 阅读更多 →
栈与队列计数问题解析:卡特兰数与出队序列唯一性

栈与队列计数问题解析:卡特兰数与出队序列唯一性

先说结论:n个互异元素依次入栈,能产生的不同出栈序列数是第n个卡塔兰数;而同样的n个元素依次入队,能产生的出队序列数却是1。“n元栈和队列的两个计数问题的解析求解”这个标题,浓缩的就是两个问题:一个是栈…

2026/10/18 20:17:54 阅读更多 →

最新新闻

AI原生开发平台架构规划与落地实操指南

AI原生开发平台架构规划与落地实操指南

做技术交流的时候,被问得最多的一个问题,差不多就是标题这句:AI原生开发平台到底是什么、架构怎么规划、怎么落地。说实话,每次回答完我都觉得还有话没说完,因为这三个问题其实是层层递进的——概念不清就谈不上规划&a…

2026/10/19 7:38:21 阅读更多 →
diagram-design:从草图到可维护图示系统的设计方法论

diagram-design:从草图到可维护图示系统的设计方法论

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题第一次听到“diagram-design”这个词,很多人会以为它只是“画图工具”的另一个说法。但真正在项目里摸爬滚打过的人都知道,图这件事从来不是“画出来”那么简单。它背后牵扯的是信…

2026/10/19 7:38:21 阅读更多 →
MCP 三种传输方式全解析:stdio、SSE、Streamable HTTP 选型实战

MCP 三种传输方式全解析:stdio、SSE、Streamable HTTP 选型实战

聊 MCP 的三种传输方式之前,先承认一件事:大多数人在看 MCP 文档的时候,最容易卡住的就是传输层这一节。stdio、SSE、Streamable HTTP 三个词单独拎出来都认识,合在一起却不知道它们为什么同时存在、各自解决什么问题。这不怪你&a…

2026/10/19 7:38:21 阅读更多 →
AI论文降重指令实战:6类提示词破解查重与AIGC检测

AI论文降重指令实战:6类提示词破解查重与AIGC检测

2025年的毕业季明显比前几年多了一道坎:不只是查重率,还多了AI检测。我身边好几个准备答辩的朋友,论文初稿写得很顺,结果一查重,标红一片;好不容易把重复率压下来了,送审前又被提醒“部分段落机…

2026/10/19 7:38:21 阅读更多 →
rea模块开发指南:从命名解析到高复用架构设计与性能优化

rea模块开发指南:从命名解析到高复用架构设计与性能优化

1. 从“rea”这个标题说起:一个被低估的通用缩写第一次看到“rea”这个标题的时候,我脑子里蹦出来的第一反应是——这大概率又是一个被缩写玩坏了的项目名。在技术圈混久了你会发现,越是短到只有三个字母的标题,背后藏的东西往往越…

2026/10/19 7:38:21 阅读更多 →
diagram-design:从设计令牌到语义化图表的系统化设计方法

diagram-design:从设计令牌到语义化图表的系统化设计方法

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题第一次听到 “diagram-design” 这个词,很多人会以为它只是“画图工具”的另一个说法。但真正在项目里被图表折磨过的人知道,问题从来不是“画不出来”,而是“画得乱、…

2026/10/19 7:37:20 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →