大模型微调相关知识

一般而言,一个完整的LLM训练过程,包括模型预训练(Pretrain)、指令微调(Instruction Tuning)和强化学习(RLHF)等环节。 此图摘自happy-llm。

大模型训练方法

预训练

大模型预训练和传统预训练模型类似(如BERT),同样是将海量无监督样本(无监督,指未曾标注)喂给大模型,使其学习人类浩如烟海的知识和基本的语言推理能力。
传统预训练模型: 如BERT,有 base 和 large 两个版本。BERT-base 模型由 12个 Encoder 层组成,其 hidden_size 为 768,使用 12个头作为多头注意力层,整体参数量为 1亿(110M);而 BERT-large 模型由 24个 Encoder 层组成,hidden_size 为 1024,有 16个头,整体参数量为 3亿(340M)。同时,BERT 预训练使用了 33亿(3B)token 的语料,在 64块 TPU 上训练了 4天。
大模型: 通常具有数百亿甚至上千亿参数,即使是广义上最小的 LLM,一般也有十亿(1B)以上的参数量。例如以开山之作 GPT-3 为例,其有 96个 Decoder 层,12288 的 hidden_size 和 96个头,共有 1750亿(175B)参数,比 BERT 大出快 3个数量级。即使是目前流行的小型 LLM 如 Qwen-1.8B,其也有 24个 Decoder 层、2048的 hidden_size 和 16个注意力头,整体参数量达到 18亿(1.8B)。

模型 hidden_layers hidden_size heads 整体参数量 预训练数据量
BERT-base 12 768 12 0.1B 3B
BERT-large 24 1024 16 0.3B 3B
Qwen-1.8B 24 2048 16 1.8B 2.2T
LLaMA-7B 32 4096 32 7B 1T
GPT-3 96 12288 96 175B 300B

由于大规模训练所需要的算力,大多数公司很难有这样的财力和算力来进行预训练。但其实,对于开发人员来说,也无需特别关注预训练,我们只需要基于通用的大模型,在其上微调即可,成本相对小很多,收益也会不错。

微调

预训练是大模型强大的根本,但还需要第二步将其激活出来。经过预训练的大模型对于什么样的问题,都能流畅的输出下一句,但它可能在胡说八道。这一现象的本质是因为,LLM 的预训练任务就是经典的 CLM,也就是训练其预测下一个 token 的能力,在没有进一步微调之前,其无法与其他下游任务或是用户指令适配。
传统预训练模型: 对于能力有限的传统预训练模型,我们需要针对每一个下游任务单独对其进行微调以训练模型在该任务上的表现。例如要解决文本分类问题,我们需要基于该分类任务的训练数据,对 BERT 进行微调。
大模型: 面对能力强大的大模型,我们可以训练模型的"通用指令遵循能力",通过指令微调的方式来进行SFT。所谓指令微调,即我们训练的输入是各种类型的用户指令(有监督数据),而需要模型拟合的输出则是我们希望模型在收到该指令后做出的回复。例如,我们的一条训练样本可以是:

lua 复制代码
input:告诉我今天的天气预报?
output:根据天气预报,今天天气是晴转多云,最高温度26摄氏度,最低温度9摄氏度,昼夜温差大,请注意保暖哦

微调方法

总的分为大两类:

  1. 全参数微调:需要大量数据,训练的参数过多,容易导致模型发生知识遗忘。
  2. 高效微调:仅训练一部分参数,训练成本较低,目前使用最广泛,可以分为以下几类: 增加额外参数微调、选择性微调和重参数微调。

增加额外参数微调

如:Prefix Tuning、Prompt Tuning、Adapter Tuning及其变体。

选择性微调

如:BitFit

重参数微调

通过对模型参数进行重新表示来实现高效微调,通常涉及低秩分解或其他形式的参数压缩,如:LoRA、AdaLoRA和QLoRA等,下面以LoRA为例。

LoRA通过低秩矩阵分解的思想,将原始的高维权重矩阵分解为两个低秩矩阵的乘积,减少权重的数量和计算复杂度。

LoRA 通过低秩矩阵分解的思想,将原始的高维权重矩阵分解为两个低秩矩阵的乘积,减少权重的数量和计算复杂度。 降低了存储需求和计算成本。提高了模型的训练速度和推理速度。 可能降低模型的准确性,因为使用了低精度权重。适用性受限,主要适用于具有低秩特性的增量矩阵。

一般使用peft库来实现模型的LoRA微调,peft库是huggingface开发的第三方库,其中封装了包括 LoRA、Adapt Tuning、P-tuning 等多种高效微调方法,可以基于此便捷地实现模型的 LoRA 微调。

强化学习

RLHF,全称是 Reinforcement Learning from Human Feedback,即人类反馈强化学习,是利用强化学习来训练 LLM 的关键步骤。相较于在 GPT-3 就已经初见雏形的 SFT,RLHF 往往被认为是 ChatGPT 相较于 GPT-3 的最核心突破。事实上,从功能上出发,我们可以将 LLM 的训练过程分成预训练与对齐(alignment)两个阶段。预训练的核心作用是赋予模型海量的知识,而所谓对齐,其实就是让模型与人类价值观一致,从而输出人类希望其输出的内容。在这个过程中,SFT 是让 LLM 和人类的指令对齐,从而具有指令遵循能力;而 RLHF 则是从更深层次令 LLM 和人类价值观对齐,令其达到安全、有用、无害的核心标准。

RLHF 就类似于 LLM 作为一个学生,不断做作业来去提升自己解题能力的过程。如果把 LLM 看作一个能力强大的学生,Pretrain 是将所有基础的知识教给他,SFT 是教他怎么去读题、怎么去解题,那么 RLHF 就类似于真正的练习。LLM 会不断根据 Pretrain 学到的基础知识和 SFT 学到的解题能力去解答练习,然后人类作为老师批改 LLM 的练习,来让 LLM 反思错误的解题方式,不断强化正确的解题方式。

实际应用中如何调优

随着大模型被广泛应用于实际的业务场景中,我们也能发现大模型常见的问题:

  1. 不遵循指令:体现在返回的结果不全面、格式不符合要求,甚至有可能答非所问、回答错误等。
    对于此类情况,业界有一些调优方法,如Prompt调优、模型微调以及RAG等,下面简单介绍下这几种方法。

Prompt调优

通过观察各种bad case,调整prompt让大模型返回更优质的结果。

优点:成本低、灵活;

缺点:依赖模型本身的知识和提示词优化的能力。

模型微调

构建优质的标注数据集,让大模型将知识内化。

优点:效果更好、定制化

缺点:成本高、数据质量要求高以及模型训练所用的知识可能过时

可以直接使用Hugging face提供的transformers框架,来进行分布式的预训练和有监督微调。

微调数据集如何准备

数据集中应该包含业务领域的专用知识,以及为提升该业务场景中大模型的效果,应标注一份相关数据(格式如下),这样能够让大模型更遵循指令。

lua 复制代码
input:告诉我今天的天气预报?
output:根据天气预报,今天天气是晴转多云,最高温度26摄氏度,最低温度9摄氏度,昼夜温差大,请注意保暖哦

RAG

外挂知识库,当模型需要回答问题时,它会首先从知识库中查找并收集相关信息,然后基于这些信息回答问题。

优点:能够外挂新知识,知识库能够不断更新,与时俱进,缓解模型的幻觉;

缺点:过于依赖知识库检索能力。 如果大模型的通用知识无法满足业务需求的话,可以考虑微调。因为大模型虽然拥有海量的知识储备,但无法覆盖各行各业,如果大模型关于该业务的知识不足够的话,用再好的提示词也是浪费;而RAG知识外挂知识,知识虽然在那,但依赖于知识的检索能力,大模型最后还得根据检索的知识,给出最终结果;所以可以考虑微调,让大模型真正理解问题,内化知识。

参考资料

happy-llm:datawhalechina.github.io/happy-llm/#...

微调方法:zhuanlan.zhihu.com/p/682082440

相关推荐
coderSong25682 小时前
Java高级 |【实验八】springboot 使用Websocket
java·spring boot·后端·websocket
Mr_Air_Boy3 小时前
SpringBoot使用dynamic配置多数据源时使用@Transactional事务在非primary的数据源上遇到的问题
java·spring boot·后端
咖啡啡不加糖4 小时前
Redis大key产生、排查与优化实践
java·数据库·redis·后端·缓存
int型码农4 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
大鸡腿同学5 小时前
纳瓦尔宝典
后端
UFIT5 小时前
NoSQL之redis哨兵
java·前端·算法
喜欢吃燃面5 小时前
C++刷题:日期模拟(1)
c++·学习·算法
SHERlocked935 小时前
CPP 从 0 到 1 完成一个支持 future/promise 的 Windows 异步串口通信库
c++·算法·promise
怀旧,5 小时前
【数据结构】6. 时间与空间复杂度
java·数据结构·算法
积极向上的向日葵5 小时前
有效的括号题解
数据结构·算法·