内容纲要
上文:🚀 Transformer → BERT → ChatGPT:一步步走向“语言智能体”
这一讲我们从最底层的基石——Transformer 开始,搭起整套语言模型的“钢筋框架”。
好嘞,我们从最底层的基石——Transformer 开始,搭起整套语言模型的“钢筋框架”。
🌐 目录预览
- 为什么需要 Transformer?(动机)
- 核心结构总览图
- Self-Attention 是什么?怎么计算?(公式 + 动图)
- Transformer Encoder 结构详解
- 最简 Transformer 编码器 PyTorch 实现
- 小测验 + 示例:输入一句话,看输出向量
1️⃣ 为什么要用 Transformer?
传统的 RNN/LSTM 存在如下问题:
- 序列依赖,无法并行;
- 长期依赖问题:越靠后的词越难获得前面的信息;
- 训练慢,信息传播路径长。
于是——Transformer 来了,全靠 Self-Attention 搞定一切。
2️⃣ Transformer 结构总览图(Encoder 版)
+----------------------------+
输入 → 词嵌入 →| 加位置编码 Positional Encoding |→
+----------------------------+
↓
多头自注意力 Multi-Head Attention
↓
残差 + LayerNorm
↓
前馈网络 FeedForward
↓
残差 + LayerNorm
↓
输出向量
3️⃣ Self-Attention 是个啥?
每个词都和句子中其他词“交互打分”,根据重要性来“加权融合”。
计算步骤
假设输入是词向量矩阵 ( X \in \mathbb{R}^{n \times d} )
-
计算 Query、Key、Value:
Q = XW^Q,\quad K = XW^K,\quad V = XW^V
-
计算注意力权重:
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
-
多头注意力(Multi-head)是把上面步骤做多次,然后拼起来。
动图理解
想象每个词都伸出“注意力触角”,根据句子中的其他词重要程度,把信息“吸”过来,融合成新表示。
4️⃣ Transformer Encoder 模块结构
每个编码器 Layer 包含两个主要子模块:
模块 | 功能 | 输出维度保持 |
---|---|---|
多头注意力 | 建立上下文关系 | 是(残差连接) |
前馈网络 | 增强特征非线性 | 是(残差连接) |
5️⃣ 最简 Transformer Encoder PyTorch 实现(核心代码)
import torch
import torch.nn as nn
import math
class SelfAttention(nn.Module):
def __init__(self, dim, heads):
super().__init__()
self.heads = heads
self.scale = math.sqrt(dim // heads)
self.qkv = nn.Linear(dim, dim * 3)
self.out = nn.Linear(dim, dim)
def forward(self, x):
B, N, D = x.shape
qkv = self.qkv(x).reshape(B, N, 3, self.heads, D // self.heads)
q, k, v = qkv.unbind(dim=2) # shape: (B, N, heads, D//heads)
attn = (q @ k.transpose(-2, -1)) / self.scale
attn = attn.softmax(dim=-1)
out = (attn @ v).transpose(1, 2).reshape(B, N, D)
return self.out(out)
class TransformerEncoderBlock(nn.Module):
def __init__(self, dim, heads, ff_dim):
super().__init__()
self.attn = SelfAttention(dim, heads)
self.norm1 = nn.LayerNorm(dim)
self.ff = nn.Sequential(
nn.Linear(dim, ff_dim),
nn.ReLU(),
nn.Linear(ff_dim, dim)
)
self.norm2 = nn.LayerNorm(dim)
def forward(self, x):
x = x + self.attn(self.norm1(x)) # 注意力+残差
x = x + self.ff(self.norm2(x)) # 前馈+残差
return x
6️⃣ 示例:输入一句话,得到向量输出
vocab = {"hello": 0, "world": 1}
x = torch.tensor([[0, 1]]) # 假设 batch_size=1
embedding = nn.Embedding(10, 32)
inputs = embedding(x) # shape: [1, 2, 32]
encoder = TransformerEncoderBlock(dim=32, heads=4, ff_dim=64)
output = encoder(inputs) # 输出仍是 [1, 2, 32]
print(output.shape)
✅ 小结(图 + 关键词)
关键词 | 解释 |
---|---|
Self-Attention | 全局信息交互 |
多头注意力 | 多路并行注意力,增强表示能力 |
残差连接 | 防止梯度消失,加速收敛 |
位置编码 | 弥补无序结构,编码顺序信息 |
🔜 接下来怎么搞?
后续路线:
4 Comments