Appearance
第4天:Transformer与大语言模型(2017-2022)
学习目标
- 理解Transformer架构的诞生背景和核心思想
- 掌握Self-Attention机制的原理
- 了解BERT和GPT系列的演进
- 掌握预训练+微调范式
- 理解大语言模型时代的特点
课程内容
1. Transformer的诞生
1.1 RNN的局限性
问题1:序列处理
- RNN必须按顺序处理序列
- 无法并行计算
- 训练效率低
问题2:长期依赖
- 即使是LSTM,长序列仍有困难
- 信息在传递中逐渐丢失
- 难以捕捉长距离关系
问题3:固定长度表示
- 最后的隐藏状态需要编码整个序列
- 信息压缩导致损失
- 难以表示复杂关系
1.2 Transformer的突破
2017年:Google发表《Attention Is All You Need》
核心思想:
- 完全基于注意力机制
- 抛弃RNN和CNN
- 实现完全并行计算
- 捕捉长距离依赖
影响:
- 开启了NLP的新时代
- 成为大语言模型的基础
- 推动了多模态AI的发展
2. Transformer架构
2.1 整体架构
Encoder-Decoder结构:
输入 → Encoder → Decoder → 输出Encoder:
- 多层堆叠
- 每层包含Self-Attention和Feed-Forward Network
- 处理输入序列
Decoder:
- 多层堆叠
- 每层包含Self-Attention、Encoder-Decoder Attention和Feed-Forward Network
- 生成输出序列
2.2 Self-Attention机制
2.2.1 基本思想
核心思想:计算序列中每个元素与其他所有元素的相关性。
示例:
句子:"The cat sat on the mat"
对于单词"cat":
- 与"The"的相关性:0.1
- 与"cat"的相关性:0.9
- 与"sat"的相关性:0.3
- 与"on"的相关性:0.2
- 与"the"的相关性:0.1
- 与"mat"的相关性:0.4
"cat"的表示 = 0.1*"The" + 0.9*"cat" + 0.3*"sat" + 0.2*"on" + 0.1*"the" + 0.4*"mat"2.2.2 数学表达
Query、Key、Value:
Q = X * W_Q
K = X * W_K
V = X * W_V注意力分数:
Attention(Q, K, V) = softmax(QK^T / √d_k) * V步骤:
- 计算Query和Key的点积
- 除以√d_k进行缩放
- 应用softmax得到注意力权重
- 用权重加权Value
示例:
python
import numpy as np
def scaled_dot_product_attention(Q, K, V):
"""
Q: (seq_len, d_k)
K: (seq_len, d_k)
V: (seq_len, d_v)
"""
# 计算注意力分数
scores = np.dot(Q, K.T) / np.sqrt(Q.shape[-1])
# 应用softmax
attention_weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True)
# 加权Value
output = np.dot(attention_weights, V)
return output, attention_weights
# 示例
X = np.random.randn(6, 512) # 6个词,512维
W_Q = np.random.randn(512, 64)
W_K = np.random.randn(512, 64)
W_V = np.random.randn(512, 64)
Q = np.dot(X, W_Q)
K = np.dot(X, W_K)
V = np.dot(X, W_V)
output, weights = scaled_dot_product_attention(Q, K, V)
print("Output shape:", output.shape)
print("Attention weights shape:", weights.shape)2.2.3 Multi-Head Attention
基本思想:使用多个注意力头,捕捉不同的关系。
结构:
输入
├─ Head 1: Attention(Q1, K1, V1)
├─ Head 2: Attention(Q2, K2, V2)
├─ Head 3: Attention(Q3, K3, V3)
└─ Head 4: Attention(Q4, K4, V4)
→ 拼接 → 线性变换 → 输出数学表达:
MultiHead(Q, K, V) = Concat(head_1, ..., head_h) * W^O
head_i = Attention(Q * W_i^Q, K * W_i^K, V * W_i^V)优势:
- 捕捉多种关系
- 增强表达能力
- 提高模型性能
示例:
python
class MultiHeadAttention:
def __init__(self, d_model, num_heads):
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads
# 权重矩阵
self.W_Q = np.random.randn(d_model, d_model)
self.W_K = np.random.randn(d_model, d_model)
self.W_V = np.random.randn(d_model, d_model)
self.W_O = np.random.randn(d_model, d_model)
def forward(self, X):
batch_size, seq_len, d_model = X.shape
# 计算Q, K, V
Q = np.dot(X, self.W_Q)
K = np.dot(X, self.W_K)
V = np.dot(X, self.W_V)
# 重塑为多头
Q = Q.reshape(batch_size, seq_len, self.num_heads, self.d_k).transpose(0, 2, 1, 3)
K = K.reshape(batch_size, seq_len, self.num_heads, self.d_k).transpose(0, 2, 1, 3)
V = V.reshape(batch_size, seq_len, self.num_heads, self.d_k).transpose(0, 2, 1, 3)
# 计算注意力
scores = np.dot(Q, K.transpose(0, 1, 3, 2)) / np.sqrt(self.d_k)
attention_weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True)
output = np.dot(attention_weights, V)
# 合并多头
output = output.transpose(0, 2, 1, 3).reshape(batch_size, seq_len, d_model)
# 线性变换
output = np.dot(output, self.W_O)
return output2.3 Position Encoding
问题:Self-Attention没有位置信息,无法区分词序。
解决方案:添加位置编码。
公式:
PE_{pos, 2i} = sin(pos / 10000^(2i/d_model))
PE_{pos, 2i+1} = cos(pos / 10000^(2i/d_model))示例:
python
def positional_encoding(seq_len, d_model):
"""
seq_len: 序列长度
d_model: 模型维度
"""
PE = np.zeros((seq_len, d_model))
for pos in range(seq_len):
for i in range(d_model):
if i % 2 == 0:
PE[pos, i] = np.sin(pos / (10000 ** (i / d_model)))
else:
PE[pos, i] = np.cos(pos / (10000 ** ((i - 1) / d_model)))
return PE
# 示例
PE = positional_encoding(100, 512)
print("Positional encoding shape:", PE.shape)2.4 Feed-Forward Network
结构:
FFN(x) = max(0, xW1 + b1)W2 + b2作用:
- 非线性变换
- 增强表达能力
- 捕捉复杂模式
2.5 残差连接和层归一化
残差连接:
Output = LayerNorm(x + Sublayer(x))层归一化:
LayerNorm(x) = γ * (x - μ) / √(σ² + ε) + β作用:
- 加速训练
- 稳定梯度
- 防止梯度消失
2.6 完整的Transformer Block
Encoder Block:
输入
├─ Multi-Head Self-Attention
├─ Add & Norm
├─ Feed-Forward Network
└─ Add & Norm
→ 输出Decoder Block:
输入
├─ Masked Multi-Head Self-Attention
├─ Add & Norm
├─ Multi-Head Encoder-Decoder Attention
├─ Add & Norm
├─ Feed-Forward Network
└─ Add & Norm
→ 输出3. BERT系列
3.1 BERT(Bidirectional Encoder Representations from Transformers)
2018年:Google发表BERT
核心思想:
- 使用Transformer Encoder
- 双向上下文理解
- 预训练+微调范式
3.1.1 预训练任务
任务1:Masked Language Model(MLM)
方法:
- 随机mask输入序列中15%的token
- 预测被mask的token
示例:
原始句子:"The cat sat on the mat"
Mask后:"The [MASK] sat on the [MASK]"
预测:"cat", "mat"Mask策略:
- 80%替换为[MASK]
- 10%替换为随机词
- 10%保持不变
任务2:Next Sentence Prediction(NSP)
方法:
- 给定两个句子,预测它们是否连续
示例:
句子A:"The cat sat on the mat"
句子B:"It was very comfortable"
预测:是(连续)3.1.2 模型架构
BERT-Base:
- 12层Transformer Encoder
- 768维隐藏层
- 12个注意力头
- 110M参数
BERT-Large:
- 24层Transformer Encoder
- 1024维隐藏层
- 16个注意力头
- 340M参数
3.1.3 微调
方法:
- 使用预训练的BERT作为特征提取器
- 在下游任务上添加任务特定的层
- 微调整个模型或部分层
示例:
python
from transformers import BertTokenizer, BertForSequenceClassification
import torch
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 输入文本
text = "This movie is great!"
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
# 预测
outputs = model(**inputs)
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
print("Prediction:", predictions.item())3.2 BERT的变体
3.2.1 RoBERTa(Robustly optimized BERT approach)
改进:
- 更大的训练数据
- 更长的训练时间
- 移除NSP任务
- 更大的batch size
- 动态masking
3.2.2 ALBERT(A Lite BERT)
改进:
- 参数共享
- 句子顺序预测(SOP)代替NSP
- 更少的参数
3.2.3 DistilBERT
改进:
- 知识蒸馏
- 更少的层数
- 更快的推理速度
3.2.4 ELECTRA
改进:
- 替代token检测(RTD)
- 更高效的预训练
4. GPT系列
4.1 GPT-1(2018)
核心思想:
- 使用Transformer Decoder
- 单向自回归语言建模
- 预训练+微调范式
模型架构:
- 12层Transformer Decoder
- 768维隐藏层
- 12个注意力头
- 117M参数
预训练任务:
- 给定前面的token,预测下一个token
示例:
输入:"The cat sat on the"
预测:"mat"4.2 GPT-2(2019)
改进:
- 更大的模型(1.5B参数)
- 更多的训练数据(WebText)
- 更好的零样本能力
模型规模:
- GPT-2 Small: 117M参数
- GPT-2 Medium: 345M参数
- GPT-2 Large: 774M参数
- GPT-2 XL: 1.5B参数
能力:
- 文本生成
- 故事创作
- 代码生成
- 翻译
4.3 GPT-3(2020)
突破:
- 巨大的模型(175B参数)
- 强大的few-shot学习能力
- 展示了scaling laws
模型规模:
- GPT-3 Ada: 350M参数
- GPT-3 Babbage: 1.3B参数
- GPT-3 Curie: 6.7B参数
- GPT-3 Davinci: 175B参数
能力:
- 文本生成
- 问答
- 翻译
- 代码生成
- 数学推理
Few-shot Learning:
Zero-shot: 直接给出任务描述
One-shot: 给出一个示例
Few-shot: 给出几个示例示例:
Zero-shot:
输入:"翻译成中文:Hello world"
输出:"你好世界"
One-shot:
输入:
"翻译成中文:Hello world -> 你好世界
翻译成中文:Good morning"
输出:"早上好"
Few-shot:
输入:
"翻译成中文:Hello world -> 你好世界
翻译成中文:Good morning -> 早上好
翻译成中文:How are you"
输出:"你好吗"4.4 GPT-3.5(2022)
改进:
- 更好的指令跟随能力
- 更强的推理能力
- ChatGPT的基础
ChatGPT:
- 基于GPT-3.5
- RLHF(Reinforcement Learning from Human Feedback)
- 对话能力
- 代码能力
RLHF过程:
- SFT(Supervised Fine-tuning):使用人工标注的数据微调
- RM(Reward Model):训练奖励模型
- PPO(Proximal Policy Optimization):使用强化学习优化
5. 预训练+微调范式
5.1 预训练
目标:在大规模无标注数据上学习通用表示。
数据:
- 文本:维基百科、Common Crawl、书籍
- 代码:GitHub、Stack Overflow
- 多模态:图像-文本对
任务:
- MLM(Masked Language Model)
- NSP(Next Sentence Prediction)
- 自回归语言建模
5.2 微调
目标:在下游任务上适应预训练模型。
方法:
- 全量微调:微调所有参数
- 部分微调:只微调部分层
- 参数高效微调(PEFT):只微调少量参数
示例:
python
from transformers import BertForSequenceClassification, AdamW
from torch.utils.data import DataLoader
# 加载预训练模型
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 优化器
optimizer = AdamW(model.parameters(), lr=2e-5)
# 训练循环
model.train()
for epoch in range(3):
for batch in train_dataloader:
optimizer.zero_grad()
outputs = model(**batch)
loss = outputs.loss
loss.backward()
optimizer.step()5.3 提示工程(Prompt Engineering)
核心思想:通过设计提示(prompt)来引导模型生成期望的输出。
技巧:
- Few-shot:提供示例
- Chain-of-Thought:引导推理过程
- Role-playing:设定角色
- Format specification:指定输出格式
示例:
Few-shot:
"Q: 1+1=?
A: 2
Q: 2+2=?
A: 4
Q: 3+3=?
A:"
Chain-of-Thought:
"Q: 如果我有3个苹果,吃了1个,又买了2个,我现在有几个苹果?
A: 让我们一步步思考:
1. 最初有3个苹果
2. 吃了1个,剩下3-1=2个
3. 又买了2个,现在有2+2=4个
答案:4个苹果"6. 多模态AI的兴起
6.1 CLIP(Contrastive Language-Image Pre-training)
2021年:OpenAI发表CLIP
核心思想:
- 联合训练图像和文本编码器
- 学习图像和文本的对齐
- 零样本图像分类
训练方法:
- 对比学习
- 正样本对:图像-文本匹配
- 负样本对:图像-文本不匹配
应用:
- 零样本图像分类
- 图像检索
- 文本检索
示例:
python
import clip
import torch
from PIL import Image
# 加载模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
# 准备图像和文本
image = preprocess(Image.open("cat.jpg")).unsqueeze(0).to(device)
text = clip.tokenize(["a dog", "a cat", "a bird"]).to(device)
# 计算特征
with torch.no_grad():
image_features = model.encode_image(image)
text_features = model.encode_text(text)
# 计算相似度
logits_per_image, logits_per_text = model(image, text)
probs = logits_per_image.softmax(dim=-1).cpu().numpy()
print("Label probs:", probs)6.2 DALL-E
2021年:OpenAI发布DALL-E
核心思想:
- 文本生成图像
- 基于Transformer架构
- 展示了生成式AI的潜力
DALL-E 2(2022):
- 更高的图像质量
- 更大的模型
- 更强的理解能力
6.3 Stable Diffusion
2022年:Stability AI发布Stable Diffusion
核心思想:
- 文本生成图像
- 基于扩散模型
- 开源、可商用
优势:
- 开源
- 可本地运行
- 社区活跃
7. 大语言模型时代的特点
7.1 技术特点
Scaling Laws:
- 模型性能随参数量、数据量、计算量增加而提升
- 涌现能力(Emergent Abilities)
- 超大规模模型展现出小模型没有的能力
涌现能力:
- 上下文学习
- 指令跟随
- 推理能力
- 代码生成
7.2 应用特点
通用性:
- 一个模型可以处理多种任务
- 无需针对每个任务训练
- 提示即可使用
创造性:
- 文本生成
- 图像生成
- 代码生成
- 音乐生成
7.3 产业影响
AI应用爆发:
- ChatGPT
- GitHub Copilot
- Midjourney
- DALL-E
行业变革:
- 软件开发
- 内容创作
- 客服
- 教育
实践任务
任务1:实现Self-Attention
目标:从零实现Self-Attention机制。
要求:
- 实现Scaled Dot-Product Attention
- 实现Multi-Head Attention
- 可视化注意力权重
- 在简单任务上测试
代码框架:
python
import numpy as np
import matplotlib.pyplot as plt
class ScaledDotProductAttention:
def __init__(self, d_k):
self.d_k = d_k
def forward(self, Q, K, V):
"""
Q: (batch_size, seq_len, d_k)
K: (batch_size, seq_len, d_k)
V: (batch_size, seq_len, d_v)
"""
# 计算注意力分数
scores = np.dot(Q, K.transpose(0, 2, 1)) / np.sqrt(self.d_k)
# 应用softmax
attention_weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True)
# 加权Value
output = np.dot(attention_weights, V)
return output, attention_weights
class MultiHeadAttention:
def __init__(self, d_model, num_heads):
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads
self.attention = ScaledDotProductAttention(self.d_k)
# 权重矩阵
self.W_Q = np.random.randn(d_model, d_model)
self.W_K = np.random.randn(d_model, d_model)
self.W_V = np.random.randn(d_model, d_model)
self.W_O = np.random.randn(d_model, d_model)
def forward(self, X):
"""
X: (batch_size, seq_len, d_model)
"""
batch_size, seq_len, d_model = X.shape
# 计算Q, K, V
Q = np.dot(X, self.W_Q)
K = np.dot(X, self.W_K)
V = np.dot(X, self.W_V)
# 重塑为多头
Q = Q.reshape(batch_size, seq_len, self.num_heads, self.d_k).transpose(0, 2, 1, 3)
K = K.reshape(batch_size, seq_len, self.num_heads, self.d_k).transpose(0, 2, 1, 3)
V = V.reshape(batch_size, seq_len, self.num_heads, self.d_k).transpose(0, 2, 1, 3)
# 计算注意力
output, attention_weights = self.attention.forward(Q, K, V)
# 合并多头
output = output.transpose(0, 2, 1, 3).reshape(batch_size, seq_len, d_model)
# 线性变换
output = np.dot(output, self.W_O)
return output, attention_weights
# 测试
batch_size = 2
seq_len = 10
d_model = 512
num_heads = 8
X = np.random.randn(batch_size, seq_len, d_model)
mha = MultiHeadAttention(d_model, num_heads)
output, weights = mha.forward(X)
print("Output shape:", output.shape)
print("Attention weights shape:", weights.shape)
# 可视化注意力权重
plt.figure(figsize=(10, 8))
plt.imshow(weights[0, 0], cmap='viridis')
plt.colorbar()
plt.title('Attention Weights (Head 1, Batch 1)')
plt.xlabel('Key Position')
plt.ylabel('Query Position')
plt.show()任务2:使用预训练模型
目标:使用Hugging Face的预训练模型。
要求:
- 使用BERT进行文本分类
- 使用GPT-2进行文本生成
- 使用CLIP进行图像分类
- 分析模型输出
代码框架:
python
from transformers import BertTokenizer, BertForSequenceClassification, GPT2LMHeadModel, GPT2Tokenizer
import torch
# BERT文本分类
def bert_classification(text):
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
outputs = model(**inputs)
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
return predictions.item()
# GPT-2文本生成
def gpt2_generation(prompt, max_length=100):
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')
inputs = tokenizer(prompt, return_tensors='pt')
outputs = model.generate(**inputs, max_length=max_length, num_return_sequences=1)
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
return generated_text
# 测试
text = "This movie is great!"
print("BERT Classification:", bert_classification(text))
prompt = "Once upon a time"
print("GPT-2 Generation:", gpt2_generation(prompt))任务3:提示工程
目标:研究不同提示策略的效果。
要求:
- 设计不同的提示
- 测试Zero-shot、One-shot、Few-shot
- 测试Chain-of-Thought
- 分析提示效果
示例:
python
def zero_shot(prompt):
# Zero-shot提示
return prompt
def one_shot(prompt, example):
# One-shot提示
return f"{example}\n\n{prompt}"
def few_shot(prompt, examples):
# Few-shot提示
examples_str = "\n\n".join(examples)
return f"{examples_str}\n\n{prompt}"
def chain_of_thought(prompt):
# Chain-of-Thought提示
return f"{prompt}\n\n让我们一步步思考:"
# 测试
question = "如果我有3个苹果,吃了1个,又买了2个,我现在有几个苹果?"
# Zero-shot
print("Zero-shot:")
print(zero_shot(question))
# One-shot
example = "Q: 1+1=?\nA: 2"
print("\nOne-shot:")
print(one_shot(question, example))
# Few-shot
examples = [
"Q: 1+1=?\nA: 2",
"Q: 2+2=?\nA: 4",
"Q: 3+3=?\nA: 6"
]
print("\nFew-shot:")
print(few_shot(question, examples))
# Chain-of-Thought
print("\nChain-of-Thought:")
print(chain_of_thought(question))课后作业
作业1:BERT vs GPT
题目:比较BERT和GPT的架构和能力。
要求:
- 分析BERT和GPT的架构差异
- 比较预训练任务
- 比较适用场景
- 撰写1500字的分析报告
作业2:预训练模型微调
题目:在下游任务上微调预训练模型。
要求:
- 选择一个预训练模型(如BERT)
- 选择一个下游任务(如情感分析)
- 微调模型
- 评估性能
作业3:提示工程研究
题目:研究提示工程的效果。
要求:
- 设计多种提示策略
- 在不同任务上测试
- 比较提示效果
- 总结最佳实践
参考资料
必读文献
Vaswani, A., et al. (2017). "Attention Is All You Need". NeurIPS.
- Transformer原始论文
Devlin, J., et al. (2019). "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding". NAACL.
- BERT原始论文
Brown, T., et al. (2020). "Language Models are Few-Shot Learners". NeurIPS.
- GPT-3原始论文
Radford, A., et al. (2021). "Learning Transferable Visual Models From Natural Language Supervision". ICML.
- CLIP原始论文
推荐阅读
Howard, J., & Ruder, S. (2018). "Universal Language Model Fine-tuning for Text Classification". ACL.
- ULMFiT论文
Liu, Y., et al. (2019). "RoBERTa: A Robustly Optimized BERT Pretraining Approach". arXiv.
- RoBERTa论文
Ouyang, L., et al. (2022). "Training language models to follow instructions with human feedback". NeurIPS.
- InstructGPT论文
在线资源
Hugging Face Transformers: https://huggingface.co/docs/transformers/
- Transformers库文档
The Illustrated Transformer: https://jalammar.github.io/illustrated-transformer/
- Transformer可视化解释
OpenAI API: https://platform.openai.com/docs/
- OpenAI API文档
扩展阅读
Transformer变体
Child, R., et al. (2019). "Generating Long Sequences with Sparse Transformers". arXiv.
- Sparse Transformer
Beltagy, I., Peters, M. E., & Cohan, A. (2020). "Longformer: The Long-Document Transformer". arXiv.
- Longformer
多模态AI
Ramesh, A., et al. (2021). "Zero-Shot Text-to-Image Generation". ICML.
- DALL-E论文
Rombach, R., et al. (2022). "High-Resolution Image Synthesis with Latent Diffusion Models". CVPR.
- Stable Diffusion论文
下节预告
下一节我们将学习生成式AI爆发(2022-2023),了解ChatGPT现象、AIGC技术、Prompt Engineering、AI应用爆发,以及它们如何开启生成式AI时代。

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态
