1. 从文字到向量:NLP的基石
在自然语言处理领域,文字需要转换为计算机能够理解的数值形式。最直观的想法可能是将每个文字映射为一个独立的维度,比如中文常用字约两万个,就创建两万维的向量。但这种方法存在明显问题:
- 维度灾难:两万维的向量空间会导致计算量剧增
- 语义缺失:简单的one-hot编码无法表达词语之间的语义关系
- 上下文无关:同一个词在不同语境下含义不同,但静态编码无法体现
实际应用中,我们采用词嵌入(Word Embedding)技术,典型如Word2Vec、GloVe等。这些方法通过神经网络训练,将词语映射到低维连续向量空间(通常50-300维),使得语义相似的词语在向量空间中距离相近。例如:
- "国王" - "男人" + "女人" ≈ "女王"
- "巴黎" - "法国" + "中国" ≈ "北京"
注意:词嵌入的质量很大程度上取决于训练语料的大小和质量。在实际项目中,对于专业领域(如医疗、法律),使用通用预训练词向量后还需要进行领域适配训练。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 序列建模的演进:从RNN到Transformer
2.1 循环神经网络(RNN)的局限
RNN通过循环连接处理序列数据,其核心公式为:
code复制h_t = f(W_x * x_t + W_h * h_{t-1} + b)
其中h_t是当前时刻的隐藏状态,x_t是当前输入。
但RNN存在两个根本性问题:
- 梯度消失/爆炸:长距离依赖难以保持
- 顺序计算:无法并行处理序列
2.2 LSTM的改进机制
LSTM通过三个门控单元解决长程依赖问题:
| 门控类型 | 数学表达 | 功能说明 |
|---|---|---|
| 遗忘门 | f_t = σ(W_f·[h_{t-1},x_t]+b_f) | 决定丢弃多少旧记忆 |
| 输入门 | i_t = σ(W_i·[h_{t-1},x_t]+b_i) | 决定更新多少新信息 |
| 输出门 | o_t = σ(W_o·[h_{t-1},x_t]+b_o) | 决定输出多少当前状态 |
虽然LSTM缓解了梯度问题,但顺序计算的本质限制依然存在。处理长度为n的序列,时间复杂度为O(n),无法充分利用现代GPU的并行计算能力。
3. 自注意力机制详解
3.1 核心思想与架构
自注意力机制的核心创新在于:
- 并行计算:同时处理整个序列
- 全局感知:每个位置都能直接访问所有位置的信息
其计算流程可分为四个步骤:
-
线性变换:将输入X通过三个不同的权重矩阵W_Q、W_K、W_V,得到查询(Query)、键(Key)和值(Value)矩阵
code复制Q = XW_Q, K = XW_K, V = XW_V -
注意力打分:计算Q与K的点积并缩放(除以√d_k,d_k是key的维度)
code复制Attention(Q,K,V) = softmax(QK^T/√d_k)V -
Softmax归一化:得到注意力权重矩阵
-
加权求和:用注意力权重对V进行加权
3.2 数学视角解析
假设输入序列长度为n,嵌入维度为d,则:
- Q,K ∈ ℝ^{n×d_k}, V ∈ ℝ^
- 注意力分数矩阵A = QK^T ∈ ℝ^
- 经过softmax的行归一化后,A'_{i,j}表示第i个位置对第j个位置的关注程度
这种设计使得:
- 计算复杂度为O(n²d),当n<d时比RNN的O(nd²)更高效
- 每个位置都能直接捕获全局依赖关系
3.3 位置编码的奥秘
自注意力机制本身是排列等变的(permutation equivariant),即打乱输入顺序会得到对应打乱的输出。为解决这个问题,Transformer引入了位置编码:
code复制PE(pos,2i) = sin(pos/10000^{2i/d})
PE(pos,2i+1) = cos(pos/10000^{2i/d})
这种正弦编码的优势:
- 能表示绝对和相对位置信息
- 可以外推到比训练时更长的序列
- 与词嵌入维度相同,可以直接相加
实际应用中发现,对于不超过512个token的序列,学习式的位置嵌入与正弦编码效果相当。但对于更长的序列,正弦编码展现出更好的泛化能力。
4. Transformer架构解析
4.1 编码器结构
Transformer编码器由N个相同层堆叠而成(通常N=6或12),每层包含:
- 多头注意力(Multi-Head Attention)
- 前馈网络(Feed Forward)
- 残差连接和层归一化
多头注意力将Q、K、V投影到h个不同的子空间(通常h=8),允许模型在不同表示子空间关注不同位置:
code复制MultiHead(Q,K,V) = Concat(head_1,...,head_h)W^O
where head_i = Attention(QW_i^Q, KW_i^K, VW_i^V)
4.2 BERT的预训练策略
BERT采用两种预训练任务:
-
Masked Language Model (MLM):
- 随机遮盖15%的token
- 其中80%替换为[MASK],10%随机替换,10%保持不变
- 预测被遮盖的原始token
-
Next Sentence Prediction (NSP):
- 50%的样本是连续句子
- 50%的样本是随机组合的句子
- 预测两句话是否连续
这种设计使BERT能学习丰富的上下文表示,在下游任务中只需添加简单的输出层即可微调。
4.3 解码器与生成模型
解码器在编码器基础上增加了:
- 掩码多头注意力:防止当前位置关注后续位置
- 编码器-解码器注意力:将解码器查询与编码器输出键值对交互
GPT系列模型采用纯解码器架构,通过自回归方式生成文本:
code复制P(x_t|x_{<t}) = softmax(W_oh_t + b_o)
其中h_t是第t个位置的隐藏状态。
5. 实践中的关键技巧
5.1 注意力机制变体
| 类型 | 计算公式 | 适用场景 |
|---|---|---|
| 缩放点积 | softmax(QK^T/√d_k)V | 标准Transformer |
| 局部注意力 | 限制注意力窗口大小 | 长序列处理 |
| 稀疏注意力 | 预设注意力模式 | 降低计算开销 |
| 线性注意力 | sim(Q,K)=ϕ(Q)ϕ(K)^T | O(n)复杂度 |
5.2 训练优化策略
-
学习率预热:
code复制lr = d_model^{-0.5} * min(step^{-0.5}, step*warmup^{-1.5})典型warmup_steps=4000
-
标签平滑:防止模型对预测结果过度自信
code复制y' = (1-ε)y + ε/K其中K是类别数,ε通常取0.1
-
梯度裁剪:限制梯度范数(通常取1.0或5.0)
5.3 常见问题排查
-
注意力权重饱和:
- 现象:softmax后某些位置权重接近1
- 解决:尝试更大的√d_k缩放因子
-
长序列性能下降:
- 检查位置编码是否合理
- 考虑使用相对位置编码
-
训练不稳定:
- 检查残差连接和层归一化的实现
- 确认梯度裁剪是否生效
在最近的项目中,我们发现当序列长度超过512时,直接使用原始Transformer会出现性能下降。通过引入Blockwise Attention将长序列分块处理,在保持95%准确率的同时将内存占用降低了60%。具体实现时需要注意块间的信息传递,通常保留每块首尾各10%的token作为上下文桥梁。
