一、选择模型结构
1、模型架构的选择
1. RNN (Recurrent Neural Network):
• 用于处理序列数据。
• 有记忆功能,可以处理任意长度的序列。
• 存在长期依赖问题。
2. LSTM (Long Short-Term Memory):
• RNN的一种变体,设计用于解决长期依赖问题。
• 通过“门”结构来控制信息流。
3. GRU (Gated Recurrent Unit):
• LSTM的简化版本,具有相似的性能。
• 有两个门结构:重置门和更新门。
4. Transformer:
• 采用自注意力机制处理序列数据。
• 能够并行处理序列中的所有元素,速度快。
• 架构非常灵活,已成为NLP领域的主流。
5. BERT (Bidirectional Encoder Representations from Transformers):
• 基于Transformer的预训练模型,考虑了文本的双向上下文。
• 可以进行微调,以应对各种NLP任务。
6. GPT (Generative Pre-trained Transformer):
• 使用Transformer架构的生成式预训练模型。
• 在自回归任务上进行预训练,然后可以应用于各种任务。
7. T5 (Text-to-Text Transfer Transformer):
• 所有NLP任务都被视为文本到文本的转换。
• 使用Transformer架构。
8. XLNet:
• 与BERT和GPT相结合的架构。
• 使用双向和自回归方法。
9. RoBERTa:
• BERT的变种,通过调整预训练策略和参数来优化。
10. ALBERT (A Lite BERT):
• BERT的轻量级版本。
• 减少了模型的大小,但保持了相似的性能。
当下主流大预言模型选用架构:
1、ChatGPT 4
ChatGPT是基于GPT模型的AI聊天产品,后文均简称为GPT。
从技术上看,GPT是一种基于Transformer架构的大语言模型(LLM)。GPT这个名字,实际上是”Generative Pre-trained Transformer”的缩写,中文意为“生成式预训练变换器”。
2、文心一言
ERNIE(Enhanced Representation through kNowledge IntEgration)是百度提出的一种预训练语言模型,ERNIE 模型基于 Transformer 结构,与 BERT 模型类似。然而,ERNIE 引入了一种全新的预训练任务设计,对各种类型的知识进行建模,从而改善自然语言理解任务的性能。ERNIE 在多个自然语言处理任务(如阅读理解、命名实体识别和情感分类等)上取得了显著的性能提升。
3、通义千问
QWen-7B是基于Transformer的预训练语言模型。 与标准transformer的主要区别如下:1)使用untied embedding嵌入;2)使用旋转位置嵌入-即RoPE相对位置编码;3)normalization实现–即RMSNorm代替LayerNorm;4)FFN激活函数-即SwiGLU代替 ReLU;5)attention中除QKV外无bias–采用flash attention加速训练…..
4、LLaMA
LLaMA 是一个基于 Transformer 架构的基础的大型语言模型。 与 GPT 系列和其他基于 Transformer 的 LLM 类似,LLaMA 由嵌入层、多个 Transformer 块和语言模型头组成。 LLaMA 还结合了不同模型中使用的改进,例如预先标准化、SwiGLU 激活和旋转位置嵌入。 LLaMA 有四种不同的型号尺寸:7B、13B、33B 和 65B。
2.1 LLAMA
LLaMA (Touvron et al., 2023) is a foundational, decoder-only large language model built upon the
transformer architecture (Vaswani et al., 2017). Similar to the GPT series and other transformerbased LLMs, LLaMA consists of an embedding layer, multiple transformer blocks, and a language
model head. LLaMA also incorporates improvements utilized in different models, such as prenormalization (Zhang & Sennrich, 2019), SwiGLU activation (Shazeer, 2020), and rotary embeddings (Su et al., 2021). LLaMA is available in four different model sizes: 7B, 13B, 33B, and 65B. –LLaMA技术报告
特性
|
Transformer
|
RNN
|
---|---|---|
工作原理 | 自注意力机制:Transformer 使用了一种称为“自注意力”(self-attention)的机制,它允许模型在处理一个词时,关注输入序列中的其他词。这种机制使模型能够捕捉长距离依赖关系。 | 序列处理:RNN通过逐步处理输入序列的方式来工作,每个时间步的输出依赖于前一个状态和当前的输入,这使得它天然适合处理序列数据,但也限制了其捕捉长距离依赖的能力。 |
并行化 | 高(得益于自注意力机制) | 有限(顺序性质) |
远距离依赖 | 优秀(有效捕捉依赖关系) | 较差(难以处理长距离依赖) |
在NLP任务中的表现 | 大多数复杂任务表现更优 | 适合更简单/早期的任务 |
训练难度 | 较易(不太容易梯度消失/爆炸) | 较难(容易梯度消失/爆炸) |
计算资源需求 | 较高(参数更多) | 较低(参数较少) |
数据需求 | 较高(数据越多表现越好) | 较低(可以用较少的数据训练) |
适用于简单任务 | 可能过度设计 | 非常适合 |
Decoder
- 用途:Decoder架构通常用于生成任务,如文本生成、语言模型等。它们能够基于给定的上下文或条件生成连续的文本序列。
- 工作方式:在Decoder模型中,每次生成一个新的输出(如一个词),都会将之前生成的输出作为下一步的输入。这意味着生成的每个词都依赖于之前所有生成的词。
- 例子:GPT系列模型是典型的以Decoder架构为基础的模型。
Encoder
- 用途:Encoder架构通常用于处理和理解输入数据,例如进行特征提取、信息压缩、文本分类等任务。Encoder将输入数据转换为一种固定长度的内部表示形式,这个表示形式捕捉了输入数据的关键信息。
- 工作方式:Encoder模型接受一系列输入(如一句话),并转换成一个抽象的内部表示,该表示可以用于各种下游任务,但不直接用于生成文本。
- 例子:用于句子分类或相似度任务的模型通常采用Encoder架构。
Encoder-Decoder
- 用途:Encoder-Decoder架构(也称为Seq2Seq模型)适用于需要将输入序列转换为输出序列的任务,例如机器翻译、文本摘要、问答系统等。这种架构可以将一个域(如一种语言)的数据转换为另一个域(如另一种语言)的数据。
- 工作方式:Encoder部分首先将输入序列转换成一个内部表示,然后Decoder部分使用这个内部表示来生成输出序列。通常,Decoder在生成每个词时都会考虑Encoder提供的信息,以及它自己到目前为止生成的序列。
- 例子:Transformer模型就是一个典型的Encoder-Decoder架构,它在诸如BERT(主要用作Encoder)和GPT(主要用作Decoder)等变种中得到应用。
一些主流模型的配置
2、分词器模型选择
Tokenizer决定了如何将原始文本拆分成模型可以理解的单元(tokens)。这些tokens可以是单词、子词或字符。通俗来讲,tokenizer 的目的就是将一句话进行切词,并将切好词的列表喂给模型进行训练。
在选择分词器模型时,重要的是要考虑不同分词方法的特点以及它们如何适应特定的语言和任务需求,
在处理某些语言时,特定的分词方法可能更为有效。例如,对于中文,可能需要基于字符的分词方法,因为中文没有像空格这样的明确的词边界。
对于像德语这样的黏着语,其中单个词可以由多个较小部分组合而成,可能需要一种能够有效分解这些复合词的分词方法。
分词方法:
word:
优点:词的边界和含义得到保留;
缺点:1)词表大,稀有词学不好;2)OOV:罕见词或是派生词,词的复数或者其他的一些组合词的规则而产生的词无法用现有词向量模型表示;3)无法处理单词形态关系和词缀关系;
char:
优点:词表极小,比如26个英文字母几乎可以组合出所有词,5000多个中文常用字基本也能组合出足够的词汇;
缺点:1)无法承载丰富的语义;2)序列长度大幅增长;
subword:可以较好的平衡词表大小与语义表达能力;
常见分词器(Tokenizer):
1.BPE
BPE最早其实是一种数据压缩算法,基本思想是将经常一起出现的数据对替换为不在数据串中的其他字符
核心思想:
从一个基础小词表开始,通过不断合并最高频的连续token对来产生新的token。
具体做法:
输入:训练语料;词表大小V
1.准备基础词表:比如英文中26个字母加上各种符号;
2.基于基础词表将语料拆分为最小单元;
3.在语料上统计单词内相邻单元对的频率,选择频率最高的单元对进行合并;
4.重复第3步直到达到预先设定的subword词表大小或下一个最高频率为1;
输出:BPE算法得到的subword词表
下面是一个BPE的训练示例:
2.Byte-level BPE
核心思想:
将BPE的思想从字符级别扩展到子节级别。
具体做法:
3. WordPiece
核心思想:
WordPiece基于概率生成新的subword而不是下一最高频字节对
4.SentencePiece
核心思想:
直接从原始文本中学习词汇的分词器。它将文本视为一个字符序列。
分词器模型
|
原理
|
优点
|
缺点
|
适用性
|
---|---|---|---|---|
BPE | 从一个基础小词表开始,通过不断合并最高频的连续字符对来产生新的token。 | 减少词汇表大小,处理未知词汇 | 可能不生成语义上有意义的子词单元 | 使用字母表书写的语言,如英语 |
WordPiece | WordPiece基于概率生成新的subword而不是下一最高频字节对 | 生成的子词适应语言模型任务 | 需要预定义词汇表,训练过程可能较复杂 | 多种语言,被广泛应用于BERT等模型 |
SentencePiece | 直接在字符级别上学习词汇,无需预先分词 | 无需预定义词汇表,适用于没有明确词边界的语言 | 可能生成较多非语义子单元 | 不同语言类型,特别是不使用空格分隔的语言 |
BBPE | 将BPE的思想从字符级别扩展到字节级别。 | BPE的优点,且更适合大词汇表 | 仍可能生成一些非语义子词单元 | 适用于需要处理大词汇表的场景,如多语言模型 |
主流大模型使用的分词器:
3、确定词表大小
扩充词表的目的通常是为了使模型能够更好地处理各种语料,特别是那些在原始训练数据中不常见或完全不存在的词汇。
目的:
为了平衡计算效率和模型性能,词嵌入层的参数数量是由词汇表的大小和嵌入向量的维度决定的,如果词汇表的大小是V(也就是说,有V个唯一的单词或标记),并且每个单词的嵌入向量的维度是D,那么词嵌入层将有V×D个参数。
如果词汇表更大,每个词的代表形式可能更精确,较少的词条就可以表示一个句子。相反,如果词汇表较小,例如只包含字符级别的条目,那么模型输入的序列长度可能会更长,因为每个单词需要更多的字符级条目来表示。这可能导致较低的压缩率。
词汇表大小与计算效率:
更大的词汇表可能会导致模型输入的序列长度变短,因为更多的词汇可以直接从词汇表中找到,而不需要分解为子词。短的序列可以加快模型的计算速度。
但更大的词汇表也意味着嵌入层的参数更多,这可能会增加计算的复杂性。
词汇表大小与模型性能:
较大的词汇表可能会提供更丰富、更具体的词条表示,有助于模型理解和生成文本。
但如果词汇表太大,且没有足够的数据来充分训练每个词条的嵌入,那么模型性能可能会受到影响。
另一方面,过小的词汇表可能会导致信息损失,因为复杂的词汇需要被分解为不太精确的子词。
方法:
1、基于新的训练数据:收集新的训练数据,处理数据后用分词模型(例如BPE创建新的词表),得到新的词表后,将新老词表合并。
2、现有词表的格式和结构,手动向词表里添加新的词汇。
二、预训练数据
1、数据采集:
需要关注数据来源和分布,对不同的数据源采用不同的比例,缓解模型在训练的时候受到数据集规模大小的影响。
数据处理:
1 文档准备
分为URL过滤,文档提取,以及语言选择
1.1 URL过滤
目的是过滤掉低质量的网站例如,主要是色情、暴力、与赌博有关的网站等。有两种过滤方法,一种是基于Google’s SafeSearch过滤器。另一种是基于手动单词列表过滤器。
1.2 文档提取
互联网上爬取的数据,并不是纯文本存储的,通常使用WARC、WAT和WET格式的数据存储。首先从爬取的文件中(可以从Common Crawl 网站上获取)筛选WET文件,再将其中的HTML页面转换为纯文本。一种方法是使用trafilatura等专门用于检索内容的库提取页面的主要内容,忽略菜单、页眉、页脚和广告等。另一种方法基于树状结构提取HTML页面中的文本,并在后续的过滤中对文档内容进行清洗。
WARC(Web ARChive):它是一种用于存储和传输Web资源(例如HTML页面,图像和视频文件等)的文件格式。 WARC文件通常包含HTTP响应和元数据,用于记录Web爬虫收集的信息。
WAT(Web Archive Transformation):它是一种元数据文件格式,用于描述WARC文件中记录的Web内容。 WAT文件通常包含URL,域名和其他有关记录的元数据信息。
WET(Web Extraction Toolkit):它是一种将HTML页面转换为文本格式的文件格式。 WET文件通常包含从HTML页面中提取的文本内容,但不包括图像和其他资源。
1.3 语言识别
语言识别可以在文档准备时完成,也可以在过滤中完成。首先对文档进行语言分类,再选择目标语言文档。Gopher和Bloom使用CCNet的fastText语言分类器对文档进行语言分类,这是一种基于字符级n-gram,并在维基百科上训练的支持176种语言的语言分类器。
2 过滤
过滤的方法主要有两种,一种是基于模型的方法,一种是基于启发式的方法。前者的代表有Megatron和GPT-3,后者的代表有Gopher和BLOOM等。
2.1 基于模型的方法
具体的做法是基于一些高质量的语料库例如WebText, Wikiedia, 和web books等作为正样例,从待过滤的文档中提取样本作为负样例训练一个分类器,然后用这个分类器对待过滤的文档中的样例进行打分。最后使用分类器的打分,根据帕累托分布来过滤部分低质量文档。
2.2 基于启发式的方法
又可以具体分为文档清洗和文档移除。前者的目的是删除被认为不是主文档一部分的文本,文档范围的清理函数主要针对非自然语言,例如HTML标记。后者的目的是从语料库中删除整个文档。选择完全删除文档的原因多种多样,例如文档质量太差,太复杂而无法自动修复,或者重复内容较多等等。两种方法的具体的做法都是人工定义web内容的质量指标,例如字符重复率,单词重复率,特殊字符的比例,停用词的比例,困惑度分数,单词的数量等等。其中高质量的文本被定义为“由人类为人类编写的”,没有内容的区别或语法的先验判断。然后可以通过定义截止阈值来过滤掉特定的文档。
3 去重
删除训练语料中相似度高的文档,用于数据集内部或者跨数据集之间。分为模糊去重和精确去重。
3.1 模糊去重
模糊去重的一般做法是基于hash算法计算文档相似度,再对文档进行去重。例如:SimHash算法、MinHash算法。
3.2 精确去重
一种做法是基于子串的精确匹配去重,在序列级而不是文档级进行操作。通过使用后缀数组查找字符串之间的精确匹配,然后删除文档中重复的字符串及相关段落。对于较长的文档,子串去重准确率更高。
4 下游文档处理
为了避免数据污染,一些论文会检查训练语料中和测试样例重叠的文档段落,并移除重叠的文档段落。GPT-3采用的方法是基于n-gram的重叠法。出于过滤的目的,gram定义为小写的、用空格分隔的、没有标点符号的单词。具体的做法对于训练集中的文档如果和测试集中的样例有13-gram的重叠,则删去该文档中重叠的13-gram以及周围的200个字节,并将该文档从该处分成片段。对于小于200个字节以及片段数多于10的文档,则整个删除。另外也可以采用模糊去重算法移除和测试集重复率较高的训练文档。
百川2对数据的处理
2、预训练
基于Transformer解码器架构的LM的预训练的方法是让模型做 Next Token Prediction 任务。
1、 模型结构改进
1、归一化
作用:
归一化是机器学习中常用的数据预处理步骤,目的是改变值的范围以保证不同特征的尺度统一。在神经网络中,特别是在深度学习的Transformer架构中,通常使用层归一化(Layer Normalization)来稳定学习过程,有助于加快训练速度并提高模型性能。
Layer Norm
进入任何其他层(如注意力机制或前馈神经网络)之前,先对输入数据进行层归一化(Layer Normalization)。
以一个简单的例子来说明:
假设我们有一个隐藏层,输出是一个向量:2,4,6。
1、首先,我们计算该向量的均值:(2 + 4 + 6) / 3 = 4。
2、接下来,计算标准差。标准差为1.63。
3、使用均值和标准差,我们可以将原始向量中的每个值归一化:
(2−4)/1.63,(4−4)/1.63,(6−4)/1.63
结果是一个均值为0,标准差为1的新向量:(-1.23,0,1.23)
归一化是为了使数据分布更加稳定,有助于提高模型的训练速度和性能。在Transformer架构中,使用层归一化有助于避免梯度消失或梯度爆炸问题。因为它确保了网络中每一层的输出都有相似的尺度。通过对每一层的输出进行归一化,我们能够保证数据流经网络时不会变得过小或过大,这样可以使梯度更新更稳定。
RMSNorm
RMSNorm是一种用于神经网络中的归一化技术。其目的是调整神经网络中的激活值,使其分布更加稳定,从而帮助模型更好地训练。归一化技术可以提高训练速度、提高模型的收敛性能,且通常还能获得更好的泛化性能。
RMSNorm的名字来源于”Root Mean Square Normalization”,即均方根归一化。它是一种简单的元素级归一化方法,与Layer Normalization和Batch Normalization不同,RMSNorm只依赖于单个数据点而不是整个批次或层的数据。
RMSNorm 的不同之处在于它不从每个元素中减去均值,只是通过该层的均方根(root mean square)进行归一化,这使得它的计算更为高效。
计算复杂度:RMSNorm 由于省略了均值的计算,计算上更为简单高效。
去中心化:层归一化会先对输入去中心化(减去均值),而 RMSNorm 不进行这一步骤。
稳定性:层归一化因为包含了去中心化步骤,通常被认为在训练过程中更稳定。
2、激活函数
为什么需要激活函数:
想象神经网络是一位厨师在烹饪美食,仅用线性计算就像他只能用盐和胡椒调味。就像厨师需要各种调料来创造丰富的口味,神经网络也需要激活函数来理解复杂的数据模式。没有激活函数,无论我们的网络有多复杂,它只能处理简单的、直接的问题。激活函数就像是添加了芥末和罗勒一样,使得网络能够理解更复杂的、非直观的信息。
激活函数的作用:
如果没有激活函数,神经元将只是对输入进行线性数学运算。这意味着无论我们在网络中添加多少层神经元,它所能学习的东西仍然是有限的,因为输出总是输入的简单线性组合。
激活函数通过在网络中引入非线性来解决问题。通过添加非线性,网络可以模拟输入和输出之间更复杂的关系,从而发现更多有价值的模式。这就好比让厨师掌握了新的烹饪技巧,可以制作出更加美味和复杂的菜肴。
用 SwiGLU 激活替代 ReLU,提高模型性能。
GLU(门控线性单元):
GLU是一种特殊的激活函数,它接受两部分输入,一部分直接通过,另一部分经过sigmoid函数处理后与前一部分相乘。
sigmoid函数的输出在0到1之间,所以它的功能就像一个”门”,决定了多少输入信号可以通过。
简单地说,假设我们有两部分输入,A和B。在GLU中,A直接通过,B经过sigmoid处理后与A相乘。所以,如果B经sigmoid处理后的值接近0,那么输出就会减少;如果B的值接近1,那么输出就接近A的原始值。
SwiGLU(开关激活的GLU变体):
SwiGLU是GLU的变体,但它引入了额外的参数来控制输入的部分。
SwiGLU有一个“双线性”层,这意味着它在计算过程中结合了两部分输入的线性组合。
与GLU不同,SwiGLU包含三个参数矩阵,这增加了它的复杂性和表现能力。
用一个简单的比喻:假设你在调节音响的音量,GLU就像是一个基本的音量旋钮,可以调节音量的大小;而SwiGLU就像是一个高级的音响系统,除了可以调节音量,还可以调节音质、低音、高音等,给你更多的控制自由度。
在选择激活函数时,我们要考虑的是如何使网络最有效地学习。传统的ReLU因其简单高效而广泛使用,但是新型的激活函数如SwiGLU,通过更复杂的内部机制,提供了更精细的控制,有助于提升网络处理复杂数据的能力。常见的激活函数包括ReLU (Rectified Linear Unit)、sigmoid、tanh等
3、位置编码
Transformer 的自注意力机制同时处理整个序列的所有词,不像 RNN 之类的结构是一个接一个地处理词。这意味着,如果没有其他的位置信息,Transformer 就无法知道词在序列中的位置,或者说无法区分“我爱你”和“你爱我”之间的区别。因此,我们需要为每个词添加位置信息。
位置编码需要考虑的地方:
连续性和平滑性:简单地为每个位置分配一个整数序号可能会导致模型难以学习位置之间的连续性和平滑性。例如,位置1和位置2之间的差异与位置1和位置10之间的差异是相同的,但我们可能希望模型能够认识到位置1和位置2是更为相近的。
高维表示:Transformer模型中的嵌入是高维的。为了与这些嵌入兼容,位置编码也需要是高维的。使用正弦和余弦函数等方法可以为每个位置生成一个高维向量,这有助于模型更好地捕获位置信息。
泛化到不同长度的序列:一些位置编码方法,如正弦和余弦位置编码,允许模型泛化到训练时未见过的序列长度。这是因为这些方法为每个可能的位置生成一个独特的编码,而不仅仅是训练数据中出现的位置。
模型性能和训练稳定性:实践中发现,某些位置编码方法可能会导致模型的性能和训练稳定性更好。这可能与如何将位置信息与令牌嵌入结合起来有关。
常规的自注意力查询需要大量的计算和存储资源,相较于常规的绝对位置编码,相对位置编码在长序列上性能更好,例如RoPE和ALiBi编码方法。
正弦余弦位置编码 (Sinusoidal Position Encoding)
在原始的Transformer模型中,每个位置的编码是一个维度与序列长度相同的向量,其中包含正弦和余弦函数的值。这些值是关于位置的函数,其波长形成一个几何级数。
优点:
1、可以处理任意长度的序列,因为函数是连续的。
2、不需要学习,编码是固定的,可以直接计算出来。
3、由于其周期性,对于模型理解两个词之间的距离可以很有帮助。
缺点:
因为它们是固定的,所以可能不会对所有任务都是最优的。
可能不如学习到的位置编码表现得那么好,特别是在处理高度复杂的序列任务时。
相对位置编码 (Relative Position Encoding)
相对位置编码,如在Transformer-XL中使用的,不直接编码绝对位置。相反,它通过考虑词与词之间的相对距离来编码位置信息。在自注意力机制中,这意味着模型不仅仅学习词的内容,还学习词之间的距离。
优点:
1、提供了序列中词之间相对位置的动态表示,可以更灵活地处理长序列。
2、可以帮助模型更好地理解长范围的依赖关系。
缺点:
1、相对复杂,可能需要更多的计算资源。
2、学习相对位置编码可能需要更多的训练数据来达到最佳效果。
一些常用的归一化、激活函数、位置编码方法:
2、 训练时的优化
1、混合精度
模型通常使用float32精度进行训练,使用FP32精度意味着模型中的参数、梯度、中间层的激活输出等都使用32位浮点数进行表示和计算。但是,并不是所有的场合都使用FP32,随着模型越来越大,训练的硬件成本和时间成本急剧增加。采用float16精度进行训练可以解决这一问题。但是随着模型的训练,梯度值太小小,超出float16表示的精度,导致权重都不再更新,模型难以收敛。
因此模型训练采用混合精度,即训练中模型权重以及梯度使用float16,优化器参数使用float32。同时优化器保存一份float32的权重,以及两个参数状态(均值和方差)。具体的更新步骤如下图:模型使用float16进行前向传播,计算损失值。然后反向传播得到float16的梯度;通过优化器将float16的梯度转化成float32精度的权重更新量;更新float32的权重;将float32的权重转换成float16
2、优化器
优化器的角色:
优化器就像是导航系统,它指引深度学习模型沿着正确的路径前进,目标是找到最理想的参数(比如权重和偏置),这些参数能使我们的模型最准确地完成其任务,如预测或分类。
如何工作:
想象你正在训练一个模型来预测房价,你有一堆数据告诉你房子的大小(x)和相应的价格(y)。你的模型开始时是个空白,不知道房价如何随房子大小变化,优化器的工作就是逐步调整模型的假设,以更好地匹配实际数据。假设y = wx +b
1、前向传播:模型根据当前的权重(w)和偏置(b)做出房价的预测。
2、损失计算:通过损失函数(比如均方误差)来衡量模型的预测与实际价格的差异。
3、反向传播:确定如何调整 w 和 b 来减少损失,这涉及到计算损失函数对 w 和 b 的梯度。
4、更新权重:根据这些梯度调整 w 和 b,使得下一次预测时损失更小。
这个过程会迭代进行,每次迭代都会使模型的预测更加准确。优化器决定了参数调整的大小和方向,也就是说,它决定了模型学习的速度和效率。就像调整车速和方向一样,不同的优化器策略(如SGD、Adam或RMSprop)会影响训练的快慢和模型的最终性能。
常见的优化器:
1. 随机梯度下降(SGD):这是最基础的优化算法,它使用每个样本或小批量样本的梯度来更新模型参数。
2. 动量(Momentum):Momentum是基于SGD的一个变种,它考虑了之前的梯度来加速SGD。它模拟了一个物体下坡的动量,即使在陡峭的斜坡也不会停止。
3. Nesterov 动量(Nesterov Accelerated Gradient,NAG):这是动量的一个改进版本,它在计算梯度时会提前“看一眼”更新后的位置。
4. AdaGrad(Adaptive Gradient Algorithm):这个优化器调整学习率,针对每个参数提供定制化的更新,这通常使得训练更快收敛。
5. RMSProp(Root Mean Square Propagation):RMSProp是为了解决AdaGrad学习率递减过快的问题而设计的。它使用一个移动平均值来计算梯度的平方,并调整每个参数的学习率。
6. Adam(Adaptive Moment Estimation):Adam结合了Momentum和RMSProp的思想,它计算过去梯度的指数移动平均值,并调整每个参数的学习率。
7. AdaDelta:与AdaGrad类似,但它试图减少其自适应学习率的下降速度。
8. Nadam:结合了Adam和Nesterov动量的优点。
9. L-BFGS (Limited-memory Broyden–Fletcher–Goldfarb–Shanno):这是一个用于非线性优化的算法,尤其适用于小型数据集。
10. FTRL (Follow The Regularized Leader):主要在大规模在线学习场景中使用,通常与L1正则化一起使用。
11.AdamW 是 Adam 优化器的一个变种,它在权重衰减(weight decay)方面进行了修改。AdamW 由 Ilya Loshchilov 和 Frank Hutter 在 2017 年提出,主要为了解决权重衰减在 Adam 优化器中的一些不良行为。
3、一些模型训练时的参数
Model: 模型的名称及其大小。
Batch Size (#tokens): 每批处理的标记数量,这会影响模型训练的内存消耗和速度。
Learning Rate: 学习率,控制在每次优化迭代中权重更新的幅度。
Warmup: 是否使用了学习率预热,这通常意味着在训练开始时逐渐增加学习率,以防止模型在最初的训练阶段学习得太快。
Decay Method: 学习率衰减方法,随着训练的进行逐渐减小学习率,以便模型收敛到更稳定的状态。
Optimizer: 用于训练模型的优化算法。
Precision Type: 使用的数值精度类型,FP16表示16位浮点数,这会影响模型训练的计算速度和内存使用。
Weight Decay: 权重衰减,用于正则化的技术,可以防止模型过拟合。
Grad Clip: 梯度裁剪,用于防止梯度爆炸,即避免更新步骤过大。
Dropout: 随机丢弃神经网络中的单元,用于防止过拟合。
4、硬件层面提升性能,提升训练速度
背景
当LLM由于规模庞大,无法在单张GPU上运行或者单卡的利用率低时,需要采取并行策略加速训练。首选张量并行,其次是进一步结合流水线并行。在计算资源丰富的情况下,进一步结合ZeRO数据并行实现3D并行,多张GPU并行训练。
在单卡显存不足时,还可以结合一些小技巧,例如CPU offload 技术,将计算的中间激活结果暂时放到内存(CPU)中,需要的时候再放回显存(GPU)中,用额外的通讯开销换取显存;或者采用checkpointing (recompute),在前向传播时,删除一些暂时用不到的中间激活结果以降低存储空间,在反向传播时,再根据需要临时进行前向计算或者从checkpoint中加载。
方法
分布式训练
一机配多张显卡——数据拆分,分成多份,分到多个显卡上,在显卡上统一跑一遍算法,然后把所有显卡上算出来的结果平均一下再去调整参数,进行第二轮训练
多台机器——涉及到不同机器之间的通信,一台机器的几块显卡之间,这属于内部通信,需要合理的拆分方案
模型拆分——横向把模型的一层拆分掉,分给多个显卡或者多台机器来运算,然后统一计算出结果,再反馈给模型的下一层,如果还不行,那就只能从纵向再拆分一次,把不同的层也拆分到不同的机器里
问题
会产生分布式运算问题,通信问题、算子优化问题等等
三、对齐
目的:
该步骤的目的是使模型和人类对齐。通过使用用户的真实反馈对模型训练(SFT / RLHF),使LLM的输出更符合人类偏好,并与用户意图保持一致。这既包括明确的意图,如遵循指示,也包括隐含的意图,如保持诚实,不偏见,或其他有害的价值观。最关键的是步骤是收集真实多样的指令以及回复,得到指令跟随数据集(问答形式)。同时,可以混合一些对话形式的指令跟随数据(把之前发生的所有对话都写进下一个问题的提示中),让LLM能够以对话形式和用户交流。
ChatGPT训练三阶段:预训练——补全、监督微调——对话、RLHF
例如InstructGPT,https://openai.com/research/instruction-following
prompt:
用几句话向 6 岁的孩子解释登月。
GPT-3:
向 6 岁的孩子解释重力理论。
用几句话向 6 岁的孩子解释相对论。
向 6 岁的孩子解释大爆炸理论。
向 6 岁的孩子解释进化论。
InstructGPT:
人们登上月球,拍摄了他们所看到的照片,然后将它们发送回地球,以便我们都可以看到它们。
GPT-3 模型未接受过遵循用户指令的训练。我们的 InstructGPT 模型(突出显示)会根据用户指令生成更有用的输出。
预训练主要针对补全能力。如果给预训练模型一个问题,比如“How to make pizza”(如何制作比萨),以下任何一种都是有效的补全:
1、给问题添加更多上下文:“for a family of six(为一个六口之家)”
2、添加后续问题:“? What ingredients do I need? How much time would it take?(?需要哪些配料?需要多长时间?)”
3、给出实际答案
如果你只是想知道如何制作,那么第三个选项是首选。SFT的目的就是优化预训练模型,使其生成用户所期望的回答。
如何做到这一点?我们知道模型会模仿其训练数据。所以在SFT阶段,我们向语言模型展示了不同使用情况下如何恰当回答提示的示例(例如,问答、摘要、翻译),这些示例都遵循一定格式(提示,回回答),被称为演示数据。OpenAI将SFT称为行为克隆(behavior cloning):你向模型展示应该如何做,而模型则克隆这种行为。
用于微调InstructGPT的提示分布
要想训练模型来模仿演示数据,你可以从预训练模型开始微调,也可以从头开始训练。事实上,OpenAI已经证明,InstructGPT模型(13亿参数)的输出比GPT-3(1750亿参数)的输出更受欢迎。微调方法产出的结果更为出色。
OpenAI的40名标注者为InstructGPT创建了大约13,000个演示对(提示,回答)。以下是一些示例:
提示
|
回答
|
---|---|
“Serendipity(机缘巧合)”是指某件事情在偶然的情况下发生或发展,并以快乐或有益的方式进行。请用“Serendipity”造句。 | 偶遇Margaret,并将其介绍给Tom,这是一次Serendipity。 |
用通俗易懂的语言解释:为什么在压力大或情绪低落时,我们会感到胸口有种“焦虑结块”的感觉? | 喉咙中的焦虑感是由于肌肉紧张导致声门张开,以增加气流。胸部的紧绷或心痛感是由迷走神经引起的,迷走神经会让器官加快血液循环,停止消化,并产生肾上腺素和皮质醇。 |
根据此食谱创建购物清单:修剪西葫芦的两端, 将其纵向切成两半;挖出果肉,留下 1/2 英寸的壳,切碎果肉。在平底锅中,用中火煮牛肉、西葫芦果肉、洋葱、蘑菇和彩椒,直到肉色不再粉红,再沥干水分,离火;加入1/2杯奶酪、番茄酱、盐和胡椒,充分搅拌;将13×9英寸的烤盘涂油,用勺子将混合物舀入西葫芦壳中,再放入烤盘;撒上剩余的奶酪。 | 西葫芦、牛肉、洋葱、蘑菇、辣椒、奶酪、番茄酱、盐、胡椒 |
监督微调不仅可以使模型更好地回答问题,还可以对模型的输出进行更精确的控制,以避免产生不适当、不安全或有害的内容,如暴力、色情等。通过为模型提供明确的、不含这些内容的标注数据,你可以训练模型避免生成这些不适当的内容,并更好地符合用户的预期和需求。
四、RLHF人类反馈的强化学习
RLHF(Reinforcement Learning from Human Feedback)是一种强化学习方法,其中模型通过从人类反馈中学习来改进其性能。这种方法的核心思想是使用人类提供的反馈作为奖励信号,来引导模型进行更好的学习。RLHF是解决那些难以为其定义明确奖励函数的问题的一种方法
RLHF在两种场景下特别有用 :
第一种情况是当你无法创建一个好的损失函数时
例如,在语言生成任务中,人们很难定义出“正确”的输出是什么,因为它往往具有很大的灵活性和多样性。在这种情况下,通过人类反馈进行强化学习可能是一种更合适的方法,因为人类可以直接提供关于系统行为的反馈,而无需定义一个复杂的损失函数。
第二种情况是当您想要使用生产数据进行训练,但难以对生产数据进行标记时
例如,我们可以让模型生成一些文本,并请求人类阅读、理解该文本并向模型提供反馈。通过这种方法,模型可以在实际场景下学习,并根据人类反馈不断改进,以更好地满足生产需求。
基本步骤和概念:
-
初始模型训练:首先,你需要一个初始模型。这个模型可以是预训练的,或者是通过其他方法得到的。
-
收集人类反馈:使用初始模型在一些任务上生成输出,并请人类对其进行评估。例如,对于聊天机器人,可以展示模型的回答并询问人类评价者哪些回答是好的,哪些是坏的。
-
创建奖励模型:使用收集到的人类反馈数据,训练一个奖励模型。这个模型的任务是为模型的每一个可能的输出提供一个奖励值。
-
强化学习优化:使用上一步中的奖励模型,通过强化学习的技巧(如Proximal Policy Optimization)来优化你的初始模型。模型会尝试优化其输出,以获得最大的奖励。
-
迭代:为了进一步改进模型,你可以重复上述步骤,持续地收集人类反馈,更新奖励模型,然后进行强化学习优化。
RLHF的优点是它可以有效地解决那些难以直接为其定义清晰奖励函数的问题。通过人类的评估和反馈,模型可以学习复杂的任务,并在很多实际应用中表现得更好。
参考文档
百川2技术报告,https://cdn.baichuan-ai.com/paper/Baichuan2-technical-report.pdf
llama2技术报告,https://arxiv.org/abs/2304.08177
InstructGPT官方网站,https://openai.com/research/instruction-following
大模型训练技巧:https://zhuanlan.zhihu.com/p/635321983
万字长文全面解读LLM中的分词算法与分词器,https://zhuanlan.zhihu.com/p/626080766
大模型综述,https://arxiv.org/pdf/2303.18223.pdf
一文总结当下常用的大型 transformer 效率优化方案,https://zhuanlan.zhihu.com/p/623744798
chatGPT是在做什么,为什么它有效,https://waytoagi.feishu.cn/wiki/LnMOwmKIwihcRakRalcczNgrnjf?chunked=false