预训练模型 - HappyLLM

预训练模型 - HappyLLM
Mr.L预训练语言模型
Encoder-only PLM
Transformer 结构主要由 Encoder、Decoder 两个部分组成,两个部分分别有不一样的结构和输入输出。
针对 Encoder、Decoder 的特点,引入 ELMo 的预训练思路,开始出现不同的、对 Transformer 进行优化的思路。例如:
- Google 选择了 Encoder 层,通过将 Encoder 层进行堆叠,提出不同的预训练任务-掩码语言模型(Masked Language Model,MLM),打造了自然语言理解(Natural Language Understanding,NLU)任务的代表模型——BERT。
- OpenAI 则选择了 Decoder 层,使用原有的语言模型(Language Model,LM)任务,通过不断增加模型参数和预训练语料,打造了在自然语言生成(Natural Language Generation,NLG)任务上的 GPT 系列模型。
- Google 发布的 T5 模型同时保留 Encoder 与 Decoder,打造预训练的 Transformer 模型。
在本小节中,将以 Encoder-Only、Encoder-Decoder、Decoder-Only 的顺序依次介绍 Transformer 时代的各个主流预训练模型的核心架构、预训练任务及其独特优势。
BERT
BERT( Bidirectional Encoder Representations from Transformers),由 Google 团队在 2018 年发布论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》,在 GLUE、MultiNLI 等七个自然语言处理评测任务达到最优性能(State Of The Art,SOTA)。
自 BERT 推出以来,预训练+微调 的模式开始成为自然语言处理任务的主流,不仅 BERT 自身在不断更新迭代提升模型性能,也出现了如 MacBERT、BART 等基于 BERT 进行优化提升的模型。可以说,BERT 是自然语言处理的一个阶段性成果,标志着各种自然语言处理任务的重大进展以及预训练模型的统治地位建立。
一直到 LLM 的诞生,NLP 领域的主导地位才从 BERT 系模型进行迁移。即使在 LLM 时代,要深入理解 LLM 与 NLP,BERT 也是无法绕过的一环。
思想沿承
BERT 是一个统一多种思想的预训练模型, 其所沿承的核心思想包括:
- Transformer 架构: BERT 沿承了 Transformer 的思想,在 Transformer 的模型基座上进行优化,通过将 Encoder 结构进行堆叠,扩大模型参数,打造了在 NLU 任务上的专属模型架构;
- 预训练+微调范式:
- 同样在 2018年,ELMo 的诞生标志着预训练+微调范式的诞生。ELMo 模型基于双向 LSTM 架构,在训练数据上基于语言模型进行预训练,再针对下游任务进行微调,将 NLP 领域导向预训练+微调的研究思路。
- BERT 采用了该范式,将模型架构调整为 Transformer,引入更适合文本理解、能捕捉深层双向语义关系的预训练任务 MLM,将预训练-微调范式推向了高潮。
接下来,我们将从模型架构、预训练任务以及下游任务微调三个方面深入剖析 BERT,分析 BERT 的核心思路及优势。
模型架构—Encoder-Only
BERT 的输入一般是文本序列,而输出一般是 Label,例如情感分类的积极、消极 Label。
正如 Transformer 是一个 Seq2Seq 模型,使用 Encoder 堆叠而成的 BERT 本质上也是一个 Seq2Seq 模型,只是没有加入对特定任务的 Decoder,因此,为适配各种 NLU 任务,在模型的最顶层加入了一个分类头 prediction_heads,用于将多维度的隐藏状态通过线性层转换到分类维度(例如,如果一共有两个类别,prediction_heads 输出的就是两维向量)。
BERT 的模型架构采用 Transformer 的 Encoder 部分堆叠而成,其结构如图所示:

**模型组成:**模型整体既是由 Embedding、Encoder 、 prediction_heads 组成:
Tokenizer: 将输入的文本序列(text)转化成 input_ids ;
BERT 采用 WordPiece 作为分词方法。
WordPiece 是一种基于统计的子词切分算法,其核心在于将单词拆解为子词(例如,“playing” -> [“play”, “##ing”])。其合并操作的依据是最大化语言模型的似然度。
对于中文等非空格分隔的语言,通常将单个汉字作为原子分词单位(token)处理。
Embedding : 将输入 input_ids 转化为特定维度的 hidden_states;
Encoder: N 层 Encoder Layer 堆叠,将 Embedding 层映射的 hidden_states 喂入 attention 机制,然后通过残差连接和原输入相加,再经过一层 Intermediate 层得到最终输出。
Intermediate 层是 BERT 的特殊称呼,即一个线性层加上激活函数
模型参数: base 版本(12层 Encoder Layer,768 的隐藏层维度,总参数量 110M),large 版本(24层 Encoder Layer,1024 的隐藏层维度,总参数量 340M)。
位置编码: 相对位置编码(可训练的权重参数);
- **与Transformer的差异:**BERT 完成注意力分数的计算,通过 Position Embedding 层融入相对位置信息。
- **Position Embedding :**一层线性矩阵,通过可训练的参数来拟合更丰富的相对位置信息,但也增加了模型参数,无法处理超过模型训练长度的输入(例如,对 BERT 而言能处理的最大上下文长度是 512 个 token)
原始 BERT(即论文提出)使用和 Transformer 一致的绝对位置编码,后续改进(包括 BERT 的各种变体)使用了相对位置编码;
prediction_heads: 将 Encoder 的输出 hidden_states 转化为最后的类别概率,经过 Softmax 计算出模型预测的类别。
- **组成:**两个线性层加上激活函数,最后一个线性层的输出维度和任务的类别数相等;
激活函数: GELU 函数(高斯误差线性单元激活函数);
**核心思路:**将随机正则的思想引入激活函数,通过输入自身的概率分布,来决定抛弃还是保留自身的神经元。
随机正则:在训练时,主动给网络注入随机噪声 / 随机掩码 / 随机丢弃,强迫模型不要死记训练数据,而是学习更通用、更鲁棒的特征,防止过拟合。


预训练任务—— MLM + NSP
预训练-微调范式的核心优势在于将预训练和微调分离,完成一次预训练的模型仅通过微调就可以应用在几乎所有下游任务上,只要微调的成本较低,即使预训练成本是之前的数倍甚至数十倍,模型仍然有更大的应用价值。
因此,通过进一步扩大模型参数和预训练数据量,使用海量的预训练语料来让模型拟合潜在语义与底层知识,从而让模型通过长时间、大规模的预训练获得强大的语言理解和生成能力。
传统的 LM 预训练任务: 模拟“人类写作”,对于任意文本,只需要将下文遮蔽将上文输入模型要求其预测就可以实现 LM 训练,但有如下局限:
- 拟合从左到右的语义关系,但忽略了双向的语义关系;
- 虽然 Transformer 通过位置编码表征了文本序列中的位置信息,但这和直接拟合双向语义关系还是有本质区别
- 例如,BiLSTM(双向 LSTM 模型)在语义表征上就往往优于 LSTM 模型,就是因为 BiLSTM 通过双向的 LSTM 拟合了双向语义关系。
因此,有没有一种预训练任务,能够既利用海量无监督语料,又能够训练模型拟合双向语义关系的能力?
BERT 另一创新点在于提出的两个预训练任务上——MLM 和 NSP(Next Sentence Prediction,下一句预测)。
MLM——掩码语言模型(Token级)
MLM: 模拟“完形填空”, 在一个文本序列中随机遮蔽部分 token,然后将所有未被遮蔽的 token 输入模型,要求模型根据输入预测被遮蔽的 token。
- 局限性: 在下游任务微调和推理时,不存在
<MASK>,直接通过原文本得到对应的隐藏状态再根据下游任务进入分类器或其他组件。预训练和微调不一致,会影响模型在下游任务微调的性能; - **改进:**训练时,随机选择训练语料中 15% 的 token 用于遮蔽, 这 15% 被遮蔽的 token 中有 80% 的概率被 mask,10% 的概率被替换任意一个 token,还有 10% 的概率保持不变。
- 10% 保持不变是为了消除预训练和微调的不一致;
- 10% 的随机替换是使模型无法确定需要预测的 token,从而迫使模型保持对上下文信息的学习(由于随机 token 的概率很低,并不会影响模型实质的语言理解能力);
- 若全部mask,模型仅需处理被mask的位置,仅学习要预测的 token, 而丢失了对上下文的学习。
1 | 输入:I <MASK> you because you are <MASK> |
NSP——下一句预测(句子级)
NSP: 针对句级 NLU 任务,训练模型判断句对关系,从而迫使模型拟合句子之间的关系,例如问答匹配、自然语言推理等。
- 问答匹配:输入一个问题和若干个回答,找出问题的真正回答;
- 自然语言推理:输入一个前提和一个推理,判断推理是否是符合前提的。
1 | 输入: |
数据来源:
- 正样本:可以从无监督语料中随机抽取任意连续的句子;
- 负样本:可以对句子打乱后随机抽取(保证不要抽取到原本连续的句子);
在具体预训练时,BERT 使用了 800M 的 BooksCorpus 语料和 2500M 的英文维基百科语料,90% 的数据使用 128 的上下文长度训练,剩余 10% 的数据使用 512 作为上下文长度进行预训练,总共约训练了 3.3B token。
BERT 的训练语料共有 13GB 大小,其在 256 的 batch size 上训练了 1M 步(40 个 Epoch)。相较而言,LLM 一般都只会训练一个 Epoch,且使用远大于 256 的 batch size。相比于传统的非预训练模型,其训练的数据量指数级增长。
当然,海量训练数据需要更大成本的算力,BERT 的 Base 版本和 Large 版本分别使用了 16块 TPU 和 64块 TPU 训练了 4天才完成。
下游任务微调
**Bert正式确立了预训练-微调的两阶段思想:**在海量无监督语料上预训练获得通用的文本理解与生成能力,再在对应的下游任务上进行微调。
那么预训练得到的强大能力能否通过低成本的微调快速迁移到对应的下游任务上呢?
针对这一点,BERT 设计更通用的输入和输出层适配多任务下的迁移学习。对每一个输入的文本序列,BERT 在首部加入一个特殊 token <CLS>。在后续编码中,该 token 代表的是整句的状态,也就是句级的语义表征。在进行 NSP 预训练时,就使用了该 token 对应的特征向量来作为最后分类器的输入。
在完成预训练后,针对下游任务,只需要使用一定量的全监督数据微调即可。所谓微调,其实和训练时更新模型参数的策略一致,只不过在特定的任务、更少的训练数据、更小的 batch_size 上进行训练。
对于绝大部分下游任务,都可以直接使用 BERT 的输出:
- 文本分类任务:修改模型结构中的 prediction_heads 最后的分类头即可;
- 序列标注任务:可以集成 BERT 多层的隐藏层向量再输出最后的标注结果;
- 文本生成任务:可以取 Encoder 的输出直接解码得到最终生成结果;
BERT 一经提出,直接在 NLP 11个赛道上取得 SOTA 效果,成为 NLU 方向上当之无愧的霸主,后续若干在 NLU 任务上取得更好效果的模型都是在 BERT 基础上改进得到的。直至 LLM 时代,BERT 也仍然能在很多标注数据丰富的 NLU 任务上达到最优效果,事实上,对于某些特定、训练数据丰富且强调高吞吐的任务,BERT 比 LLM 更具有可用性。
RoBERTa
传统的深度学习范式中,每一个任务,我们需要从零训练一个模型,那么就无法使用太大的模型参数,否则需要极大规模的有监督数据才能让模型较好地拟合,成本太大。
预训练-微调的一个核心优势在于可以使用远大于之前训练数据的海量无监督语料进行预训练,只需要一次预训练好的模型,后续在每一个下游任务上通过少量有监督数据微调即可。
BERT 使用了 13GB(3.3B token)的数据进行预训练。但是,13GB 的预训练数据是否让 BERT 达到充分拟合呢?如果使用更多预训练语料,是否可以进一步增强模型性能?BERT 所选用的预训练任务、训练超参数是否是最优的?由 Facebook 发布的 RoBERTa 应运而生。
优化一:去掉 NSP 预训练任务
RoBERTa 的模型架构与 BERT 完全一致,使用了 BERT-large(24层 Encoder Layer,1024 的隐藏层维度,总参数量 340M)的模型参数。
在预训练任务上,有学者质疑 NSP 任务并不能提高模型性能,因为其太过简单,加入到预训练中并不能使下游任务微调时明显受益,甚至会带来负面效果。RoBERTa 设置了四个实验组:
四个实验组:
1 | 1. 段落构建的 MLM + NSP:BERT 原始预训练任务,输入是一对片段,每个片段包括多个句子,来构造 NSP 任务; |
实验结果证明,后两组显著优于前两组,且单文档的 MLM 组在下游任务上微调时性能最佳。因此,RoBERTa 在预训练中去掉了 NSP,只使用 MLM 任务。
同时,RoBERTa 对 MLM 任务本身也做出了改进。
- BERT :Mask 的操作是在数据处理的阶段完成的,后期预训练时同一个样本待预测的
<MASK>总是一致的。BERT 共训练了 40 个 Epoch,为使模型的训练数据更加广泛,BERT 将随机 Mask 四次,也就是每 10个 Epoch 模型训练的数据是完全一致的。 - RoBERTa: 将 Mask 操作放到了训练阶段,也就是动态遮蔽策略,每一个 Epoch 的训练数据 Mask 的位置都不一致。
实验结果:动态遮蔽仅有很微弱的优势优于静态遮蔽,但由于动态遮蔽更高效、易于实现,后续 MLM 任务基本都使用了动态遮蔽。
优化二:更大规模的预训练数据和预训练步长
RoBERTa 使用更大量的无监督语料进行预训练,共计 160GB 的数据,十倍于 BERT;
RoBERTa 认为更大的 batch size 既可以提高优化速度,也可以提高任务性能。因此,实验在 8K 的 batch size(对比 BERT 的 batch size 为 256)下训练 31K Step,即总训练 token 数和 BERT 一样是 3.3B 时,模型性能更好,从而证明了大 batch size 的意义。一共训练了 500K Step(约合 66个 Epoch)。
RoBERTa 不再采用 BERT 在 256 长度上进行大部分训练再在 512 长度上完成训练的策略,而是全部在 512 长度上进行训练。
优化三:更大的 BPE 词表
与 BERT 使用的 WordPiece 算法不同,RoBERTa 使用了 BPE 作为 Tokenizer 的编码策略。
BPE,即 Byte Pair Encoding,字节对编码,以子词对作为分词的单位,例如:
- 对“Hello World”这句话,可能会切分为“Hel,lo,Wor,ld”四个子词对;
- 对于以字为基本单位的中文,一般会按照字节编码进行切分;在 UTF-8 编码中,“我”会被编码为“E68891”,那么在 BPE 中可能就会切分成“E68”,“891”两个字词对。
一般来说,BPE 编码的词典越大,编码效果越好,但越大的词表也会带来模型参数的增加,因为 Embedding 层将 token 从词典空间映射到隐藏空间(也就是说 Embedding 的形状为 (vocab_size, hidden_size),。
BERT 原始的 BPE 词表大小为 30K,RoBERTa 选择了 50K 大小的词表来优化模型的编码能力。
ALBERT
在 BERT 基础上,RoBERTa 探究了更大规模预训练的作用, ALBERT 则从减小模型参数是否能够保持模型能力的角度展开探究。
ALBERT 通过对模型结构进行优化并对 NSP 预训练任务改进,成功以更小规模的参数实现了超越 BERT 的能力。
虽然 ALBERT 提出的一些改进思想并没有在后续研究中被广泛采用,但其降低模型参数的方法及提出的新预训练任务 SOP 对 NLP 领域提供了重要参考意义。
优化一:将 Embedding 参数进行分解
BERT 等预训练模型具有远超传统神经网络的参数量,BERT-large 具有 24层 Encoder Layer,1024 的隐藏层维度,参数量达 340M, Embedding 层的参数矩阵维度为 ,此处的 为词表大小 30K, 即为隐藏层大小 1024,参数达 30M。
于是,当 Google 探索更宽(即隐藏层维度更大)的模型时发现,隐藏层维度的增加会带来 Embedding 层参数的巨大上升,如果把隐藏层维度增加到 2048,Embedding 层参数就会膨胀到 61M,极大增加了模型的计算开销。
而从另一个角度看,Embedding 层输出的向量是对文本 token 的稠密向量表示,从 Word2Vec 的成功经验来看,这种词向量不需要很大维度,Word2Vec 仅用 100维大小就取得了不错的效果,Embedding 层的输出也许不需要和隐藏层大小一致。
因此,ALBERT 对 Embedding 层的参数矩阵分解,让 Embedding 层的输出维度和隐藏层维度解绑,即在 Embedding 层后面加入一个线性矩阵进行维度变换。ALBERT 设置 Embedding 层的输出维度为 128,并加入一个 128 × 1024 的线性矩阵将 Embedding 层的输出升维到隐藏层大小。参数从 降低到了,当 的大小远小于 时,该方法对 Embedding 层参数的优化会很明显。
优化二:跨层进行参数共享
通过对 BERT 的参数分析,ALBERT 发现各个 Encoder 层的参数出现高度一致的情况。由于 24个 Encoder 层带来巨大的模型参数,
因此,ALBERT 提出让各个 Encoder 层共享模型参数,来减少模型的参数量。
在具体实现上,ALBERT 仅初始化一个 Encoder 层,在计算过程中,仍会进行 24次计算,但是每一次计算都经过这个 Encoder 层。因此,虽然是 24个 Encoder 计算的模型,但只有一层 Encoder 参数,从而大大降低了模型参数量。在这样的情况下,就可以极大程度地扩大隐藏层维度,实现一个更宽但参数量更小的模型。
实验证明 ,相较于 334M 的 BERT,同样是 24 层 Encoder 但将隐藏层维度设为 2048 的 ALBERT(xlarge 版本)仅有 59M 的参数量,效果上更优于 BERT。
局限: 虽然 ALBERT 的参数量远小于 BERT,但训练效率只略优于 BERT,因为各层虽共享权重,但计算时仍然要通过 24次 Encoder Layer 的计算,也就是说训练和推理时的速度相较 BERT 还会更慢。这也是 ALBERT 最终没能取代 BERT 的一个重要原因。
优化三:提出 SOP 预训练任务
类似于 RoBERTa,ALBERT 也认为 NSP 任务简单,在预训练中无法对模型效果带来显著影响。不同于 RoBERTa 去掉 NSP,ALBERT 选择改进 NSP,增加其难度,来优化模型的预训练。
传统的 NSP 任务中,正例是由两个连续句子组成的句对,而负例则是从任意两篇文档中抽取出的句对,模型可以较容易地判断正负例,并不能很好地学习深度语义。
SOP 任务: 正例同样由两个连续句子组成,负例是将这两个顺序反过来。模型不仅要拟合两个句子之间的关系,更要学习顺序关系。
1 | 输入: |
实验证明,SOP 预训练任务对模型效果显著提升,使用 MLM + SOP 预训练的模型效果优于仅使用 MLM 预训练的模型更优于使用 MLM + NSP 预训练的模型。
通过上述三点优化,ALBERT 以更小的参数实现更强的性能,虽然由于其架构带来的训练、推理效率降低限制了模型进一步发展,但打造更宽的模型这一思路仍为众多强大模型提供了参考价值。
Encoder-Decoder PLM
BERT 是一个基于 Transformer 的 Encoder-Only 模型,通过预训练任务 MLM 和 NSP 来学习文本的双向语义关系。但是,BERT 也存在一些问题,例如 MLM 任务和下游任务微调的不一致性,以及无法处理超过模型训练长度的输入等问题。
为了解决这些问题,研究者们提出了 Encoder-Decoder 模型,通过引入 Decoder 部分来解决这些问题,同时也为 NLP 领域带来了新的思路和方法。
在本节中,主要介绍 T5 的模型架构和预训练任务,以及 T5 模型首次提出的 NLP 大一统思想;
T5
T5(Text-To-Text Transfer Transformer): 由 Google 提出的一种基于 Transformer 架构的预训练语言模型;
大一统思想: T5 将不同的 NLP 任务如文本分类、问答、翻译等统一表示为输入文本到输出文本的转换,简化了模型设计、参数共享和训练过程,提高了模型的泛化能力和效率。
模型结构:Encoder-Decoder
T5 采用基于 Transformer 架构设计 Encoder-Decoder 结构。编码器用以处理输入文本,解码器用以生成输出文本。编码器和解码器之间通过注意力机制进行信息交互,从而实现输入文本到输出文本的转换,其结构如图所示:

模型组成: 从整体来看T5 的模型结构包括 Tokenizer 部分和 Transformer 部分。
Tokenizer : 将输入文本转换为模型可接受的输入格式,包括分词、编码等操作;
Transformer: 分为 EncoderLayers 和 DecoderLayers 两部分,由一个个小的 Block组成,每个 Block 包含了多头注意力机制、前馈神经网络和 Norm 层。
Self-Attention 用于捕捉输入序列中的全局依赖关系;
前馈神经网络用于处理特征的非线性变换;
LayerNorm 采用 RMSNorm,通过计算每个神经元的均方根(Root Mean Square)来归一化每个隐藏层的激活值。RMSNorm 的参数设置与Layer Norma 相比更简单,只有一个可学习参数。
其中, 是输入向量的第 个元素, 是可学习的缩放参数, 是输入向量的维度数量, 是一个小常数,用于数值稳定性(以避免除以零的情况)
预训练任务
T5 的预训练任务,主要包括以下几个部分:
预训练任务: T5模型的预训练任务是 MLM,也称为BERT-style目标。具体来说,就是在输入文本中随机遮蔽15%的token,然后让模型预测这些被遮蔽的token。这个过程不需要标签,在大量未标注的文本上进行。
输入格式: 预训练时,T5将输入文本转换为"文本到文本"的格式。对于一个给定的文本序列,随机选择一些token进行遮蔽,并用特殊的占位符(token)替换。然后将被遮蔽的token序列作为模型的输出目标。
预训练数据集: T5 使用一个大规模的文本数据集,包含各种各样的文本数据,如维基百科、新闻、书籍等,最终得到用于训练的750GB 的数据集 “Colossal Clean Crawled Corpus” (C4),且已在 TensorflowData 中开源。该数据集从Common Crawl中提取了大量干净的英语文本。C4数据集经过了一定的清洗,去除了无意义的文本、重复文本等。
多任务预训练: 不仅仅是MLM任务,T5 还尝试了将多个任务混合在一起进行预训练。这有助于模型学习更通用的语言表示。
预训练到微调的转换: 预训练完成后,T5模型在下游任务上微调。微调时,模型在任务特定的数据集上进行训练,根据任务调整解码策略。
通过大规模预训练,T5 模型能够学习到丰富的语言知识,获得强大的语言表示能力,在多个NLP任务上取得了优异的性能,预训练是T5成功的关键因素之一。
大一统思想
T5模型的一个核心理念是大一统思想 ,即所有的 NLP 任务都可以统一为文本到文本的任务。其设计理念是将所有不同类型的 NLP 任务转换为一个统一的格式:输入和输出都是纯文本,简化任务处理流程,增强模型的通用性和适应性。
对于不同的任务,每次输入前加上一个任务描述前缀,明确指定当前任务类型,帮助模型在预训练阶段学习到不同任务之间的通用特征,也便于在微调阶段迅速适应具体任务:
对于文本分类任务,输入可以是“classify: 这是一个很好的产品”,输出是“正面”;
对于翻译任务,输入可以是“translate English to French: How are you?”, 输出是“Comment ça va?”
“summarize: ”用于摘要任务;
“translate English to German: ”用于翻译任务。

T5通过在大规模的文本数据预训练,然后在具体任务上进行微调。这一过程与BERT、GPT等类似,但T5将预训练和微调阶段的任务统一为文本到文本的形式,使其在各种任务上的适应性更强。
Decoder-only
除了在前两节提到的由 Transformer 发展而来的两种模型架构——以 BERT 为代表的 Encoder-Only 模型和以 T5 为代表的 Encoder-Decoder 模型外,还有一种模型架构——Decoder-Only,即只使用 Decoder 堆叠而成的模型。
事实上,Decoder-Only 就是目前大火的 LLM 的基础架构,目前所有的 LLM 基本都是 Decoder-Only 模型(RWKV、Mamba 等非 Transformer 架构除外)。引发 LLM 热潮的 ChatGPT,正是 Decoder-Only 系列的代表模型 GPT 系列模型的大成之作。而目前作为开源 LLM 基本架构的 LLaMA 模型,也正是在 GPT 的模型架构基础上优化发展而来。
因此,在本节中会详细分析 Decoder-Only 代表模型 GPT 的原理、架构和特点,深入到目前的主流开源 LLM,分析它们的结构、特点,以及 LLM 是如何一步步从传统 PLM 中发展而来的。
ChatGPT
GPT,即 Generative Pre-Training Language Model,是由 OpenAI 团队于 2018年发布的预训练语言模型。虽然学界普遍认可 BERT 作为预训练语言模型时代的代表,但首先明确提出预训练-微调思想的模型其实是 GPT。
GPT 提出通用预训练的概念,即在海量无监督语料上预训练,进而在每个特定任务上进行微调,从而实现这些任务的巨大收益。
虽然在发布之初,其性能略输于不久后发布的 BERT,没能取得轰动性成果,也没能让 GPT 所使用的 Decoder-Only 架构成为学界研究的主流,但 OpenAI 团队坚定地选择了不断扩大预训练数据、增加模型参数,在 GPT 架构上不断优化,最终在 2020年发布的 GPT-3 成就了 LLM 时代的基础,并以 GPT-3 为基座模型的 ChatGPT 成功打开新时代的大门,成为 LLM 时代的最强竞争者也是目前的最大赢家。
模型架构——Decoder-only
由于 Decoder-Only 结构天生适用于文本生成任务,所以相较于更贴合 NLU 任务设计的 BERT,GPT 和 T5 的模型设计更契合于 NLG 任务和 Seq2Seq 任务,其模型架构如图所示:

**模型组成:**GPT 的整体结构和 BERT 类似,只是相较于 BERT 的 Encoder,选择使用 Decoder 进行模型结构的堆叠。
Tokenizer: 将文本的输入进行分词并转化为对应词典序号的 input_ids。
Embedding: 输入的 input_ids 通过 Embedding 层,再经过 Positional Embedding 进行位置编码。
- 不同于 BERT 选择可训练的全连接层作为位置编码,GPT 沿用 Transformer 的经典 Sinusoidal 位置编码
Decoder: N 层 Decoder Layer 堆叠,将 Embedding 层映射的 hidden_states 进行 LayerNorm,再进行掩码注意力计算 ,随后经过残差连接和 LayerNorm 进入到 MLP 中并得到最后输出
- 相较于 Transformer 原始 Decoder 层的双注意力层设计, GPT 的 Decoder 更像 Encoder 层;
- Decoder 层仅保留了一个带掩码的注意力层,通过掩码矩阵遮蔽未来 token 的注意力权重,从而限制每一个 token 只能关注到它之前 token 的注意力,来实现掩码自注意力的计算;
- GPT 的 MLP 层没有选择线性矩阵来进行特征提取,而是选择两个一维卷积核提取,不过,从效果上这两者没有太大区别。
通过 N 个 Decoder 层后的 hidden_states 经过线性矩阵映射到词表维度,转化成自然语言的 token,从而生成目标序列。
预训练任务——CLM
因果语言模型(Causal Language Model,CLM): 基于一个自然语言序列的前面所有 token 来预测下一个 token,不断重复该过程来实现目标文本序列的生成,是一个经典的补全形式。
- CLM 可以看作 N-gram 语言模型的扩展。N-gram 语言模型基于前 N 个 token 来预测下一个 token。
对于一个输入目标序列长度为 256,期待输出序列长度为 256 的任务,模型会不断根据前 256 个 token、257个 token(输入+预测出来的第一个 token)… 进行 256 次计算,最后生成一个序列长度为 512 的输出文本。例如,CLM 的输入和输出可以是:
1 | input: 今天天气 |
优势: CLM 是更直接的预训练任务,和人类书写自然语言文本的习惯契合,也和下游任务直接匹配,相对于 MLM 更加直接,可以在任何自然语言文本上直接应用。因此,CLM 也可以使用海量的自然语言语料进行大规模的预训练;
GPT 系列模型的发展
自 GPT-1 推出开始,OpenAI 一直坚信 Decoder-Only 的模型结构和 “体量即正义” 的优化思路,不断扩大预训练数据集、模型体量,并对模型做出一些小的优化和修正,不断探索更强大的预训练模型。
从被 BERT 压制的 GPT-1,到没有引起足够关注的 GPT-2,再到激发了涌现能力、带来大模型时代的 GPT-3,最后带来了跨时代的 ChatGPT,OpenAI 通过数十年的努力证明了其思路的正确性。
下表总结了从GPT-1 到 GPT-3 的模型架构、预训练预料的变化:
| 模型 | Decoder Layer | Hidden_size | 注意力头数 | 注意力维度 | 总参数量 | 预训练语料 |
|---|---|---|---|---|---|---|
| GPT-1 | 12 | 3072 | 12 | 768 | 0.12B | 5GB |
| GPT-2 | 48 | 6400 | 25 | 1600 | 1.5B | 40GB |
| GPT-3 | 96 | 49152 | 96 | 12288 | 175B | 570GB |
GPT-1 是 GPT 系列的开山之作,也是第一个使用 Decoder-Only 的预训练模型。但是,GPT-1 的模型体量和预训练数据都比较少,沿承了传统 Transformer 的模型结构,使用 12层 Decoder Block 和 768 的隐藏层维度,模型参数量仅有 1.17亿(0.12B),在大小为 5GB 的 BooksCorpus 数据集上预训练得到。
- GPT-1 的参数规模与预训练预料规模和 BERT-base 大致相当,但表现却不如 BERT-base ,这是 GPT 系列模型没能成为预训练语言模型时代的代表的原因。
GPT-2 是 OpenAI 在 GPT-1 的基础上进一步探究预训练语言模型多任务学习能力的产物。GPT-2 的模型结构和 GPT-1 大致相当,只是扩大了模型参数规模、将 Post-Norm 改为了 Pre-Norm(即先进行 LayerNorm 计算,再进入注意力层计算)。这些改动的核心原因在于,模型层数增加、体量增大,梯度消失和爆炸的风险也不断增加,为使模型梯度更稳定对结构进行优化。主要突破如下:
- 大幅增加预训练数据集和模型体量。 GPT-2 的 Decoder Block 层数达到 48(共发布四种规格的模型,此处指规格最大的 GPT-2 模型),隐藏层维度达到 1600,模型整体参数量达 15亿(1.5B),40GB 大小的 WebText 数据集进行预训练,不管是模型结构还是预训练大小都超过了 GPT-1 一个数量级。
- 以 zero-shot(零样本学习)为主要目标。 不需要收集几百上千的训练样本对模型进行微调,直接向预训练模型描述问题去解决任务。
但是在 GPT-2 的时代,模型能力还不足够支撑较好的 zero-shot 效果,在大模型时代,zero-shot 及其延伸出的 few-shot(少样本学习)才开始逐渐成为主流。
GPT-3 则进一步展示了 OpenAI “力大砖飞” 的核心思路,也是 LLM 的开山之作。在 GPT-2 的基础上,OpenAI 进一步增大了模型体量和预训练数据量,整体参数量达 175B,是当之无愧的 “大型语言模型” 。
- 在模型结构上,基本没有大改进,只是由于模型巨大体量使用 稀疏注意力机制 来取代传统注意力机制;
- 在预训练数据上,分别从 CC、WebText、维基百科等大型语料集中采样,共采样 45T、清洗后 570GB 的数据。根据推算,GPT-3 需要在 1024张 A100(80GB 显存)的分布式训练集群上训练 1个月。
- 除巨大体量带来涌现能力外,GPT-3 提出了 few-shot (也称为上下文学习,In-context Learning)。few-shot 是在 zero-shot 上的改进,研究者发现即使是 175B 大小的 GPT-3,想要在 zero-shot 上取得较好表现仍是一件较为困难的事情。而 few-shot 是对 zero-shot 的一个折中,旨在让模型从少样的示例学习问题的解决方法。few-shot 一般会在 prompt(即模型的输入)中增加 3~5 个示例,来帮助模型理解。例如,对于情感分类任务:
1 | zero-shot:请你判断‘这真是一个绝佳的机会’的情感是正向还是负向,如果是正向,输出1;否则输出0 |
GPT-3 在 few-shot 上展现的强大能力,为 NLP 的突破带来了重要进展。如果对于绝大部分任务都可以通过人为构造 3~5个示例就能让模型解决,其效率将远高于传统的预训练-微调范式,意味着 NLP 的进一步落地应用成为可能——而这,也正是 LLM 的核心优势。
在 GPT 系列模型的基础上,通过引入预训练-指令微调-人类反馈强化学习的三阶段训练,OpenAI 发布了跨时代的 ChatGPT,引发了大模型的热潮。
LLaMA
LLaMA 模型是由 Meta(前Facebook)开发的一系列大型预训练语言模型。从 LLaMA-1 到 LLaMA-3,LLaMA系列模型展示了大规模预训练语言模型的演进及其在实际应用中的显著潜力。
模型架构——Decoder Only
LLaMA模型的架构如图所示:

模型组成: LLaMA 模型的整体结构与GPT系列模型类似,只是在模型规模和预训练数据集上有所不同。
- Tokenizer: 将输入文本通过tokenizer进行编码,转化为一系列的input_ids 。
- **Embedding: ** 将 input_ids 输入 Embedding 层获得高维词向量,同时也会通过 Positional Embedding 层编码,形成 hidden_states;
- Decoder: 多个 decoder block 组成。每个 decoder block 负责对 hidden_states 进行深入分析和转换;
- 首先是一个 masked self-attention 层,分别计算query、key和 value 三个向量(由hidden_states 线性变换得到);
- 随后使用 softmax 函数计算 attention score,反映不同位置之间的关联强度;
- 然后,value 向量与 attention score 相乘,得到加权后的 value,即 attention 的结果。
- 在 masked self-attention 层之后,hidden_states 进入 MLP 层,通过两个全连接层进一步特征提取。
- 第一个全连接层将 hidden_states 映射到一个中间维度,然后通过激活函数进行非线性变换,增加模型的非线性能力;
- 第二个全连接层则将特征再次映射回原始的hidden_states维度;
经过多个 decoder block 处理,hidden_states 通过一个线性层映射,生成目标序列的概率分布(输出维度与词表维度相同),最后通过采样或贪婪解码等方法,生成最终的输出序列。
LLaMA系列发展
LLaMA-1 系列:
- Meta于2023年2月发布了 LLaMA-1,包括7B、13B、30B和65B四个参数量版本。
- 模型在超过 1T token 的语料上预训练,其中最大的 65B 参数模型在2,048张A100 80G GPU上训练了近21天。
- LLaMA-1 因其开源性和优异性能迅速成为开源社区中最受欢迎的大模型之一。
LLaMA-2 系列:
- 2023年7月,Meta发布了LLaMA-2,包含7B、13B、34B和70B四个参数量版本,除了34B模型外,其他均已开源。
- LLaMA-2 将预训练的语料扩充到了 2T token,并将模型的上下文长度从 2,048 翻倍到 4,096。
- 引入了分组查询注意力机制(Grouped-Query Attention, GQA)等技术。
LLaMA-3 系列:
- 2024年4月,Meta发布了LLaMA-3,包括8B和70B两个参数量版本,同时透露400B的LLaMA-3还在训练中。
- LLaMA-3支持 8K 长文本,并采用了编码效率更高的tokenizer,词表大小为128K。
- 使用了超过 15T token 的预训练语料,是 LLaMA-2 的7倍多。
LLaMA 模型以其技术创新、多参数版本、大规模预训练和高效架构设计著称。模型支持从7亿到数百亿不等的参数量,适应不同规模的应用需求。
LLaMA-1 以其开源性和优异性能迅速受到社区欢迎,而 LLaMA-2 和 LLaMA-3 进一步引入分组查询注意力机制和支持更长文本输入,显著提升了模型性能和应用范围。特别是LLaMA-3,通过采用128K词表大小的高效tokenizer和15T token的庞大训练数据,实现了在多语言和多任务处理上的重大进步。
Meta对模型安全性和社区支持的持续关注,预示着LLaMA将继续作为AI技术发展的重要推动力,促进全球范围内的技术应用和创新。
GLM
GLM 系列模型是由智谱开发的主流中文 LLM 之一,包括 ChatGLM1、2、3及 GLM-4 系列模型, 其中 ChatGLM-6B 是 GLM 系列开山之作,也是 2023 年国内最早的开源中文 LLM,也是最早提出不同于 GPT、LLaMA 的独特模型架构的 LLM。
模型架构 - 相对于 GPT 的略微修正
GLM 是由清华计算机系推出的一种通用语言模型基座,其核心思路是在传统 CLM 预训练任务基础上,加入 MLM 思想,构建一个在 NLG 和 NLU 任务上都具有良好表现的统一模型。
在整体模型结构上,GLM 和 GPT 大致类似,均是 Decoder-Only 的结构,仅有三点细微差异:
使用 Post Norm 而非 Pre Norm。Post Norm 是指在进行残差连接计算时,先完成残差计算,再进行 LayerNorm 计算;而GPT、LLaMA 等模型都使用了 Pre Norm,先进行 LayerNorm 计算,再进行残差的计算。
- Post Norm 由于在残差之后做归一化,对参数正则化的效果更强,模型的鲁棒性也会更好;
- Pre Norm 则因为有一部分参数直接加在后面,不需要对这部分参数进行正则化,可以防止模型的梯度爆炸或者梯度消失。
- 因此,对于大体量模型来说,一般认为 Pre Norm 效果会更好。但 GLM 论文提出,使用 Post Norm 可以避免 LLM 的数值错误(虽然主流 LLM 仍然使用了 Pre Norm);
使用单个线性层实现最终 token 的预测,而不是使用 MLP;
- 这样的结构更加简单也更加鲁棒,减少了最终输出的参数量,将更大的参数量放在模型本身;
激活函数从 ReLU 换成了 GeLUs。
ReLU 是传统的激活函数,其核心计算逻辑为去除小于 0 的传播,保留大于 0 的传播;
GeLUs 是对接近于 0的正向传播,做一个非线性映射,保证了激活函数后的非线性输出,具有一定的连续性。
预训练任务——GLM
GLM(General Language Model,通用语言模型): 结合自编码思想和自回归思想的预训练方法。
- 自编码思想:其实就是 MLM 的任务学习思路,在输入文本中随机 mask 连续的 tokens,要求模型学习被 mask 的 tokens;
- 自回归思想:传统的 CLM 任务学习思路,要求模型按顺序重建连续 tokens。
GLM 通过优化一个自回归空白填充任务来实现 MLM 与 CLM 思想的结合。其核心思想是,对于一个输入序列,会类似于 MLM 一样进行随机的掩码,但遮蔽的不是和 MLM 一样的单个 token,而是每次遮蔽一连串 token (Span mask);模型在学习时,既需要使用未遮蔽部分的上下文预测遮蔽部分,在遮蔽部分内部又以 CLM 的方式完成被遮蔽的 tokens 的预测。例如,输入输出可能是:
1 | 输入:I <MASK> because you <MASK> |
通过将 MLM 与 CLM 思想结合,既适配逐个 token 生成的生成类任务,也迫使模型从前后两个方向学习输入文本的隐含关系,从而适配了理解类任务。
不过,GLM 预训练任务更多优势还是展现在预训练模型时代,迈入 LLM 时代后,针对于超大规模体量的预训练,CLM 展现出远超 MLM 的优势。通过将模型体量加大、预训练规模扩大,CLM 预训练得到的生成模型在文本理解上也能具有超出 MLM 训练的理解模型的能力.
因此,ChatGLM 系列模型也仅在第一代模型使用了 GLM 的预训练思想,从 ChatGLM2 开始,回归了传统的 CLM 建模。
虽然从 LLM 的整体发展路径来看,GLM 预训练任务似乎是一个失败的尝试,但通过精巧的设计将 CLM 与 MLM 融合,并第一时间产出了中文开源的原生 LLM,其思路仍然存在较大的借鉴意义。
3. GLM 系列的发展
在 GLM 模型(即使用原生 GLM 架构及预训练任务的早期预训练模型)的基础上,参考 ChatGPT 的技术思路进行 SFT 和 RLHF,智谱于 2023 年 3 月发布了第一个中文开源 LLM ChatGLM-6B,成为了众多中文 LLM 研究者的起点。ChatGLM-6B 在 1T 语料上进行预训练,支持 2K 的上下文长度。
在 23 年 6 月,智谱开源了 ChatGLM2-6B。相对于一代,ChatGLM2 将上下文长度扩展到了 32K,通过更大的预训练规模实现了模型性能的大幅度突破。不过,在 ChatGLM2 中,模型架构就基本回归了 LLaMA 架构,引入 MQA 的注意力机制,预训练任务也回归经典的 CLM,放弃了 GLM 的失败尝试。
ChatGLM3-6B 发布于 23年 10月,相对于二代在语义、数学、推理、代码和知识方面都达到了当时的 SOTA ,但官方给出的技术报告说明 ChatGLM3 在模型架构上相对二代没有变化,最主要的优化来源是更多样化的训练数据集、更充足的训练步骤和更优化的训练策略。ChatGLM3 的另一个重要改进在于其开始支持函数调用与代码解释器,开发者可以直接使用开源的 ChatGLM3 来实现 Agent 开发,具有更广泛的应用价值。
2024年 1月,智谱发布了支持 128K 上下文,包括多种类型的 GLM-4 系列模型,评估其在英文基准上达到了 GPT-4 的水平。不过,智谱并未直接开源 GLM-4,而是开源了其轻量级版本 GLM-4-9B 模型,其在 1T token 的多语言语料库上进行预训练,上下文长度为 8K,并使用与 GLM-4 相同的管道和数据进行后训练。在训练计算量较少的情况下,其超越了 Llama-3-8B,并支持 GLM-4 中所有工具的功能。





