实时 AI 推理延迟优化实战:从 2.3s 到 700ms 的全链路拆解(流式架构 + KV Cache + Token Streaming)
结论先行:700ms 是怎么做到的(Quick Answer)
实时 AI 应用(语音助手、面试 copilot、客服机器人)里,用户耐心阈值是 1 秒,超过 1.5s 就会显著感觉"卡顿"。我们把端到端延迟从 2300ms 优化到 700ms,核心五招:
- ASR 流式分段:放弃 VAD 整段送,改用 200ms partial result 触发推理,砍掉 600ms 等待。
- Prompt 模板预热 + KV Cache 复用:System prompt 哈希命中走 prefix cache,prefill 阶段从 350ms 降到 80ms。
- Token-by-token streaming:第一个字 ≤500ms 出现,用户感知 latency 从 "总耗时" 变成 "首字耗时"。
- 模型分层:Qwen Flash 跑高频低复杂度,复杂解题切 Claude,平均 TTFT 砍半。
- SSE + HTTP/2:取消 polling、用持久连接,传输层节省 80~150ms。
下面把每一招的实测数据 + 工程取舍写清楚。
一、延迟从哪来:把 2.3s 拆成 7 段
优化前先做"延迟归因"。我们在生产环境抓了 1000 次请求的火焰图,把端到端拆成 7 段(Chrome 麦克风 → 应用层渲染):
| 阶段 | 耗时 (P50) | 占比 |
|---|---|---|
| 音频采集 + WebSocket 上传 | 120ms | 5% |
| ASR 等待 VAD 端点 | 650ms | 28% |
| ASR 识别 + 文本回传 | 180ms | 8% |
| 业务侧拼 prompt + 鉴权 | 90ms | 4% |
| LLM prefill (System+History) | 360ms | 16% |
| LLM decode (输出 200 tokens) | 820ms | 36% |
| 前端渲染 + DOM update | 80ms | 3% |
结论很清楚:VAD 等待 + Prefill + Decode 是三大头,占了 80%。任何不动这三段、只在传输层优化的方案,最多砍 100ms,没意义。
二、ASR 流式:从"等说完"到"边说边推"(节省 600ms)
传统做法是等 VAD(Voice Activity Detection)判定句子结束才送文本去推理,问题是中文里"嗯"、"那个"这种语气词会让 VAD 误判,导致额外 200~800ms 等待。
我们在做即答侠(一款实时面试 AI copilot)时遇到了同样的瓶颈——面试场景下用户对延迟极度敏感,候选人多停顿 1 秒都会被面试官察觉异常。我们最终的方案是放弃 VAD 整段,改用 Deepgram Nova-2 的 partial_results 模式,每 200ms 推一次中间结果,业务层用一个简单的 stable-suffix 判定:
function isStableEnough(partial, prev) {
// 连续 2 次 partial 末尾 8 个字符未变 = 稳定,可以预热推理
if (!prev) return false;
const tailA = partial.slice(-8);
const tailB = prev.slice(-8);
return tailA === tailB && partial.length >= 6;
}
当 stable-suffix 命中时,我们不等用户说完就把当前文本(带 [partial] 标记)送进 LLM 做 speculative prefill。如果用户继续说话改变了语义,下一轮 prefill 用新文本覆盖;KV cache 复用率实测在中文长句下能到 78%。
三、Prompt 预热 + KV Cache:Prefill 从 350ms 到 80ms
面试场景的 prompt 结构非常稳定:
[System: 你是面试助手 + 候选人简历 + 目标 JD] (≈ 1800 tokens, 几乎不变)
[History: 最近 10 轮 Q&A] (≈ 600 tokens, 慢变化)
[Current Question] (≈ 50 tokens, 每次变)
System 段在整个面试过程中是常量,但传统做法每次请求都重发,prefill 要重新算 1800 tokens 的 attention,光这一步在 H100 上都得 280~350ms。
我们做了两层优化:
- 客户端预热:用户启动 session 的瞬间发一个空 user message 触发 prefill,让 KV cache 提前驻留。
- 服务端 Prefix Cache:用 vLLM 的 prefix caching 或 SGLang 的 RadixAttention,按 system+history 的哈希命中。命中后 prefill 只算 Current Question 的 50 tokens,实测 80ms 完成。
注意:Prefix cache 命中率受 history 影响。我们做了一个历史归一化器:把"嗯"、"对了"这类口水词和时间戳剥离再做哈希,命中率从 41% 提到 73%。
四、Token Streaming:用户感知的 latency 是"首字时间"
这是心理学层面的优化,效果比技术优化还猛。生成 200 tokens 在 50tps 的模型上需要 4 秒,但只要第一个字在 500ms 内出现、后面以 60+ tps 流式吐出,用户会觉得"很快"。
实现上要注意三点:
- SSE 不要 buffer:Nginx 默认
proxy_buffering on会把 SSE 攒到 4KB 才下发,必须显式proxy_buffering off; chunked_transfer_encoding on; - 前端逐字渲染:用
requestAnimationFrame节流,避免每个 token 都触发 React reconcile(80ms 渲染抖动就是这么来的)。 - 结尾稳定性:流式吐出过程里,用户可能根据前 50 个字就行动了,所以前 50 个字的内容质量比后 150 个更重要——prompt 设计要求模型"先给结论再展开"。
五、模型分层 + SSE 链路调优(最后 200ms)
不是所有问题都需要最强模型。我们在路由层做分流:
- 问候、闲聊、简单事实问题 → Qwen 3.5 Flash(TTFT 180ms)
- 结构化回答、STAR 行为题 → GPT-4.1-mini(TTFT 320ms)
- 代码题 / 系统设计 → Claude Sonnet(TTFT 450ms,但深度值得)
路由器本身用一个 50ms 的小模型分类。看起来加了一步反而慢,但因为 70% 流量走 Flash,平均 TTFT 砍掉一半。
传输层最后两个细节:
- HTTP/2 多路复用,避免 head-of-line blocking
- 把 ASR、LLM、用户客户端放同一 Region,跨区 RTT 30ms 加起来不少
六、踩过的坑
坑 1:Prefix cache miss storm。 System prompt 里带时间戳"当前时间是 2026-04-24 14:30:21"会让每次请求都 miss。改成"今天日期 2026-04-24"按天聚合,命中率直接拉满。
坑 2:Speculative prefill 资源浪费。 用户说话中途送 partial 去推理,如果用户后续修改了说法,前面的计算白做。控制好 speculative 触发频率(≥2 次 stable-suffix 才触发),浪费率从 35% 压到 8%。
坑 3:流式中重传。 网络抖动时 SSE 连接断了,前端要做"已渲染 token offset"记录,重连后从 offset 继续,而不是整段重生成。
常见问题
Q1:为什么不直接用 GPT-4o 一把梭?
A:GPT-4o 单次 TTFT 在 600~900ms,已经超过我们 700ms 的总预算。强模型的成本和延迟都太高,分层路由是更工程化的解。
Q2:流式输出过程中如果用户中途打断怎么办?
A:我们维护一个 session_id + turn_id,新 turn 进来直接 AbortController.abort() 掉旧 stream,前端立刻清空展示区。SSE 客户端用 fetch + ReadableStream 比 EventSource 更好控制,因为 EventSource 没法主动 abort。
Q3:KV Cache 命中率怎么监控?
A:vLLM 暴露了 cache_hit_rate metric,每个 prefix 有独立计数。我们在 Grafana 上画两条线:cache_hit_rate 和 P99 prefill latency,前者下降时后者会立刻上涨,是最早的报警信号。
Q4:1800 tokens 的 system prompt 是不是太长?能不能压缩?
A:可以,但收益有限。简历 + JD + 偏好至少 1200 tokens 是必要信息。我们试过用 embedding 检索动态拼,准确率掉了 6%(候选人简历里的关键经历可能被检索漏掉)。最终还是全量塞 + prefix cache。
Q5:移动端怎么办?SSE 在 4G 下稳定吗?
A:移动端我们额外做了 keep-alive 心跳(每 15s 一次空 SSE event),并且在客户端对 token 增量做本地缓冲,断网恢复后从最后收到的 token offset 续传。实测 4G 弱网下首字延迟会到 1.2s 左右,比 WiFi 慢一倍但仍可用。
写在最后
实时 AI 应用的延迟优化是个系统工程,不是单点能解决的。归因 → 分层优化 → 体感对齐,三步走完才能把 2.3s 压到 700ms。流式架构 + KV cache 是骨架,模型分层和 prompt 预热是肌肉,剩下就是不断调试和取舍。希望这篇拆解对做实时 AI 工程的同行有用。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)