Agentic Research

TTFT(首字延遲/第一個 token 的時間)

又稱:首字延遲 · 第一個 token 的時間 · time to first token · 首 token 延遲 · 等待時間

從你按下送出,到第一個字出現之間那段「畫面毫無反應」的時間。它主要由提示長度與 prefill 決定,是使用者的確感受為「卡」的那個數字。

你會在什麼時候遇到它

這是使用者「感覺慢」的真正來源,但規格表幾乎不談它,因為它不好行銷。你會在做互動式工具時遇到它:一個 TTFT 很長的系統,就算之後生成很快,使用者也會覺得「按下去沒反應」。只盯 tokens/second 而忽略 TTFT,你會做出一個數字漂亮、體感卻很差的產品。

打個比方

像你問朋友一個問題,他低頭想了三秒才開口說第一個字。那幾秒的沉默(TTFT)決定了你覺不覺得他「反應慢」;一旦他開口,講得多快(tokens/second)是另一回事。沉默越久,越讓人不耐煩。

最小範例

同一次請求的兩個數字:
  TTFT(首字延遲)       ← prefill:把整段提示讀進去、算一遍
  生成速度 tokens/second  ← decode:之後一個個吐字

提示越長(塞了整份文件或超長對話)
  → prefill 要算的越多 → TTFT 越長
高並發下還要排隊 → TTFT 再被拉長

使用者「按下去卡住」的感受,幾乎全來自 TTFT,不是 tokens/second。

prefill 是計算密集的,所以 TTFT 對算力與提示長度敏感;decode 是記憶體密集的,所以 tokens/second 對頻寬敏感。這是兩個不同的瓶頸,要分開量、分開優化。

大模型運算:prefill 與 decode 兩個階段流程圖:生成其實分兩個階段。第一階段 prefill 把整段提示一次平行處理,把每個 token 的 K 與 V 存進 KV cache,這段是 compute-bound,決定了 TTFT(首字延遲)。第二階段 decode 一次只產一個 token:讀 cache、做一次 forward、把新 token 附回 cache,再重複,直到模型吐出 EOS 或撞到輸出上限;這段是 memory-bandwidth-bound,決定了 tokens/second。底部的時間軸說明兩段瓶頸不同,所以縮短提示救的是 TTFT,讓模型少廢話救的是總時間。階段一 · PREFILL(整段提示,一次平行處理)你幫我解釋這段… 共 N 個 token一次 forward pass,全部 token 同時算compute-bound:瓶頸在算力,所以提示越長這段越久KV cache每個 token 的 K 與 V,算過就存起來prefill 的結果存進 cache階段二 · DECODE(一次只產一個 token,重複到結束)讀 cache + 新 tokenmemory-bandwidth-bound產出 1 個 token並 append 回 cache剛產出的 token 變成下一步的輸入 —— 這就是 autoregressive停下來只有兩種原因:模型吐出 EOS,或撞到 max output 上限使用者實際感受到的時間TTFT ← 由提示長度決定tokens/second ← 由輸出長度決定兩段瓶頸不同,所以優化手段也不同:縮短提示(或做前綴快取)救 TTFT;讓模型少廢話救總時間。把兩者混成一個「速度」數字,就會優化錯地方。
1/8輸入:一整段提示
系統提示、歷史、文件、這次的問題,全部拼成一個 token 序列送進去。
第 1 步,共 8 步 輸入:一整段提示

最常搞錯的地方

  • 用 tokens/second 衡量「響應快不快」。使用者感受到的「卡」是 TTFT;生成再快,第一個字遲遲不出來,體感一樣差。
  • 以為提示塞越滿越聰明,忽略 TTFT 代價。把整份文件或超長歷史塞進去,prefill 要算的量上升,每次互動都要重付這筆延遲。
  • 只看平均 TTFT,不看尾延遲(p95/p99)。高並發時排隊會讓少數請求的 TTFT 暴增,平均值把這些長尾藏起來了。

相關詞條

下一步