跳到主要内容

TTFT 才是用户真正感知到的唯一延迟指标

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的模型在 8 秒内生成了一段 500 词的响应,而竞品模型生成同样内容需要 12 秒。直觉上,你的产品应该更快。但如果你的第一个 Token 在 2.5 秒后才出现,而竞品的第一个 Token 在 400 毫秒就出现了,用户会觉得你的产品很慢——无论总生成时间如何。这就是 LLM 延迟的核心悖论:你的基础设施团队优化的指标(端到端生成时间、每秒 Token 数)并不是用户实际体验到的指标。用户真正感知的,是首 Token 时间(TTFT)。

TTFT 不是一个细节,而是用户判断你的 AI 功能是否响应灵敏的首要信号。忽视它,意味着你构建的是快速却体验迟钝的系统。

TTFT 究竟衡量什么

首 Token 时间(TTFT)是指从提交请求到第一个输出 Token 被渲染给用户所经过的时间。它涵盖了一切:网络传输、队列等待、Prefill 计算(对所有输入 Token 的前向传播),以及 HTTP 响应启动。它不包括生成剩余 Token 的时间。

这一区分至关重要,因为 Prefill 和 Decode 是计算性质不同的操作。Prefill 并行处理所有输入 Token——受内存带宽限制,随上下文长度线性增长。Decode 逐个生成输出 Token——受延迟限制,随输出长度增长。当上下文较长或系统负载较高时,Prefill 开销变大,TTFT 随之上升。

每秒 Token 数(TPS)和总生成时间是另外两个主要指标,它们描述吞吐量,对批量工作负载、成本和容量规划很重要。但在交互场景中——聊天、Copilot、代码助手——用户在 TPS 变得有意义之前早已形成了印象。在 500 毫秒的节点,他们已经开始评判了。

流式传输如何掩盖延迟(以及为什么这既是优势也是陷阱)

流式传输是一种感知层面的技巧。当模型在生成 Token 的同时就开始输出,用户体验到的是对话,而非查询-响应循环。研究表明,即使总生成时间完全相同,用户对流式响应的感知速度也比非流式响应快 40–60%。打字光标的幻觉奏效了。

但流式传输只能在第一个 Token 出现之后掩盖延迟。如果 TTFT 是 3 秒,流式传输毫无帮助——用户会看到 3 秒的空白屏幕,然后才是一阵突然涌现的内容。流式传输提供的感知响应性,依赖于 TTFT 足够短。TTFT 很慢、随后流式很快的体验,甚至比缓慢的非流式响应更糟糕,因为用户已经被引导期待内容即将出现,却要主动等待。

还有第二种失败模式:流式传输了错误的内容。当模型正在生成一段不正确或幻觉的响应时,流式传输会把这个错误逐步暴露给用户。用户读完一段措辞自信的错误答案的第一段,模型才开始纠正——或者根本没纠正。与缓冲响应(可以在显示前做校验)不同,流式响应让 UI 承诺展示处于生成中的内容。这提高了你最先流式传输什么的赌注:大纲、澄清问题或状态行,都比错误答案的开头更合适。

实际上,流式传输还需要仔细的渲染逻辑。不完整的 Markdown Token——未闭合的代码块、渲染了一半的标题——可能在流式传输中途破坏 UI 布局。任何消费流式 LLM 输出的渲染器,都需要缓冲不完整的 Markdown 语法,而不是逐块直接渲染。

你需要了解的数字

人类感知研究给出了清晰的延迟阈值:低于 100 毫秒感觉是即时的;100 毫秒到 1 秒之间,用户会注意到延迟,但不会打断思路;超过 1 秒,用户需要主动等待;超过 10 秒,用户通常会放弃。

对于 LLM 聊天界面,这些阈值大致对应如下目标:

  • TTFT 低于 500ms:感觉响应灵敏,用户不会有意识地感到等待
  • TTFT 500ms–1 秒:可接受,尤其是有清晰加载指示器的情况下
  • TTFT 1–2 秒:明显偏慢,用户开始对可靠性产生疑虑
  • TTFT 超过 2 秒:体验受损,用户会放弃或重试

这些阈值因任务类型而异。代码补全要求更严格——TTFT 超过 100 毫秒就会破坏自动补全的幻觉。文档摘要则可以容忍 2–3 秒,因为用户理解这是一项更耗时的任务。交互模式决定了容忍窗口的大小。

工程师们常常忽视平均 TTFT 和尾部 TTFT 之间的差异。一个 p50 TTFT 为 300ms 的系统,p99 可能达到 3 秒——意味着 1% 的用户等待时间是中位数的 10 倍。这个 p99 代表了你给用户留下的最差印象:在 Prefill 峰值、高并发、长上下文窗口下命中系统的用户。请分别追踪 p50、p95 和 p99,对 p95 设置告警,按照 p99 进行设计。

什么驱动了 TTFT,你能做什么

TTFT 由一系列因素决定,其中大多数是可控的。

上下文长度对用户可见影响最大。在典型服务条件下,每增加一个输入 Token,TTFT(p95)大约增加 0.2–0.24ms。在实践中这近似线性,尽管注意力机制在理论上是二次复杂度——GPU 硬件在适中序列长度下掩盖了这一差距。但在 1 万、5 万或 10 万 Token 时,累积效应变得显著。Prompt 工程的纪律——消除冗余上下文、积极截断历史记录、精简 Schema 和示例——直接转化为更低的 TTFT。

Prefill 缓存是大多数团队可用的最高杠杆优化手段。当请求的前缀与之前计算的 KV 缓存匹配时,服务层可以完全跳过重新计算。节省效果非常显著:对于长上下文请求,复用缓存前缀可以将 TTFT 从数秒降低到数百毫秒。NVIDIA 报告称,TensorRT-LLM 中的 KV 缓存提前复用可将 TTFT 提升 5 倍。生产级服务系统——vLLM、SGLang、NVIDIA NIM——都实现了前缀缓存。如果你的服务栈支持,请启用它。如果你的请求共享公共前缀(系统提示词、工具 Schema、少样本示例),请对其进行结构化以最大化缓存命中率。

队列深度和并发会产生隐藏的 TTFT 峰值。低负载时,请求能快速到达 GPU。高并发时,请求在队列中等待其他请求的 Prefill 操作完成。这是 p99 TTFT 退化的主要驱动因素。分块 Prefill——将长提示词拆分成更小的块,与 Decode 迭代交错执行——是一种缓解措施:它防止单个长上下文请求长时间阻塞队列。分离式 Prefill-Decode 架构更进一步,将独立的 GPU 池分别用于 Prefill 和 Decode,在研究环境中实现了 4 倍的吞吐量提升。

服务商选择比大多数团队想象的更重要。 在 2025–2026 年的主要服务商中,同一模型类别在相似条件下的 TTFT 差异高达 3–5 倍。一些服务商优化吞吐量(更高 TPS,更慢 TTFT),另一些则优化延迟(更低 TTFT,适中 TPS)。在假设你的服务商表现良好之前,请测量你实际生产中的 TTFT——而非合成基准——并按百分位和上下文长度细分。

围绕 TTFT 约束进行设计

如果你无法完全消除 TTFT,你可以围绕它进行设计。

最可靠的技术是在慢速部分到来之前给用户一些有意义的内容。一行状态提示——"正在搜索文档……"、"正在分析你的代码……"——建立了一个处理框架,让 1.5 秒的 TTFT 感觉像是进展而非沉默。这就是骨架屏优于空白加载状态的原因:它们表明正在发生某事,并大致勾勒出响应的轮廓。

第二种模式:在流式传输内容之前先流式传输大纲或计划。如果模型需要生成一段较长的结构化响应,先输出章节标题可以在正文生成期间给用户一个导航框架。这需要通过 Prompt 工程来引导模型产生这种输出顺序,但通过思维链提示或明确的输出格式指令是可以实现的。

第三种模式:将上下文消耗作为 UI 信号暴露出来,而不是隐藏它。理解请求为什么更慢——"正在处理 45,000 个 Token 的上下文"——的用户,比面对无法解释的延迟的用户更有耐心。这在文档分析、代码库搜索或长对话历史的场景中尤为重要。

应该避免的一种模式是隐藏限制然后硬性失败。隐藏上下文窗口或延迟信号的界面,看起来很神奇——直到它不再神奇。当失败模式是用户已经输入消息后突然出现 10 秒的空白屏幕或错误提示时,对信任的损害是不成比例的。

在生产中对 TTFT 进行监控埋点

大多数应用层 LLM SDK 并不将 TTFT 作为一等指标暴露出来,你需要自己进行埋点。

测量方式很直接:在发出请求时记录时间戳,在处理第一个流式块时记录另一个时间戳,计算差值。将其作为直方图指标发出,附带模型、上下文长度桶、用户层级及其他你关心的维度标签。当 p95 超过该用例的阈值时设置告警。

不那么显而易见的是:你需要从用户的角度测量 TTFT,而非服务器的角度。你的 LLM 服务商和你的应用服务器之间的网络传输,不包含在服务商侧的延迟报告中。如果你的应用服务器在美国东部,而你的用户在欧洲,你额外增加了 80–120ms 的往返时间。在你的前端测量客户端 TTFT——从请求发起到第一个字符渲染的时间差——并与服务器侧测量值进行比较。差值告诉你延迟在哪里积累。

针对不同请求类型分别追踪 TTFT。短上下文的简短提示词与长上下文的文档分析请求,TTFT 分布会大相径庭。将它们聚合为一个指标,会用一类的良好表现掩盖另一类的退化。

TTFT 中隐藏的产品决策

TTFT 本质上是一个伪装成基础设施指标的产品决策。一个团队选择在实时自动补全功能中使用 700 亿参数模型,已经做出了 TTFT 承诺——无论他们是否这样分析过。一个为简单的问答查询发送 50,000 个 Token 上下文的团队,也做出了同样的隐性决策。

正确的框架是:每次用户交互都有一个延迟预算。TTFT 在第一个输出字符出现之前就消耗了其中大部分。剩余的部分——用户感到摩擦之前的容忍窗口——决定了你的模型能生成多久。根据交互类型设定 TTFT 目标,然后反推模型大小、上下文长度和基础设施层级。

感觉快的功能并不总是真的快。感觉慢的功能也并不总是真的慢。大多数时候,区别在于第一个 Token 何时出现。

测量它,对它设置告警,围绕它进行设计。

References:Let's stay in touch and Follow me for more thoughts and updates