AI 科普笔记

一次生成是怎么发生的:从 token 到 token

2026/11/2

#推理#原理#性能

你可能已经习惯了大模型「边想边打字」的样子。但那个一个字一个字往外蹦的过程,其实是一次完整的模型前向计算只产出一个 token,然后把它接回输入,再来一遍。

这篇文章把这套流程拆开,顺便解释几个常被搞混的性能指标。

第一步:文本变成 token

模型不认识汉字,也不认识英文字母。输入先经过分词器(tokenizer)切成 subword 单元,再映射成整数 ID。

一个中文字通常 1–2 个 token,英文常见词 1 个 token,生僻词会被拆成几段。这就是为什么「同样长度的中英文,token 数差很多」——计费和上下文占用都按 token 算,不按字数算。

第二步:预填充(Prefill)

整段 prompt 一次性送进模型,所有位置并行做注意力计算。这一步是算力密集的:矩阵乘法吃满 GPU,速度快,耗时随输入长度线性增长。

这一步产出的东西里,最关键的是 KV 缓存:每一层的 Key 和 Value 向量被存下来,后面生成时不用重算。没有 KV 缓存,生成第 100 个 token 就要把前面 99 个重新算一遍,成本会爆炸。

第三步:逐 token 解码(Decode)

从最后一个位置的输出里取出词表上的概率分布,按采样策略选一个 token:

  • 贪心:永远选概率最高的,确定但容易重复、呆板;
  • 温度采样:按概率随机抽,温度越高越发散;
  • top-p / top-k:只在概率最高的一小撮候选里抽,砍掉离谱选项。

选出的 token 拼回输入,再前向一次。每生成一个 token 就是一次完整的前向计算,只不过这次输入只有 1 个 token,主要开销变成读取模型权重和 KV 缓存——所以 decode 阶段是显存带宽密集,不是算力密集。

两个指标别搞混

指标含义通常瓶颈
TTFT(首字延迟)从发出请求到第一个 token 出来prefill,长 prompt 明显变慢
TPS(吐字速度)每秒生成多少 tokendecode,受显存带宽和 batch 影响

用户体感主要由 TTFT 决定,而账单和总等待时间由 TPS 决定。这也是为什么「流式输出」几乎是必选项——总时长没变,但体感完全不同。

几个由此推出的结论

  1. 长 prompt 贵在 prefill,不只是贵在 token 数量。
  2. 并发能提升吞吐但不能降低单请求延迟,批量处理把带宽利用率拉满,代价是排队。
  3. KV 缓存是显存大户,长上下文 + 高并发时它比权重还占地方,这也是各种「上下文缓存」「PagedAttention」要解决的问题。
  4. 投机解码(用小模型先猜几个 token、大模型批量验证)能显著提速,因为验证是并行的,而猜中的部分省掉了串行等待。

理解了这条流水线,很多工程取舍就变得显而易见了:为什么上下文越长越慢、为什么同样的模型在不同服务商那里速度差好几倍、为什么「128K 上下文」在实际使用中往往要打折。