从 BERT 到 GPT:聊聊它们的原始架构——Transformer 模型

391 阅读6分钟

前言

这几年 AI 迅速发展,各大公司争先涌入这个赛道,希望借助 AI 改变格局,抓住这波重新洗牌的机会。这时候企业在如何使用 AI 时,也会面临选择难题,一是采用通用模型,但这有一定的限制不一定适合自己且有泄密的风险;二是继续训练自己的模型,但需要很大的成本。

两种方式各有优缺点,企业需要根据自己的实际需要选择最适合自己的方案。但毫无疑问,AI已成为企业未来发展不可或缺的重要组成部分,而模型作为AI最重要的核心,由于各大公司的产业赛道不同,目前已经演化出各种各样的数据模型,今天就让我们一起来了解下一个原始AI大模型的发展历程——Transformer模型。

历史

Transformer 模型是自然语言处理(NLP)领域中的一种重要架构,由 Vaswani 等人在 2017 年提出,具有极大的影响力。

自从 Transformer 模型首次提出以来,它已经成为处理各种复杂任务的核心架构。这些模型,包括BERT、GPT 系列、T5、RoBERTa、XLNet、ALBERT、DistilBERT等,通过其强大的自注意力机制和深度学习能力,大幅度提升了文本理解、生成和翻译的精度。

Transformer 的引入不仅推动了语言模型的革命,也扩展到计算机视觉领域,产生了如 DETR 和 ViT 等创新应用。这种广泛应用和显著的性能提升凸显了 Transformer 框架在构建智能系统中的关键地位。以下是对 Transformer 模型的详细介绍:

1. Transformer 模型概述

Transformer 模型主要用于处理序列数据,并且不依赖于传统的递归神经网络(RNN)结构,它的核心优势在于其强大的并行处理能力和对长距离依赖的建模能力。它由以下几个主要组件组成:

  1. 自注意力机制(Self-Attention): 使模型能够关注输入序列中所有位置的单词,并根据其重要性加权组合信息,从而捕捉长距离的依赖关系。

  2. 位置编码(Positional Encoding): 由于 Transformer 不具备序列处理的固有能力,需要通过位置编码为每个词汇添加位置信息,以保持序列的顺序。

  3. 编码器-解码器结构(Encoder-Decoder Structure): Transformer 通常包括两个主要部分——编码器和解码器。编码器将输入序列转换为上下文相关的表示,解码器生成输出序列。

image.png

2. 关键组件

2.1 自注意力机制

自注意力机制使模型能够计算输入序列中每个词对其他词的关注程度。它有两个核心点:

一是计算注意力权重: 使用查询(Q)、键(K)和值(V)矩阵计算每个词的注意力权重。

二是加权求和: 根据注意力权重加权求和值向量,生成新的词表示。

2.2 多头机制

多头机制的核心点在于将自注意力机制分成多个头,每个头在不同的子空间中计算注意力。这允许模型捕捉不同的特征和信息。

2.3 位置编码

位置编码的本质就是添加位置信息,通过使用正弦和余弦函数生成位置编码,添加到词嵌入中,以保持词汇的位置信息。

2.4 前馈神经网络

每个位置的表示都通过相同的前馈神经网络,包含两个全连接层和激活函数,用于增强模型的表达能力。

2.5 残差连接和

在每个子层(如自注意力层和前馈层)后添加残差连接,有助于梯度流动和训练稳定性。

2.6 层归一化

层归一化就是在每个子层的输出进行层归一化,以稳定和加速训练过程。

3. Transformer 模型的结构

image.png

Transformer 模型的结构主要由两个核心点组成:一是编码器层,二是解码器层。

堆叠的编码器层

每个编码器层由自注意力机制和前馈神经网络组成。编码器将输入序列转换为上下文相关的表示。

堆叠的解码器层

每个解码器层包括自注意力机制、编码器-解码器注意力机制(用于关注编码器的输出)、和前馈神经网络。解码器生成输出序列,逐步预测每个词。

4. 应用

1)机器翻译: Transformer 模型的初始应用是机器翻译,模型能够高效地翻译文本。

2)文本生成: GPT 系列等模型基于 Transformer 架构生成连贯的文本。

3)文本分类和情感分析: BERT 和其他 Transformer 模型用于文本分类、情感分析等任务。

4)问答系统: Transformer 模型能够理解和回答问题。

5. 示例

以下是一个简化的 Transformer 模型的代码示例(基于 PyTorch深度学习框架):

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader, TensorDataset

class TransformerModel(nn.Module):
    def __init__(self, vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers, dim_feedforward=2048):
        super(TransformerModel, self).__init__()
        self.embedding = nn.Embedding(vocab_size, d_model)
        self.positional_encoding = nn.Parameter(torch.zeros(1, 5000, d_model))  # Positional Encoding
        self.transformer = nn.Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers, dim_feedforward)
        self.fc_out = nn.Linear(d_model, vocab_size)
        
    def forward(self, src, tgt):
        src = self.embedding(src) + self.positional_encoding[:, :src.size(1), :]
        tgt = self.embedding(tgt) + self.positional_encoding[:, :tgt.size(1), :]
        output = self.transformer(src, tgt)
        output = self.fc_out(output)
        return output


# 示例数据
def generate_data(vocab_size, seq_length, num_samples):
    src = torch.randint(0, vocab_size, (num_samples, seq_length))
    tgt = torch.randint(0, vocab_size, (num_samples, seq_length))
    target = torch.randint(0, vocab_size, (num_samples, seq_length))
    return src, tgt, target

# 参数设置
vocab_size = 10000
seq_length = 20
num_samples = 1000

# 生成数据
src, tgt, target = generate_data(vocab_size, seq_length, num_samples)
dataset = TensorDataset(src, tgt, target)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

# 参数配置
d_model = 512
nhead = 8
num_encoder_layers = 6
num_decoder_layers = 6
dim_feedforward = 2048

# 初始化模型
model = TransformerModel(vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers, dim_feedforward)

# 优化器和损失函数
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练步骤
num_epochs = 5

for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for batch in dataloader:
        src, tgt, target = batch
        optimizer.zero_grad()
        output = model(src, tgt)
        output = output.view(-1, vocab_size)
        target = target.view(-1)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    
    print(f"Epoch {epoch+1}, Loss: {total_loss / len(dataloader)}")

# 评估模型
def evaluate(model, src, tgt):
    model.eval()
    with torch.no_grad():
        output = model(src, tgt)
        return output

# 示例输入数据
test_src, test_tgt, _ = generate_data(vocab_size, seq_length, 1)
output = evaluate(model, test_src, test_tgt)

print("模型输出形状:", output.shape)

这个完整的实例展示了如何使用 PyTorch 实现一个基本的 Transformer 模型。它的主要流程如下:

1)模型定义:使用 nn.Transformer 构建了基本的 Transformer 结构。

2)数据准备:创建了示例数据和数据加载器。

3)模型训练:展示了如何训练模型并计算损失。

4)模型评估:演示了如何对模型进行评估并输出预测结果。

最后再输出模型的形状。