大语言模型

Stanford Alpaca  Self-Instruct收集数据
Vicuna ShareGPT 收集用户日常对话数据

Alpaca 模型介绍

Alpaca是斯坦福在LLaMa-7B的基础上监督微调出来的模型,斯坦福是用OpenAI的Text-davinci-003 API配合self-instruct技术,使用175个提示语种子自动生成了52K条提示-回复的指示数据集,在LLaMa-7B上微调得到的模型,在8张80G的A100上训练了3小时。

Vicuna是在LLaMa-13B的基础上使用监督数据微调得到的模型,数据集来自于ShareGPT.com 产生的用户对话数据,共70K条。使用Pytorch FSDP在8张A100上训练了一天。相较于Alpaca,Vicuna在训练中将序列长度由512扩展到了2048,并且通过梯度检测和flash attention来解决内存问题;调整训练损失考虑多轮对话,并仅根据模型的输出进行微调。通过GPT4来打分评测,Vicuna可以达到ChatGPT 90%的效果。并且还提供了可调用的分布式聊天服务FastChat。

扩展原始词汇表  中文预训练 微调

垂直领域 对话数据集


AlpacaLoRA

commmon crawl

c4

wudaocoropra

starcoder

Accelerate  

Accelerate. 该代码库是一个旨在简化模型分布式训练和混合精度训练的
Python 库,专门针对 PyTorch 开发。 Accelerate 库全面支持分布式训练,实现了
混合精度训练,并完善了并行训练时多设备的自动管理。该库降低了用户进行分
布式训练的难度,仅通过少量代码,用户便能在各种分布式配置中执行 PyTorch 程
序,从而便捷地使用大规模计算资源,有效加快模型训练的进度。此外, Accelerate
还提供了一个可配置的命令行界面工具,进一步简化了训练环境的配置与测试流
程。

对预训练数据进行去重处理是一个重要步骤。由于大语言模型具有较强的数
据拟合与记忆能力,很容易习得训练数据中的重复模式,可能导致对于这些模式
的过度学习。

数据量的扩
展性本质上来源于 Transformer 模型的可扩展性,这也是大语言模型能够取得成功
最为关键的基础要素。

将语料中 0.1% 的数据重复 100 次后,基于这些
包含重复数据语料训练的 800M 参数模型,其性能仅能达到在无重复语料上训练
的 400M 参数模型的相同表现。

一旦数据中包含有偏、有毒、隐私的内容,
将会对于模型造成严重的不良影响。在有偏内容上训练可能会导致语言模型学习
并复制这些偏见,进而在其生成的文本中表现出对诸如种族、性别和年龄的偏好
或歧视。

因此,一些语言模型开始
采用字符作为最小单位来分词。

PE 算法从一
组基本符号(例如字母和边界字符)开始,迭代地寻找语料库中的两个相邻词元,
并将它们替换为新的词元,这一过程被称为合并。合并的选择标准是计算两个连
续词元的共现频率,也就是每次迭代中,最频繁出现的一对词元会被选择与合并。
合并过程将一直持续达到预定义的词表大小。


WordPiece 是谷歌内部非公开的分词算法,最初是由谷歌研究人员在开发语音
搜索系统时提出的。
WordPiece 分词和 BPE 分词的想法非常相似,都
是通过迭代合并连续的词元,但是合并的选择标准略有不同。在合并前, WordPiece
分词算法会首先训练一个语言模型,并用这个语言模型对所有可能的词元对进行
评分。然后,在每次合并时,它都会选择使得训练数据的似然性增加最多的词元


为了训练出高效的分词器,我们应重点关注以下几个因素。首先,分词器必
须具备无损重构的特性,即其分词结果能够准确无误地还原为原始输入文本。其
次,分词器应具有高压缩率,即在给定文本数据的情况下,经过分词处理后的词
元数量应尽可能少,从而实现更为高效的文本编码和存储。具体来说,压缩比可
以通过将原始文本的 UTF-8 字节数除以分词器生成的词元数(即每个词元的平均
字节数)来计算:
压缩率 = UTF-8 字节数
词元数 . (4.2)
例如,给定一段大小为 1MB(1,048,576 字节)的文本,如果它被分词为 200,000
个词元,其压缩率即为 1,048,576/200,000=5.24。

SwiGLU
Pre RMS

softmax公式

为了学习复杂的函数关系和特征, Transformer 模型引入了一个前馈网络层
(Feed Forward Netwok, FFN),对于每个位置的隐藏状态进行非线性变换和特征
提取。

在注意力和前馈网
络后,模型使用层归一化和残差连接来加强模型的训练稳定度。其中,残差连接
(Residual Connection)将输入与该层的输出相加,实现了信息在不同层的跳跃传
递,从而缓解梯度爆炸和消失的问题。而 LayerNorm 则对数据进行重新放缩,提
升模型的训练稳定性


与编码
器不同,解码器需要引入掩码自注意力(Masked Self-attention)模块,用来在计算
注意力分数的时候掩盖当前位置之后的词,以保证生成目标序列时不依赖于未来
的信息。


在训练过程中,解码器可以通过一次前向传播,让
每个词元的输出用于预测下一个词元。而在解码过程,解码器需要经过一个逐步
的生成过程,将自回归地生成完整的目标序列


批次归一化(Batch Normalization, BN) [161]
是一种广泛采用的归一化方法。然而,该方法难以处理可变长度的序列数据和小
批次数据。

因此,相关研究提出了层归一化这一技术 [158],针对数据进行逐层归
一化。具体而言,层归一化会计算每一层中所有激活值的均值 𝝁 和方差 𝝈,从而
865.2 详细配置
重新调整激活值的中心和缩放比例


为了提高层归一化的训练速度, RMSNorm [159] 仅利用激活值
总和的均方根 RMS(𝒙) 对激活值进行重新缩放。使用 RMSNorm 的 Transformer 模
型相比于之前 LayerNorm 训练的模型在训练速度和性能上均具有一定优势。采用
RMSNorm 的代表性模型包括 Gopher [123] 和 Chinchilla [22]。其计算公式如下所


DeepNorm 由微软的研究人员提出 [160],旨在稳定深层 Transformer 的训练。具体而言, DeepNorm 在 LayerNorm 的基础上,在残差连接中对
之前的激活值 𝒙 按照一定比例 𝛼 进行放缩。通过这一简单的操作, Transformer 的
层数可以被成功地扩展至 1,000 层 [160],进而有效提升了模型性能与训练稳定性。


归一化模块的位置通常有三种选择,分
别是层后归一化(Post-Layer Normalization, Post-Norm)、层前归一化(Pre-Layer
Normalization, Pre-Norm)和夹心归一化(Sandwich-Layer Normalization, SandwichNorm)。

Post-Norm. Post-Norm 是在原始 Transformer 模型中所使用的一种归一化技
术。其中,归一化模块被放置于残差计算之后。其计算公式如下:
Post-Norm(𝒙) = Norm(𝒙 + Sublayer(𝒙)),


Pre-Norm. 与 Post-Norm 不同, Pre-Norm [164] 将归一化模块应用在每个子
层之前。其计算公式如下:
Pre-Norm(𝒙) = 𝒙 + Sublayer(Norm(𝒙)),


Sandwich-Norm(𝒙) = 𝒙 + Norm(Sublayer(Norm(𝒙))). (5.19)
本质上, Sandwich-Norm 可以看作是 Pre-Norm 和 Post-Norm 两种方法的组合,理
论上具有更加灵活的表达能力。但是研究人员发现, Sandwich-Norm 有时仍然无
法保证大语言模型的稳定训练,甚至会引发训练崩溃的问题



原始的 Transformer 中采用了 ReLU(Rectified Linear Unit)激活函数。该激活函数
计算较为简单,仅仅是将对输入中每个神经元和“零值”进行比较,并将小于零
的神经元的值设置为 0。然而, ReLU 可能会产生神经元失效的问题,被置为 0 的
神经元将学习不到有用的信息。 ReLU 函数的具体形式如下所示:
ReLU(𝑥) = max(𝑥, 0)


不同于其他激活
函数, GLU 激活函数引入了两个不同的线性层。其中一个线性层的输出将被输入
到一个激活函数(例如, GeGLU 采用 GELU 激活函数)中,其结果将和另一个线
性层的输出进行逐元素相乘作为最终的输出。相比于其他的激活函数,使用 GLU
895.2 详细配置
激活函数变体通常能够带来更佳的性能表现 [168]。 SwiGLU 和 GeGLU 激活函数
的计算公式如下所示:
SwiGLU(𝒙) = Swish(𝑾𝐺𝒙) ⊙ (𝑊𝑈𝒙), 
GeGLU(𝒙) = GELU(𝑾𝐺𝒙) ⊙ (𝑊𝑈𝒙). 

与绝对位置编码不同,相对位置编码是根据键和查询之间
的偏移量计算得来的。计算得到的相对位置编码通常应用于注意力矩阵的计算中,
而不是直接与词元本身的位置编码进行相加。


绝对位置编码相比,应用了相对位置编码的 Transformer
模型常常可以对比训练序列更长的序列进行建模,即具备一定的外推能力 [170]。
T5 相对位置编码的计算可以表达为:
𝐴𝑖 𝑗 = 𝒙𝑖𝑾𝑄𝑾𝐾 ⊺𝒙⊺𝑗 + 𝑟𝑖− 𝑗, (5.29)
其中 𝑟𝑖− 𝑗 表示基于查询和键之间偏移的可学习标量


旋转位置编码(Rotary Position Embedding, RoPE) . RoPE 巧妙地使用了基于
915.2 详细配置
绝对位置信息的旋转矩阵来表示注意力中的相对位置信息。 RoPE 根据位置信息为
序列中每个词元所对应的设置了独有的旋转矩阵,并和对应的查询和键进行相乘
进行融合。形式化,位置索引为 𝑡 对应的旋转矩阵定义如下所示:


ALiBi 位置编码: ALiBi [170] 是一种特殊的相对位置编码,主要用于增强
Transformer 模型的外推能力。具体来说, ALiBi 通过在键和查询之间的距离上施
加相对距离相关的惩罚来调整注意力分数。其计算公式如下:
𝐴𝑖 𝑗 = 𝒙𝑖𝑾𝑄𝑾𝐾 ⊺𝒙⊺𝑗 − 𝑚(𝑖 − 𝑗),


多查询/分组查询注意力. 为了提升注意力机制的效率,多查询注意力(MultiQuery Attention, MQA)提出针对不同的头共享相同的键和值变换矩阵 [171]。这种
方法减少了访存量,提高了计算强度,从而实现了更快的解码速度

GQA 将全部的头划分为若
干组,并且针对同一组内的头共享相同的变换矩阵。这种注意力机制有效地平衡
了效率和性能,被 LLaMA-2 模型所使用

相比于传统的注意力
实现方式, FlashAttention 通过矩阵分块计算以及减少内存读写次数的方式,提高
注意力分数的计算效率; PagedAttention 则针对增量解码阶段,对于 KV 缓存进行
分块存储,并优化了计算方式,增大了并行计算度,从而提高了计算效率。

在混合专家架构中,每个混合专家层包含 𝐾 个专家组件,记为 [𝐸1, 𝐸2, . . . , 𝐸𝐾],
其中每个专家组件 𝐸𝑖 都是一个前馈神经网络。对于输入的每个词元表示 𝒙𝑡,模
型通过一个路由网络(或称为门控函数) 𝐺 来计算该词元对应于各个专家的权重。
在路由函数中,首先通过线性层 𝑾𝐺 ∈ R𝐻×𝐾 映射为 𝐾 个专家的得分,并基于此
选择出概率最高的 𝑘 个专家进行激活。随后,这 𝑘 个专家的得分将被送入 softmax
函数计算出它们的权重 𝐺(𝒙𝑡) = [𝐺(𝒙𝑡)1, . . . , 𝐺(𝒙𝑡)𝑘],没有被选择的专家权重将
被置为 0。上述路由网络的计算过程如下式所示:
𝐺(𝒙𝑡) = softmax(topk(𝒙𝑡 · 𝑊𝐺)). (5.35)
之后,每个被选择的词元的输出的加权和将作为该混合专家网络层的最终输出 𝒐𝑡:
𝒐𝑡 = MoELayer(𝒙𝑡) =𝐾∑𝑖=1 
𝐺(𝒙𝑡)𝑖 · 𝐸𝑖(𝒙𝑡)

在预训练语言模型时代,自然语言处理领域广泛采用了预训练 + 微调的范式,
并诞生了以 BERT 为代表的编码器(Encoder-only)架构、以 GPT 为代表的解码
器(Decoder-only)架构和以 T5 为代表的编码器-解码器(Encoder-decoder)架构的
大规模预训练语言模型。

随着 GPT 系列模型的成功发展,当前自然语言处理领域
走向了生成式大语言模型的道路,解码器架构已经成为了目前大语言模型的主流
架构。进一步,解码器架构还可以细分为两个变种架构,包括因果解码器(Causal
Decoder)架构和前缀解码器(Prefix Decoder)架构。值得注意的是,学术界所提
到解码器架构时,通常指的都是因果解码器架构。


首先,因果解码器没
有显式地区分输入和输出部分。如图 5.6 所示,该架构采用了单向的掩码注意力机
制,使得每个输入的词元只关注序列中位于它前面的词元和它本身,进而自回归
地预测输出的词元。此外,由于不含有编码器部分,因果解码器删除了关注编码
器表示的交叉注意力模块。经过自注意力模块后的词元表示将直接送入到前馈神
经网络中。在因果解码器架构中,最具有代表性的模型就是 OpenAI 推出的 GPT
系列。其中, GPT-3 将模型参数拓展到了 100B 级别,并展现出了强大的零样本和
少样本学习能力。伴随着 GPT-3 的成功,因果解码器被广泛采用于各种大语言模
型中,包括 BLOOM、 LLaMA 和 Mistral 等。

对于前缀解码器,也可以由现有的因果解码器继
续预训练转换而来,进而加速该模型的训练。例如, U-PaLM [175] 是从 PaLM [33]
继续预训练而来的。当前,基于前缀解码器架构的代表性大语言模型包括 GLM-
130B [162] 和 U-PaLM [175]。


给定一个预训练后的大语言模型,如何有效拓展其上下文窗口以应对更长的
文本数据成为当前学术界的研究焦点。目前,增强大语言模型长文本建模能力的
研究主要集中在两个方向:一是扩展位置编码(详见第 5.4.1 节),二是调整上下
文窗口(详见第 5.4.2 节)。

在基于 Transformer 架构的大语言模型中,模型的上下文建模能力通常受到训
练集中文本数据长度分布的限制。一旦超出这个分布范围,模型的位置编码往往
无法得到充分训练,从而导致模型处理长文本的性能下降。因此,当大语言模型
面临超出其最大训练长度的任务时,需要对于位置编码进行扩展,以适应更长的
绝对或相对位置

实际上,某些特定的位置编码在超出原始上下文窗口的文本上,也能够表现
出较好的建模能力,这种能力通常被称为外推(Extrapolation)能力。在已有的基
于相对位置的位置编码方法中, T5 偏置 [77]、 ALiBi [170] 以及 xPos [176] 等方法
都展现出了不同程度的外推能力。值得注意的是,尽管这种外推能力可以确保模
型在长文本上继续生成流畅的文本,但模型对长文本本身的理解能力可能无法达
到与短文本相同的水平。为了真正增强长文本建模能力,通常还需要在更长的文
本上进行一定的训练


直接微调
为了使大语言模型适应更长的上下文长度,一种直接的策略是使用相应的长
文本数据对于模型进行微调。在这种情况下,模型可以直接根据相对位置计算出
对应的位置编码,而无需对 RoPE 本身进行任何修改。

位置索引修改
鉴于直接微调可能引发旋转角度增大和注意力值爆炸的问题,有必要对旋转
角度施加限制,以确保拓展后的上下文窗口中的旋转角度得到充分且有效的训练。
为实现这一目标,可以通过修改位置索引 𝑔(𝑡) 来调整所有子空间的旋转角度,从
而保证其不超过原始上下文窗口所允许的最大值。具体来说,位置索引的修改可
采用以下两种方法:
位置内插
位置内插 [157] 方法对于位置索引进行特定比例的缩放,以保证
旋转角度不会超过原始上下文窗口的最大值。具体来说,该策略将所有位置索引
乘以一个小于 1 的系数 𝑇max/𝑇max ′ (其中 𝑇max < 𝑇max ′ ), 𝑇max 和 𝑇max ′ 分别表示原始
上下文窗口和拓展后的上下文窗口的长度。通过进行这样的缩放,新的旋转角度
计算公式变为:

位置截断. 不同于位置内插,位置截断针对不同距离采用了不同的处理方
1035.4 长上下文模型
式。该方法依据语言建模的局部性原理,对模型中近距离敏感的位置索引进行保
留,同时截断或插值处理远距离的位置索引,确保其不超出预设的最大旋转角度。
具体来说,采用位置截断的 ReRoPE 和 LeakyReRoPE [177] 方法首先设定一个不大
于原始上下文窗口长度的窗口大小 𝑤 (𝑤 ≤ 𝑇max)。在此窗口范围内的部分,仍使
用原始相对位置索引;对于超出此窗口的部分,位置索引则会被截断至窗口大小,
即𝑔(𝑡) = 𝑤;或通过线性插值方式,将目标上下文窗口长度的位置索引映射回原始
上下文窗口长度

为了解决 Transformer 架构对于上下文窗口的限制,除了使用扩展位置编码来
拓宽上下文窗口外,另一种行之有效的策略是采用受限的注意力机制来调整原始
的上下文窗口,从而实现对更长文本的有效建模。

并行上下文窗口
并行上下文窗口方法 [181] 采用了一种分而治之的策略来处理输入文本。具
体来说,该方法将输入文本划分为若干个片段,每个片段都进行独立的编码处理,
并共享相同的位置编码信息。在生成阶段,通过调整注意力掩码,使得后续生成
的词元能够访问到前序的所有词元。然而,该方法无法有效地区分不同段落之间
的顺序关系,在某些特定任务上可能会限制模型的表现能力。

每个片段都进行独立的编码处理,
并共享相同的位置编码信息。在生成阶段,通过调整注意力掩码,使得后续生成
的词元能够访问到前序的所有词元。


基于序列中当前位置之前的词元序
列 𝒖<𝑡,采用自回归的方式对于目标词元 𝑢𝑖 进行预测。在训练过程中,模型通常
根据以下的似然函数进行优化:
LLM(𝒖) =
𝑇∑𝑡=1
log 𝑃(𝑢𝑡 |𝒖<𝑡 ). (6.1)
可以发现,语言建模任务与人类生成语言数据(如口语表达、书面写作等)的方
式存在相似之处,都是基于前序内容生成(或预测)后续的内容。

可以看到,前缀语言建模任务本质上是基于前缀信息来预测后缀的词元,这与自
然语言处理任务中常见的基于输入来预测输出的模式十分相似。


现有的大语言模型在预训练阶段通常采用相似的学习率调整策略,包括预热
阶段和衰减阶段。预热阶段一般占整个训练步骤的 0.1% 至 0.5%,然后学习率便
开始进行衰减。在模型训练的初始阶段,由于参数是随机初始化的,梯度通常也
比较大,因此需要使用较小的学习率使得训练较为稳定。

常见的衰减策略有线性衰减,余弦衰减,
平方根倒数衰减,


在已有的工作中,大语言模型的训练通常采用Adam [195] 及其变种 AdamW [196]
作为优化器。 Adam 优化器使用梯度的“动量”作为参数的更新方向,它使用历史
更新步骤中的梯度加权平均值来代替当前时刻的梯度,从而缓解样本随机性带来
的损失震荡。进一步, Adam 使用自适应的学习率方法,通过梯度的加权“二阶矩”
对梯度进行修正(可以看做使用“标准差”进行“归一化”),从而防止梯度过小
导致模型难以优化。


PyTorch 中也实现了与 ZeRO 相似的技
术,称为完全分片数据并行(Fully Sharded Data Parallel, FSDP)。

早期的预训练语言模型(例如 BERT)主要使用单精度浮点数(FP32)表示模
型参数并进行优化计算。近年来,为了训练超大规模参数的语言模型,研发人员
提出了混合精度训练(Mixed Precision Training)技术,通过同时使用半精度浮点
数(2 个字节)和单精度浮点数(4 个字节)进行运算,以实现显存开销减半、训练
效率翻倍的效果。具体来说,为了保证表示精度,需要保留原始 32 位模型的参数
副本。但在训练过程中,会先将这些 32 位参数转换为 16 位参数,随后以 16 位精
度执行前向传播和反向传播等操作,最后在参数更新时再对 32 位模型进行优化。
由于在模型训练中前向传播和反向传播占用了绝大部分优化时间,混合精度训练
因而能够显著提升模型的训练效率。常见的半精度浮点数表示方式为 FP16,其包
含 1 位符号位、 5 位指数位和 10 位尾数位,表示范围为 −65504 到 65504。进一步,
谷歌的研究人员深度学习场景提出了新的半精度浮点数表示 BF16,其包含 1 位符
号位、 8 位指数位和 7 位尾数位,表示范围可以达到 1038 数量级。相比于 FP16,
BF16 有着更大的数值范围,在大模型训练中被广泛使用。值得一提的是,目前较
为主流的 GPU (例如英伟达 A100)都支持 16 位计算单元运算,因此混合精度训
练能够被硬件很好地支持。

参数量计算
由于当前主流的大模型普遍采用因果解码器架构,因此下面以 LLaMA 模型
为范例,深入剖析其参数数量计算方式。对于其他模型,其参数量计算算法可参
照此方法计算。首先,假设词表大小为 𝑉,模型包含 𝐿 层解码器,中间状态的维
度大小为 𝐻,前馈网络层的中间状态维度大小为 𝐻′。我们主要关注计算以下几个
部分的参数量:
• 输入嵌入层. 首先,输入嵌入层( 𝑬 ∈ R𝑉×𝐻)将词表中的每个单词映射到一
个 𝐻 维的向量,因此输入编码层有 𝑉𝐻 个参数。
• 多头注意力层. 传统的注意力机制部分包含查询(𝑾𝑄 ∈ R𝐻×𝐻)、键(𝑾𝐾 ∈
R𝐻×𝐻)和值(𝑾𝑉 ∈ R𝐻×𝐻)的线性变换矩阵,每个变换矩阵都包含 𝐻2 个参数,
所以这部分需要 3 × 𝐻2 个参数。同时还需要一个额外的线性变换来将多头注意力
机制的输出拼接后映射成最终输出(𝑾𝑂 ∈ R𝐻×𝐻),这又需要 𝐻2 个参数。因此,
多头注意力层总共需要 4 × 𝐻2 个参数。
• 前馈网络层. LLaMA 的前馈网络层由三个线性变换组成,中间有一个非线
性激活函数。前两个线性变换(𝑾𝑈 ∈ R𝐻×𝐻′ 和 𝑾𝐺 ∈ R𝐻×𝐻′)将输入从 𝐻 维映射
到 𝐻′ 维,需要 2 × 𝐻𝐻′ 个参数;最后一个线性变换(𝑾𝐷 ∈ R𝐻′×𝐻)将输出从 𝐻′
维映射回 𝐻 维,需要 𝐻𝐻′ 个参数。因此,前馈网络层总共需要 3 × 𝐻𝐻′ 个参数。
• 归一化层. 每一层解码器还包含两个 RMSNorm 操作,分别用于对多头注意
力层和前馈网络层的输入进行归一化处理,共需要 2 × 𝐻 个参数。此外,最后一层
的输出也需要进行归一化处理,这又需要额外的 𝐻 个参数。
• 输出层. 最后, LLaMA 的输出层包含一个线性变换(𝑾𝐿 ∈ R𝐻×𝑉),将解码
器的输出映射到词表大小 𝑉 的维度上,使用 softmax 归一化后预测下一个单词的
1236.4 模型参数量计算与效率分析
概率分布。这个线性变换需要 𝑉𝐻 个参数。
综上所述,累积输入嵌入层、输出层和 𝐿 层解码器每层的多头注意力层、前
馈网络层和归一化层, LLaMA 模型的参数量计算公式为:
参数量 = 2𝑉𝐻 + 𝐻 + 𝐿 · (4𝐻2 + 3𝐻𝐻′ + 2𝐻). (6.5)
以 LLaMA (7B) 为例计算其参数量,给定 𝑉 = 32000, 𝐿 = 32, 𝐻 = 4096, 𝐻′ = 11008,
将这些值代入上述公式中:
参数量 = 2 × 32000 × 4096 + 4096 + 32 × (4 × 40962 + 3 × 4096 × 11008 + 2 × 4096)
= 6, 738, 415, 616.
计算得到的参数量与 LLaMA (7B) 模型的实际参数量完全一致


Self-Instruct 目前已经成为一种合成指令的基础方法,原始论文使用 GPT-3 合
成了 Self-Instruct-52K 数据集, Alpaca 进一步使用了能力更强的 text-davinci
-003 合成了 Alpaca-52K 数据集,之后研究人员陆续采用了更强大的模型(例如
GPT-4)来合成各种语言、各种领域的指令数据。


在指令微调中,指令数据的格式、数量等因素对微调后的模型性能有着重要
影响。下面将从指令格式设计、扩展指令数量、指令重写与筛选等三个方面介绍
如何构建高质量的指令数据集。

指令格式设计


为了激发大模型的逐步推理能力,研究人员还尝试在指令微调数据集中引入
思维链数据

扩展指令数量
对于 NLP 任务数据集而言, FLAN-T5 [41] 研究了指令数量对于模型在未知
NLP 任务上的性能影响。通过逐步将指令数量扩展至 0.18M、 5.55M、 7.2M 以及
17.26M,研究人员发现模型性能呈持续上升的趋势。然而,当指令数量达到 7.2M
后,模型性能的提升变得非常缓慢。

指令重写与筛选
一方面,研究人员尝试从大量数据集中筛选出部分指令来进行微调。 Alpagasus 利用 GPT-4 从原始的 52K 条 Alpaca 数据中筛选出 GPT-4 评分较高的 9 千条。
使用这 9 千条数据进行指令微调训练,便可以在下游测试任务中达到与原始 52K
条数据接近的效果。 YuLan-Chat-3 提出了“平衡指令难度”策略,其用大模型的困
惑度分数来估算指令数据的难度水平,删除过于简单或过于困难的指令数据,从
而缓解大模型训练不稳定或者过拟合的现象

目标函数. 预训练阶段通常采用语言建模损失(详见第 6.1.1 节),优化模型
在每一个词元上的损失。而指令微调可以被视为一个有监督的训练过程,通常采
用的目标函数为序列到序列损失,仅在输出部分计算损失,而不计算输入部分的
损失。

多轮对话数据的高效训练. 对于一个多轮对话数据,通常的训练算法是将其
拆分成多个不同的对话数据进行单独训练。为了提升训练效率,可以采用特殊的
掩码机制来实现多轮对话数据的高效训练。在因果解码器架构中,由于输入输出
没有明显的分界,可以将所有一个对话的多轮内容一次性输入模型,通过设计损
失掩码来实现仅针对每轮对话的模型输出部分进行损失计算,从而显著减少重复
前缀计算的开销。如例 7.1 所示,多轮对话涉及多次用户输入和模型的输出,但是
训练中仅需要在模型的输出上计算损失


LoRA [214] 提出在预训练模型的参数矩阵上添加低秩分解矩阵来近似每层的
1487.3 参数高效的模型微调
参数更新,从而减少适配下游任务所需要训练的参数。给定一个参数矩阵 𝑾,其
更新过程可以一般性地表达为以下形式:
𝑾 = 𝑾0 + Δ𝑾, (7.1)
其中, 𝑾0 是原始参数矩阵, Δ𝑾 是更新的梯度矩阵。 LoRA 的基本思想是冻结原
始矩阵 𝑾0 ∈ R𝐻×𝐻,通过低秩分解矩阵 𝑨 ∈ R𝐻×𝑅 和 𝑩 ∈ R𝐻×𝑅 来近似参数更新
矩阵 Δ𝑾 = 𝑨 · 𝑩⊺,其中 𝑅 ≪ 𝐻 是减小后的秩。在微调期间,原始的矩阵参数 𝑾0
不会被更新,低秩分解矩阵 𝑨 和 𝑩 则是可训练参数用于适配下游任务。在前向传
播过程中,原始计算中间状态 𝒉 = 𝑾0 · 𝒙 的公式修改为:
𝒉 = 𝑾0 · 𝒙 + 𝑨 · 𝑩⊺ · 𝒙. 


QLoRA [216] 将原始的参
数矩阵量化为 4 比特,而低秩参数部分仍使用 16 比特进行训练,在保持微调效果
的同时进一步节省了显存开销。


有用性(Helpfulness)、诚实性(Honesty)和无害性(Harmlessness),这三
种对齐标准已被现有的大语言模型对齐研究广泛使用


有用性. 在实际应用中,大语言模型需要提供有用的信息,能够准确完成任
务,正确理解上下文,并展现出一定的创造性与多样性。

诚实性. 模型的输出应具备真实性和客观性,不应夸大或歪曲事实,避免产
生误导性陈述,并能够应对输入的多样性和复杂性。

无害性. 大语言模型应避免生成可能引发潜在负面影响或危害的内容。在处
理敏感主题时,模型应遵循道德标准和社会价值观,从而消除冒犯性与歧视性。


RLHF 算法系统
RLHF 算法系统主要包括三个关键组成部分:需要与人类价值观对齐的模型、
基于人类反馈数据学习的奖励模型以及用于训练大语言模型的强化学习算法。

由于贪心搜索所采取的是确定性
策略,它的效果在不同类型的任务中具有一定的差异。在机器翻译和文本摘要等
任务中,任务输出高度依赖于输入内容,贪心搜索通常能够获得不错的结果,但
是在开放式生成任务(如故事生成和对话系统)中,贪心搜索有时会因为过于关
注局部最优,而生成不自然、重复的句子 


贪心搜索在每个生成步骤中均选择最高概率的词元,这可能会由于忽略在某
些步骤中概率不是最高、但是整体生成概率更高的句子而造成局部最优。为了解
决这个问题,可以进一步采用以下的改进策略。


Beam search
当 𝑛 = 1,束搜索就退化为贪心搜索。如图 9.3 所示(𝑛 = 2),第一步保留了
概率最高的两个词“coffee”和“water”作为候选;第二步基于“coffee”和“water”
均进行扩展,得到模型在两个上下文内容下的概率分布,最后选择联合概率最高
的两个句子“coffee then”和“coffee and”作为候选。在下面的生成步骤中,将会继
续基于这两个候选去进行扩展,每次都选择联合概率最高的两个句子。最后,当
两个束的句子均生成结束后,选择整体生成概率最高的候选句子作为最终的输出。
在实践中,束的数量通常设定在 3 到 6 的范围内,设置过大的束会显著增加运算
开销,并可能会导致性能下降。

如果没有长度惩罚,传统
的束搜索会倾向于生成较短的句子,因为每生成一个单词,都会乘以一个小于 1
的概率,使得句子的生成概率逐渐变小。因此,可以在生成概率的计算中引入长
度惩罚,通过将句子概率除以其长度的指数幂 𝛼,对于句子概率进行归一化处理,
从而鼓励模型生成更长的句子。在实践中, 𝛼 通常设置为 0.6 到 0.7 之间的数值。


具体地,出现惩罚在生成过程中会将已
经生成词元的 logits(公式 5.11)减去惩罚项 𝛼 来降低该词元之后生成的概率。频
率惩罚相较于出现惩罚,会记录每个词元生成的数目,然后减去出现次数乘以惩
罚项 𝛼,因此如果一个词元生成得越多,惩罚也就越大。在实践中, 𝛼 的取值范围
通常在 0.1 到 1 之间。这些重复惩罚方法不止适用于贪心搜索,对于随机采样也均
适用


温度采样(Temperature Sampling) . 为了调节采样过程中的随机性,一种有
效的方法是调整 softmax 函数中的温度系数。具体来说,公式 5.11 中的 𝒍 = 𝑾𝐿𝒚𝐿
称为 logits,调整温度系数后的 softmax 计算式如下:
𝑃(𝑢 𝑗|𝒖<𝑖) =
exp (𝑙 𝑗/𝑡)
∑𝑗′ exp (𝑙 𝑗′/𝑡) , (9.3)
其中, 𝑙 𝑗′ 表示每个候选词元的 logit, 𝑡 是温度系数。具体来说,降低温度系数 𝑡 会
使得概率分布更加集中,从而增加了高概率词元的采样可能性,同时降低了低概
率词元的采样可能;当温度系数 𝑡 设置为 1 时,该公式退化为标准的随机采样方
法;而当 𝑡 趋近于 0 时,实际上等同于贪心搜索,即总是选择概率最高的词。此
外,当 𝑡 趋近于无穷大时,温度采样会退化为均匀采样。图 9.4 展示了在温度系数
分别设置为 1.3、 1.0 和 0.7 时下一个词元的概率分布情况。


Top-𝑘 采样(Top-𝑘 Sampling) . 与温度采样不同, top-𝑘 采样策略是直接剔除概
率较低的词元,限制模型从概率最高的前 𝑘 个词元中进行采样 [237]。以图 9.5 (a) 中
所示的生成过程为例,当采用 top-3 采样策略时,模型将会从“coffee”、“water”、“tea”
这三个概率最高的词元中,基于原始概率分布进行采样。

Top-𝑝 采样(Top-𝑝 Sampling) 

在具体的实现过程中, top-𝑝 采样首先会按照生成概率从高到低的
顺序对词元进行排序,然后不断将词元添加到一个临时的集合中,直到集合的累
积概率首次超过阈值 𝑝。


基于上述的量化基础知识,本部分将主要介绍大语言模型相关的量化方法。
通常来说,模型量化方法可以分为两大类,即量化感知训练(Quantization-Aware
Training, QAT)和训练后量化(Post-Training Quantization, PTQ)。
从方法的名字可以看出,量化感知训练方法需要更新权重进而完成模型量化,而训练后量化方法
则无需更新模型权重。与小型语言模型相比,在为大语言模型设计或选择量化方
法时需要侧重关注两个主要因素。


为了有效地优化该目标函数, GPTQ [246] 的基本想法是在逐层量化的基础上,
进一步将权重矩阵按照列维度分组(例如 128 个列为一组),对一个组内逐列进行
量化,每列参数量化后,需要适当调整组内其他未量化的参数,以弥补当前量化
造成的精度损失。在具体的实现中, GPTQ 还进一步采用了特殊设计的优化方法
来加速整个过程,如延迟批次更新、 Cholesky 重构等。 GPTQ 可以在 3 比特或 4 比
特精度下实现对于大语言模型的有效权重量化。
进一步, AWQ [247] 发现在逐层和逐组权重量化过程中,对于模型性能重要
的权重只占全部参数的一小部分(0.1%∼1%),并且应该更加关注那些与较大激
活值维度相对应的关键权重,因为它们对应着更为重要的特征。


bitsandbytes

GPTQ-for-LLaMA


它基于 GPTQ 算
法 [246] 进行开发,可以对于各种参数规模大小的 LLaMA 模型(7B、 13B 和 33B)
进行 4 比特权重量化。


分解为简单且详细的子任务. 该原则的目标是将一个复杂任务分解为若干个
相对独立但又相互关联的子任务,每个子任务都对应原始任务的某个方面或步骤。
特别地,我们可以显式地将子任务按编号列出。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值