LLaMa2
LLAMA2:预训练+SFT+RLHF详解(官方)及对话指令SFT+LORA全流程记录(自己)
LLAMA2 训练流程:
- 先经过自监督学习训练,得到llama2基座模型
- 再经过SFT再有标签的数据上进行有监督学习训练
- 再进行RLHF,其中使用拒绝采样和PPO算法
- 在RLHF流程中,使用到由用户偏好数据训练得到的两个RM,对RLHF的模型评判,反馈训练
Pretraining
预训练阶段需要大量的数据,数据的量级往往是nT级别,通过预训练可以让模型学习到大量的知识。
训练数据
LLAMA2以LLAMA1中描述的预训练方法为基础,采用了optimized auto-regressive transformer。但是做了以下优化:1、进行了更鲁棒的数据清洗。2、更新了数据,使得总token数增加了40%(两万亿)。3、将上下文长度翻倍,并使用了grouped-query attention(GQA)来提高大模型推理的可扩展性。对比如下图所示:
关于GQA:在Transformer的decoder中每一个timestep都要将之前一个timestep的k,v保存到cache中,这就是KV Cache。这种方法对于小模型是没有问题的,但是遇到大模型的时候就行不通了——我们记transformer模型的层数为$l$,隐藏层维度为$h$,训练数据的批次大小为$b$,输入序列长度为$s$,输出序列长度为$n$,并且以fp16来保存KV Cache,那么KV cache的峰值显存占用大小为$2\timesb\times(s+n)\timesh\timesl\times2$其中第一个2表示k、v,第二个2表示fp16占用的2个bytes,稍微带入计算就知道这个大小仿佛是在开玩笑,因此必须对MHA方法进行改进,大致有两种改法,如下图所示:
首先是原始的 **MHA(Multi-Head Attention)**,QKV 三部分有相同数量的头,且一一对应。每次做 Attention,head1 的 QKV 就做好自己运算就可以,输出时各个头加起来就行。
而 MQA 则是,让 Q 仍然保持原来的头数,但 K 和 V 只有一个头,相当于所有的 Q 头共享一组 K 和 V 头,所以叫做 Multi-Query 了。实现改变了会不会影响效果呢?确实会影响但相对它能带来的收益,性能的些微降低是可以接受的。能带来多大的收益呢,实验发现一般能提高 30%-40% 的吞吐。收益主要就是由降低了 KV cache 带来的。实际上 MQA 运算量和 MHA 是差不多的,可理解为读取一组 KV 头之后,给所有 Q 头用,但因为之前提到的内存和计算的不对称,所以是有利的。
而 GQA 呢,是 MHA 和 MQA 的折衷方案,既不想损失性能太多,又想获得 MQA 带来的推理加速好处。具体思想是,不是所有 Q 头共享一组 KV,而是分组一定头数 Q 共享一组 KV,比如上面图片就是两组 Q 共享一组 KV。以上。
训练细节
设置 | 设置值 |
---|---|
架构 | standard transformer architecture (Vaswani et al., 2017) |
pre-normalization | RMSNorm (Zhang and Sennrich, 2019) |
activation function | SwiGLU (Shazeer, 2020) |
positional embedding | rotary positional embeddings (RoPE, Su et al. 2022) |
optimizer | AdamW (Loshchilov and Hutter, 2017) |
β1 | 0.9 |
β2 | 0.95 |
eps | 10 ^ −5 |
schedule | cosine learning rate schedule |
warmup | 2000 steps,decay final learning rate down to 10% of the peak learning rate |
weight decay | 0.1 |
gradient clipping | 1.0 |
tokenizer | bytepair encoding (BPE,Sennrich et al., 2016) && SentencePiece (Kudo and Richardson, 2018) |
vocabulary size | 32k tokens |
训练结果评估
作者对预训练模型进行了多种评估:
- 代码:评估了我们的模型在HumanEval和MBPP上的平均pass@1得分;
- 常识推理:我们评估了PIQA、SIQA、HellaSwag、WinoGrande、ARC简单和挑战、OpenBookQA和CommonsenseQA的平均得分。对于CommonsenseQA,我们评估了7-shot结果,对于其他所有基准测试,我们评估了0-shot结果;
- World Knowledge:我们评估了 NaturalQuestions 和 TriviaQA 的 5-shot 性能;
- 阅读理解:我们评估了在SQuAD、QuAC 和 BoolQ 上的0-shot平均值;
- 数学:我们评估了GSM8K(8个样本)和MATH(4个样本)基准测试的平均结果
- Popular Aggregated Benchmarks:我们评估了MMLU(5个样本)、Big Bench Hard(3个样本)和AGI Eval(3-5个样本)的整体结果。对于AGI Eval,我们仅评估英语任务并报告平均结果。
总的来说LLAMA2超过了所有的开源模型,但是在预训练阶段没有超过任何一个著名的闭源模型。
Supervised Fine Tuning
在SFT阶段的最开始,使用的是《Scaling instruction-finetuned language models》这篇论文中贡献的指令微调数据集。
作者发现现有的指令微调数据集虽然很多,但是在多样性和数据质量上都难以令人满意,通过实验作者发现只需要10^4这个量级的高质量、高多样性的指令微调数据就足以获得高质量的结果了,因此作者只构建了27540条指令数据(自己的注释以及对其他数据集的筛选)。此外,标注人员的标注质量会很大程度地影响模型的性能。作者用微调过的模型生成的指令跟标注人员手写的指令进行了对比,发现两者的质量相当。
设置 | 设置值 |
---|---|
schedule | cosine learning rate schedule |
initial learning rate | 2 x 10 ^ -5 |
weight decay | 0.1 |
batch size | 64 |
sequence length | 4096 tokens |
sample | 由一个 prompt 和一个 answer 组成 |
训练数据集 | 所有prompt和answer都拼接起来,用一个特殊的token将两者区分开 |
objective | 使用自回归目标,将来自prompt的token损失置零,只对answer token反向传播 |
fine-tune epochs | 2 |
LLAMA2分为基础版本和chat版本,这篇文章主要描述了基础版本,因此没有chat版本在对话数据上做SFT的描述。
Reinforcement Learning with Human Feedback
RLHF被应用在微调过的大语言模型上,目的是进一步让大语言模型的行为与人类偏好以及指令遵循一致。作者首先收集了人类偏好数据(对两个模型的输出进行二元选择,挑出喜欢的那一个),然后利用人类反馈训练一个奖励模型,最后用奖励模型微调大语言模型。
人类偏好数据收集
首先要求注释员编写一个prompt,然后根据提供的标准在两个模型响应中进行选择。为了最大化收集的prompt的多样性,给定prompt的两个响应是从两个不同的模型变体中采样的,并且改变了温度超参数。除了这种选择之外,还要求标注者对他们选择的回答和备选回答之间的偏好程度进行标注:明显更好,更好,稍微更好以及几乎没有区别。
奖励模型建模
以一个prompt和它的响应作为输入,输出一个代表响应质量的标量。由于safety和helpfulness在有些时候时冲突的,因此作者训练了两个不同的奖励模型,一个关注有用性,一个关注安全性。奖励模型是从预训练模型初始化来的,架构和超参数都完全一样,仅仅只将预测下一个token的分类头变成了预测质量评价标量的回归头。
作者将收集到的成对人类偏好数据转换为二元排名标签格式(即选择和拒绝),并确保所选响应的得分高于其余的响应。使用的损失函数是 binary ranking loss:
$$
\mathcal{L}_{ranking}=-log(\sigma(r_\theta(x,y_c)-r_\theta(x,y_r)))
$$
其中$r_\theta(x,y)$代表使用模型权重$\theta$对提示x和响应y进行评分的标量分数。$y_c$是注释者选择的首选回复,而$y_r$是被拒绝的对应回复。这个评分用于训练奖励模型,以将人类偏好转化为二元排名标签格式,并确保首选回复的得分高于被拒绝的回复。此外,由于作者设置了四种偏好程度,可以利用这些信息来明确教导奖励模型为具有更大差异的生成结果分配更不一致的分数,因此对损失函数进行了修改:
$$
\mathcal{L}_{ranking}=-log(\sigma(r_\theta(x,y_c)-r_\theta(x,y_r)-m(r)))
$$
$m(r)$是根据偏好评分来确定的离散函数。对于具有不同响应的对,使用较大的值,而对于具有相似响应的对,使用较小的值。
训练细节如下所示:
设置 | 设置值 |
---|---|
epoch | 1 |
maximum learning rate | 5 x 10 ^ -6(70B)&& 1 x 10 ^ -5(others) |
schedule | cosine learning rate schedule |
minimum learning rate | 10% of maximum |
warm up | 3% of total steps |
batch size | 512 pairs |
总的来说,meta的两个奖励模型要超过所有baseline模型,包括GPT-4.
迭代化微调
作者尝试了两种主要的RLHF微调算法:
- Proximal Policy Optimization(PPO)算法,由Schulman等人于2017年提出;
- Rejection Sampling fine-tuning :从模型中采样K个输出,使用奖励模型选择出最佳候选者,进一步使用选定的输出进行梯度更新。这种方法将获得最高奖励分数的样本视为新的标准,然后在这个新的排名样本集上进行模型的微调,加强奖励。
这两种 RL 的方法主要的区别在于:
宽度:在拒绝抽样中,模型对于给定的提示会探索K个样本,而在PPO中,只生成一个样本;
深度:在PPO中,训练的每一步中,样本是基于上一步梯度更新后的更新模型策略的函数。而在拒绝抽样的微调中,我们会对初始模型策略生成的所有输出进行抽样,以收集新的数据集,然后进行类似于SFT的微调。然而,由于我们应用了迭代的模型更新,这两种强化学习算法之间的基本差异变得不那么明显。
设置 | 设置值 |
---|---|
optimizer | AdamW |
β1 | 0.9 |
β2 | 0.95 |
eps | 10 ^ −5 |
weight decay | 0.1 |
gradient clipping | 1.0 |
fixed learning rate | 10 ^ -6 |
PPO batch size | 512 |
PPO clip threshold | 0.2 |
KL penalty | 0.01(7B,13B)&& 0.005(34B,70B) |
iterations | 200-400 |
作者给出了一个重要的结论:SFT不能替代RLHF(We posit that the superior writing abilities of LLMs, as manifested in surpassing human annotators in certain tasks, are fundamentally driven by RLHF, as documented in Gilardi et al. (2023) and Huang et al. (2023))。
System Message for Multi-Turn Consistency
作者详细描述了他们是如何通过Ghost Attention(GAtt)方法改进多轮对话一致性问题的。
在对话的场景下,我们通常需要设置system prompt,比如让他扮演xx角色,或者按照什么风格说话,作者发现几轮对话下来,模型容易忘记这样的“系统设定”。
假定有一个多轮对话数据集,用户和assistant之间交替对话,现将这个system prompt插入到每一轮对话中的用户消息中。然后用最新的RLHF模型从这个合成数据中选择样本,然后对于选择出来的样本,只在最开始保留system prompt,之前在每一轮对话中都插入了system prompt,现在要都移除掉,不然这个会跟之前模型RLHF以及SFT阶段不一致,为此,作者会把之前轮数的上下文的loss置为0(我的理解是依旧类似于SFT中把prompt的loss置为0)。最后,在训练过程中让模型根据这个新的样本数据进行微调,以便模型在后续的对话中能够继续遵循system prompt进行回答。
safety
略