你在對話框打了一句話,按下 Enter,然後——差不多就是眨眼之間——答案開始一個字一個字地浮出來。
這個過程太順了,順到你從來沒想過要問:這零點幾秒裡面,到底發生了什麼事?
這篇文章只做一件事:把這「一眨眼」放大成一條可以逐段量度的鏈路。而且不是比喻,是真實量測——我用一次真正的 API 呼叫,把每個階段的時間都記錄下來。讀完你會得到一個具體到可以拿去優化系統的時間預算表。
先給你結論:
一次提問,實測總時間 854 毫秒。其中網絡只佔 4.1%,其餘 96% 全部發生在模型內部。
換句話說,你以為慢在「網速」,其實完全不是。這篇文章會拆給你看。
第一幕:0 到 35 毫秒——建立連線
在你打的字離開你的電腦之前,它得先找到對方。
| 步驟 | 實測 |
|---|---|
| DNS 解析(把網域名稱換成 IP) | 2.9 ms |
| TCP 連線(跟對方握手確認可通訊) | 10.2 ms |
| TLS 握手(加密協商) | 21.5 ms |
| 合計 | 約 35 ms |
這三步叫做「連線建立」,是每次呼叫都要做的固定開場。35 毫秒——大約是相機閃光燈的十分之一。
這裡有個實務含義:如果你要連續問很多問題,保持連線(keep-alive)可以省下這 35 毫秒。對單次對話無感,但對一次跑幾百個請求的批次任務,差別就出來了。
第二幕:微秒級——你的句子被切成 token
模型的母語不是中文,也不是英文。
它讀的是 Token(詞元)——一種介於「字」與「詞」之間的單位。我用的那句問題(「天空為什麼是藍色的?請用兩句話回答。」)在模型眼中是 16 個 token。
切詞快嗎?快到你量不到:
| 文本 | token 數 | 每次切詞耗時 |
|---|---|---|
| 天空為什麼是藍色的?請用兩句話回答。 | 17 | 2.6 µs |
| 天空為什麼是藍色的? | 10 | 1.7 µs |
| The sky appears blue because... | 17 | 3.2 µs |
微秒是百萬分之一秒。 也就是說,切詞大約佔整條鏈路的 0.0004%——完全可以忽略。這個「分詞」動作的細節,站內 Tokenization(分詞) 有完整說明。
:::note 一個誠實的說明:上表用的是 tiktoken(OpenAI 的開源切詞器)作代理量測。不同模型的分詞器不一樣,token 數會有出入——但「切詞耗時屬微秒級、可忽略」這個結論不受影響。 :::
順帶破除一個迷思:很多新手以為「中文比較慢因為字比較多」。實際上中文的效率通常比英文好(常用漢字往往一個字就一個 token),真正的成本差異來自模型的定價,不是切詞速度。
第三幕:最貴的一段——474 毫秒
這裡是整條鏈路的重頭戲。
你的 16 個 token 到了伺服器之後,模型要做一件很反直覺的事:它必須先把你整句話全部讀完,才能吐出第一個字。
這一段叫 prefill(預填充)。它包含四件事:請求上載到伺服器、在佇列裡排隊等 GPU 有空、把 16 個 token 一層一層送進神經網絡、算出第一個字的機率分佈並挑出一個 token。
從你按下 Enter,到畫面上出現第一個字——這段時間有個專門的名字:TTFT(首字延遲/第一個 token 的時間)。
我連續跑了三次:
| 次數 | TTFT |
|---|---|
| 第 1 次 | 577 ms |
| 第 2 次 | 248 ms |
| 第 3 次 | 474 ms |
| 中位數 | 474 ms |
474 毫秒,佔了整條鏈路的 55.5%。
這裡藏著一個很多人踩過的坑:TTFT 和「總時間」是兩件不同的事。 使用者感受到的「卡不卡」,主要取決於 TTFT;而「答案要等多久才吐完」取決於後面那段。所以做產品時,如果覺得回應「很慢」,先分清你抱怨的是哪一個。
第四幕:380 毫秒——一個字一個字吐出來
第一個 token 出現之後,模型不會停下來。它會把剛生成的 token 接回輸入的末端,再預測下一個,如此類推。
這就是你看到的「打字機效果」——不是動畫,是真的在一個一個算。
| 項目 | 實測 |
|---|---|
| 生成 token 數 | 48 個 |
| 生成耗時 | 380 ms |
| 換算速率 | 約每秒 126 個 token |
每秒 126 個 token 是什麼概念?大約等於每秒 80 到 100 個中文字——比你閱讀的速度快好幾倍。
這也解釋了為什麼「輸出很長」的答案是慢的:不是模型卡住,是它真的在逐個字算。想理解這一步為什麼不必每次重算前面的內容,可以看 KV Cache(鍵值快取);想知道為什麼對話越長越慢,看 Context Window(上下文視窗)。
第五幕:854 毫秒——答案回到你眼前
把五段加起來:
| 階段 | 實測 | 佔比 |
|---|---|---|
| 建立連線(DNS + TCP + TLS) | 35 ms | 4.1% |
| 切詞 | < 0.01 ms | ~0% |
| 讀完問題 + 吐出第一個字(TTFT) | 474 ms | 55.5% |
| 逐字生成(48 tokens) | 380 ms | 44.5% |
| 總計 | 854 ms | 100% |
不到一秒。你按下 Enter 的那一下,你的問題在另一端被切成了 16 個碎片、穿過了十幾層神經網絡、跟幾千億個參數打過照面、然後被逐個字地重新拼成一句對你有用的話。
自己拖一次看看
數字看多了會麻木。下面這條時間軸可以拖——建議你拖到 474 毫秒,感受一下「第一個字出現」與「答案完成」之間,其實隔了將近一半的時間。
數據包先要找到對方
35 ms · 4.1%DNS 解析 2.9 ms → TCP 連線 10.2 ms → TLS 加密協商 21.5 ms。每次呼叫都要做的固定開場;連續問很多問題時,保持連線(keep-alive)可省下這一段。
數據來源:2026-10-02 本機實測,deepseek-chat,提問「天空為什麼是藍色的?請用兩句話回答。」 |TTFT 為三次中位數(248 / 474 / 577 ms)|切詞以 tiktoken 作代理量測
最反直覺的一點:96% 的時間不在網絡
回頭看那張表:
- 網絡相關(建立連線 35 ms)= 4.1%
- 模型相關(prefill + 生成 854 − 35 = 819 ms)= 95.9%
這意味著什麼?
如果你覺得 AI 回應慢,換更快的網絡通常没有用。 真正決定速度的是:
- 模型大小——參數越多,每層計算越久
- 排隊情況——尖峰時段,你的請求得等 GPU
- 輸出長度——答案越長,逐字生成越久
- 是否快取——重複的系統提示可被快取,可省下大量 prefill 時間
而反過來,模型廠商真正在拼的,也是這幾件事:更大的頻寬、更好的排隊演算法、更快的推理硬件(例如把權重回放與計算重疊)。想知道每一段成本怎麼換算成錢,見 LLM API 計費。
附錄:完整可重現的量測方法
任何人都可以覆核上面的數字。
環境:macOS(Apple Silicon)· Node v26 · 2026-10-02
模型:deepseek-chat(api.deepseek.com)
提問:「天空為什麼是藍色的?請用兩句話回答。」
量測網絡三段(curl 計時):
curl -sS -o /dev/null --max-time 20 \
-w "dns=%{time_namelookup}s tcp=%{time_connect}s tls=%{time_appconnect}s\n" \
https://api.deepseek.com/
量測 TTFT 與生成速率(Python,串流):
import json, time, urllib.request
req = urllib.request.Request(
"https://api.deepseek.com/chat/completions",
data=json.dumps({
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "天空為什麼是藍色的?請用兩句話回答。"}],
"stream": True, "max_tokens": 120,
}).encode(),
headers={"Content-Type": "application/json",
"Authorization": "Bearer " + API_KEY},
)
t0 = time.perf_counter()
ttft = None
for raw in urllib.request.urlopen(req, timeout=120):
line = raw.decode("utf-8", "ignore").strip()
if not line.startswith("data:"):
continue
if line[5:].strip() == "[DONE]":
break
delta = json.loads(line[5:])["choices"][0]["delta"].get("content", "")
if delta and ttft is None:
ttft = time.perf_counter() - t0 # 首個 token
print(f"TTFT = {ttft*1000:.0f} ms")
print(f"總時間 = {(time.perf_counter()-t0)*1000:.0f} ms")
量測切詞速度(Python):
import time, tiktoken
enc = tiktoken.get_encoding("o200k_base")
text = "天空為什麼是藍色的?請用兩句話回答。"
N = 200
t0 = time.perf_counter()
for _ in range(N):
enc.encode(text)
print(f"{len(enc.encode(text))} tokens, {(time.perf_counter()-t0)/N*1e6:.1f} µs / 次")
量測誤差說明:TTFT 三次結果為 248 / 474 / 577 ms,離散度不小——因為 GPU 排隊與網絡抖動都會影響。單次量測不足以下結論,本文採用中位數。 你重複跑出不同數值是完全正常的。
學完之後,你可以往下走
- 想親手發出第一個請求:第一次呼叫 LLM API
- 想知道「一次對話為什麼會越問越慢」:Context Window(上下文視窗)
- 想知道「為什麼長對話又慢又貴」:KV Cache(鍵值快取)
- 想知道「怎麼把回應變便宜」:LLM API 計費
- 想知道這些名詞的定義:Token(詞元)、TTFT(首字延遲/第一個 token 的時間)、Tokens/second(每秒生成 token 數)、Inference(推理)
一句話總結:你按下 Enter 之後的 0.85 秒,不是「網頁在載入」,而是一台讀過整個人類互聯網的機器,正在為你重組一句話。