GPT-2原理解析:生成式预训练的力量

🎙️ 语音朗读 当前: 晓晓 (温柔女声)

前言

GPT-2(Generative Pre-Training 2)是由OpenAI在2019年发布的文本生成模型,以其惊人的文本生成能力引起了广泛关注。本文将深入解析GPT-2的核心原理和技术细节。

GPT系列的发展历程

GPT系列经历了三个重要阶段:

版本 发布时间 参数量 主要特点
GPT-1 2018 1.17亿 首次提出预训练-微调范式
GPT-2 2019 15亿 更大规模、零样本学习
GPT-3 2020 1750亿 上下文学习、few-shot

GPT-2的核心架构

GPT-2基于Transformer的解码器架构,采用单向(从左到右)自注意力:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import torch
import torch.nn as nn
from transformers import GPT2LMHeadModel, GPT2Tokenizer

class GPT2Config:
"""GPT-2配置参数"""
def __init__(self):
self.vocab_size = 50257
self.n_positions = 1024 # 最大上下文长度
self.n_ctx = 1024
self.n_embd = 768 # 嵌入维度
self.n_layer = 12 # 层数
self.n_head = 12 # 注意力头数
self.afn = "gelu" # 激活函数
self resid_dropout = 0.1
self.embd_dropout = 0.1
self.attn_dropout = 0.1
self.layer_norm_epsilon = 1e-5
self.bos_token_id = 50256
self.eos_token_id = 50256

Transformer解码器实现

GPT-2使用带掩码的Transformer解码器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class TransformerBlock(nn.Module):
"""GPT-2的Transformer块"""
def __init__(self, config):
super().__init__()
hidden_size = config.n_embd
num_heads = config.n_head
self.attention = nn.MultiheadAttention(hidden_size, num_heads)
self.layer_norm1 = nn.LayerNorm(hidden_size)
self.layer_norm2 = nn.LayerNorm(hidden_size)

self.mlp = nn.Sequential(
nn.Linear(hidden_size, hidden_size * 4),
nn.GELU(),
nn.Linear(hidden_size * 4, hidden_size)
)

def forward(self, x, attention_mask=None):
# 自注意力层
attn_output, _ = self.attention(x, x, x, attn_mask=attention_mask)
x = self.layer_norm1(x + attn_output)

# 前馈网络
ff_output = self.mlp(x)
x = self.layer_norm2(x + ff_output)

return x

class MaskedAttention(nn.Module):
"""带因果掩码的注意力"""
def forward(self, query, key, value, attention_mask=None):
d_k = query.size(-1)
scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)

# 创建因果掩码
seq_len = query.size(1)
causal_mask = torch.triu(
torch.ones(seq_len, seq_len), diagonal=1
).bool().to(query.device)
scores.masked_fill_(causal_mask, float('-inf'))

# 应用注意力掩码
if attention_mask is not None:
scores.masked_fill_(attention_mask == 0, float('-inf'))

attn_weights = F.softmax(scores, dim=-1)
return torch.matmul(attn_weights, value)

GPT-2的文本生成

GPT-2的核心能力是文本生成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def generate_text(model, tokenizer, prompt, max_length=100, temperature=0.7, top_k=50):
"""文本生成函数"""
model.eval()

# 编码输入
input_ids = tokenizer.encode(prompt, return_tensors='pt')

# 逐词生成
with torch.no_grad():
for _ in range(max_length):
# 获取模型输出
outputs = model(input_ids)
logits = outputs.logits[:, -1, :] / temperature

# Top-k采样
if top_k > 0:
values, indices = torch.topk(logits, top_k)
probs = F.softmax(values, dim=-1)
next_token = indices.gather(-1, torch.multinomial(probs, 1))
else:
next_token = torch.argmax(logits, dim=-1, keepdim=True)

input_ids = torch.cat([input_ids, next_token], dim=1)

# 遇到结束符停止
if next_token.item() == tokenizer.eos_token_id:
break

return tokenizer.decode(input_ids[0], skip_special_tokens=True)

# 实际使用示例
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')

prompt = "Artificial intelligence will"
generated = generate_text(model, tokenizer, prompt, max_length=50)
print(generated)

GPT-2的不同规模版本

OpenAI发布了多个规模的GPT-2:

模型 参数量 层数 隐藏维度
Small 1.17亿 12 768
Medium 3.45亿 24 1024
Large 7.74亿 36 1280
XL 15亿 48 1600
1
2
3
4
5
6
7
# 加载不同规模的GPT-2
from transformers import GPT2LMHeadModel

model_small = GPT2LMHeadModel.from_pretrained('gpt2') # 117M
model_medium = GPT2LMHeadModel.from_pretrained('gpt2-medium') # 345M
model_large = GPT2LMHeadModel.from_pretrained('gpt2-large') # 774M
model_xl = GPT2LMHeadModel.from_pretrained('gpt2-xl') # 1.5B

零样本学习能力

GPT-2的一个重要特性是零样本学习能力:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 文本分类示例(无需微调)
def zero_shot_classification(model, tokenizer, text, labels):
"""零样本分类"""
results = []

for label in labels:
prompt = f"{text}\n\nThe topic is {label} or not: Yes"
input_ids = tokenizer.encode(prompt, return_tensors='pt')

with torch.no_grad():
outputs = model(input_ids)
logits = outputs.logits[:, -1, :]
probs = F.softmax(logits, dim=-1)

results.append(probs[0, tokenizer.encode(' Yes', add_special_tokens=False)[0]])

return labels[torch.argmax(torch.tensor(results))]

实际应用场景

GPT-2广泛应用于:

  • 内容创作:辅助写作、故事生成
  • 代码补全:GitHub Copilot早期技术基础
  • 对话系统:构建聊天机器人
  • 文本摘要:关键信息提取

总结

GPT-2展示了大规模语言模型的惊人能力,其基于Transformer解码器的架构和生成式预训练范式为后续的GPT-3等更大模型奠定了基础。

参考资源

© 2019-2026 ovo$^{mc^2}$ All Rights Reserved. | 站点总访问 28969 次 | 访客 19045
Theme by hiero