LLM 预训练|SFT监督微调|推理
交叉熵损失
熵(Entropy)是信息论中的一个核心概念,它量化了一个随机变量的不确定性或信息内容。交叉熵(Cross Entropy)进一步发展了这个概念,用于衡量两个概率分布之间的差异。
L
=
−
1
N
∑
i
=
1
N
y
i
,
c
log
P
(
y
^
i
,
c
)
L = -\frac{1}{N} \sum_{i=1}^{N} y_{i,c} \log P(\hat{y}_{i,c})
L=−N1i=1∑Nyi,clogP(y^i,c)
在LLM中交叉熵损失实际上也是衡量两个概率分布的之间的差异:
- X:预测的下一个token在词表中的概率分布
- Y:真实的下一个token的One-Hot编码
预训练阶段
现在的大模型在进行预训练时大部分都采用了GPT的预训练任务,即 Next token prediction。预训练的目的是:在训练过程中,模型通过大量的文本数据来学习文本之间的模式和结构。
LLM所学习的数据只有输入给模型的文本,根据这个文本构建模型预训练的输入和目标:
- 首先token化,将文本序列转换成离散的token
- 根据当前token和前文的token,一起预测下一个token
- 将预测得到token与目标token做交叉熵损失
这里通过一个完整的例子来介绍一下这个过程,假设现在有一个用来预训练的数据集
你知道什么是预训练吗?
假设经过分词后
你: 9
知道: 3
什么: 6
是: 4
预训练: 2
吗: 1
?: 5
原来的数据变为如下序列,后面补了三个0(假设我们希望最大序列长度是10)
9 3 6 4 2 1 5 0 0 0
预测下一个token就类似于9预测3,9+3预测6,9+3+6预测4,以此类推,因此损失函数计算的次数大概就是:batch_size x sequnce_len
。
但是如果这样拆成很多个数据段其实比较低效,因此就可以考虑移位来构造数据,即
- 模型输入X为
9 3 6 4 2 1 5 0 0 0
- 模型目标Y为
3 6 4 2 1 5 0 0 0 0
但每条预训练样本只完整前向计算1次,为了保证看不到后面的token,需要在网络结果中采用masked self-attention
SFT微调阶段
其实本质上和预训练阶段一样,对模型的输出和targets做交叉熵损失,不同点在于:
预训练阶段是直接丢给模型一堆文字,通过token化+shift操作就能构建出输入和targets,即对全文做交叉熵损失,学习并记忆文本中的内容和结构;
SFT微调阶段,输入给模型的是<Prompts>
+<Response>
我们只需要输入Prompts得到模型的预测结果与Response做交叉熵损失。
在具体实现部分,会使用mask将Prompts部分掩盖,从而只对Response做Cross Entropy。
推理阶段
以自回归的方式进行预测
- 每次预测下一个token
- 将预测的token拼接到当前已经生成的句子上
- 再基于拼接后的句子进行预测下一个token
- 不断重复直到结束
其中,在预测下一个token时,每次我们都有一个概率分布用于采样,根据不同场景选择采样策略会略有不同,不然有贪婪策略、核采样、Top-k采样等,另外经常会看到Temperature这个概念,它是用来控制生成的随机性的,温度系数越小越稳定。
参考文献:
LLM 大模型基础|预训练|有监督微调SFT | 推理-CSDN博客