2、大模型推理基础:Transformer架构、自回归生成、KV Cache、预填充与解码阶段、推理延迟与吞吐量指标
大模型部署优化的核心,在于深刻理解模型推理的底层机制。无论是动态批处理、连续批处理还是投机采样,其设计初衷都是为了解决Transformer架构在自回归生成过程中暴露出的计算与访存瓶颈。本章将系统梳理Transformer的推理特性、自回归生成范式、KV Cache的引入动机、预填充与解码两个阶段的本质差异,以及衡量推理性能的关键指标。只有将这些基础概念内化,后续的优化策略才能有的放矢。
2.1 Transformer 架构的推理特性
Transformer 架构由堆叠的解码器层构成,每一层包含两个核心子层:多头自注意力机制(Multi-Head Self-Attention)和前馈神经网络(Feed-Forward Network, FFN)。在推理阶段,每个 Token 的向量表示逐层经过这两个子层,最终通过输出层映射为词表上的概率分布。从计算视角看,自注意力机制负责捕捉序列内 Token 之间的依赖关系,其计算复杂度为 O(n²)(n 为序列长度);而 FFN 则对每个 Token 独立进行非线性变换,计算复杂度为 O(n)。
然而,推理时的实际瓶颈往往并非计算量本身,而是访存带宽。在解码阶段,模型权重(如 7B 参数约 14GB 的 FP16 权重)需要从显存加载到计算单元,而每个 Token 的计算量相对较小,导致计算单元大量时间处于等待数据加载的状态。这种现象被称为访存密集(Memory-Bound)。理解这一点是后续优化(如算子融合、量化、批处理)的前提。
核心要点:Transformer 推理是计算密集与访存密集的混合体。预填充阶段因处理大量 Token 而偏计算密集,解码阶段因每次仅处理 1 个 Token 而偏访存密集。优化策略必须针对不同阶段分别设计。
2.2 自回归生成范式
大语言模型的文本生成采用自回归(Autoregressive)方式:模型在每一步仅预测下一个 Token,然后将该 Token 拼接至输入序列末尾,作为下一步的输入。这一过程循环往复,直到生成结束符或达到最大长度。自回归生成的串行特性决定了其无法像 BERT 那样并行处理整个序列的输出,这是推理延迟的根本来源。
从工程角度看,自回归生成涉及两个关键操作:采样策略(如贪心解码、温度采样、Top-p 采样)和序列终止条件。采样策略影响生成质量与多样性,而终止条件(如 max_tokens 限制、结束符检测)则直接关系到推理时延的上限。在实际部署中,需要根据业务场景(如聊天、代码生成、摘要)合理设置采样参数,避免无效生成导致资源浪费。
| 采样策略 | 特点 | 适用场景 |
|---|---|---|
| 贪心解码 | 每步取概率最高 Token,输出确定性高 | 代码补全、翻译等要求精确的任务 |
| 温度采样 | 通过温度系数调整概率分布平滑度 | 创意写作、对话生成 |
| Top-p 采样 | 在累积概率达 p 的候选集中采样 | 平衡多样性与质量,通用场景 |
2.3 KV Cache:避免重复计算的基石
在自回归生成的每一步,注意力机制都需要计算当前 Token 的 Query(Q)与所有历史 Token 的 Key(K)和 Value(V)的点积。如果不做缓存,每步都要重新计算历史 Token 的 K 和 V,计算量将随序列长度平方级增长,完全不可接受。KV Cache 的核心思想是:在预填充阶段计算并存储所有输入 Token 的 K 和 V 矩阵;在解码阶段,仅计算新 Token 的 K 和 V,并追加到缓存中,同时复用历史缓存进行注意力计算。
KV Cache 的显存占用公式为:2 × 层数 × 注意力头数 × 头维度 × 序列长度 × 批大小 × 字节数。以 7B 模型(32 层,32 个头,头维度 128,FP16)为例,单条序列每增加 1 个 Token,KV Cache 增加约 2 × 32 × 32 × 128 × 2 = 512KB。当并发请求增多、序列变长时,KV Cache 会迅速占据大量显存,成为部署时的主要容量瓶颈。
风险提示:KV Cache 的显存占用是动态增长的。若未提前规划最大序列长度和批大小,极易触发显存溢出(OOM)。部署时需根据模型参数和 GPU 显存计算可承载的最大并发数。
2.4 预填充与解码阶段
一次完整的推理请求被划分为两个阶段:预填充(Prefill)和解码(Decode)。预填充阶段处理用户输入的提示词(Prompt),并行计算所有输入 Token 的注意力,生成初始的 KV Cache。此阶段计算量大,但并行度高,GPU 利用率通常较高。解码阶段则逐 Token 生成输出,每次仅计算 1 个新 Token,计算量小,但需要频繁访问 KV Cache 和模型权重,受限于显存带宽。
两个阶段的性能特征截然不同,优化手段也因此分化。预填充阶段可通过并行策略(如张量并行)缩短延迟;解码阶段则更适合通过批处理(同时处理多个请求)来提高吞吐量,因为批处理可以将多个请求的权重加载合并,摊薄访存开销。动态批处理(Continuous Batching)正是针对解码阶段设计的优化方案,它允许在序列级进行调度,而非等待整个批次完成。
经验之谈:在监控推理服务时,应分别统计 Prefill 耗时和 Decode 耗时。若 Prefill 耗时过长,需关注输入长度和并行度;若 Decode 耗时过长,则需关注批大小和显存带宽利用率。
2.5 推理延迟与吞吐量指标
衡量推理服务性能的核心指标包括:首 Token 延迟(Time To First Token, TTFT)、每 Token 输出延迟(Time Per Output Token, TPOT)、端到端延迟以及吞吐量(Throughput)。TTFT 主要受预填充阶段影响,决定了用户感知的响应速度;TPOT 决定生成流畅度,受解码阶段影响;吞吐量则指系统在单位时间内生成的 Token 总数,是衡量系统整体效率的关键。
这些指标之间存在相互制约关系。增大批大小可以提升吞吐量,但会同时增加 TTFT 和 TPOT,因为计算资源被多个请求共享。因此,部署优化需要在延迟和吞吐量之间寻找平衡点。例如,在交互式聊天场景中,TTFT 应控制在 500ms 以内,TPOT 应小于 100ms;而在离线批量处理场景中,则更关注吞吐量,可以容忍较高的单请求延迟。
| 指标 | 定义 | 影响因素 | 优化方向 |
|---|---|---|---|
| TTFT | 从请求发出到生成第一个 Token 的时间 | 输入长度、模型并行度、批大小 | 缩短输入、增加并行、减少批大小 |
| TPOT | 生成每个输出 Token 的平均耗时 | 显存带宽、KV Cache 大小、批大小 | 增大批大小、使用量化、优化算子 |
| 吞吐量 | 单位时间内生成的 Token 总数 | GPU 利用率、批大小、序列长度分布 | 动态批处理、抢占调度、投机采样 |
2.6 案例拆解:7B 模型部署的指标权衡
假设我们在一张 NVIDIA A100 (80GB) 上部署 7B 模型(FP16,权重约 14GB)。初始配置为静态批处理,批大小固定为 8,最大序列长度 2048。实测结果:TTFT 平均 800ms,TPOT 平均 45ms,吞吐量约 180 tokens/s。用户反馈首字响应偏慢,且生成速度不稳定。
分析过程:首先检查显存占用,发现 KV Cache 在序列长度达到 2048 时占用约 8 × 512KB × 2048 ≈ 8GB,加上权重和中间激活,总显存约 30GB,仍有较大余量。进一步使用 nsys 性能分析工具,发现解码阶段 GPU 计算单元利用率仅为 12%,而显存带宽利用率接近 90%,确认瓶颈为访存。
优化操作:将静态批处理改为动态批处理(如使用 vLLM 框架),允许请求在序列级完成时立即释放资源,并动态加入新请求。同时将批大小上限提升至 16。优化后,TTFT 降至 450ms(因批大小增大,预填充计算竞争加剧,但通过调度优化部分抵消),TPOT 降至 38ms(因批处理摊薄了权重加载开销),吞吐量提升至 420 tokens/s。代价是单请求的 TPOT 波动略有增加,但整体用户体验显著改善。
复盘经验:静态批处理在请求到达不均匀时会造成严重的资源浪费。动态批处理通过细粒度调度,将访存密集的解码阶段与计算密集的预填充阶段混合执行,有效提升了 GPU 利用率。但需注意,动态批处理对调度器要求较高,需合理设置最大批大小和队列策略,避免请求饥饿。
总结:Transformer 推理的优化必须基于对 Prefill 和 Decode 阶段差异的深刻理解。KV Cache 是连接两个阶段的桥梁,也是显存管理的核心对象。延迟与吞吐量的权衡是部署调优的永恒主题,而动态批处理正是平衡二者的关键手段之一。掌握这些基础,后续章节的优化技术将水到渠成。