大模型训练流程
预训练阶段
Tokenizer Training
选择一个预训练的模型基座、并进行词表扩充
Language Model PreTraining
Pretraining 的思路很简单,就是输入一堆文本,让模型做 Next Token Prediction 的任务
预训练过程中所用到的方法:数据源采样、数据预处理、模型结构
数据源采样
规模大的数据集少训练,规模小的数据集多训练,这样一来就能使得模型不会太偏向于规模较大的数据集,从而失去对规模小但作用大的数据集上的学习信息。
数据预处理
数据预处理主要指如何将「文档」进行向量化,就是如何拆文章呗。
通常来讲,在 Finetune 任务中,我们通常会直接使用 truncation 将超过阈值(2048)的文本给截断,
但在 Pretrain 任务中,这种方式显得有些浪费。
以书籍数据为例,一本书的内容肯定远远多余 2048 个 token,但如果采用头部截断的方式,
则每本书永远只能够学习到开头的 2048 tokens 的内容(连序章都不一定能看完)。
因此,最好的方式是将长文章按照 seq_len(2048)作分割,将切割后的向量喂给模型做训练
模型结构
为了加快模型的训练速度,通常会在 decoder 模型中加入一些 tricks 来缩短模型训练周期。
数据集清理
这是干啥?继续构建数据集?
模型效果评测
关于 Language Modeling 的量化指标,较为普遍的有 [PPL],[BPC] 等
指令微调阶段(Instruction Tuning Stage)
预训练任务的本质在于「续写」,而「续写」的方式并一定能够很好的回答用户的问题。
用户问题 | 用户预期回答 | 模型续写结果 |
《无间道》的主演有哪些? | 刘德华、梁朝伟 | 《无间道》的主演有哪些?不少观众期待看到阵容公告,今天小编... |
但是这并不代表模型不知道,可以:
用户问题 | 用户预期回答 | 模型续写结果 |
《无间道》的主演有 | 刘德华、梁朝伟 | 《无间道》的主演有刘德华、梁朝伟和黄秋生,而这部电影也是香港警匪片的代表作之一。 |
这就是 Instruction Tuning 要做的事情,即指令对齐。
Self Instruction
通过 ChatGPT 的输入输出来蒸馏自己的模型,让ChatGPT自己想问题,并自己生成答案
相关项目:英文项目Alpaca和中文项目 [BELLE]
模型的评测方法
比起预训练(Pretrain)环节里相对明确的评价指标(如PPL、NLL等),
Instruction 环节中的评价指标。。。。
一种比较流行的方式是像 [FastChat] 中一样,利用 GPT-4 为模型的生成结果打分
奖励模型(Reward Model)
奖励模型(Reward Model)的必要性
SFT一直都在告诉模型什么是「好」的数据,却没有给出「不好」的数据。判断样本数据的「好坏」除了昂贵的人工标注之外,那就是 Reward Model 大显身手的时候了。
自我进行迭代的方法:[RLHF],[DPO]
RL 是直接告诉模型当前样本的(好坏)得分,DPO 是同时给模型一条好的样本和一条坏的样本。
利用偏序对训练奖励模型
在 OpenAI 的 [Summarization] 和 [InstructGPT] 的论文中,都使用了「偏序对」来训练模型。
偏序对是指:不直接为每一个样本直接打分,而是标注这些样本的好坏顺序。
使用多少数据能够训练好一个RM?
在 OpenAI Summarize 的任务中,使用了 [6.4w 条] 偏序对进行训练。
在 InstructGPT 任务中,使用了 3.2w 条 [4~9] 偏序对进行训练。
在 [StackLlama] 任务中,使用了 10w 条 [Stack Exchange] 偏序对进行训练。
RM 模型的大小限制?
Summarize 使用了 6B 的 RM,6B 的 LM。
InstructGPT 使用了 6B 的 RM,175B 的 LM。
DeepMind 使用了 70B 的 RM,70B LM。
强化学习(Reinforcement Learning,PPO)
在获得了一个 Reward Model 后,我们便可以利用这个 RM 来进化我们的模型。目前比较主流的优化方式有 3 种:BON,DPO 和 PPO。
Best-of-N(BON)
BON 也叫 reject sampling,是指我们通过设置 temperature 值让同一个模型生成若干回复,
接着,使用 Reward Model 挑出这些回复中得分较高的回复并再次训练原本的模型。
BON 和 RL 的区别主要有以下 2 点:
-
探索广度:对同一个 prompt,BON 一次会进行 N 次采样,但 PPO 每次只会采样 1 个答案。
-
进化深度:BON 的方法只会进行一次模型的「采样-迭代」,而 PPO 会重复进行「采样-进化-采样-进化」。但我们同样可以持续做多个轮回的 BON,这种情况下这 2 种方法的差别就不那么大。
Direct Preference Optimisatio(DPO)
[DPO] 是一种不需要 Reward Model 的训练方法,它可以用训练 RM 的偏序对来直接训练模型本身。
其目标是:对于同一个 prompt,尽可能大的拉开 selected 答案和 rejected 答案之间的生成概率。
Proximal Policy Optimization(PPO)
[PPO] 是强化学习中一种基于AC架构(Actor-Critic)的优化方法,其前身是TRPO,
PPO通过引入重要性采样(Importance Sampling)来缓解 on policy 模型一次采样数据只能更新一次模型的问题,提升了数据利用率和模型训练速度。
在 LLM 的训练中,使用 PPO 需要同时载入 4 个模型:
-
Actor Model:用于进化训练的生成模型
-
Critic Model:用于进化训练的评判模型
-
Ref Model:参照模型,通过 KL 来限制 Actor 模型的训练方向
-
Reward Model:奖励模型,用于指导 Actor 进化
大模型微调方法
-
Houlsby N 等人提出的 Adapter Tuning
-
微软提出的 LORA
-
斯坦福提出的 Prefix-Tuning
-
谷歌提出的 Prompt Tuning
-
清华提出的 P-tuning v2
LORA 的效果会好于其它几种方法,其它方法都有各自的一些问题:
-
Adapter Tuning 增加了模型层数,引入了额外的推理延迟
-
Prefix-Tuning 难于训练,且预留给 Prompt 的序列挤占了下游任务的输入序列空间,影响模型性能
-
P-tuning v2 很容易导致旧知识遗忘,微调之后的模型,在之前的问题上表现明显变差
LORA 相比其它微调方法,可训练参数最少,但是整体上效果最好。
Deepspeed
DeepSpeed提供的支持:
-
优化器状态分区(ZeRO stage 1)
-
梯度分区(ZeRO stage 2)
-
参数分区(ZeRO stage 3)
-
传统的混合精度训练
-
一系列快速的基于CUDA扩展的优化器
-
ZeRO-Offload到CPU和NVMe
混合精度训练
主要思想是:用FP16代替FP32
FP16的优点:
-
内存占用少,相关参数占用只需要原来的一半
-
计算更快:FP16的计算吞吐量是FP32的2~8倍
缺点:
-
数据溢出:训练后期激活函数的梯度非常小,梯度*学习率更小,可能导致underflow
-
舍入误差
精度还不一样。。。
上面问题的解决办法:
-
FP32 权重备份:解决舍入误差,用fp32备份一个权重,舍入误差主要是由于公式权重 = 旧权重 + lr * 梯度,所以进行梯度更新的时候用fp32来更新。重点在于:实际训练中内存中占据大部分的是activations的值,尤其是batchsize很大的情况,所以主要是把这块内存给节省了
-
Loss Scale:解决 fp16 underflow 的问题
上面实验的一些结论:
-
开启XLA加速后,模型训练速度变慢了许多。原因不明。
-
根据 Nvidia 官方的建议,模型中权重的纬度是8的倍数时,效果最佳。我在实验中也证明了,如果Transofmer模型输入的词表大小不是8的倍数,则混合精度训练的加速比只有 1.22x
-
开启混合精度加速后,模型吞吐量约有 1.4x 倍的提升;
-
开启混合精度加速后,单卡的最大 batchsize 可以从 3584 提升到 4562;
-
开启混合精度加速后,Training 对 CPU 的利用率会变得很敏感。如果训练时候 CPU 大量被占用(利用利用空闲CPU进行decode)的话,会导致严重的减速。具体表现在:
-
CPU被大量占用后,GPU-kernel的利用率下降明显。估计是因为混合精度加速有大量的cast操作需要CPU参与,如果CPU拖了后腿,则会导致GPU的利用率也下降。
-
CPU被 decode 占用后,导致 steps/sec 从2.5+ 下降到 1.35+
-
-
T2T开启混合精度加速后,和论文 Scaling Neural Machine Translation 中的 fairseq 框架相比(t2t 官方中也有不少人指出这个问题),加速比不尽如人意。论文中指出,同样的模型 fairseq 开启混合精度加速后,加速比能到达 2.9x。
-
T2T中加速比不尽如人意,可能也有 Tensorflow 的锅。有一些工作指出,tensorflow 中的自动混合加速为了保证通用性,加速方式上做的比较保守,因此加速效果上不佳。有团队基于 Tensorflow 中的 LossScaleOptimizer 进行优化,实现更优的混合精度加速比。
训练过程中出现NAN:
一般是fp16 溢出了,一些解决方法:
-
自动混合精度训练可以处理一些
-
手动给optimizer 加一个scale
在 NVIDIA A100 张量核心上,以 TF32 格式运行的数学运算的吞吐量比上一代 Volta V100 GPU 上运行的 FP32 高出 10 倍,从而使 DL 工作负载的性能提高了 5 . 7 倍。