为什么大模型推理服务要计算首个token的延迟?其他token的耗时不需要考虑吗?
后续 token 的生成相比首个 token 的计算开销较小,主要是因为在生成过程中,很多计算可以通过增量更新(incremental computation)来优化,从而大大减少了重复计算的工作量。具体来说,以下几个因素解释了为何后续 token 生成的花销通常比首 token 小:
1. 缓存机制与增量计算
大多数现代大模型(如 Transformer 类模型)在推理过程中,处理每个 token 时会使用到“注意力机制”(Attention Mechanism)。为了生成一个新的 token,模型需要根据上下文(输入的 tokens)来计算当前 token 的表示。
首个 token 的计算:
首个 token 的生成需要从头开始计算。首先,模型要对输入的初始上下文(如某些提示语句或开始符号)进行编码(例如,文本的嵌入层),然后对其进行多层的计算以生成第一个 token 的预测。这一过程涉及了从模型的输入到生成第一个输出的全面计算。
此外,Transformer 模型还需要在每一层的计算中存储、更新一些中间变量,特别是注意力机制中的键(K)、值(V)和查询(Q)矩阵的计算,所有这些都需要在第一个 token 生成时进行完整的计算。
后续 token 的生成:
当生成第二个 token 时,模型已经对首个 token 做了计算并产生了一个输出。此时,生成后续 token 时,模型会将第一个 token 的输出作为新的上下文,并基于这个已有的上下文进行增量更新。
增量更新的关键是,模型不需要重复计算已经处理过的部分。例如,在 Transformer 中,计算每一层的 attention 时,注意力的 K 和 V 会被缓存,在生成新的 token 时,模型只需要使用这些已缓存的信息,同时计算新的 token 的查询(Q)并更新模型的输出。
由于大部分计算都可以通过增量更新的方式复用之前的计算结果,后续 token 的生成相较于首个 token 要更高效,因为它避免了重复计算已处理的上下文和中间表示。
2. 自注意力机制的工作原理
Transformer 模型的核心计算就是自注意力机制(Self-Attention),其关键思想是对输入的所有 token 进行相互之间的加权求和。在生成每个 token 时,需要计算当前 token 对所有前面已经生成的 token 的影响。
在生成首个 token 时,模型需要从零开始生成上下文,并计算每个 token 的影响和权重。
在生成后续 token 时,已经生成的 token 会作为上下文传入模型,并影响后续 token 的生成。每次生成新的 token 时,模型只需要对当前生成的 token 和前面的所有 token 进行一次新的计算,这意味着后续 token 的计算可以通过增量更新完成,不需要重新处理所有 token。
例如,在解码器阶段(如 GPT 系列的自回归生成),每生成一个 token 后,它会被追加到当前的上下文中,然后基于更新后的上下文继续生成下一个 token。因为之前生成的 token 的计算结果已被缓存,所以生成每个新的 token 时,计算量大大减少。
3. 模型的内部缓存
大多数现代语言模型(如 GPT 或 T5)使用内部缓存机制来优化生成过程。具体来说:
在生成第一个 token 时,模型需要为每一层的计算存储相关的中间变量,例如注意力的 K、V 和 Q 矩阵。
在生成后续 token 时,已经存储的 K 和 V 矩阵不需要重新计算,而是直接在缓存中使用。这使得生成后续 token 时的计算成本比首个 token 低很多。
由于缓存机制,后续每个 token 的生成仅需要计算新生成的 token 的查询(Q)向量与之前生成的键(K)和值(V)的相互作用,避免了重复计算之前已经生成的内容。
4. 加速技术:批量计算与并行化
为了进一步降低后续 token 生成的计算开销,一些模型采用了并行化和批量计算的技术:
批量生成:在许多实现中,可以同时生成多个 token(比如使用 beam search 或并行解码策略)。这样,模型的计算可以在多个 token 之间共享相同的计算资源,从而减少重复计算。
并行化计算:由于每个 token 生成时只需要考虑已经生成的 token,并不会依赖于未来的 token,这种特性使得模型能够在一定程度上并行化后续 token 的计算。虽然这种并行化通常会受到硬件架构的限制,但仍能显著提高生成效率。
5. 累积推理与局部性原理
在生成后续 token 时,通常会使用之前生成的 token 来逐步改进模型的推理。这个过程中,模型的推理依赖于局部上下文(即前面生成的 token)。相比于完全从头开始的首个 token 生成,后续 token 的生成仅依赖于较小的局部上下文,从而能够更快速地推理。
总结
总的来说,后续 token 生成的计算花销通常低于首个 token,因为:
增量计算:后续 token 只需要基于前面已生成的 token 来更新当前输出,避免了重复计算。
缓存机制:已经计算好的中间结果(如 K 和 V)可以复用,不需要重新计算。
并行化:后续 token 的生成过程更适合并行化计算和批量生成,从而提高推理效率。
自注意力的局部性:后续 token 的生成只涉及局部上下文,相比首个 token 的全局计算,减少了计算量。
这些因素共同作用,使得生成后续 token 时的计算开销显著低于生成首个 token。