Transformer模型基础:注意力机制、层结构、推理过程
核心原理:从词向量到上下文感知表示
Transformer 架构自 2017 年提出后,迅速成为大语言模型(LLM)的事实标准。理解其核心机制,是后续掌握 vLLM 量化与吞吐优化的前提。Transformer 的本质是一个基于自注意力(Self-Attention)的编码-解码或纯解码(Decoder-only)网络,它通过并行计算取代了 RNN 的串行依赖,从而大幅提升了训练与推理效率。
在推理阶段,每个输入 token(词元)首先被映射为一个高维向量,称为 embedding。随后,该向量会与位置编码(Positional Encoding)相加,以引入 token 在序列中的顺序信息。Transformer 的每一层(Layer)主要由两个子层构成:多头自注意力(Multi-Head Self-Attention) 和 前馈神经网络(Feed-Forward Network, FFN)。每个子层之后都接有残差连接(Residual Connection)与层归一化(Layer Normalization)。
自注意力机制的核心在于计算序列中每个 token 与其他所有 token 的相关性。对于输入矩阵 X,通过三个可学习的权重矩阵 W_Q、W_K、W_V 分别生成查询(Query)、键(Key)和值(Value)矩阵。注意力分数的计算公式为:
Attention(Q, K, V) = softmax(Q × K^T / √d_k) × V
其中 d_k 是键向量的维度,除以 √d_k 是为了防止点积结果过大导致 softmax 梯度消失。下图展示了单层 Transformer 解码器在推理时的数据流与核心张量形状变化,这是理解 KV Cache 与量化误差传播的基础。
层结构与多头机制
一个标准的 Transformer 解码器层由以下组件按固定顺序组成:
- 掩码多头自注意力(Masked Multi-Head Attention):在自回归生成时,当前位置只能看到它之前的 token,因此注意力分数矩阵需要应用上三角掩码(Mask),将未来位置的值设为负无穷。
- 残差连接与层归一化:将注意力输出与输入相加,再进行归一化。vLLM 等推理引擎通常采用 Pre-LN 结构(归一化在子层之前),这有助于训练稳定性。
- 前馈网络(FFN):包含两个线性变换和一个非线性激活函数(如 GELU)。FFN 的参数占据了模型总参数量的 2/3,是量化误差的主要来源之一。
多头机制将 d_model 维的 Q、K、V 切分为 h 个头,每个头独立计算注意力,最后拼接并经过一个输出投影矩阵。以 Llama-7B 为例,其典型配置为 d_model=4096,h=32,每个头的维度 d_head=128。多头允许模型在不同子空间关注不同的位置关系,例如一个头关注语法依赖,另一个头关注指代关系。
推理过程与 KV Cache 机制
在推理阶段,Transformer 采用自回归解码方式,即逐个 token 生成。整个过程分为两个阶段:
- 预填充阶段(Prefill):处理完整的输入提示词(Prompt),并行计算所有位置的注意力,并生成对应的 K 和 V 矩阵。此阶段计算密集,GPU 利用率高。
- 解码阶段(Decode):每生成一个新 token,只需计算该 token 的 Q,并与之前所有 token 的 K、V 进行注意力计算。此时,历史 token 的 K、V 被缓存下来,避免重复计算,这就是 KV Cache 的由来。
KV Cache 的大小直接影响推理的内存占用。对于 batch 大小为 B、序列长度为 S、层数为 L 的模型,KV Cache 的显存占用约为:
显存 ≈ 2 (K和V) × L × B × S × d_model × 字节数
以 Llama-7B(d_model=4096,L=32)为例,当 B=1,S=2048,使用 FP16(2字节)时,单条序列的 KV Cache 占用为:
2 × 32 × 1 × 2048 × 4096 × 2 = 1,073,741,824 字节 ≈ 1 GB
这意味着,即使模型权重只有约 14 GB(FP16),一条长序列的 KV Cache 也可能消耗数 GB 显存。vLLM 的核心优化之一就是通过 PagedAttention 管理 KV Cache 的内存碎片,将显存利用率提升至接近 90%。
量化敏感度分析与误区复盘
在量化部署前,需要识别模型中哪些部分对量化误差更敏感。下表总结了不同组件的量化敏感度特征:
| 组件 | 参数量占比 | 量化敏感度 | 原因分析 |
|---|---|---|---|
| 注意力 Q/K/V 投影 | 约 25% | 中 | Q/K 的点积结果经过 softmax,误差会被压缩;但 V 的误差会直接累加到输出。 |
| 注意力输出投影 | 约 8% | 中高 | 将多头结果拼接后投影,误差会跨头传播。 |
| FFN 第一层(升维) | 约 33% | 高 | 将维度从 d_model 扩展到 4×d_model,激活值范围大,离群点(Outlier)多。 |
| FFN 第二层(降维) | 约 33% | 高 | 将 4×d_model 压缩回 d_model,累加误差较大。 |
| LayerNorm | 极小 | 极高 | 通常保留 FP32,量化会导致均值/方差偏移,模型崩溃。 |
另一个易被忽略的点是 KV Cache 的量化。由于 KV Cache 占用大量显存,将其量化为 INT8 可以显著提升吞吐。但 K 和 V 的分布特性不同——K 矩阵通常更集中,V 矩阵更分散——因此需要分别计算缩放因子。vLLM 在实现 KV Cache 量化时,支持 per-head 的缩放参数,以平衡精度与性能。
torch.profiler 或 nvidia-smi 观察模型推理时的显存占用分布。如果 KV Cache 占用超过总显存的 30%,优先考虑 KV Cache 量化;如果权重占主导,则优先对 FFN 层做 INT8 或 INT4 量化。始终以端到端的吞吐(tokens/s)和延迟(TTFT/TPOT)作为最终衡量指标。