本文为《大规模语言模型-从理论到实践》 第五章有监督微调的学习笔记,在介绍基本内容的同时会补充一些扩展知识和案例来帮助大家更好地理解该章。
一、前言
大模型调整的历程经历了显著的演变,从最初的“预训练-微调”范式开始,模型首先在大规模无监督数据上进行预训练,然后在特定任务上通过有监督微调来优化性能。随着计算能力和数据集的扩展,模型规模迅速扩大,从数亿参数增长到数千亿参数,推动了如GPT-3等模型的出现,这些模型展示了在多任务环境中的优越性能。这种规模的增长也带来了少样本和零样本学习的能力,降低了对大规模标注数据的依赖。近年来,指令微调和对齐技术的引入使模型能够更好地理解和执行人类指令,同时确保输出符合人类价值观。多模态模型的兴起进一步拓宽了大模型的应用范围,使其能够处理文本、图像等多种数据类型。为应对大模型微调的计算开销,高效微调技术如参数高效微调(PEFT)和低秩适应(LoRA)被提出,允许在不修改大部分参数的情况下实现高效微调。这些发展反映了大模型在技术和应用上的持续进步,极大地推动了人工智能在各个领域的广泛应用。
什么是微调?
Fine-tuning 指在已经预训练好的大型语言模型基础上(一般称为“基座模型”),使用特定的数据集进行进一步的训练,让模型适应特定任务或领域。
二、提示学习和语境学习
1. 提示学习
步骤:
- 基于模版添加提示:x ➡️ x'
- 答案搜索:在答案空间总搜索得分最高输出
- 基于规则进行输出映射
2. 语境学习
核心:从类比中学习,不做参数更新,仅执行向前推理
缺点:对性能敏感(模版、事例选择、排列顺序)
三、微调技术
全量微调 vs LoRA vs QLoRA
全量微调困境
1)参数量大:计算量大、耗时长(计算资源和储存空间)
2)性能问题:直接修改预训练模型所有参数会破坏模型原始性能;实时性应用效果差(微调会增加推理阶段的计算延迟)
3)存储需求大:不论是参数,还是梯度过程都需要存储在GPU中,对GPU显存需求大;保存模型,对硬盘内存要求大
1. LoRA (Low-rank Adaptation)
前提假设:参数更新主要在一个低维子空间,如果参数更新发生在高维空间,可能会导致重要信息遗漏和LoRA方法失效。
主要原理:增加一个小网络(低阶矩阵分解),通过只对小网络进行更新的方式进行微调;保持原始模型参数不变;只训练额外增加的部分,节省模型优化的梯度和优化器状态的现存占用。
重要参数:
1)两个矩阵:B初始化为0,A是随机初始化矩阵,服从正态分布;这样设置新增的部分 ∆W = BA 对原始权重影响为0
2)两个核心参数:r和参数量正比,alpha是放缩系数,参数更新量∆W 会与 α/r 相乘后再与原本的模型参数相加
核心问题
1)为什么要初始化正态分布?
①确保初始梯度的有效传播:避免梯度消失或者爆炸
②提供足够的随机性:能够探索更广泛的参数空间,增加模型找到最优解的可能
③平衡训练初期的影响:对预训练权重的影响为0,避免破坏预训练模型初始性能
2)为什么一个初始化正态分布另一个初始化为0?
①如果全部为0,容易导致梯度缺失
②如果A和B全部正态,模型训练开始会有比较大偏移值∆W ,难以收敛
损失函数(回归):通常是均方误差,使得W‘=BA和∆W越近越好
3)参数选择和模型效果的关系?
①QKVO应用:可以用到单个上,但是最好的效果是用到每一个参数矩阵上(当GPU比较大的时候,可以指定参数target_modules=[‘q_proj’ ,‘k_proj’, ‘v_proj’, ‘o_proj’, ‘gate_proj’, ‘up_proj’]),用小一点的秩。
②最优r的选择:不一定越多越好;初始一般r从8开始,tips是alpha设置成r的两倍(16),缩放因子scaling=alpha/r=2(权重远大,影响越大),scaling一是可以缩放更新幅度,确保低秩矩阵的更新对模型参数的影响在不同的 ( r ) 值下保持一致,其次可以稳定训练,通过调整更新幅度,避免因过大的更新导致模型不稳定。
(如下图:几个组合中,表现最好的是在qkvo都应用,同时r=2,此时应用层多,但是秩的选择却很低)
4)LoRA应用层的选择?
①全连接层:包含大量参数(减少需要微调的参数数量);计算量大(低秩近似可以有效降低计算复杂度)
②注意力层:QKV对模型性能影响重大(低秩近似可以显著影响模型的表达能力);投影矩阵包含大量参数(减少参数数量,降低计算和存储需求)
③嵌入层:高维向量来降低维度;提升训练效率
2. QLoRA(Quantized Low-Rank Adaptation)
核心原理:在LoRA基础上,进一步减少forward中的现存占用,先将预训练模型量化到4-bit,再添加一组可学习的低秩适配器权重。
三种解决措施:4-bit NormalFloat、双重量化、分页优化器。
量化定义:降低模型计算复杂度和储存需求的技术,核心思想是将模型的权重和激活值从高精度表示转换为低精度表示,从而在减少计算和内存使用的同时尽量保持模型性能,分为权重量化(将模型权重从高精度表示转换为低精度表示)和激活量化(将模型激活值从高精度表示转换为低精度表示)。
解决措施
1)4-bit NormalFloat
①步骤:
- 数据标准化:
- 计算分位数:共需要2^4+1=17个分位数
- 计算量化值
- 数据映射:将标准化后的数据映射到最近的量化值
②缺点:数据缩放,分位数离散化每一步骤都导致了误差累积,且4-bit量化只能选择16个离散值之一,误差进一步增加
③优点:高效存储,数据压缩提高存储和传输效率
2)双重量化
①原理:两次量化,降低内存需求
②步骤:使用8-bit对初识量化结果进一步压缩,通过减少位宽来进一步减少储存空间同时保持数据准确性
3)分页优化器
①原理:解决内存峰值,动态将不常用的数据或者参数调出到较慢的储存中去(CPU)
②步骤:
- 方案选择:对称量化(QLoRA,使用统一的缩放因子和零点)和非对称量化(针对每个权重或激活值使用不同的缩放因子和零点)
- 计算scale和zero-point:用于将浮点数映射到整数范围
- 公式应用:将浮点数转化为整数表示
量化方案对比
对称量化假设数据分布对称,因此只需要考虑一个缩放因子(absmax),非对称量化考虑了数据的实际最大最小值,适用于数据分布不对称的情况。
1)对称量化(QLoRA中使用)
①原理:使用绝对值的最大值进行标准化,将数据映射到 [-127,127]
②步骤:
- 分块
- 计算量化常数:对每个块求absmax,
- 应用量化:
- 反量化:,和原始非常接近来验证
2)非对称量化
①步骤:
- 确定最大最小值,如果量化到8位
- 计算scaling和zero-point:
- 数值转换:
- 验证量化效果(反量化):存在细微误差,但基本保持原始分布
3)分块量化(Chunk-based Quantization):通过将张量划分为较小的块,分别对每个块进行量化,从而提高量化后的精度和模型性能。
①作用:
- 提高精度:当数值范围较大,统一量化常数无法精确表示所有值,通过分块可以让每个块的范围相对较小,提高量化精度
- 减少量化误差:全局量化可能忽略数据统计差异,分块能够让每个块独立确定最适合的量化常数,减少全局量化带来的误差积累
- 适应不同数据分布:适应极端值
②适用场景:模型部署在资源受限的环境,且量化精度对模型性能有较大影响;或有较大动态范围和复杂分布的数据时。
四、指令微调
构建指令数据:手动 OR 自动
- 手动:高质量且多样
- 自动:流程图如下
五、DeepSpeed Chat
一种快速(整个训练只需要通过一行命令完成)、经济实惠、可扩展且开放的系统框架,可实现端到端强化学习人类反馈(RLHF)训练实验,从而生成多种模式高质量ChatGPT式模型。
1. 核心功能
1)简化ChatGPT类型模型训练和强化推理的体验:只需一个脚本实现多个步骤;还提供一个易于使用的推理API,用于用户在模型训练后测试对话式交互
2)RLHF模块:复刻了instruct GPT论文中的训练模式,包括监督微调、奖励模型微调和RLHF;此外还提供数据抽象和混合功能,支持使用多个不同来源的数据源进行训练
3)RLHF系统:将训练和推理引擎整合到一个统一的混合引擎(DeepSpeed-HE)中用于RLHF训练。能够无缝地在推理和训练模式之间切换
2. RLHF流程
1)监督微调(SFT):使用精选人类回答来微调预训练的语言模型以应对多种查询
2)奖励模型微调:使用一个包含人类对同一查询的多个答案打分的数据集来训练一个独立的(通常比SFT小的)的奖励模型(RW)
3)RLHF训练:利用PPO算法(Proximal Policy Optimization 近端策略优化)利用RW模型的奖励反馈进一步微调SFT模型。PPO的目标函数是限制策略比率变动,避免策略更新过大导致性能不稳定。
3. DeepSpeed-HE
通过Actor model启用eval和train模式,两个引擎间的过渡是无缝的,选择不同的优化来运行模型提高整个系统的吞吐量;
ZeRO用于训练过程中将模型状态分割到不同GPU上,实现超线性扩展;ZeRO和LoRA结合,在混合引擎中彼此兼容,提高训练效率。
本书其余章节指路:
第一章&第二章 👉 【大模型连载 1/6】第一章&第二章-大语言模型
第四章 👉 大模型训练之三头六臂 -- 分布式训练
第六章 👉 【大模型连载 4/6】第六章-强化学习
第七章 👉
第八章 👉