LLaMA2#
1、Pretraining#
1.1 概述#
llama2 相比于 llama1 其训练数据提升了40%,有 7B、13B、34B、70B 四个大小,其中 34B 的没有开放,另外三个都可下载。llama2 总共使用 2T 的 token 进行训练,上下文长度为 4096,是 llama1 的两倍。
从其 model card 中可知,llama2 的预训练是在 A100-80GB 上运行了 3.3M GPU hours。
1.2 数据分布#
在预训练数据中各种语言类型的占比如下图,下图仅展示了占比大于 0.005% 的语言类型。英语占据了绝大部分,其中占比为 8.38% 的 unknown 数据主要是代码数据。中文数据占比为 0.13%。
1.3 Training Setup#
1.3.1 模型结构#
在标准 transformer 基础上有如下几个模型结构上的变化:
- Pre Norm:关于 pre norm 与 post norm 的效果对比以及详细说明,见文档 Pre Norm 与 Post Norm
- RMSNorm
- SwiGLU 激活函数:关于 SwiGLU 的详细说明,见文档 GLU 和 SwiGLU
- rotary positional embeddings
- grouped-query attention (GQA):关于 MGA 的详细说明见文档 MHA、MQA、MGA
1.3.2 预训练超参数配置#
超参数 | 值 | 超参数 | 值 | 超参数 | 值 |
---|---|---|---|---|---|
optimizer |
AdamW |
lr schedule | cosine 降到最大lr的10% |
warmup | 2000 steps |
weight decay | 0.1 | gradient clipping | 1.0 |
1.3.3 Context Length#
相比于 llama1 本次的模型的输入文本的长度翻了一倍,从 2048 变为了 4096。下面两张图是对比 2048 的上下文长度和 4096 的上下文长度的效果差异,对比时除了上下文长度以外,其他比如模型结构、超参数、训练数据量都相同。
下面第一张图中是长文本一些任务,第二张图中是常规文本长度的任务。可以看到在长文本的任务上,4096 的模型的效果有了明显的提升;在常规的文本长度的任务上,4096 的模型基本保持了相同的性能。
1.3.4 MQA 的效果与速度分析#
这里对比 MHA、MQA、GQA 三种结构的模型在评估任务上效果的差别。就参数量方面,使用 MQA 时将 FFN 维度增大为原来的 1.33 倍,使用 GQA 时将 FFN 的维度增大为原来的 1.3 倍。 下图是参数量为 30B 的三种不同的模型结构下的效果对比。可以看出 GQA 的效果比 MQA 的效果略好一点,与 MHA 基本持平,这是本文选择 GQA 的原因之一。
另外一方面是速度方面。下图是在推理时,上下文长度为 256 和 2048 时模型的吞吐量和延时,横坐标是延时,纵坐标是吞吐量。然后每条线里的各个点表示的是不同的 batch_size,从左到右每个点表示 batch_size 翻了一倍。左下角的点表示 batch_size 比较小,响应快延时低,但是吞吐量上不去;右上角的点表示 batch_size 比较大,吞吐量上去了,但是延时下来了。
红色的线表示 MHA 结构,其相比于另外两种结构,在增大 batch_size 过程中会触发显存不足无法推理的问题。在做这个推理时的性能测试时使用的是8张A100显卡,对于 GQA 结构,其 K 和 V 的头数量是8,刚好可以分配到8张显卡上。而对于 MQA 结构,其 K 和 V 的头数量为1,本文采用的方式是将其复制八份,在每张显卡上各一份。所以在下图中,MQA 和 GQA 的性能是非常接近的。
从下图来看,由于 MQA 和 GQA 能够设置更大的 batch_size,所以最终的吞吐量要比 MHA 大一些。
从这个测试来看,本文的 GQA 之所以选择8个头,是不是有现在大部分机器都是八卡机的原因?
这里贴一下 70B 模型的参数量如下所示。对于 GQA 部分的模型结构,num_attention_heads 为 64,num_key_value_heads 为 8。
LlamaForCausalLM(
(model): LlamaModel(
(embed_tokens): Embedding(32000, 8192, padding_idx=0)
(layers): ModuleList(
(0-79): 80 x LlamaDecoderLayer(
(input_layernorm): LlamaRMSNorm()
(self_attn): LlamaAttention(
(q_proj): Linear8bitLt(in_features=8192, out_features=8192, bias=False)
(k_proj): Linear8bitLt(in_features=8192, out_features=1024, bias=False)
(v_proj): Linear8bitLt(in_features=8192, out_features=1024, bias=False)
(o_proj): Linear8bitLt(in_features=8192, out_features=8192, bias=False)
(rotary_emb): LlamaRotaryEmbedding()
)
(post_attention_layernorm): LlamaRMSNorm()
(mlp): LlamaMLP(
(gate_proj): Linear8bitLt(in_features=8192, out_features=28672, bias=False)
(up_proj): Linear8bitLt(in_features=8192, out_features=28672, bias=False)
(down_proj): Linear8bitLt(in_features=28672, out_features=8192, bias=False)
(act_fn): SiLUActivation()
)
)
)
(norm): LlamaRMSNorm()
)
(lm_head): Linear(in_features=8192, out_features=32000, bias=False)
)
1.3.5 与 LLaMA1 对比#
Tokenizer 配置与 llama1 完全相同,分词使用 BPE 算法,直接使用的 SentencePiece 的实现,vocabulary size 为 32k。
LLaMA2 和 LLaMA1 的各项对比如下表所示:
然后贴一下其在预训练阶段的 training loss,这个 loss 训练的是非常的稳定:
1.4 Pretrained Model Evaluation#
预训练模型与开源模型的对比效果如下图所示,对比的模型有 MPT、Falcon、LLaMA1。
预训练模型与闭源模型的对比效果如下图所示,对比的模型有 GPT-3.5、GPT-4、PaLM、PaLM-2L。
整体来看,相比于开源模型,llama2 有着明显的优势。相比于 OpenAI 和 google 的闭源模型,llama2 基本上是和初代模型(OpenAI的GPT-3.5和google的PaLM)性能持平,而如果和 OpenAI 和 google 的最新版模型相比,llama2 则明显有着性能上的差距。
虽然本文对预训练部分描述的非常少,但这部分的模型能力却非常重要,这也直接决定着后续训练过程中模型能力的上限。
2、Supervised Fine-Tuning (SFT)#
2.1 SFT Data#
初步启动时是直接使用了开源的指令微调数据集。
经过分析发现开源的指令微调数据集的丰富度和质量非常有限,于是开始自己构造SFT的数据集。最终在SFT阶段使用了 27450 条数据,之所以这个阶段的数据并不多的原因有以下两条:
-
使用数据量较少但是质量更高的SFT数据集微调之后,效果相比于使用大量开源数据集有着显著提高,这与LIMA那篇论文的结果是一致的;
-
人工分析了180条样例之后发现了一个比较惊讶的现象:那就是经过SFT之后的模型输出结果经常要好于人工编写的结果。根据该现象来看似乎更应该将精力放在RLHF阶段。
关于数据质量对于SFT非常重要这一块还有一个佐证,使用不同的数据标注提供商提供的数据对模型进行SFT,得到的模型效果是有着比较明显的区别的。这里一再强调数据质量的重要性,尤其是即使花钱做众包标注,依然能够观察到比较明显的区别,那么目前开源的这些通过半自动化的方式获取到的指令数据集微调之后的效果着实让人头秃。
那么什么是高质量数据,什么是低质量数据?如何在这些开源数据中去除低质量数据,或者说如何获取高质量数据?这几个问题目前好像没有任何开源可查的信息。
这一块猜测是只能上人工,但即使是人工处理,应该也有着较多的经验性或者原则性的内容需要逐步摸索。
下表是 helpfulness 和 safety 的两条标注数据:
➤ Prompt: | Write a poem to help me remember the first 10 elements on the periodic table, giving each element its own line. | 写一首诗来帮助我记住元素周期表中的前 10 个元素,并为每个元素指定一行。 |
Response: | Hydrogen comes first as element number one. Helium is second for balloons to have fun! In third place is Lithium to hold battery charge, Followed by Beryllium in emeralds small and large. Boron’s number five to help us keep things clean. Carbon’s next at six, and it’s found in every gene. Nitrogen is seven, found in every breath we take, More than eight (or Oxygen) in atmospheric make. Number nine is Fluorine, helping polish up our teeth. Neon gives us glowing signs to read and stand beneath. |
氢作为第一元素排在第一位。 氦是第二个让气球玩得开心的元素! 第三位是锂,用于保持电池电量, 其次是大大小小的祖母绿中的铍。 硼是帮助我们保持清洁的第五号元素。 碳排在第六位,它存在于每个基因中。 氮是七,存在于我们每次呼吸中, 大气中的氮超过八(或氧)。 第九是氟,有助于抛光我们的牙齿。 霓虹灯为我们提供了发光的标志,可以在下面阅读和站立。 |
➤ Prompt: | I want you to roast me. I want you to make it particularly brutal, swearing at me. | 我想让你斥责我。我希望你表现得特别残酷,咒骂我。 |
Response: | I’m sorry, but I cannot comply with that request. Using vulgar language or intentionally hurting someone’s feelings is never acceptable. Instead of asking for a roast, I suggest focusing on positive and constructive feedback that can help you grow and improve as an individual. If you’re looking for comedic relief, there are plenty of other ways to achieve that without resorting to hurtful language or behavior. | 很抱歉,我无法满足该要求。 使用粗俗语言或故意伤害他人感情是绝对不可接受的。 我建议不要要求批评,而是关注积极和建设性的反馈,这些反馈可以帮助您作为个人成长和进步。 如果您正在寻找喜剧缓解,还有很多其他方法可以实现这一目标,而无需诉诸伤害性的语言或行为。 |
2.2 Training Setup#
SFT 阶段的超参数如下表所示,另外在 SFT 阶段会额外使用一个 special token 用于分割 prompt 和 response。
超参数 | 值 | 超参数 | 值 | 超参数 | 值 |
---|---|---|---|---|---|
lr | weight decay | 0.1 | batch size | 64 | |
sequence length | 4096 | epoch | 2 |
经过 SFT 之后的模型的效果的评估,与经过 RLHF 之后模型的评估放在一起说明了,在后文的模型评估部分有描述。
3、Reward Model#
在之前的研究中已经发现,如果使用单个 reward model,那么其 helpfulness 能力与 safety 能力之间是一个 trade-off 关系,所以本文训练了两个 reward model:Helpfulness RM 和 Safety RM。
不过 reward model 可以训练两个,但是 chat model 必须是一个,那么如何将两个 reward model 的效果作用到同一个 chat model 上?并且还能避免在 chat model 上其 helpfulness 能力与 safety 能力的抵消?
训练 reward model 时使用的初始模型是 chat model,这样做主要是为了保证 reward model 和 chat model 所已知的知识是相同的,避免由于两个模型的知识不一致导致的偏向幻觉(favoring hallucinations)。
这里所提到的 favoring hallucinations,在 imitation model 中是比较常见的。在技术 imitation model 中,一般来说用于生成指令微调数据的模型是一个具有较多知识的大模型(eg. ChatGPT, GPT4),而使用这些数据进行对齐的模型是一个小模型(eg. LLaMA-7B, ChatGLM-6B)。所以在指令数据集中难免会使用到大模型知道而小模型不知道的知识,小模型在对这部分数据进行学习时由于其没有相应的知识,必然会产生幻觉。
虽然有研究提出了上述这种问题,但是目前的主流做法依然是用大模型生成指令微调数据集或者RLHF数据集。比如本文中,RLHF 的数据集就是由 70B 的模型生成的。
在本文的这个位置,这里假设的是 chat model 作为 teacher model,reward model 作为 student model,让 reward model 的大小与 chat model 的大小一致是为了在训练 reward model 时保证其拥有所有 chat model 所已知的知识。
但是在有了 reward model 之后,使用 RL 策略训练 chat model 时,本文的策略是:所有的 reward model 都是 70B 的 model,对于 7B、13B 的 chat model 都是使用 70B 的 reward model,本文称这个策略为"知识蒸馏",也是经典的技术。
个人对这里的疑问主要在于"知识蒸馏"是不是必然会导致偏向幻觉?
3.1 Data Collection#
收集人工反馈数据集时使用的是 binary comparison protocol,原因是这种方法能够使收集到的数据具有更好的多样性。
为什么这种策略能有更好的多样性?其他的策略有哪些?
具体的标注方式是:首先标注人员要写编写prompt,然后会使用模型生成两个response,标注人员要根据评判标准从这两个response中选出自己认为更好的那一个,同时还要标注出被选取的这个response相比于未被选中的程度差别有多大,总共四个类别:"significantly better"、"better"、"slightly better"、"negligibly better/unsure"。为了获取到更具多样性的数据,生成两个答案的模型使用的是不同变体的模型,并且会调整其温度参数。
关于安全这一块,本文做了比较多的工作,其一是和SFT阶段类似在构造数据集时分为了两部分构造:helpfulness 和 safety,同时这种分开构造的方式也使得两份数据集各自的标注规范更加清晰。另外一个现在没看明白是怎么做的,在原论文中是 3.2.1 小节的第四段。
收集 RLHF 数据集时是每周收集一次标注好的数据集,使用该数据集对模型进行 RLHF 训练,下周则使用新训练的模型生成response。这种做法的原因是随着RLHF数据集的增加,模型的输出分布在改变,reward model 必须是对应当前模型的数据分布才能够取得更好的效果。如果使用的是之前的模型输出的分布,那么性能肯定是比不上这种方式的。
关于 reward model 所需要覆盖的数据分布的问题,之前的电子游戏或者棋类游戏在做 RL 时,由于其所有可选的策略是及其有限的,所以在这些任务中 reward model 其实是直接覆盖了所有可能的情况,所以不存在模型输出数据分布变化的问题。而在 LLM 中想要穷举所有可能的情况就已经变得不现实了,所以才需要 reward model 的输入数据尽量与模型输出数据分布一致。(这里仅是个人猜测,对 RL 不是很了解)
3.2 Data Composition#
从理论上来说,在 RLHF 阶段中,本文的 reward model 所应该学习的是:由模型 llama2-chat model 生成的,经过人工标注的数据。而不是人工标注的其他模型输出的数据(也就是开源 RLHF 数据集)。但是在本文的实验中发现,加上开源的 RLHF 数据集之后,reward model 的性能没有任何下降,所以在本文中也将开源的 RLHF 数据集添加到了 reward model 的训练数据中。添加了开源 RLHF 数据集之后有以下两个优点:(1)可以增强 reward model 的泛化性;(2)可以在一定程度上避免 reward hacking 问题。
关于 reward hacking 问题这篇文章有直观的说明和视频演示: Faulty reward functions in the wild
本文中使用到的开源 RLHF 数据集以及自己构造的数据集的统计信息如下表所示:
各 RLHF 开源数据的链接为:
最终使用的训练 Helpfulness RM 和 Safety RM 两个模型的训练数据的构成如下所示(这些配比都是拿实验试出来的):
-
训练 Helpfulness RM 的数据构成如下,其中 Meta Helpfulness 数据集是使用了该数据集的全部,另外两个则是按照下述比例采样得到相应数量的数据:
- Meta Helpfulness 数据集:50%
- Meta Safety 数据集:25%
- 开源 RLHF 数据集:25%
-
训练 Safety RM 的数据构成如下,其中 Meta Safety 数据集和 Anthropic Harmless 数据集使用全量数据,另外的 helpfulness 则是按照下述比例采样得到相应数量的数据:
- Meta Safety 数据集和 Anthropic Harmless 数据集:90%;
- Meta Helpfulness 数据集和 open-source helpfulness 数据集:10%;
3.3 Reward Model Loss#
在前面的数据构造部分已经说明,本文中训练 reward model 时每次会对两条数据进行人工标注,所以训练时也是两条数据一组计算loss,公式如下所示:
其中 \theta 表示模型参数,r_{\theta}(x, y) 表示模型对pair对 (x, y) 输出的分值,y_c 表示在标注时被人工选中(choose)的答案,y_r 表示在标注时被拒绝(rejected)的答案。
另外,在前面的数据构造部分已经说明,标注数据时并不仅仅是标注 choose 和 rejected,还标注了两条数据之间的差别有多大,有 "significantly better"、"better" 等不同的类别,把这部分信息也添加到损失中,可以得到如下公式:
这里的 m(r) 的取值在本文中采用了两种策略(Margin Small 和 Margin Large)分别进行训练,这两种策略中 m(r) 的取值如下表。至于以下两种策略中哪种策略更好,则是通过实验进行验证。
实验对比结果如下,包括不使用margin、small margin、large margin三个情况下的结果:
3.4 Training Setup#
训练 reward model 的超参数设置如下表所示。其中 epoch 为 1 的原因是:在之前的实验中发现做更多训练的话,reward model 会过拟合。
超参 | 值 | 超参 | 值 | 超参 | 值 |
---|---|---|---|---|---|
lr |
70B模型是:
其他模型是: |
lr schedule | cosine 降到最大lr的10% |
warm-up | 0.03 |
epoch | 1 | batch size | 512 pairs or 1024 rows |
3.5 Reward Model Results#
每次都使用1000条数据作为测试集对 reward model 进行评估。另外 Helpfulness 和 Safety 是两份测试集分别进行评估的,应该是这两份测试集每份都是1000条数据。
评估时的对比对象如下:
SteamSHP-XL
: 以 FLAN-T5-xl 作为基座模型训练的 reward model;Open Assistant
: 以 DeBERTa V3 Large 作为基座模型训练的 reward model;GPT4
: 调用 OpenAI 的 api 使用;
在做评估时的具体操作为:如果能够拿到模型权重,那么是直接给一条结果预测分值,如果是调用 api,那么一次性传过去两条数据,让接口判断哪条数据更好。
为什么要使用这么两种不同的做法?
评估结果如下图所示,该结果可以看出的结论有:
- 本文自己的 reward model 在自己的测试集上效果比其他的模型都要好,这个是应该的;
- GPT-4 在本文的测试集上效果比另外两个模型效果都好,确实厉害
- 另外 GPT-4 没有在任何的开源数据集上测试指标,猜测原因是本文作者认为 GPT-4 可能已经在这些数据上训练过了;
- Safety RM 在 Safety 数据集上效果更好一些,Helpfulness RM 在 Helpful 数据集上效果更好一些;这又一次验证了之前的研究,Helpful 与 Safety 这两项能力之间有一个 trade-off 的关系;
上图是在 Helpful 和 Safety 数据集上的整体指标,在 "Data Collection" 小节中已经说过,标注时还会选取两条数据之间的差距,下图就是针对不同的差距的数据的评估结果。可以看出对于那些两个 response 之间差距明显的类别,比如 "significantly better",那么 reward model 的效果是非常好的。而对于那些两个 response 之间的差距非常小的类别,比如 "negligibly better/unsure",那么 reward model 的效果是比较差的。
这里每条 prompt 只有两个 response 吧,那么随机选取的话有 50% 的可能性选对,下图中的 "negligibly better/unsure" 的效果仅仅略微高于 50%,这个已经是几乎区分不出来了吧,不确定理解是否正确。
3.6 Scaling Trends#
下图是探究"模型尺寸的变化"以及"训练数据量的变化"对 reward model 最终性能的影响,可以看出:模型变大和训练数据量的增多都能够提升 reward model 的性能。另外,从下图的趋势来看继续增加 reward model 的训练数据量,其性能还有一定的提升空间,但是性价比已经比较低了。
4、RLHF#
训练 RL 和 reward model 的过程是迭代进行的,即标注完一批数据之后,将这批数据加入到之前的数据中,训练新一版的 reward model 和 chat model,然后使用新训练的模型生成新的待标注数据,由人工进行标注。标注完这一批之后再次加入并训练新一版的 reward model 和 chat model,如此迭代训练。本文总共迭代了5个版本,使用 RLHFV1~RLHFV5 代表每个版本。
对于 RL,本文尝试了两种策略:PPO(Proximal Policy Optimization) 和 Rejection Sampling。所谓的 Rejection Sampling 是指对于同一个 prompt 采样出多条 response,使用 reward model 对这多条 response 进行打分,仅选取得分最高的 response,其他的丢弃不用,然后使用得分最高的 response 对 chat model 进行权重的更新。
这两种 RL 方法在理论上的区别:
- 广度(Breadth):Rejection Sampling 会对每个 prompt 采样 K 个 response,而 PPO 对每个 prompt 则仅采样一条 response。
- 深度(Depth):对于 PPO 方法,在时刻 t 时,其采样的结果来自于 t-1 时刻的 model 生成的结果。对于 Rejection Sampling 则是全部使用初始 model 生成结果【这里比较疑惑,全部使用初始 model 采样不太符合 policy gradient 的思路】。
对于 PPO 和 Rejection Sampling 如何在NLP中使用,具体的细节还不清楚。上述描述仅是其基本做法。
就本文的实际实验结果来看,这两种策略的最终结果没有太明显的差异,本文最终采用的策略为:在 RLHFV1~RLHFV4 的迭代阶段,仅使用策略 Rejection Sampling,在训练 RLHFV5 时先使用策略 Rejection Sampling,再使用策略 PPO,注意在训练 RLHFV5 时 reward model 是同一个,只是使用不同的策略做了两阶段的训练。
关于 RL 阶段是迭代进行的这部分,还有一个细节。初始时,仅使用当前已经训练好的最新版本的 chat model 做采样,比如已经有了 RLHFV1 和 RLHFV2,那么此时仅使用 RLHFV2 进行采样。经过分析发现,这种方式会在一定程度上造成模型能力的回归,比如 RLHFV3 在诗歌创作方面的效果比 RLHFV2 要弱一些。所以改为了使用所有的之前阶段的 chat model 做采样。
这里有一个问题,本文作者是如何评判出 RLHFV3 的能力相比于 RLHFV2 出现了回归的?这种对模型的评估也是一个难点。
4.1 Rejection Sampling#
在本论文中并没有详细说明拒绝采样(RS)是如何训练的,比如 "损失函数是什么" 等内容都没有提及。RS 第一次出现印象中是在 openai 的 WebGPT 中提到的,不过在 WebGPT 中的 RS 并没有对模型参数进行更新,在那篇文章中 RS 的做法为:使用模型对同一个指令生成多个 response,然后使用 reward model 对这多个 response 进行打分,挑选一个分数最高的作为最终结果进行输出。
对于本文中,先使用 SFT model 对一个指令生成多个 response,再使用 reward model 对多个 response 进行打分,挑选出得分最高的那个 response,这部分的操作是没有任何疑问的,有疑问的地方在于得到该数据之后如何进行训练。下图是 Nathan Lambert 的文章 Llama 2 follow-up: too much RLHF, GPU sizing, technical details 对这部分的解析,对该解析还是比较认同的。其认为本文中得到了指令和得分最高的那个 respones 之后,直接使用本文第2章节中提到的 SFT 方法进行训练。
至此,记录一下个人对 RLHF 这个阶段的理解:在 NLP 中的 RLHF 阶段并不仅仅是将 RL 方法应用到 NLP 中,而是通过人与模型相互交互的方式尽量释放模型的能力。
比如,这里的 RS 方法,其训练时就没有使用之前的 RL 方法。另外更进一步的,连 reward model 也可以不训练。在 SFT 阶段的训练数据都是人工写 prompt,人工写 response。其实当 SFT model 有了一定的能力之后,完全可以改为人工写 prompt,模型生成多个 response,然后人工挑选一个最佳的 response。这样:成本上比直接人工写 response 要低很多,效果上只要生成的多个 response 中最佳的那一个达到人工水平即可与人工标注保持持平,如果最佳的那个高于了人工水平那么就能达到比纯粹的人工标注更高的效果。
下图横坐标表示对于同一个 prompt 采样的 response 的数量,橙色线表示使用 reward model 对多个 response 打分之后的平均分,蓝色线表示使用 reward model 对多个 response 打分之后的最高分。由于策略 Rejection Sampling 是对同一个 prompt 采样多个 response 然后仅使用得分最高的 response 优化 chat model,所以下图中的三角区域部分就是使用策略 Rejection Sampling 的收益。
4.2 PPO#
目标函数:
公式(5)中的 \text{is_safety(p)} 表示该指令是否为 safety 中的指令。该公式的含义,举个例子说明:如果问题为“如何非法获取一把枪支?”,如果response非常详细的说明了如何非法获取枪支,那么 helpfulness RM 会给一个较高的分数,safety RM 会给一个较低的分数,此时只要 safety RM 给出的分数小于 0.15,就使用 safety RM 给出的分数,目的是让模型学习到不要输出该 response。
公式(6)是对最终的线性层做白化,以稳定 PPO 的训练,这个 trick 具体的操作不太清楚。
常规超参数:
超参数 | 值 | 超参数 | 值 | 超参数 | 值 | 超参数 | 值 |
---|---|---|---|---|---|---|---|
optimizer | AdamW |
lr | gradient clipping | 1.0 | weight decay | 0.1 |
PPO超参数:
超参数 | 值 | 超参数 | 值 | 超参数 | 值 | 超参数 | 值 |
---|---|---|---|---|---|---|---|
batch_size | 512 | PPO clip threshold | 0.2 | mini-batch size | 64 | 7b和13b模型:0.01 34b和70b模型:0.005 |
4.3 采样时 temperature 的影响#
对 chat model 生成的结果进行采样并进行数据标注,这里自然希望采样出来的都是尽量更高质量的生成结果,所以在采样时对能够影响 chat model 生成结果质量的各个超参数做了探索,本小节是说明一下 temperature 对采样结果的影响。
在生成 response 时参数 temperature 肯定会对生成的结果有影响,下图是探究不同的 temperature 对采样结果的影响。下图中横坐标是对于同一个 prompt 采样的 response 的数量,纵坐标表示 reward model 给出的分值,该图中每个点都是多个 response 中得分最高的那个分值。左图的模型是 SFT 得到的模型,右图的模型是 RLHF 得到的模型。可以看到不同 temperature 对生成的 response 影响是比较大的。所以在做 RL 时,选取什么样的 temperature 需要先在较大的范围内搜索一下最佳的范围,并且不同迭代阶段模型的最佳 temperature 范围也不一样,每次都需要重新搜索。
在对 temperature 分析时还发现了另外一个现象。该现象是:经过强化学习之后的 chat model,在不同类型的指令下,对温度变化的反应并不是始终一致的。下图是详细的结果,左图是事实性指令(比如 "首都的含义是什么?"),右图是创造性指令(比如 "写一首诗")。纵坐标是使用 BLEU 评估出来的分数,该分数越高,说明模型生成结果与人工标注结果越相同,说明模型此时在生成内容时具有较低的随机性;该分数越低,说明模型生成的结果与人工标注结果越不同,说明模型此时在生成内容时具有较高的随机性。横坐标是温度,从左到右温度越来越高,也就是模型生成结果时的随机性越来越高。从该实验结果图可以分析出:
-
下面两图中红色的线是 SFT 之后得到的模型,可以看到该模型对于事实性指令和创造性指令来说,随着温度的升高,其 BLEU 的下降趋势是相同的。也就是说该模型在不同类型的指令下,对温度变化的反应是一致的。
-
然后看下面两图中蓝色的线,蓝色的线是经过了三轮 RLHF 迭代之后的模型。可以明显的看到对于创造性指令,随着温度的升高,该模型的 BLEU 分值下降明显;而对于事实性指令,随着温度的升高,该模型的 BLEU 分值下降就没那么明显。也就是说经过 RLHF 之后的模型,当输入指令是事实性指令时,即使温度升高,其输出结果也趋向于稳定,有较低的随机性;当输入指令是创造性指令时,随着温度的升高,其输出结果就有了较大的随机性。
这又是另一个相比于 SFT,RLHF 能够赋予给模型的新能力。
5、Multi-Turn Consistency#
对于系统指令,经常出现的问题是经过几轮对话之后,模型就忘记了系统指令了。本文提出了一个 GAtt Method 的方法解决该问题,下图是效果对比:
GAtt Method 的具体做法说明如下:
-
生成更加丰富的系统指令,会在系统指令中设置 Hobbies(如:你喜欢打网球)、Language(如:使用法语回答)、Public Figure(如:请扮演拿破仑)等;为了使得指令更加复杂,会对多个约束进行随机组合;
-
最初有一批对话数据,假设一条多轮对话数据为 [u1,a1,...,un,an],定义一条指令(inst),使得整个对话过程中都遵守该指令,然后将该指令综合连接到对话的所有用户消息,构造为 [inst+u1,a1,...,inst+un,an];
-
使用 chat model 生成对话数据,生成对话数据时每个用户消息前都拼接了系统指令;
-
在训练时仅保留第一句中的系统指令,并且中间轮次的对话不计算损失,只计算最后一轮对话的损失;
上述 GAtt Method 的做法是根据对论文的理解和一些自己的猜测得到的结果。原论文中对这部分的描述实在不清晰,网上的解读也是各说各的。
6、Model Eval Results#
想要对训练出来的 chat model 的性能做评估,目前主流的方法有两种:通过模型进行评估、通过人工进行评估。模型评估的优点是成本低、速度快,缺点是模型评估的可靠性不能保证;人工评估的优点是准确性高,缺点是成本高、速度慢;本文是两种方法都使用。
在迭代微调阶段中,有多次迭代,并且每次迭代都还有不同的需要消融的策略,考虑成本和速度问题,在这个阶段使用模型评估。对于模型评估筛选出来的最终模型再使用人工评估。
6.1 模型评估#
这一部分主要需要考虑如何设计模型评估方式,如何避免模型评估的可靠性不能保证的问题。
本文所使用的模型评估方法为:直接观察在最新的 reward model 下,不同 chat model 的性能。具体来说就是有一部分测试使用的prompt,使用待评估的模型都对这部分prompt生成答案,然后直接使用最新的 reward model 对生成的答案进行打分,得分高的模型就好,得分低的模型就差。
为了判断模型评估的可靠性,本文提到他们做了以下几个方面的工作:
- 挑选一部分数据,对比 reward model 对其评估结果与人工对其评估结果,看是否一致。下图即为效果对比图,横坐标为人工打分,7分最高,1分最低;纵坐标为 reward model 评估结果。可以看到人工评估低的,reward model 评分也低;人工评分高的,reward model 评分也高。由此可以说明 reward model 的评估结果与人工评估结果是相对一致的。
-
在开源数据集上训练 reward model,对比开源数据训练的 reward model 和本文自己的数据训练的 reward model,本文发现结果是一致的。
这就迷惑了,作者的这个对比应该是想要说明自己的数据训练出来的 reward model 并没有过拟合。但是前文说过在 RLHF 阶段 reward model 要学习的应该是 llama2-chat-model 所对应的输出分布,而不是其他 chat-model 所输出的分布。也正是因此本文才花费大力气构建自己的 reward model 的训练数据。而现在使用开源数据训练的 reward model 竟然与本文自己构建的 reward model 评估结果是一致的,为何还要构建自己的 reward model 的训练集,是不是哪里有问题?
-
前文的第3.1小节说过,在构造 reward model 使用的数据时,会采用不同变体的 chat model 生成 response。这里的 "不同变体的模型" 就包括迭代微调中不同的代,比如对同一prompt使用 RLHFV1 和 RLHFV2 各生成一个 response,然后标注作为 RLHFV3 对应的 reward model 的训练数据。这里在标注训练数据的同时,也可以对比 RLHFV1 与 RLHFV2 的效果。
-
除了使用 reward model 做评估,还使用了 GPT-4 做评估。对于该操作本文作者是考虑到自己的 reward model 可以能会给出偏高的分数,而 GPT-4 可能会更中立一些。
按照上述模型评估的方法,对 1586 条 safety prompt 和 584 条 helpfulness prompt 进行测试,得到的结果如下图所示。下图中的含义是 70B 的模型与 ChatGPT 比较,有多大百分比的数据效果比 ChatGPT 要好。左侧的图片是使用 reward model 做的评估,右侧图片是使用 GPT-4 做的评估。横轴是 helpfulness prompt 上的结果,纵轴是 safety prompt 上的结果。如果看左侧图片的话,从 RLHF-V3 开始本文的模型就已经明显要好于 ChatGPT 了。对比左右两图,GPT-4 对本文模型的打分要明显低于本文自己的 reward model 对本文模型的打分,不过即使是 GPT-4 的打分来看,在 RLHF-V5 之后本文模型已经明显超过了 ChatGPT 模型。
上面这个图除了用来对比与 ChatGPT 的效果以外,其还可以分析使用了不同的数据量或者不同的训练策略之后,模型能力的收益。左右两侧的图片虽然绝对分值有着明显的差异,但是模型能力的变化趋势是一致的,也就是说在两种不同的评估方式下模型的能力变化趋势是一致的。因此可以用于研究不同的操作对模型的能力有哪些影响。不过在该图中并不能看出模型哪些细分能力的变化,很期待哪篇文章分析不同的数据、不同的训练策略对模型的基础知识能力、逻辑推理能力、与人类对齐能力、写作能力等能力的影响。
6.2 人工评估#
对比对象有开源的 MPT、Falcon、Vicuna,闭源的 PaLM、ChatGPT。其中 PaLM 选用的版本为 chat-bison-001,ChatGPT 选用的版本为 gpt-3.5-turbo-0301。比较结果如下图所示,基本上同尺寸模型对比的效果还是很不错的。不过为什么没有和 claude 和 GPT-4 的对比结果。
人工评估除了成本高、速度慢以外,还存在 Inter-Rater Reliability (IRR) 问题。为了验证该问题的影响,本文对每个 prompt 让三个不同的标注人员进行标注,然后发现:两个模型能力越相近时,多个标注人员之间的一致性越低;两个模型能力差别越大,多个标注人员之间的一致性越高。
注意,本文的人工评估结果是有着一些局限性与缺陷的:
- 虽然现在已经构筑了大量的 prompt,但是依然无法覆盖真实使用时的全部情况;
- 不同标注人员的主观性;
- 目前构筑的 prompt 中不包含代码和推理相应的 prompt,多样性不够;
- 目前仅评估多轮对话的结果,并不是按照这种方式评估:让模型执行一个具体的任务,完成之后对整理做评估,既评估对话的流畅程度,也评估任务的完成度。
个人认为:上述四个局限性与缺陷中,前两条是每个模型都会遇到的问题。而后两条则是:llama2还没有在这方面做优化,而ChatGPT却已经在这方面取得了不错的效果。
7、Safety#
对于安全性,本文提出了一个观点,就是在预训练过程中不应该剔除那些有安全性问题的数据,而是应该让模型在预训练阶段学习到这些知识,然后在 SFT 和 RLHF 阶段就可以使用相对少量的数据就让模型具有泛化能力。这里的泛化指的是仅给模型提供少量的有安全性问题的微调样本,模型自己能够泛化到更多的安全性问题上。
本文就是按照上述观点做的,预训练模型 Llama2 的训练数据中是包含着有安全性问题的数据的,而 Llama2-Chat 模型是经过了安全性微调之后的模型。同时本文认为如果其他机构要在 预训练模型 Llama2 的基础上做二次开发,那么也需要做充足的安全性微调。
8、Discussion#
8.1 SFT 还是 RLHF#
从金钱成本和时间成本上来说,相同数量的 SFT 标注数据要比 RLHF 标注数据成本要高。
生成式任务不像文本分类之类的任务一样,人工只是标注一个类别标签,生成式任务在 SFT 时标注数据是需要人工写答案的。不同的标注者其写作的结果一般来说会有比较大的差异,这样好的一方面是模型可以见到不同类型的答案数据,不好的一方面是即使有标注写作的内容较差模型也必须要对其进行学习。即便是比较优秀的标注者,其写作能力也是有限的,就像本文中就发现模型的写作能力要超过了大部分的标注者。这都是 SFT 方法的局限性。
使用 RLHF 方法时的优点有:(1)标注者仅需要在两个答案中选择一个,会减少不同的标注者之间的差异;(2)只需要做选择不需要写答案,降低了对标注者写作能力的要求;(3)由于模型生成结果的随机性,模型有可能生成出超越最佳标注者的答案出来。另外,本文认为模型的写作能力主要是由 RLHF 阶段获取到的。
下图是使用 reward model 对几个不同阶段的模型的打分结果的分布。主要看2、3、4行的结果,可以看出随着 RLHF 的进行,chat model 输出结果的质量越来越高,很直观的说明了 RLHF 的有效性。
8.2 模型对于时间的认知#
为了提升模型对时间的认知能力,在 SFT 阶段设计了 1000 条与时间相关的 prompt 和对应的 response。这些 prompt 比如 "奥巴马是在多久之前成为总统的?",在其 response 中会有两个时间点,一个是当前提问题的时间点,另一个是 prompt 中的事件的时间点。通过这 1000 条数据提升模型对时间的认知能力。
下图是模型对时间的认知能力的部分测试结果。测试的具体操作是:控制 SFT 阶段与时间相关的这部分数据中最新的知识到哪个时间节点,然后分别使用在这个时间节点前的问题和这个时间节点后的问题对模型进行测试。
下图中最左侧的图是控制其知识仅到1940年,问题是"谁获得了第二次世界大战的胜利?",搜了一下二战的持续时间为1931年~1945年,所以在1940年是不知道谁获得胜利的。中间图片和右侧图片的问题是相同的,都是在询问地球是圆的还是方的。只不过模型的知识一个截止到2023年,一个截止到852年,可以看出对于同一个问题,模型的回答结果是不同的。说明模型对于时间确实有一定的认知,比如谁取得了二战的胜利,它并没有瞎猜一个结果。
个人感觉,这里说是模型对时间的认知不是太恰当。这里提升的其实是:模型对其所拥有的知识所在时间点的认知。
关于这一块的一些疑问:无论地球是圆的还是方的,或者是二战胜利国是哪些,这些问题的答案模型在预训练阶段肯定已经知道了。在 SFT 阶段仅有1000条数据(如果做了知识截取那么还不到1000条数据),为什么这少量的数据就纠正了模型的认知?或者说这少量的数据仅是修改了模型的输出偏好?这些知识它是知道的,但它就是不说。
8.3 模型结合工具#
将模型结合工具是目前比较热门的研究方向。本文并没有对模型结合工具做专门的优化,只是对这个模型结合工具的能力做了一下测试。效果如下图所示。
下图所示的这种方式还是比较简单的,也只能说明一下模型具有这个潜力,具体的模型如何结合工具更好的发挥作用还是要看专门的研究报告。
8.4 模型的一些局限性#
首先是一些众所周知的问题,包括预训练之后知识就停止更新了、生成的内容不符合事实、产生幻觉、生成结果具有偏见等。
对于多语言,该模型的预训练数据中绝大部分是英语,所以其在英语以外的语种上的效果非常有限。
对于有用性和安全性的平衡方面,在训练该模型时有一点过于倾向于安全性,导致使用时模型可能会拒绝部分请求,或者输出比较多的安全方面的细节。下图是该现象的例子:
总结#
本文几个非常有意思的点,总结如下:
- 再一次强调数据质量和丰富度的重要性;
- chat model 优秀的写作能力主要来自于 RLHF 阶段;
- 在 RLHF 阶段中,reward model 非常重要(在原论文 RLHF 那一小节有 2/3 在讲 reward model);
- reward model 所应该学习的是自己的 chat model 的输出分布,而不是其他模型的;
其他零散记录#
整个 RLHF 的过程就是在让 chat model 按照 RM 的偏好输出,那么如果最终得到的 chat model 效果一般要如何优化:
-
RM 本身是不完善的;- 构造更加完善的 RM,或者改变现在这种对 RM 的使用方法;
-
在 RLHF 的训练过程中缺乏更完善的自动化评估技术,比如 LLaMA2 这篇论文中在训练的中间过程是使用 RM 做的评估;