AI性能参数-截断、延迟与流式输出

引言

在上一篇文章中,我们讲解了 TokenContext Window 两个核心概念。今天我们继续深入,探讨当上下文窗口不够用时会发生什么------Truncation(截断) ,以及这一切会对你的使用体验产生什么影响------Latency(延迟)Streaming(流式输出)


三、Truncation(截断):当窗口装不下时

3.1 什么是截断

结合前面的 Token → Context Window,截断的本质一句话就能说清:

Truncation = 输入/输出的文本总长度超出了模型的硬性限制(主要是上下文窗口),系统按照既定规则强行"砍掉"一部分,让剩下的内容刚好能塞进去继续跑。

它不是模型"想不起来"这么文艺,而是一个非常冷酷的预处理/后处理工程机制------而且砍哪里、怎么砍,都是提前写死的规则。

3.2 两种截断场景

① Input Truncation(输入截断)

你一次性塞进去的内容(System Prompt + 历史对话 + 附件/文档 + 当前提问)转成 token 后 > 模型上下文窗口上限。

截断策略 怎么砍 后果
从头截断 Drop-Start 丢掉最早期的那部分 token 模型"失忆"了开头聊过什么,但保留当前问题和系统提示
从尾截断 Drop-End 只保留末尾 N 个 token 少见,会把刚发的提问也砍掉
智能截断 强制保留 System Prompt + 当前输入,优先砍中间历史 体验最好,很多产品级聊天界面在用

你可能经历过:"明明刚才还在聊那个方案,怎么突然 AI 像失忆了一样?"------大概率就是从头截断把早期历史切掉了。

② Output Truncation(输出截断)

就算输入顺利塞进去了,模型的输出本身也有上限 (如 max_tokens),可能是:

  • 你或 API 参数显式设了一个较小的最大值
  • 平台默认限制了单次回复长度
  • 模型触发了停止符之外的长度天花板

结果就是:回复在半截突然断掉------最后一句说到一半、代码写到一半就没了。

3.3 识别截断信号

几个很典型的信号:

现象 更像截断 更像模型问题
回复末尾突然中断,最后一句不完整
模型突然"忘了"你 5 轮前交代的重要约束
上传的文档前半部分完全没被引用
回复内容完整,但事实错误、逻辑跳步
API 返回里有 truncated: true

3.4 实用规避策略

  1. 别把上下文窗口当仓库用------对话历史越长越危险
  2. System Prompt 放"不可丢失"的全局规则------多数产品会保护 System Prompt 不被砍
  3. 长文档别硬塞------改用摘要 / RAG / 分段处理
  4. 输出被截断------说"继续"续写,或显式要求控制长度

四、Latency(延迟):你等 AI 的时间

4.1 什么是延迟

延续前面的脉络:

Token 是计量单位 → Context Window 是容量天花板 → Truncation 是超限时的硬砍 → 而 Latency 就是你为这一切付出的时间代价。

一句话定义

Latency = 从你发出请求那一刻起,到拿到(可用的)模型输出为止,经历的时间。

4.2 两个关键延迟指标

指标 全称 你感受到的是什么
TTFT Time To First Token 回车后多久出现第一个字("它有没有卡住?")
E2E Latency End-to-End Latency 完整回答全部生成完总共花多久

如果你用过流式输出(字一个个蹦出来),你直觉里其实同时在感受这两件事。

4.3 LLM 延迟的两阶段结构

传统 Web API 的延迟大致是一次性的,但 LLM 是自回归生成的,延迟结构完全不同:

arduino 复制代码
你的请求进来
    │
    ├─ [1] Prefill(预填充)阶段
    │    把你的全部输入 token 序列做一次前向传播
    │    → 计算出 KV Cache,准备好"下一个 token 的预测起点"
    │    → 这部分决定了 TTFT(首字延迟)
    │
    ├─ [2] Decode(解码/生成)阶段
    │    逐个 token 生成:生成一个 → 拼回去 → 再预测下一个 → 循环
    │    → 这部分决定了"后面字蹦多快"(TPS / 吞吐)
    │
    └─ 输出完成

4.4 反直觉的结论

  1. 输入越长 ≠ 仅仅多传点数据,而是直接推高 TTFT

    • 你塞进 context window 的每个 token 都要参与 prefill 的矩阵运算
  2. 输出越长 = 线性拉长 E2E 延迟

    • 每个输出 token 本质上是一次小步推理

4.5 影响延迟的因素

因素 推高哪段延迟 你能不能控
输入 token 数 ↑ TTFT ✅ 能:精简 prompt、清历史
输出 token 数 ↑ E2E ✅ 能:要求"控制在 X 句"
模型尺寸/参数量 两段都↑ ❌ 选模型时定
并发/负载 两段都↑ ❌ 平台侧控
是否走思维链/工具调用 E2E 暴增 ✅ 能:不是所有问题都需要
网络往返 / 流式 vs 非流式 感知延迟 ✅ 能:开流式

五、Streaming(流式输出):把等待变成陪伴

5.1 什么是流式输出

顺着前面的概念链:

Token → Context Window → Truncation → Latency

Streaming 就是为了解决"Latency 里那段最折磨人的等待"而生的传输方式:模型每生成一个 Token,不等全篇完工,立刻把它推给你。

5.2 非流式 vs 流式对比

特性 非流式 流式
模型侧行为 照常逐 token 生成,但憋着不发 照常逐 token 生成,但每出一个就发一个
网络传输 等全部生成完,一次性返回 用 chunked 分块传输,一边生一边吐
用户感受 长时间空白 → 啪一下全出来 很快出现第一个字,逐字蹦出来
E2E 总耗时 基本相同 基本相同
感知延迟 很差------等待是"死"的 好很多------等待变成"活的"

关键点:流式不加速推理,它只是提前把"已经完成的部分"交给你。

5.3 技术实现

常见的传输实现:

协议/机制 备注
SSE (Server-Sent Events) LLM API 最常用:Content-Type: text/event-stream
HTTP chunked transfer 底层分块发送
WebSocket 双向更灵活,但多数场景用 SSE 更简单

5.4 API 示例对比

关闭流式(stream: false

json 复制代码
{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "人工智能是一门研究如何让机器具备智能行为的学科......"
    }
  }],
  "usage": { "prompt_tokens": 120, "completion_tokens": 85 }
}

开启流式(stream: true

css 复制代码
data: {"choices":[{"delta":{"role":"assistant"}}]}
data: {"choices":[{"delta":{"content":"人"}}]}
data: {"choices":[{"delta":{"content":"工"}}]}
data: {"choices":[{"delta":{"content":"智"}}]}
...
data: [DONE]

5.5 为什么要流式

  1. 把 TTFT 变成"可用时间"------第一个结论片断就有决策价值
  2. 超时与失败更可控------只要有 chunk 在推,就知道它还活着
  3. 成本/中止机会------看到模型跑偏,可以中途 abort 连接

5.6 流式的"坑位清单"

现象 解法思路
JSON 解析难 流式给的是碎片,不能直接 JSON.parse 先拼完整字符串再解析
函数调用也是增量 arguments 一截一截到 按 index 拼接后再解析
截断发生在中途 尾部可能断在不完整句子 检查 finish_reason
前端闪屏/布局抖动 字一蹦出来就触发重排 用等宽容器/固定高度

完整概念链总结

sql 复制代码
Token(计量单位)
  → Context Window(容量上限,用 Token 计)
    → Truncation(塞超了就砍,砍的位置影响结果质量)
      → Latency(塞得越多、生成越长,等待时间越久)
        → Streaming(不改推理速度,但把"已完成 token"提前交付)

实用建议汇总

  1. 成本优化:看 token 数而非字符数,差别很大
  2. 体验优化:开启流式输出,把死等变成活等
  3. 内容管理:别把上下文窗口当仓库,长文档用 RAG 拆分
  4. 调试技巧:遇到 AI"失忆"先查 token 用量,遇到卡顿先查 TTFT

如果你在实际使用中有任何困惑,欢迎在评论区留言讨论!

相关推荐
浮游本尊1 小时前
Java学习第44天 - 本地二级缓存 Caffeine、Redis 分布式锁与热点 Key / 库存预扣
后端
浮游本尊1 小时前
Java学习第43天 - Redis 缓存基础、Cache-Aside 模式与缓存一致性
后端
云技纵横1 小时前
线程池 OOM 实战:无界队列配错,5 万个任务撑爆 JVM
后端
spmcor1 小时前
React 架构师之路:Next.js 全栈革命(第八篇)
前端·react.js
英勇无比的消炎药1 小时前
TinyRobot 源码深度分析:OpenTiny 的 AI 对话组件库
前端·vue.js·github
假如让我当三天老蒯1 小时前
React基础、进阶(学习用)
前端·react.js·面试
魏祖潇1 小时前
AI 能记住了,但能自己干活吗?——看懂执行系统,你就知道它怎么完成复杂任务
人工智能·ai编程
风骏时光牛马1 小时前
HTML十大经典实战代码案例合集
前端
weedsfly1 小时前
前端必知必会:从 IIFE 到 ESM,模块化到底在解决什么?
前端·javascript