面试记录:大模型的微调过程中,你调整了哪些参数,遇到了哪些问题,怎么解决的?
前言
这个问题也是很大,但与其说是八股文,其实更偏向实操。为了讲清楚呢,我这边也把步调稍微放慢一点,讲的清楚一些。
全文讲解顺序
其实普遍而言,大家都是直接在现有的参数上继续训练。而继续训练主要的两个步骤,就是领域继续训练和微调。接下来当然就以实际情况为主线进行介绍。
我们主要训练的就是某平台自研的九天基础语言大模型CM-57B-8K和CM-57B-32K。而我们的目标,也就是基于专利文档进行训练,模型生成的文本更专业、更学术、更高级,同时也要保证原有的通识能力没有衰减。
当然,数据质量也是很重要的。我们从数据质量开始保证。
数据集和语料库
考虑到现在其实大部分大模型都改成了decoder-only,因此,训练过程其实并不太依赖问答对,也可以是很长一段文本。于是,语料库是由专门的部门去收集了每年集团评选出来的优质专利,然后从中挑选步骤部分作为超长文本段落,作为语料库。
在拆分的时候,我们按照专利-步骤-片段三个层次进行划分。比如,专利里面大概分了token,按照对应汉字是大约1.6token每字的规律,大概每个片段是overlap,从而保证上下文之间有一定的联系。于是,我们选用了overlap,计算下来也是大约
综上,就构成了训练的基础语料库。
当然,考虑到专利在分段的时候也考虑了段落间的语义,如果按照专利-步骤-段落-片段这样四个层次划分也是没问题的。我们以
在准备语料库的时候,我们采集了这些信息:
id:专利编号-步骤编号-段落编号-拆分编号patent:专利编号step:专利步骤编号paragraph:专利段落编号fragment:专利段落片段编号text:专利段落片段内容source:数据来源hash:文本指纹
于是,我们就可以获得jsonl文件,如下所示:
1 | { |
多个这样的json对象组成一个jsonl文件。
数据准备好了之后,就可以开始了?
不,我们得验证一下是不是还算符合要求的。
数据集质量验证
重复率
采用n-gram对数据集进行验证,调整字符shingleMinHashLSH分桶Jaccard
其中,根据经验判断,一般网页内容的Jaccard阈值大约是
然后做一段去重,主要包括文本指纹搜索比对,然后去除重复文本,保存为新的jsonl文件。
这样一套操作下来,其实抽样估计重复率已经能降到大约
噪声
当然,不重复并不代表没问题。我们还需要保证文本是人能理解的。所以,我们用一个相对来说标准的另一个模型,去跑一下长度分桶的PPL,观察是否存在噪声(PPL较高)或者抄录(PPL较低)的情况。
按照长度桶上PPL降低一部分。
虽然数据集质量验证做的不是很多,但是到这一步基本够用了。
领域继续训练
接下来的训练过程中,首先就是领域继续训练了。
这个步骤主要是为了解决原始通识数据分布与现有领域语料分布完全不同的情况。
在调整参数的时候,主要调整的参数包括:
- 上下文长度:尝试了
和 RoPE缩放:尝试了NTK/YaRN类的position scaling,rope_theta提升至量级,避免长程退化 - 优化器:尝试了
AdamW(lr = 1e-4, warming_ratio = 1e-2) - 数据精度:
fp16 batch_size:尝试了、 、
训练的时候,主要是根据领域PPL、MMLU进行判断,额外通过一部分真实案例进行测试,包括中学相遇问题、一般地理问题以及领域问题。
当然,在这个过程中我们也遇到了一些问题。比如,在训练过程中,Loss偶尔会出现一些尖刺。主要表现为长样本下的不稳定性。后来发现,这个问题主要出现在跨文注意力未阻断导致的,使用块对角掩码就能解决这个问题。
同样的,还有当模型从RoPE出现了不匹配的问题,最终PPL也出现了很大的波动。因此,主要采用RoPE scaling和curriculum结合的方式,长文本的PPL得到了明显的改善,从
微调
微调过程相对而言更倾向于解决语料库分布没有那么大的情况。
对于LoRA过程,调整的参数主要包括:
lora_alphalora_dropoutwarming_ratio
由于后续有意图识别过程,所以在评估微调结果的时候,输出JSON的合法性也是一个考评指标。但是发现JSON格式合法率相对较低,于是我们使用了两种解决方案:
- 首先是直接提供数据支撑,在语料库中加入更多的合法
JSON回答案例; - 其次是