多种结构比较
预计学习时间:40分钟
大语言模型结构比较旨在分析不同架构设计的优缺点,包括仅编码器、仅解码器和编码器-解码器模型的特点与适用场景。
基本架构类型
大语言模型架构主要可分为三类:
- 仅编码器模型:如BERT、RoBERTa等
- 仅解码器模型:如GPT系列、LLaMA等
- 编码器-解码器模型:如T5、BART等
架构特点对比
下表对比了三种主要架构的核心特点:
特性 | 仅编码器模型 | 仅解码器模型 | 编码器-解码器模型 |
---|---|---|---|
注意力机制 | 双向注意力 | 单向自回归注意力 | 编码器双向注意力 解码器单向注意力 |
预训练目标 | 主要是MLM (掩码语言建模) | 主要是CLM (因果语言建模) | 混合目标,包括MLM、 去噪、Span预测等 |
上下文访问 | 可以访问双向上下文 | 只能看到左侧上下文 | 编码过程中双向访问 解码过程中单向访问 |
典型应用 | 分类、标注、 问答等理解任务 | 文本生成、对话、 续写等生成任务 | 翻译、摘要、 问答等转换任务 |
推理效率 | 单次前向传播 | 自回归生成 (逐token生成) | 完整编码+自回归解码 |
代表模型 | BERT、RoBERTa、 DeBERTa、ELECTRA | GPT-3/4、LLaMA、 Falcon、Claude | T5、BART、 mT5、FLAN-T5 |
仅编码器模型
仅编码器模型专注于文本理解,通过双向上下文建模:
仅编码器模型通常不适合开放式文本生成任务,但在理解类任务上表现优异。
# BERT风格编码器架构示例
class BERTEncoder(nn.Module):
def __init__(self, vocab_size, hidden_size, num_layers, num_heads):
super().__init__()
self.embedding = nn.Embedding(vocab_size, hidden_size)
self.position_embedding = nn.Embedding(512, hidden_size)
# 双向Transformer层
self.transformer_blocks = nn.ModuleList([
TransformerBlock(hidden_size, num_heads)
for _ in range(num_layers)
])
def forward(self, input_ids):
# 位置ID
position_ids = torch.arange(input_ids.size(1), device=input_ids.device).unsqueeze(0)
# 嵌入
embeddings = self.embedding(input_ids) + self.position_embedding(position_ids)
# 通过Transformer层
for block in self.transformer_blocks:
embeddings = block(embeddings)
return embeddings # 返回所有token的表示
BERT及其变种
BERT模型系列特点:
- 预训练目标:掩码语言建模(MLM)和下一句预测(NSP)
- 典型应用:文本分类、命名实体识别、问答
- 优势:双向上下文理解能力强
- 劣势:不适合生成任务
主要变种比较:
模型 | 发布年份 | 关键创新 | 改进效果 |
---|---|---|---|
BERT | 2018 | 双向Transformer架构 | 首个大规模双向预训练模型 |
RoBERTa | 2019 | 更多数据,移除NSP, 动态掩码 | 显著提升下游任务性能 |
ALBERT | 2019 | 参数共享, 句子顺序预测 | 减少参数量,提高效率 |
ELECTRA | 2020 | 判别式预训练, 替换token检测 | 预训练效率提升, 性能增强 |
DeBERTa | 2020 | 解耦注意力机制, 增强型掩码解码器 | GLUE/SuperGLUE 基准提升 |
仅解码器模型
仅解码器模型专注于文本生成,通过单向自回归预测:
# GPT风格解码器架构示例
class GPTDecoder(nn.Module):
def __init__(self, vocab_size, hidden_size, num_layers, num_heads):
super().__init__()
self.embedding = nn.Embedding(vocab_size, hidden_size)
self.position_embedding = nn.Embedding(2048, hidden_size)
# 单向注意力的Transformer层
self.transformer_blocks = nn.ModuleList([
TransformerDecoderBlock(hidden_size, num_heads)
for _ in range(num_layers)
])
self.lm_head = nn.Linear(hidden_size, vocab_size)
def forward(self, input_ids):
# 位置ID
position_ids = torch.arange(input_ids.size(1), device=input_ids.device).unsqueeze(0)
# 嵌入
embeddings = self.embedding(input_ids) + self.position_embedding(position_ids)
# 通过Transformer层 (每层使用因果注意力掩码)
for block in self.transformer_blocks:
embeddings = block(embeddings, causal_mask=True)
# 输出层预测下一个token
lm_logits = self.lm_head(embeddings)
return lm_logits
GPT系列和类似模型
GPT模型系列特点:
- 预训练目标:因果语言建模(CLM)
- 典型应用:文本生成、对话系统、代码生成
- 优势:强大的生成能力,开放式任务适应性强
- 劣势:生成内容可能存在幻觉,计算复杂度随序列长度增长
主要变种比较:
模型 | 参数量 | 上下文窗口 | 关键特性 |
---|---|---|---|
GPT-1 | 1.17亿 | 512 | 首个大规模Transformer解码器模型 |
GPT-2 | 15亿 | 1024 | 零样本任务学习能力 |
GPT-3 | 1750亿 | 2048 | 大规模预训练,少样本学习能力强 |
LLaMA | 7B-65B | 2048 | 高效训练,开源架构 |
GPT-4 | 未公开(>1.5T) | 8192-32k | 多模态能力,指令微调表现优异 |
Falcon | 7B-180B | 2048 | 高效架构,混合专家微调 |
编码器-解码器模型
编码器-解码器模型结合了前两种架构的优点:
编码器-解码器架构特别适合需要全面理解输入并生成新内容的任务,如翻译、摘要和复杂问答。
# Seq2Seq Transformer架构示例
class EncoderDecoderTransformer(nn.Module):
def __init__(self, vocab_size, hidden_size, num_encoder_layers, num_decoder_layers, num_heads):
super().__init__()
# 嵌入层
self.embedding = nn.Embedding(vocab_size, hidden_size)
self.position_embedding = nn.Embedding(512, hidden_size)
# 编码器 (双向注意力)
self.encoder_layers = nn.ModuleList([
TransformerEncoderLayer(hidden_size, num_heads)
for _ in range(num_encoder_layers)
])
# 解码器 (带交叉注意力)
self.decoder_layers = nn.ModuleList([
TransformerDecoderLayer(hidden_size, num_heads)
for _ in range(num_decoder_layers)
])
# 输出层
self.output_linear = nn.Linear(hidden_size, vocab_size)
def encode(self, src_ids):
# 编码输入序列
src_pos = torch.arange(src_ids.size(1), device=src_ids.device).unsqueeze(0)
src_emb = self.embedding(src_ids) + self.position_embedding(src_pos)
enc_output = src_emb
for enc_layer in self.encoder_layers:
enc_output = enc_layer(enc_output)
return enc_output
def decode(self, tgt_ids, encoder_output):
# 解码并预测输出序列
tgt_pos = torch.arange(tgt_ids.size(1), device=tgt_ids.device).unsqueeze(0)
tgt_emb = self.embedding(tgt_ids) + self.position_embedding(tgt_pos)
dec_output = tgt_emb
for dec_layer in self.decoder_layers:
dec_output = dec_layer(dec_output, encoder_output, causal_mask=True)
return self.output_linear(dec_output)
T5和BART等模型比较
模型 | 架构特点 | 预训练目标 | 典型应用 |
---|---|---|---|
T5 | 统一文本到文本框架 | Span掩码 | 通用NLP任务 |
BART | 序列重建 | 文本去噪 | 摘要、翻译 |
mT5 | 多语言T5变体 | 多语言Span掩码 | 跨语言任务 |
FLAN-T5 | 指令微调T5 | 多任务提示学习 | 遵循指令的任务 |
混合和特殊架构
近期出现了一些创新的混合架构:
- PaLM/Gemini模型:采用路径式语言建模和高效Transformer设计
- Mixture of Experts (MoE):如Mixtral 8x7B,使用稀疏激活的专家网络
- Prefix LM:结合双向和单向注意力的混合架构
- RetNet:结合Transformer和RNN优点的架构设计
各架构性能比较
下面对主要架构在不同任务上的性能进行比较:
任务类型 | 仅编码器模型 | 仅解码器模型 | 编码器-解码器模型 |
---|---|---|---|
分类任务 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
序列标注 | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
开放式生成 | ⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
翻译 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
摘要 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
问答 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
指令跟随 | ⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
推理效率 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
架构选择指南
选择合适的模型架构应考虑以下因素:
- 任务性质:理解型任务选择编码器模型,生成型任务选择解码器模型,复杂转换任务选择编码器-解码器模型
- 计算资源:解码器模型通常需要更多GPU内存,特别是对长序列
- 延迟要求:实时应用中,编码器模型推理更高效
- 上下文长度:需要长上下文理解时,考虑具有长上下文窗口的解码器模型
- 微调成本:较小模型微调成本低,大型解码器模型可能需要参数高效微调技术
发展趋势
大语言模型架构设计的未来发展趋势:
- 长序列建模:改进注意力机制,支持更长上下文窗口
- 模块化架构:专用模块组合,适应不同任务需求
- 稀疏激活:MoE等稀疏激活技术,提高参数效率
- 多模态融合:整合文本、图像、音频等多模态信息
- 高效注意力:线性注意力、状态空间模型等提高计算效率
小结
大语言模型的不同架构各有优势:
- 仅编码器模型在理解型任务上表现优异,计算效率高
- 仅解码器模型在生成型任务上表现卓越,成为主流大语言模型架构
- 编码器-解码器模型在需要深入理解和转换的任务上最为出色
选择合适的架构应根据具体任务需求、计算资源限制和性能要求综合考虑。