第九章、GPT1:Improving Language Understanding by Generative Pre-Training(理论部分)

0 前言

前面我们已经对transfoemer模型以及transformers库做了详细的介绍,接下来我们来看看GPT系列的开篇之作,GPT1它提出了生成式预训练模型,也是至今为止大语言模型的常用训练方式。

论文:https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf

代码:https://github.com/openai/finetune-transformer-lm

1 整体叙述

自然语言理解实际上包含许多人物

  • 文本蕴含:例 "John is a married man "可以推断出"John is a man "这就是蕴含的关系
  • 文本问答:我们现在用的deepseek和GPT都属于问答类的
  • 语义相似性判断
  • 文本分类

但自然语言处理实际上一直面临着比较大的挑战,以文本分类而言,传统的方法,我们需要先对大量的文本做标签,再利用做好的大量数据集来进行训练。但遗憾的是我们人类发展至今虽然已经有了大量语料库,但大多数数据都是没有标签的,尤其是对一些特定任务而言,这就使得从头开始用符合任务的标签数据做判别训练变得非常困难。

GPT1提出了一种利用未标记的数据做生成式预训练,再在标记数据上做微调的训练范式,并证明这样的方式对于特定任务而言是有效的。

那么,新的疑问就产生了,这个预训练模型结构是怎样的?如何做微调?

在解释这个问题之前,我们来回忆一下CV是怎么做微调的,在许多图片任务中,我们预训练的模型实际上是为了提取模型特征,在根据后续的分类任务,在模型的最后添加一个全连接来做分类。如下:

python 复制代码
# 传统方法1:修改模型架构
class TraditionalApproach:
    def __init__(self, pretrained_model):
        self.backbone = pretrained_model
        # 需要添加任务特定的层
        self.task_specific_head = nn.Linear(768, num_classes)
        self.dropout = nn.Dropout(0.1)
        # 可能还需要修改中间层
        
# 传统方法2:大幅修改参数
def traditional_finetuning():
    # 需要训练大量新参数
    # 可能破坏预训练的知识
    # 每个任务需要不同的模型架构

那这种方法的问题是什么呢?首先,显而易见我们修改了模型结构,也许不只最后一层,这会导致模型需要训练大量的新的参数,且可能破坏预训练已经学到的特征。

GPT1是怎么做的呢?

它用到了Task-aware input transformations,看起来很复杂也不太明白到底在做什么。

实际上就是现在我们熟悉的prompt,它不修改模型而是通过修改输入格式来进行微调,如下:

python 复制代码
# 不修改模型,而是修改输入格式
def task_aware_input_transform(text, task_type):
    if task_type == "sentiment_analysis":
        # 情感分析任务的输入格式
        return f"Analyze sentiment: {text} Result:"
        
    elif task_type == "summarization":
        # 摘要任务的输入格式
        return f"Summarize: {text} Summary:"
        
    elif task_type == "translation":
        # 翻译任务的输入格式
        return f"Translate to Chinese: {text} Translation:"
        
    # 通过不同的prompt模板告诉模型要做什么任务

这种方法和传统方法相比,在12个任务中有9个任务在效果上都有显著的提升。

2 训练框架

整体框架分为两步:

  • 预训练:根据超大的语料库训练一个大的语言模型
  • 微调:根据特定任务的标记数据对模型进行微调

2.1 无监督预训练

1、基础知识(可跳过)

无监督只有文本没有标签,区别如下:

json 复制代码
# 无监督数据:只有文本,没有标签
unsupervised_data = [
    "The quick brown fox jumps over the lazy dog",
    "Machine learning is a subset of artificial intelligence",
    "Python is a popular programming language",
    # 数十亿条这样的纯文本,无需人工标注
]

# 对比:监督数据需要标签
supervised_data = [
    ("This movie is great!", "positive"),  # 文本 + 情感标签
    ("I hate this product", "negative"),   # 文本 + 情感标签
]

词元语料库,或者你可以理解为token语料库(不了解token的小伙伴可以回顾一下之前的章节有说哦~)

json 复制代码
# 原始文本
raw_text = "Hello world! How are you?"

# 分词后的token序列
tokens = ["Hello", "world", "!", "How", "are", "you", "?"]

# 转换为ID序列  
token_ids = [15496, 995, 0, 1374, 389, 345, 30]

# 数学表示
U = {u1, u2, u3, u4, u5, u6, u7}
# 其中 u1="Hello", u2="world", u3="!", ...

2、GPT1无监督预训练

清楚上面这些内容之后,我们再来看GPT1的无监督预训练在做什么

目标任务:

假设我们给定一个token语料库:为U={u1,u2,⋯ ,un}U=\{u_1,u_2,\cdots ,u_n\}U={u1,u2,⋯,un}【举个例子就是U={"Hello", "world", "!", "How", "are", "you", "?"}当然史记索这个可能很长很长】

那我们要做的事情其实就是最大化似然估计(统计学中很常见的一个东西,推理比较麻烦理论部分不做叙述,感兴趣的小伙伴可以直接查相关的知识。)

L1(U)=∑ilogP(ui∣ui−k,⋯ ,ui−1;Θ)L_1(U)=\sum_{i}logP(u_{i}|u_{i-k},\cdots,u_{i-1};\Theta)L1(U)=∑ilogP(ui∣ui−k,⋯,ui−1;Θ)

其中k是文本窗的大小,实际上就是神经网络模型输入的大小,因为我们会用一个神经网络拟合上面的估计,而Θ\ThetaΘ就是神经网络待估计参数,这个参数通过随机梯度下降的方法来优化迭代。

模型:

神经网络模型实际上是由多层的Transformer解码器组成,回忆一下解码器的结构它是由带掩码的多头注意力机制+前馈层(当然可能还有残差连接,这里的具体内容会在下一章的代码详解中重新叙述)。简单来看我们可以把用到的神经网络抽象成下面的数学公式:

h0=UWe+Wph_0=UW_e+W_ph0=UWe+Wp其中U是token向量(通过字典已经对应成数字了),WeW_eWe是编码矩阵,WpW_pWp是位置编码矩阵,都是可以学习的。

hl=transformer_block(hl−1)∀i∈[1,n]h_l=transformer\block(h{l-1})\quad \forall_i\in [1,n]hl=transformer_block(hl−1)∀i∈[1,n] 这部分实际上是由很多解码器堆叠而成

P(u)=softmax(hnWet)P(u)=softmax(h_nW_e^t)P(u)=softmax(hnWet) 通过一个全连接加一个softmax将其转化成概率

再用一个很简单的例子来说明这件事。

假设我们的语料库:I am Lily and I like reading book.【因为标点符号也是放在字典里为了简单起见我们忽略它】

token 向量:[I,am,Lily,and,like,reading,book][I,am,Lily,and,like,reading,book][I,am,Lily,and,like,reading,book]

对应的token字典:dictu={1:′I′,2:′am′,3:′Lily′,4:′and′,5:′like′,6:′reading′,7:′book′}dict_u=\{1:'I',2:'am',3:'Lily',4:'and',5:'like',6:'reading',7:'book'\}dictu={1:′I′,2:′am′,3:′Lily′,4:′and′,5:′like′,6:′reading′,7:′book′}

文本数字向量化的 token :U=[1,2,3,4,1,5,6,7]U=[1,2,3,4,1,5,6,7]U=[1,2,3,4,1,5,6,7]

如果要预测下一个单词,那么模型输入就是[1,2,3,4,1,5,6][1,2,3,4,1,5,6][1,2,3,4,1,5,6],通过一系列编码,我们输出一个向量概率,实际上对应的标签应该是[0,0,0,0,0,0,1][0,0,0,0,0,0,1][0,0,0,0,0,0,1]

为什么对应标签是[0,0,0,0,0,0,1][0,0,0,0,0,0,1][0,0,0,0,0,0,1]?实际上就是最后这个位置的概率是1,也就是下一个单词应该是book。

2.2 有监督微调

数据集假设

有一个有标签的数据集 CCC,每个样本包括:

输入 token 序列 x1,...,xmx_1, ..., x_mx1,...,xm,

标签 yyy(比如分类任务的类别)。

模型结构

输入序列 x1,...,xmx_1, ..., x_mx1,...,xm 经过预训练的 Transformer 模型,得到最后一层的激活 hlmh^m_lhlm(即最后一个 token 在最后一层的输出)。

在此基础上,新增一个线性输出层(参数为 WyW_yWy),用于预测标签 yyy。

预测公式

预测公式:
P(y∣x1,...,xm)=softmax(hlmWy) P(y|x_1, ..., x_m) = \mathrm{softmax}(h^m_l W_y) P(y∣x1,...,xm)=softmax(hlmWy)

其中,hlmh^m_lhlm 表示最后一个 token 的 Transformer 激活,WyW_yWy 是新加的线性层参数。softmax 用于将输出转为概率分布,预测属于每个类别的概率。

监督目标函数

监督目标函数:
L2(C)=∑(x,y)log⁡P(y∣x1,...,xm) L_2(C) = \sum_{(x, y)} \log P(y|x_1, ..., x_m) L2(C)=(x,y)∑logP(y∣x1,...,xm)

对每个样本,最大化预测标签的概率(即最大化对数似然)。

辅助语言建模目标(Auxiliary Objective)

在微调时,除了主要的监督目标 L2(C)L_2(C)L2(C),还加入语言建模目标 L1(C)L_1(C)L1(C) 作为辅助。

这样做有两个好处:

(a) 提升模型泛化能力(减少过拟合,提升在新数据上的表现)

(b) 加快训练收敛速度(更快达到较好性能)

% 联合优化目标

联合优化目标:
L3(C)=L2(C)+λ⋅L1(C) L_3(C) = L_2(C) + \lambda \cdot L_1(C) L3(C)=L2(C)+λ⋅L1(C)

其中,L2(C)L_2(C)L2(C) 是监督任务的目标,L1(C)L_1(C)L1(C) 是语言建模目标(比如预测下一个 token),λ\lambdaλ 是权重系数,用于平衡两者的影响。

2.3 不同任务的输入变化

通过把结构化输入转化为有序文本序列,并加上特殊标记,可以让预训练模型适用于更多任务,而无需针对每个任务设计新的模型结构。

举例来说:

  • 文本蕴含(Textual entailment)
    • 输入是前提(premise, p)和假设(hypothesis, h)。
    • 做法:将前提和假设的token序列拼接在一起,中间用一个分隔符($)隔开。
    • 这样模型可以一次性处理整个输入序列,判断假设是否能从前提推断出来。
  • 相似性任务(Similarity)
    • 输入是两个句子,没有固定顺序。
    • 做法:分别生成两种顺序的输入(句子A在前,句子B在后;句子B在前,句子A在后),中间用分隔符($)。
    • 每种顺序都独立处理,得到两个序列表示(hm和hl),然后将它们按元素相加,最后送入线性输出层进行预测。
  • 问答与常识推理(Question Answering and Commonsense Reasoning
    • 输入是文档(zzz)、问题(qqq)和一组可能的答案({ak}\{ak\}{ak})。
    • 做法:将文档和问题与每个可能答案分别拼接,中间用分隔符形成[z;q;;ak][z;q;; ak][z;q;;ak]。
    • 每个拼接后的序列都独立送入模型处理,最后用softmax归一化,得到对每个答案的概率分布。
相关推荐
Yeats_Liao1 天前
华为开源自研AI框架昇思MindSpore应用案例:跑通Vision Transformer图像分类
人工智能·华为·transformer
AndrewHZ2 天前
【图像处理基石】图像Inpainting入门详解
图像处理·人工智能·深度学习·opencv·transformer·图像修复·inpainting
迪三达2 天前
GPT-0: Attention+Transformer+可视化
gpt·深度学习·transformer
AI模块工坊2 天前
CVPR 即插即用 | PConv:重新定义高效卷积,一个让模型“跑”得更快、更省的新范式
人工智能·深度学习·计算机视觉·transformer
机器学习之心HML3 天前
TCN-Transformer-LSTM多特征分类预测Matlab实现
分类·lstm·transformer
缘友一世3 天前
LLama3架构原理浅浅学学
人工智能·自然语言处理·nlp·transformer·llama
Dev7z3 天前
基于Swin Transformer的肝脏肿瘤MRI图像分类与诊断系统
人工智能·深度学习·transformer
算法打盹中3 天前
深入解析 Transformer 模型:以 ChatGPT 为例从词嵌入到输出预测的大语言模型核心工作机制
人工智能·深度学习·语言模型·chatgpt·transformer·1024程序员节
weixin_贾3 天前
水文气象领域的时间序列分析:从Pytorch/R入门到Transformer/Mamba精通
pytorch·r语言·transformer·水文气象·时间序列