流式生成与 SSE:为什么打字机效果背后有「首字延迟」
一、背景
用 ChatGPT、豆包网页版时,答案像 打字机 一行行往外冒——这叫 流式输出(Streaming)。对接 OpenAI 兼容 API 时,stream: true 一开,前端用 SSE(Server-Sent Events) 或 WebSocket 边收边渲染,用户不用干等整段生成完。
做过 自研聊天页、Copilot 类插件 的同学会注意到:首 token(TTFT) 往往最慢,后面字符连发变快——这和 Prefill / Decode、KV Cache 是一件事的两面。搞清流式协议与缓冲,排障时才不会把「网络卡」和「模型慢」搞混。
二、核心概念和核心原理(详细解答+通俗解释)
(一)核心概念(先通俗,再详细)
1. 流式 vs 非流式通俗解释:非流式:模型整段生成完,一次性返回;流式:每生成一小块(常是 若干 token)就 推一帧给客户端。详细解答:体感等待短、可中途 停止生成;缺点是 中间状态 要处理(重连、拼接、乱序)。
**2. SSE(Server-Sent Events)**通俗解释:HTTP 单向 长连接,服务端 push文本事件;浏览器
EventSource好接。详细解答:比 WebSocket 轻,但 只服务端→客户端;若还要上传语音流,可能另开通道。3. Chunk 与 JSON 行通俗解释:OpenAI 风格常 NDJSON 或
data: {...}每行一块,里面带delta.content。详细解答:前端要 容错:finish_reason、usage可能在最后一包。
(二)核心原理(通俗拆解,一步一步讲清楚)
第一步:网关到推理引擎通俗解释:请求进 API 网关,再到 vLLM / TGI /自研推理;流式要 整链路不缓冲大段。详细解答:某层 攒全了再吐 会破坏「打字机」。
第二步:首包慢、后续快通俗解释:Prefill 处理整段 prompt;Decode 逐 token。详细解答:和 KV Cache 文章一起看,用户就理解 为什么长提示首字更慢。
第三步:前端体验通俗解释:Markdown 增量渲染 要小心未闭合代码块;可用 节流 减少 DOM 抖动。详细解答:中止请求(AbortController)要及时释放连接。
三、补充进阶知识点(易懂不晦涩,适配新手进阶)
1. 代理与缓冲通俗解释:Nginx proxy_buffering off 才可能真流式。简单补充:排障先 curl -N 看服务端是否真推。
2. 多模态流通俗解释:有的 API 分通道推文本与音频块。简单补充:协议以厂商文档为准。
3. 和之前知识点的关联(重点) KV Cache、上下文窗口 决定首包与总长;Token 计费对流式同样按 token 累加;评测 可记 TTFT、TPS。
四、文章知识总结
- 背景:流式 = 边生成边推送;SSE 是常见载体。
- 核心概念:chunk/delta;单向 SSE vs 双向 WS。
- 核心原理:TTFT 与 Prefill;全链路忌乱缓冲。
- 进阶:Nginx 缓冲;Markdown 增量;中止连接。
- 核心逻辑:流式解决「体感时延」,不解决「总算力」——该等的 token 一个没少。
总结:流式是 产品体验层的标配能力;和推理原理对齐后,性能优化才有抓手。