大模型微调: SFT 经验分享

文摘   2024-09-10 07:40   美国  

微调作为一种技术手段,是在已具备广泛知识基础的大型预训练语言模型上,利用针对性的数据集实施额外的训练过程,旨在使模型更精准地契合特定任务需求或深入某一专业领域。微调的核心目标在于实现知识的精细化灌输与指令系统的精确匹配。

大模型的SFT(Supervised Fine-Tuning)方式主要包括以下几种:

1.全参数微调(Full Parameter Fine Tuning):全参数微调涉及对模型的所有权重进行调整,以使其完全适应特定领域或任务。这种方法适用于拥有大量与任务高度相关的高质量训练数据的情况,通过更新所有参数来最大程度地优化模型对新任务的理解和表现。

2.部分参数微调(Sparse Fine Tuning / Selective Fine Tuning):部分参数微调策略仅选择性地更新模型中的某些权重,尤其是在需要保留大部分预训练知识的情况下。这包括:

a.LoRA(Low-Rank Adaptation):通过向模型权重矩阵添加低秩矩阵来进行微调,既允许模型学习新的任务特定模式,又能够保留大部分预训练知识,从而降低过拟合风险并提高训练效率。

b.P-tuning v2:这是一种基于prompt tuning的方法,仅微调模型中与prompt相关的部分参数(例如,额外添加的可学习prompt嵌入),而不是直接修改模型主体的权重。

c.QLoRA:可能是指Quantized Low-Rank Adaptation或其他类似技术,它可能结合了低秩调整与量化技术,以实现高效且资源友好的微调。

3.冻结(Freeze)监督微调:在这种微调方式中,部分或全部预训练模型的权重被冻结(即保持不变不再训练),仅对模型的部分层(如最后一层或某些中间层)或新增的附加组件(如任务特定的输出层或注意力机制)进行训练。这样可以防止预训练知识被过度覆盖,同时允许模型学习针对新任务的特定决策边界。如果在资源充足的情况下,建议使用SFT进行全量微调。部分参数微调的方法不稳定,在有的场景下效果不理想。

在进行领域任务的SFT的时候我们通常会有以下训练模式进行选择,根据领域任务、领域样本情况、业务的需求我们可以选择合适的训练模式。

  • 模式一:基于base模型+领域任务的SFT;

  • 模式二:基于base模型+领域数据 continue pre-train +领域任务SFT;

  • 模式三:基于base模型+领域数据 continue pre-train +通用任务SFT+领域任务SFT;

  • 模式四:基于base模型+领域数据 continue pre-train +通用任务与领域任务混合SFT;

  • 模式五:基于base模型+领域数据 continue pre-train(混入SFT数据) +通用任务与领域任务混合SFT;

  • 模式六:基于chat模型+领域任务SFT;

  • 模式六:基于chat模型+领域数据 continue pre-train +领域任务SFT

  • ......

1 是否需要continue pre-train 大模型的知识来自于pre-train阶段,如果你的领域任务数据集与pre-train的数据集差异较大,比如你的领域任务数据来自公司内部,pre-train训练样本基本不可能覆盖到,那一定要进行continue pre-train。如果你的领域任务数据量较大(token在1B以上),并只追求领域任务的效果,不考虑通用能力,建议进行continue pre-train。

2 关于chat模型和base模型如何选择问题?如果你有一个好的base模型,在base模型基础进行领域数据的SFT与在chat模型上进行SFT,效果上差异不大。基于chat模型进行领域SFT,会很容导致灾难性遗忘,在进行领域任务SFT之后,模型通用能力会降低,如只追求领域任务的效果,则不用考虑。如果你的领域任务与通用任务有很大的相关性,那这种二阶段SFT会提升你的领域任务的效果。如果你既追求领域任务的效果,并且希望通用能力不下降,建议选择base模型作为基座模型。在base模型上进行多任务混合训练,混合训练的时候需要关注各任务间的数据配比。

3 其他

  • 在资源运行的情况下,如只考虑领域任务效果,我会选择模式二;

  • 在资源运行的情况下,如考虑模型综合能力,我会选择模式五;

  • 在资源不允许的情况下,我会考虑模式六;

SFT-训练参数如何调整

  • 学习率 学习率是一个非常重要的参数 ,如果学习率设置不当,很容易让你的SFT模型烂掉。SFT数据集不是特别大的情况下,建议设置较小学习率,一般设置为pre-train阶段学习率的0.1左右,如在pre-train阶段的学习率为9e-5,则SFT学习率设置为9e-6。在10万SFT样本上,采用与pre-train一样的学习率,发现loss一直不收敛,在调低学习率至原来0.1之后,loss在两个epoch之后就收敛。

  • warmup_ratio 通常pre-train训练的warmup_ratio 0.01~0.015之间,warmup-steps在2000左右。在SFT的时候,建议使用更小的ratio,因为相较于pre-train,SFT样本非常小,较小warmup_ratio可以使模型收敛更平滑。但如果你的学习率设置较大,那可以增大你的warmup_ratio,两者呈正相关。

  • Epoch Epoch设置可以根据loss收敛情况设置,如果SFT样本较少,可以设置较大epoch,在较小的epoch上loss会不收敛,指令都很难遵循。较大epoch会容易导致过拟合,但过拟合要优于欠拟合。如果SFT样本数量较多,如在十万以上,一般2个epoch即可收敛。


可以用来使用 SFT 训练 LLM transformer 强化学习 (TRL) Python 库,其中包含 SFT 的实现,可用于微调现有语言模型只需几行代码。

如果SFT任务类型较多,可以尝试添加system_prompt,不同的任务使用不同的system_prompt;一个好的基座模型非常重要!在SFT的时候,loss依然是你最重要的指标!

一般在SFT过程中,loss会先升后降;可以尝试多种模式训练方案,如在continue pre-train 中添加SFT数据,在SFT数据添加高质量的pre-train数据。

参考资料:

1.https://cameronrwolfe.substack.com/p/understanding-and-using-supervised

AI技术研习社
专注分享人工智能、大模型、算法、大数据开发、数据分析领域的技术干货和落地实践!
 最新文章