过拟合 跷跷板 幻觉 混合精度
怎么解决过拟合
数据增强、正则化、剪枝、Dropout、早停、交叉验证、噪声注入、批归一化、集成学习
跷跷板现象
"跷跷板现象"指的是在模型优化的过程中,某些能力得到提升的同时,其他能力却出现下降的现象。
产生跷跷板现象的原因:
优化策略的选择:在模型训练过程中,某些优化策略可能在提升模型在特定任务上的性能的同时,牺牲了模型在其他任务上的性能。例如,使用SFT和RLHF可以显著提升模型在一次性无错误编码能力(pass@1)上的表现,但可能会降低模型在多次尝试后正确编码的能力(pass@100)。
模型复杂度的增加:随着模型规模的增加和复杂度的提高,可能导致过拟合,从而在某些任务上性能下降。
可能的解决方法
设计更灵活的优化策略:开发新的优化算法,以更好地平衡模型在不同任务上的性能。
模型架构的创新:通过改进模型架构,如引入超连接(Hyper-Connections)等技术,来解决梯度消失和表示崩溃问题,从而提升模型在不同任务上的性能。
幻觉问题如何解决
想要解决幻觉问题,首先要搞清楚幻觉的来源,在准备数据的过程中、模型训练的过程中、模型推理的过程中都可能产生幻觉。因此相关的幻觉解决方案也主要是针对这几个方面:
针对模型推理过程中产生幻觉问题,主要是用我前面提到的RAG来解决,通过整合外部知识源来减少幻觉,确保生成的响应基于从可信来源检索到的事实信息。也可以基于这个方法对模型生成的回答做后处理,比如判断模型是否是依据检索到的信息给出回答而不是随意发挥。
针对数据的解决方法,可以使用包含“I don’t know”标记的响应数据集来训练模型,特别是在面对不熟悉的查询时。这种训练方法帮助模型学会在不确定时表达不确定性,而不是捏造信息。
也可以结合强化学习来鼓励模型在不确定时给出不确定的响应,而不是错误的响应。通过设计奖励函数,使得模型在给出不确定响应时获得正向反馈。也可以加入一些纠偏规则,比如采用ReAct的思想,让大模型对输出的结果进行反思。
针对prompt的优化,比如多给一些示例让大模型够从一系列相关的交互中学习,从而更好地捕捉语言和任务的细微差别。
还有一种最近比较流行的思路是集成知识图谱,就是graphrag,即不再局限于向量数据库的匹配,做召回时不仅考虑文档块,同时还考虑图谱的三元组,将只是图片集成到RAG中,通过利用知识图谱中结构化且相互关联的数据,可以显著增强RAG系统的推理能力。
不过,幻觉问题目前还没有完全解决,也是阻碍大模型落地的主要原因之一。
混合精度训练相关
混合精度训练的流程
结合Megatron的源码,混合精度训练步骤如下:
计算准备:存储一份fp32的parameter,momentum和variance。然后,将parameter复制一份,再将其精度减半,得到一份fp16的parameter。
fp32的parameter相当于“主权重”。在模型训练的过程中,执行
optimizer.step()
更新的就应该是这份权重。当模型训练完毕后,保存的也是它。fp16的parameter相当于“训练权重”,也就是在训练过程中实际参与前向传播过程的权重。
FWD:使用fp16的parameter做前向计算,在这过程中会得到fp16的activation(将在反向传播过程中被使用)。计算出来的loss用fp32精度来表示,这样做是为了保证反向传播计算梯度的精确性。
Loss计算:为了防止梯度溢出(主要是下溢情况),对loss做scale处理,得到fp32的scaled loss。
BWD:利用fp32的scaled loss做反向传播计算梯度。因为loss做过scale了,那自然得到的也是scaled gradients,为了节省显存,scaled gradients以fp16的形式存储。
Unscaled gradients:梯度以fp16的形式存储,但等到需要用梯度去更新模型权重时,就必须转换成fp32的形式了。在转换的同时,需要对梯度做unscale操作,让其恢复到原始值。
Clip gradients:在转换为fp32的梯度后,还可以执行clip等操作,来进一步预防梯度爆炸/消失。
训练阶段怎么节省显存
采用Gradient accumulation:batch大小设置为1,每隔32个batch进行一次参数更新。
采用Gradient checkpoint:前向传播的激活值不保留,在反向传播时重新计算
采用flash attention
采用qlora取代lora,量化精度选4bit。
开启混合精度训练
把模型替换为更小的模型