新闻详情

新闻详情

首页 / 资讯中心 / 详情

LLM应用性能测试:TTFT/TPOT指标拆解与缓存感知的压测落地

发布时间:2026/9/1 23:35:22来源:尧图网络
LLM应用性能测试:TTFT/TPOT指标拆解与缓存感知的压测落地
AI应用的质量保障大家盯着RAG检索命中率、回答忠实度这些对不对的指标但快不快——性能测试往往是最晚补的一课。等线上用户开始骂转圈圈才想起来压测已经晚了。LLM应用的性能测试和传统Web压测有本质区别输出是流式的延迟被拆成TTFT和TPOT两段结果受prompt缓存影响极大冷热缓存下TTFT能差一个数量级压测还会真实烧钱一次并发压测跑掉几百刀是常态。这篇文章把指标选型、压测架构、缓存感知设计和踩过的坑一次讲清楚。一、先拆指标TTFT和TPOT是两回事传统Web压测看响应时间LLM应用必须拆开看因为用户感知完全不同指标定义用户感知典型量级TTFT首token延迟请求发出到第一个token返回有没有反应300ms-3sTPOT每输出token耗时流式节奏打字快不快20-80ms/tokenE2E整轮完成时间总等待TTFT TPOT×长度Queue Time排队时间网关/推理服务内部高峰期卡住0-10sCache Hit Rate输入token缓存命中率影响TTFT和成本30%-90%关键认知TTFT是缓存和算力调度问题TPOT是推理引擎和带宽问题。优化手段完全不同——TTFT靠prompt缓存、前缀复用、更快的调度器TPOT靠小模型、量化、投机解码。不拆开测你根本不知道瓶颈在哪。下面是流式计时的最小实现用OpenAI SDK的流式接口直接量TTFT和TPOTimport time from openai import OpenAI client OpenAI() def measure_stream(model: str, messages: list, expected_tokens: int 200): t0 time.perf_counter() ttft None tokens 0 first_byte None stream client.chat.completions.create( modelmodel, messagesmessages, streamTrue, stream_options{include_usage: True} ) for chunk in stream: if ttft is None and chunk.choices and chunk.choices[0].delta.content: ttft time.perf_counter() - t0 # 首token延迟 if chunk.choices and chunk.choices[0].delta.content: tokens 1 if chunk.usage: # 流式结束携带usage first_byte time.perf_counter() - t0 tpot (first_byte - ttft) / max(tokens, 1) * 1000 # ms/token return {ttft_ms: round(ttft * 1000, 1), tpot_ms: round(tpot, 1), tokens: tokens, cache_hit: chunk.usage.prompt_tokens_details.cached_tokens 0} print(measure_stream(gpt-4o-mini, [{role: user, content: 写一段200字的RAG架构说明}]))注意两个细节一是必须用流式接口非流式只能拿到E2ETTFT完全不可见二是读prompt_tokens_details.cached_tokens顺手把缓存命中情况一起记下来后面分析数据时靠它分组。二、压测架构网关层压真实Provider层压Mock压测要分两层不要一上来就打真实模型API第一层网关/应用层自己可控的部分。用k6打HTTP接口验证的是你的编排逻辑、检索链路、限流、队列这一层可以放心跑高并发// k6 脚本对RAG网关做流式压测校验SSE与延迟SLO import http from k6/http; import { check, sleep } from k6; import { Rate, Trend } from k6/metrics; const ttft new Trend(ttft_ms, true); const failRate new Rate(ttft_slo_fail); export const options { scenarios: { ramp: { executor: ramping-vus, stages: [ { duration: 2m, target: 20 }, // 预热 { duration: 5m, target: 50 }, // 峰值 { duration: 2m, target: 0 }, // 消退 ], }, }, thresholds: { ttft_ms: [p(95)1500], // TTFT p95 1.5s failRate: [rate0.01], // SLO失败率 1% }, }; export default function () { const payload JSON.stringify({ question: 某产品线7月的退款率趋势, top_k: 5 }); const res http.post(http://gateway:8080/v1/rag/stream, payload, { headers: { Content-Type: application/json }, }); // 网关返回SSE流解析首个 data: 块出现的时间 const firstChunk res.body.indexOf(data:); const t firstChunk 0 ? firstChunk : res.timings.duration; ttft.add(t); failRate.add(t 1500); check(res, { status 200: (r) r.status 200 }); sleep(1); }第二层Provider层模型推理。真实API并发压测有两个问题贵、且会被限流(429)干扰结果。正确做法是搭一个record/replay的mock provider——用真实请求录一段响应含token节奏压测时按录制的节奏回放。这样压测可重复缓存变量被隔离不烧钱可以放心压到500并发网关层的排队、超时、重试逻辑照样被测到。录制时把TTFT和TPOT的分布也录下来回放时按分位数采样比均匀回放更接近真实。三、缓存感知不分开冷热缓存数据全是假的这是LLM压测和传统压测最大的分水岭。三家主流API的缓存机制差异很大厂商缓存方式命中收益注意点OpenAI自动无需配置输入token约50%折扣TTFT显著下降前缀≥1024 token才触发命中与否看cached_tokensAnthropic显式cache_control断点缓存段输入约90%折扣长prompt TTFT可降80%TTL 5分钟需在system prompt埋断点Gemini隐式1小时TTL命中段计费大幅降低前缀需≥1024 token同一个系统提示词比如塞了产品知识库的system prompt冷缓存TTFT可能1.8s热缓存直接掉到300ms。把冷热混在一起压p95会被冷缓存污染你会误判网关性能全用热缓存压又会把网关的问题掩盖掉。正确做法是分两个场景# 压测场景按缓存状态拆分分别出报告 SCENARIOS { cold_cache: {prompt: random_system_prompt(), warmup: 0}, # 每次换前缀模拟冷启动 warm_cache: {prompt: FIXED_SYSTEM_PROMPT, warmup: 2}, # 固定前缀先跑2轮暖缓存 } def gen_prompt(scenario: str) - list: if scenario cold_cache: return [{role: system, content: f你是客服助手。会话ID: {uuid4().hex}}, {role: user, content: USER_QUESTION}] return [{role: system, content: FIXED_SYSTEM_PROMPT}, {role: user, content: USER_QUESTION}]Anthropic侧要主动埋缓存断点长文档场景收益最大from anthropic import Anthropic client Anthropic() resp client.messages.create( modelclaude-sonnet-4-5, max_tokens1024, system[ {type: text, text: KNOWLEDGE_BASE, cache_control: {type: ephemeral}}, {type: text, text: 你是资深客服回答要简洁。}, ], messages[{role: user, content: question}], ) print(resp.usage) # cache_read_input_tokens / cache_creation_input_tokens报告里务必给两组数字TTFT_cold_p95和TTFT_warm_p95上线前的SLO以冷缓存为准用户第一次访问就是冷缓存容量规划用热缓存稳态流量下大部分是热缓存。四、踩坑记录1. 429重试风暴制造延迟假象。并发一高provider开始限流客户端SDK自动重试重试请求又挤占配额延迟曲线变成锯齿状p99直接爆表。这不是性能问题是重试策略问题。压测前先确认指数退避抖动上限设了没重试是否只对可重试错误生效gateway有没有独立的队列和熔断2. 非流式压测完全掩盖TTFT。有人图省事用普通HTTP压测工具打非流式接口拿到的E2E里TTFT和生成时间混在一起根本定位不了问题。LLM应用的压测脚本必须消费流。3. 长短prompt混跑稀释TPOT。短问答TPOT 30ms长文生成TPOT 55ms混在一起平均40ms看起来还行实际上长文场景已经超SLO。按用例类型分组出报告别只给一个总均值。4. 缓存污染让压测越跑越快。同一个system prompt跑10分钟命中率从0爬到80%TTFT曲线一路向下你以为系统变好了其实是缓存热了。压测时长超过缓存TTL(5分钟)后务必分段看数据或干脆按缓存状态分场景。5. 压测账单。一次50并发、5分钟、gpt-4o级别的压测账单可能几百刀。Provider层用mock需要真实数据时用mini档模型或降采样比如10%流量走真实API。一个排查实例TTFT从1.2s劣化到3.4s。某RAG客服应用压测数据里TTFT p95从1.2s涨到3.4s第一反应是模型变慢了。分缓存状态一看冷缓存场景TTFT没变化热缓存场景劣化严重——说明问题不在推理在网关。顺着trace查发现是新增的会话摘要中间件把整段历史对话拼进了system prompt前缀长度翻倍导致缓存命中失效命中率从82%掉到31%。修复方式是摘要前置缓存断点下沉TTFT p95回到900ms。这个案例说明两件事指标不按缓存分组问题定位会走弯路压测数据要能回溯到单次请求的trace否则只能靠猜。五、线上观测压测数据和线上数据对不上等于白测压测只是实验室结果线上真实流量才是最终裁判。建议把压测和线上观测打通共用同一套指标定义压测用k6出报告线上用Langfuse/LangSmith/Phoenix这类工具盯分位数。线上至少盯四个数TTFT p95分冷热缓存、TPOT p95、缓存命中率、单次请求成本。告警阈值不要用均值用p95p99双阈值——均值在LLM场景下几乎没有意义长尾才是用户真实体验。一个容易被忽略的点线上流量的prompt长度分布和压测脚本要一致。压测用的都是几百token的短问题线上全是带长文档的RAG查询TPOT和TTFT会系统性偏高。定期从线上采样真实prompt脱敏后回放进压测集让实验室和线上的差距可控。六、工具选型与SLO基线工具适用层特点k6网关层JS脚本、内置阈值和分位数适合进CILocust网关/自定义客户端Python适合写复杂LLM客户端逻辑Gatling网关层Scala高并发场景性能好Langfuse / LangSmith观测线上真实流量的延迟分位数、成本、缓存命中率Phoenix (Arize)观测追踪评测一体可查单次请求的token级耗时工具链搭配建议k6做压测Langfuse类工具做线上观测两者共用同一套指标名TTFT/TPOT/缓存命中率压测数据和线上数据才能对得上。给一套可落地的初始SLO按业务调整TTFT p95 1.5s冷缓存、TPOT p95 80ms/token、错误率 0.5%、单次问答成本 $0.05。压测报告里除了达标情况必须附缓存命中率和成本两个数——LLM应用的性能、成本、质量是三角关系只看延迟会漏掉一半问题。总结与进阶方向LLM应用性能测试的要点就四句话指标拆到TTFT/TPOT两级压测分层网关打真实、Provider打mock缓存状态分开测报告绑定成本。把这套跑通线上转圈圈的问题基本能提前暴露。进阶方向① 压测进CI模型版本升级、prompt模板改动时自动跑性能回归金丝雀对比新旧版本的TTFT分布② 基于OpenTelemetry GenAI语义约定gen_ai.*属性把压测和线上追踪打通单次请求从网关到provider的全链路耗时可视化③ 把性能SLO和成本SLO一起做预算管理超预算自动告警。如果你也在做 AI 应用RAG / Agent / LLM不知道质量怎么测——我最近在给 AI 应用做免费质量体检出一份可执行的测评报告检索命中率、回答忠实度、噪声敏感度等维度感兴趣可以直接私信我。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

当心陷阱!不是所有 AI 写作工具都靠谱,2026 导师力荐工具汇总 2026/9/2 0:20:27

当心陷阱!不是所有 AI 写作工具都靠谱,2026 导师力荐工具汇总

每年毕业季,无数同学深陷论文难题:开题毫无思路、搭建框架耗费数日、初稿逻辑松散、查重标红泛滥、AI检测超标、格式反复被导师驳回。面对海量的AI写作工具,不少学生抱着“试试看”的心态尝试,却在实际使用中频频碰壁。市面上通用…

阅读更多 →
三款AI写作辅助平台横评:从开题到查重怎么选才不踩坑? 2026/9/2 0:20:27

三款AI写作辅助平台横评:从开题到查重怎么选才不踩坑?

写论文这事,最怕的不是写不出来,而是写得心里没底。 题目改了七八版还怕选重了,文献下载了两百篇越读越乱,参考文献格式调到崩溃,交稿前还得担心重复率和AIGC检测。今年开学季一到,又有一波人在搜“AI论文…

阅读更多 →
留个神!不是所有 AI 写作工具都靠谱,2026 教授认可工具推荐 2026/9/2 0:20:27

留个神!不是所有 AI 写作工具都靠谱,2026 教授认可工具推荐

每年毕业季,无数同学深陷论文难题:开题毫无思路、搭建框架耗费数日、初稿逻辑松散、查重标红泛滥、AI检测超标、格式反复被导师驳回。面对繁重的写作任务,不少学生选择借助AI工具辅助完成,但市面上通用型AI工具虽种类繁多&#xf…

阅读更多 →
GD32F303 USB HID鼠标例程实战:从官方库到完整枚举 2026/9/2 0:20:27

GD32F303 USB HID鼠标例程实战:从官方库到完整枚举

简介:面向嵌入式开发者的GD32 USB鼠标例程,解决了在GD32上通过USB OTG与电容式触摸传感器构建触控鼠标的关键问题。压缩包共182个文件,大小约979KB,以80个H头文件和78个C源文件为主体,H文件承载寄存器定义与接口声明&a…

阅读更多 →
K8s集群迁移容器应用追踪CPU过高排查配置实操 2026/9/2 0:20:27

K8s集群迁移容器应用追踪CPU过高排查配置实操

K8s集群迁移容器应用追踪CPU过高排查配置实操技术栈:Kubernetes v1.32.13 Rocky Linux 8.6 OpenTelemetry Operator Java Agent Sidecar/Init Container操作环境 / 对接原理 / 详细步骤 / 完整命令 / 配置文件 / 验证流程 / 排错方案K8s集群迁移容器应用追踪CPU…

阅读更多 →
国产长芯微LPA8544完全P2P替代AD8544,1.1MHz、46μA、轨至轨 I/O、CMOS 运算放大器 2026/9/2 0:17:27

国产长芯微LPA8544完全P2P替代AD8544,1.1MHz、46μA、轨至轨 I/O、CMOS 运算放大器

描述LPA8541(单通道)、LPA8542(双通道)和LPA8544(四通道)是一系列低成本的电压反馈放大器。这些器件支持在2.1V至5.5V的单电源下工作,并且每个放大器仅消耗46μA的静态电流。它们具备轨到轨输入…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞