本文全面介绍了大模型微调技术,包括微调基本概念、监督微调(SFT)方法、领域模型适配策略以及参数高效微调(PEFT)技术。详细对比了全参数微调与LoRA、Adapter等高效微调方法的优缺点,探讨了数据准备、模型选择、显存优化等关键问题,帮助读者掌握大模型微调的核心知识与实用技巧。
前排提示,文末有大模型AGI-CSDN独家资料包哦!
1 微调通用概念
1.1 微调方法是什么?如何微调?
微调(fine-tuning)是一种迁移学习的方法,用于在一个预训练模型的基础上,通过在特定任务的数据上进行有监督的训练,来适应该任务的要求并提高模型性能。微调利用了预训练模型在大规模通用数据上学习到的语言知识和表示能力,将其迁移到特定任务上。
下面是一般的微调步骤:
- 预训练模型选择:选择一个在大规模数据集上进行预训练的基础模型,例如,可以选择一种预训练的语言模型,如bert,gpt等
- 数据准备:准备用于微调的特定任务数据集,这些数据集应该包含任务相关的样本和相应的标签和目标,确保数据集和任务的特定领域或者问题相关。
- 构建任务特定的模型头:根据任务的要求,构建一个特定的模型头,(task-specific head)。模型头是添加到预训练模型之上的额外层或者结构,用于根据任务要求进行输出预测或者分类,例如,对于文本分类任务,可以添加一个全连接层和softmax激活函数。
- 参数初始化:将预训练模型的参数作为初始参数加载到微调模型中,这些参数可以被视为模型已经学习到的通用语言表示。
- 微调训练:使用特定任务的数据集对模型进行有监督训练。这包括将任务数据输入到模型中,计算损失函数,并通过反向传播和优化算法例如梯度下降更新模型参数。在微调过程中,只有模型头部分的参数会被更新,而预训练模型的参数保持不变。
- 调整超参数:微调过程中,可以根据调整学习率,批量大小,训练迭代次数邓超参数,以达到更好的性能。
- 评估和验证:在微调完成后,使用验证集或者测试集对微调模型进行评估,以评估其在特定任务任务上的性能。可以使用各种指标,如准确率,精确率,召回率等。
- 可选的后续微调:根据实际情况,可以选择在特定任务的数据上进行进一步的微调迭代,以进一步提高模型性能。
微调的关键是在预训练模型的基础上进行训练,从而将模型的知识迁移到特定任务上,通过这种方式,可以在较少的数据和计算资源下,快速的构建和训练高性能模型。
1.2 多种不同的高效微调方法对比
- 选择性层调整(selective layer tuning):可以只微调层的一个子集,而不是微调模型的所有层,这减少了需要更新的参数数量。
- 适配器(Adapters):适配器层是插入预训练模型层之间的小型神经网络。在微调过程中,只训练这些适配器层,保持预先训练的参数冻结。通过这种方式,适配器学习将预先训练的模型提取的特征适应新任务。
- 稀疏微调(Sparse Fine-tuning):传统的微调会略微调整所有参数,但是稀疏微调只涉及更改模型参数的一个子集。这通常是基于一些标准来完成的,这些标准标识了与新任务最相关的参数
- 低秩近似(Low-Rank Approximations):另一种策略是用一个参数较少但是在任务中表现相似的模型来近似微调后的模型。
- 正则化技术(Regularization Techniques):可以将正则化项添加到损失函数中,以阻止参数发生较大的变化,从而以更“参数高效”的方式有效的微调模型。
- 任务特定的头(Task-specific heads):有时,在训先训练的模型架构中添加一个任务特定的层或者是头,只对这个头进行微调,从而减少需要学习的参数数量。
1.3 当前高效微调技术存在的一些问题
当前的高效微调技术很难在类似方法之间进行直接的比较并评估它们的真实性能,主要的原因如下所示:
- 参数计算口径不一致:参数计算可以分为三类:可训练参数的数量,微调模型与原始模型相比改变的参数的数量,微调模型和原始模型之间差异的等级,例如,DiffPruning更新0.5%的参数,但是实际参与训练的参数量是200%,这为比较带来了困难。尽管可训练的参数量是最可靠的存储高效指标,但是也不完美。Ladder-side Tuning使用一个单独的小网格,参数量高于Lora或者BitFit,但是因为反向传播不经过主网络,其消耗的内存反而更小。
- 缺乏模型大小的考虑:已有工作表明,大模型在微调中需要更新的参数量更小(无论是以百分比相对而论还是以绝对数量而论),因此基模型大小在比较不同PEFT方法时也要考虑到。
- 缺乏测量基准和评价基准:不同方法所使用的模型或者数据集组合都不一样,评价指标也不一样,难以得到有意义的结论。
- 代码实现可读性差:很多开源代码都是简单拷贝transformer代码库,然后进行小修小补,这些拷贝也不使用git fork,难以找出改了哪里,即便是能找到,可复用行也比较差(通常指定某个transformer版本,没有说明如何脱离又有代码库服用这些方法。)
2 监督微调SFT
2.1 监督微调SFT是什么?
SFT是监督微调(Supervised Fine-Tuning)是大型语言模型LLM训练流程的关键环节,它通过使用标注数据对预训练模型进行进一步训练,使模型能够适应特定任务或者领域。
核心概念:SFT是一种使用标注数据对预训练语言模型进行微调的技术,术语迁移学习的范畴。它的核心目的是将通用的大型语言模型适配到特定领域或者任务上,提升模型在目标场景下的表现。
基本特点
数据需求:依赖于高质量的标注数据集,这些数据通常是人工标注或者经过筛选的模型输出
训练目标:使用标准的语言建模目标,如交叉熵损失进行训练,但是数据质量要求远高于预训练阶段
计算成本:相比预训练成本大幅降低(从数十万美元降至数百美元级别),但比无监督预训练更昂贵。
效果优势:能显著提升模型在特定任务上的性能,同时保留预训练获得的一般知识。
2.2 监督微调SFT在大模型微调中的阶段
大型语言模型的典型训练分为三个阶段:
- 预训练:在海量无标注数据上进行自监督学习,建立基础语言能力
- 对齐:包括SFT和RLHF(基于人类反馈的强化学习),使得模型输出符合人类期望
- 领域适配:可选的进一步specialization,包括领域特定微调或者上下文学习
| 阶段 | 数据要求 | 计算成本 | 主要目标 |
|---|---|---|---|
| 预训练 | 海量无标注文本 | 极高(数十万美金) | 建立基础语言理解能力 |
| SFT | 高质量标注数据 | 中等(数百美金) | 使模型适应特定任务风格 |
| RLHF | 人类偏好数据 | 中等 | 对齐人类价值观和偏好 |
2.3 常见的SFT的开发流程是如何的?
可以分为以下几个关键步骤:
基础模型选择
选择合适的预训练模型作为微调基础,常见的选择包括:- Qwen系列
- LLaMa系列(如LLaMa2)
- GPT系列
- 其他开源模型(如MPT/Falcon)
- 领域特定基础模型(如医疗,法律等预训练模型)
选择时需要考虑模型规模(参数量),许可证,硬件资源等因素,例如Qwen1.5-7B(70亿参数)适合在消费级GPU上进行微调。
数据准备与标注
这是SFT最关键也最具挑战性的环节,包括:
数据收集:- 特定领域文本
- 高质量问答对
- 任务特定示例(如分类样本/摘要对)
- 人工生成或模型蒸馏的指令-输出对
数据格式: - 指令微调格式:
Instruction: [任务描述]
Input: [输入文本]
Output: [期望输出]
- 对话格式(多轮对话场景)
- 传统文本对格式(如问答对,文本-摘要对)
数据质量控制: - 确保标注数据的一致性
- 覆盖任务的各种边缘情况
- 适当的数据清洗和预处理
模型配置与训练
技术选择:
全参数微调(Full Fine-tuning):更新所有模型参数,效果最好但资源消耗大
参数高效微调:如LoRA(低秩适配),Adapter-tuning等,只训练少量参数。
混合方法:如前文提到的Cot-NumHG策略,结合思维链与SFT
关键参数设置:- 学习率:通常比预训练小1-2个数量级
- 批量大小:根据GPU内存调整,可使用梯度累积
- 训练轮次:防止过拟合,早期停止策略
- 正则化:Dropout,权重衰减等。
代码实现:
常用工具包括: - HuggingFace Transformers + TRL(Transformer Reinforcement Learning)库
- LLaMA-Factory
- 专业框架如MindSpore的SFT模块
评估与迭代
评估指标:- 任务特定指标(如分类准确率,BLEU分数等)
- 人工评估输出质量
- 领域知识测试集
- 通用能力保留测试(避免灾难性遗忘)
迭代优化: - 根据评估结果调整数据分布
- 增加困难样本
- 调整训练策略(如课程学习)
- 半监督方法利用未标注数据
部署与应用
完成SFT后,模型可以:- 直接用于生产环境
- 作为RLHF的基础
- 进一步压缩量化以适应边缘设备
- 集成到更大的系统中(如客服机器人)
2.4 训练数据要注重什么?
SFT的训练数据质量直接影响模型性能,以下是构建和筛选SFT数据时需要注意的关键要点,结合最新研究和实践总结:
首先,数据质量要优于数量,答案需要准确无误,避免事实错误,逻辑矛盾或者模糊表达,尤其是专业领域数据需要专家审核。其次做好数据清洗,剔除重复样本,无关内容或者标注错误的样本,例如通过自动化工具清洗GPT生成的数据。
另外,要注意任务多样性,覆盖多类指令类型(如分类,生成,推理)和表达方式(问句,祈使句),避免模型过拟合单一模式。最后要注重内容多样性,包含不同主题,难度和语境的数据,例如医疗,法律等垂直领域需要覆盖专业术语和常见场景。
2.5 大size和小size模型怎么选择
1 从模型本身考虑
大模型(如320亿参数)
优势:在复杂任务如专业领域文本生成,多轮对话等任务中表现更优,能捕捉细微语义和长程依赖。
适用场景:对输出质量要求极高(如医疗报告生成,法律文书分析等),资源充足的场景
风险:容易过拟合低质量数据,且训练成本很高(70B的模型全参数微调需要168GB显存)
小模型(如1.5亿参数)
优势:推理速度快(实时响应),资源消耗低(单卡可运行),适合简单任务(如基础文本分类,短文本摘要)
适用场景:资源受限(边缘设备),高吞吐需求(如批量处理)或者任务标准化程度高,如情感分析
风险:可能无法处理复杂逻辑或者长文本连贯性要求。
2 从硬件资源和成本权衡
显存需求
大模型:70B参数模型16位精度需要168GB显存,需多卡并行或者量化技术(如4位量化降至42GB)
小模型:1.5B参数模型仅需要数GB显存,可在消费级GPU(如RTX 3090)运行
训练成本:大模型微调耗时和电费成本可能高出10-100倍。
3 数据质量与多样性影响
大模型:依赖高质量,多样化的数据,否则易过拟合或者性能下降
建议数据量>1M条,且需要领域平衡(如混合10%的通用数据防遗忘)
小模型:对数据噪声更敏感,但可通过数据增强或者蒸馏技术(如大模型生成伪标签)提升效果
4 效率和效果平衡
参数高效微调(PEFT)
大模型:优先采用LoRA,Adapter等PEFT方法,仅微调0.1%-1%参数(如Qwen2-72B微调0.5%参数占比)
小模型:可全参数微调,因计算开销较小
推理延迟:小模型响应更快(如1.5B模型推理速度比32B快10倍)
5 实际选择建议
1 适用同源小模型(如Qwen2-1.5B)快速验证数据质量和训练策略,再扩展到大模型
2 资源有限时,选择8B左右中等模型(如deepseek-R1-8B),平衡性能和成本
3 领域适配:垂直领域优先选择领域预训练过的小模型,而非通用大模型。
2.6 SFT真的能学到有效知识么?
SFT能否有效学习新知识,取决于数据质量,训练方法和任务类型。
1 SFT的知识学习能力
有限的知识注入
SFT主要通过调整预训练模型的参数来适应特定任务,其学习新知识的能力受限于以下因素:
知识依赖性:SFT依赖标注数据中的模式匹配,而非真正的知识理解。
记忆倾向:SFT倾向于记忆训练数据中的表面模式,而非泛化到新知识,实现显示,SFT在回答训练集问题时表现良好,但对语义改写或者时间更新的问题(如年份变更)则失败。
特定场景的有效性
结构化知识:若数据包含明确的领域知识(如医学指南),SFT可部分学习并复现这些信息。
任务适配:在指令跟随或格式规范类任务(如客服话术)中表现更优,因其以来输出风格调整而非深层知识。
2.7 SFT微调方案如何选择?
在SFT监督微调方案中,需综合考虑任务需求,数据规模,资源限制以及模型特性等因素,以下是基于最新研究和实践经验的系统化选择指南:
一,基础方案选择
1 全参数微调(Full fine-tuning)
使用场景:
领域数据与预训练数据差异大(如企业内部专有数据)
资源充足(多块高端GPU),且追求最优性能
优势:彻底适配新任务,效果最佳
风险:显存需求高(如70B模型需要168GB显存),容易过拟合小数据集
2 高效参数微调(PEFT)
LoRA(低秩适配)
仅微调0.1%-1%的参数,显存需求降低80%
适合对话风格调整,知识灌注等轻量级任务
QLoRA(量化LoRA)
适合5/8位量化,适合边缘设备或者显存极端受限场景
适用场景:
资源有限(单卡消费级GPU)
需保留预训练通用能力
3 混合方案
continue Pre-train + SFT:
领域数据量大于1B token时候,现急需预训练再微调,避免知识断层。
示例:农业领域模型需先注入专业术语,再微调问答任务。
二 数据驱动的方案优化
1 小数据验证(<1K样本)
- 先用50-100条数据测试微调收益,再扩展
- 若效果不佳,需要检查数据质量或者调整学习率(建议设为预训练的10%)
2 数据筛选策略 - 多样性优先:随机选择可能优于复杂筛选方法(如LESS,IFD),尤其大规模数据时
3 动态数据混合 - 通用任务与领域任务数据比例混合(例如8:2),防止灾难性遗忘
三 训练策略调优
1 学习率和Epoch - 学习率:初始设为预训练的0.1倍(如3e-5for 7B模型),batch size增大时按平方根缩放
- epoch:小数据(<1万条)设置为3-15轮,大数据(>10w)2轮即可
2 抗遗忘技术
弹性权重共享(EWC):保护重要参数不被覆盖
经验回放:保留5%-10%预训练数据混合训练
2.8 大模型SFT过程中,为什么会出现第二个epoch的时候loss会突然下降的问题?
一 核心原因解析
- 数据顺序和学习效率突变
- 初始的epoch的欠学习:第一个epoch通常仅完成对数据的初步拟合,模型可能尚未充分捕捉到数据的关键模式,当第二个epoch重新遍历数据集时,模型突然学习到更有效的特征表示(如低频但是重要的语义关联),导致loss骤降
- 数据分布不均衡:若第一个epoch末尾批次包含了高难度样本,而第二个epoch起始批次为简单样本,会因批次差异造成loss跳变
- 优化器状态重置效应
- Adam类优化器的动量累积:第一个epoch的梯度动量可能会包含噪声方向,而第二个epoch初期动量重置后,优化方向更准确,加速收敛。
- 学习率调整影响:若采用warmup策略,第二个epoch可能进入更高学习率阶段,提升优化效率。例如SFT中学习率通常设为预训练的0.1倍,过高的初始学习率会导致第一个epoch不稳定
- 正则化机制的动态调整
- dropout/batchnorm的稳定性提升:第一个epoch中随机掩码或者归一化统计量尚未稳定,第二个epoch时正则化效果趋于一致,模型泛化能力增强。
- 梯度裁剪作用:在深层网络中,梯度裁剪可能在第一个epoch限制参数更新幅度,而第二个epoch梯度方向优化后突破限制,导致loss下降
- 模型参数跳出局部最优
- 损失曲面的过渡区特定:大模型的损失曲面存在平坦-陡峭过渡区域。第一个epoch可能使得参数停留在平坦区域,第二个epoch通过累积梯度跳出,进入更优的收敛碰盆地。
二 领域研究和实证支持
- 损失曲面的过渡区特定:大模型的损失曲面存在平坦-陡峭过渡区域。第一个epoch可能使得参数停留在平坦区域,第二个epoch通过累积梯度跳出,进入更优的收敛碰盆地。
- LLaMa-factory的观察
- 全参数微调模型时,epoch间的跳变被证实为普遍现象,尤其是数据量较小或者学习率较高的情况下更显著
- 开源社区发现,这种现象与数据shuffle策略和优化器状态紧密相关,但通常不影响最终模型性能。
- 指令微调的特殊性
- 中文LLM研究中,第二个epoch的loss下降可能反应模型从“知识回忆”到“指令遵循”的切换,尤其是混合通用和领域数据时候更加明显
- 例如,Bloomz模型在SFT后因生长长度缩短导致loss突变,说明输出分布发生了质变。
- 对比预训练的差异
- 预训练loss曲线通常平滑的,因其数据量极大且优化稳定;而sft数据量小,分布集中,更容易出现阶段性突变。
三 解决方案和调优建议
- 预训练loss曲线通常平滑的,因其数据量极大且优化稳定;而sft数据量小,分布集中,更容易出现阶段性突变。
- 训练策略调整
- 延长warmup:将warmup步数从预训练的2000增长至5000以上,使得学习率增长更加平缓。
- 动态batch调整:第一个epoch适用较小的batch size,第二个epoch逐步增大,平衡稳定性和效率
- 数据优化
- 均衡数据难度:通过k-means聚类或者IFD指标,确保每个批次包含相似难度的样本
- 增强低频特征:对于专业领域数据,可以插入知识图谱增强的样本,加速关键模式学习。
- 监控与早停
- 验证集监控:若loss下降后验证集性能同步提升,属于良性现象;若后续震荡回升,需检查过拟合。
- 梯度分析工具:适用Pytorch的
register_full_backward_hook跟踪梯度传播路径,定位突变层。
四 前沿理论解释
- transformer的跳跃链接(如残差块)在第二个epoch可能更高效的传递梯度,缓解深层网络的退化问题。
该现象是sft训练动态的正常表现,通常无须干预,若需平滑曲线,可以优先调整学习率策略和数据分布。实践中,这种现象往往预示着模型开始有效的学习任务特征,而非训练鼓掌。
2.9 微调和参数高效微调之间的区别是什么?
微调和参数高效微调是机器学习中用于提高预训练模型在特定任务上的性能的两种方法。
微调就是把一个预先训练好的模型用新的数据在一个新的任务上进一步训练它。整个预训练模型通常在微调中进行训练,包括它的所有层和参数。这个过程在计算上非常昂贵且耗时,特别是对于大型语言模型。
另一方面,参数高效微调是一种专注于只训练预训练模型参数的子集的微调方法,这种方法包括为新任务识别最重要的参数,并且只在训练期间更新这些参数,这样,PEFT可以显著减少微调所需要的计算量。
全量微调和参数高效微调是两种常见的微调方法,它们有不同的特点和适用场景。下面是对这两者的详细对比
定义
全微调:在全微调过程中,整个预训练模型的所有参数都会被更新,这意味着在微调过程中,模型会根据新的任务和数据集对所有参数进行训练;
参数高效微调:PEFT只微调模型中的一部分的参数,通常是某些特定层的参数,或者使用较小的适配块(如Adapter,LoRa等),亿减少微调所需要的计算资源和存储空间
劣势和优势
全微调-优势:
性能最佳:全微调可以充分利用预训练模型的所有知识,通常能在特定任务上·取得最佳的性能
灵活性:适用于各种类型的任务,尤其是当目标任务与预训练任务差异较大时。
劣势:
计算资源消耗大:需要较大的计算资源和内存,因为所有参数都需要进行更新。
过拟合风险:在数据量较少的情况下,模型可能会过拟合训练数据。
训练时间长:更新所有参数,训练时间相对较长。
可能会导致灾难性遗忘,即在适应新任务时丢失旧任务的记忆。
高效参数微调-优势
资源节约:只是更新部分参数,显著减少了计算和存储需求,尤其适合资源受限的环境
快速微调:由于只微调部分参数,训练时间通常较短
减少过拟合风险:通过只更新一部分参数,降低了过拟合的风险
劣势:
性能可能不如全量微调:在某些情况下,PEFT的性能可能不如全微调,尤其是在需要大量参数调整的任务中。
适用性有限:不是所有任务都适合使用PEFT,某些情况下可能需要全微调达到最佳效果。
应用场景
全微调:
- 当你有足够的计算资源和大量标注数据时,尤其是任务与预训练任务相差较大时,使用全微调可以获得最佳的模型性能。
- 适用于复杂任务,如大型文本分类、机器翻译、图像识别等。
参数高效微调:
- 当计算资源有限或数据量较小,使用 PEFT 方法可以更快速、有效地微调模型。
- 适用于快速迭代的研究环境、小规模项目、或在边缘设备上部署模型等情况。
总结
| 特性 | 全微调(Full Fine-Tuning) | 参数高效微调(PEFT) |
|---|---|---|
| 参数更新 | 所有参数都被更新 | 仅更新部分参数或特定模块 |
| 计算资源 | 高,需大量内存和计算能力 | 低,节省资源 |
| 训练时间 | 较长 | 较短 |
| 过拟合风险 | 较高 | 较低 |
| 适用场景 | 大规模数据和复杂任务 | 资源受限、小规模数据或快速迭代的任务 |
| 最终性能 | 通常最佳 | 可能较低,但仍能保持良好性能 |
通过以上对比,可以根据具体的任务需求和资源限制选择合适的微调方法。希望这能帮助你更好地理解全微调和参数高效微调之间的区别和适用场景!
目前流行的大模型微调方式主要分为全参数微调和**参数高效微调(PEFT)**两大类,后者又衍生出多种技术路线。以下是主流方法及其关系的系统梳理:
2.10 全参数微调(Full Fine-Tuning, FFT)
核心思想:更新预训练模型的所有参数以适应下游任务。特点:
- 优点:性能最优,适合数据充足、计算资源丰富的场景。
- 缺点:显存占用高(如7B模型需112GB显存),易导致灾难性遗忘
典型应用:专业领域深度适配(如医疗报告生成)。
2.11 参数高效微调(PEFT)
通过冻结大部分预训练参数,仅调整少量新增或特定参数,显著降低资源需求。可分为以下子类:
1.添加型方法(Additive)
- Adapter Tuning
- 原理:在Transformer层中插入小型全连接模块(Adapter),仅训练这些模块。
- 特点:参数量占比约3%-5%,适合多任务学习,但可能增加推理延迟 。
- 变体:AdapterDrop(动态剪枝)、AdapterFusion(多任务组合) 。
2.重参数化方法(Reparameterization)
- LoRA(低秩适配)
- 原理:将权重更新量分解为低秩矩阵(ΔW=BA),仅训练A/B矩阵(参数量≈0.1%-1%)
- 优势:可合并回原模型,推理零开销;适合单任务高效适配。
- 变体:
- QLoRA:4位量化+LoRA,显存需求降低80%。
- DoRA:分解权重为方向和幅度,提升表达力。
3.选择性方法(Selective)
- BitFit
- 原理:仅微调模型中的偏置项(bias),参数量占比极低(<0.1%) 。
- 适用场景:资源极度受限的简单任务。
2.12 其他衍生技术
混合方法
- MAM Adapter:结合Adapter和LoRA,前者处理共性特征,后者捕捉低秩模式 。
- UniPELT:动态路由选择不同PEFT方法(如Adapter/LoRA/Prefix)。
检索增强微调(RAG)
- 原理:结合外部知识库检索,动态增强模型输入,避免硬编码知识。
- 与微调关系:可单独使用或与PEFT结合(如LoRA+RAG)。
2.13 方法间关系与选型建议
选型指南
| 需求 | 推荐方法 | 理由 |
|---|---|---|
| 多任务快速切换 | Adapter/Prefix Tuning | 任务间隔离性好 27 20 |
| 资源受限的单任务 | LoRA/QLoRA | 参数量极小,支持量化 52 |
| 超大规模模型适配 | Prompt Tuning | 仅需调整输入提示 |
| 避免灾难性遗忘 | 任何PEFT方法 | 冻结原参数保留通用能力 13 |
2.14 如果想要在某个模型基础上做全参数微调,需要多少显存?
要确定进行全参数微调所需要的显存量,显存占用主要来自以下几个部分,所以需要考虑一下几个因素:
- 模型参数:模型所有参数需要加载到显存中
- 梯度:反向传播计算出的梯度需要存储
- 优化器状态:优化器需要存储的额外状态信息
- 激活值:前向传播过程中产生的中间输出
- 框架和库的开销:如Pytorch,CUDA等固定或者可变的开销
显存估算公式
对于使用FP16/BF16混合精度训练+AdamW优化器的标准配置,显存需求可以这样估算:
- 模型参数显存:X B * 2 bytes/param = 2X GB
- 梯度显存:X B * 2 bytes/param = 2X GB
- 优化器状态显存(AdamW,FP32 状态):X B * 8 bytes/param = 8X GB
- 总计(核心部分):(2 + 2 + 8)* X GB = 12X GB
考虑激活值和其他开销后,实际需求会更高: - 非常粗略的下限(梯度检查点有效且batch_size/seq_len适中):~ 14X GB到 18X GB
- 更实际的考虑(包含一定的激活值和开销):可能需要~20GB或者更多
具体例子说明
例子1:LLaMA-7B模型全参数微调
对于7B(70亿)参数的LLaMA模型:
- 核心部分:
- 模型参数:7 * 2 = 14GB
- 梯度:7 * 2 = 14GB
- 优化器状态:7 * 8 = 56GB
- 总计:14+14+56 = 84GB
- 加上激活值和开销:
- 即使使用梯度检查点,总显存需求可能轻松超过100GB
- 经验值约为7 * 20 = 120GB
- 实际配置:
- 单个A100/H100(80GB)通常不够
- 需要2 * A100(80GB)并配合DeepSpeed ZeRO Stage2 或者3
例子2:LLaMA-70B模型全参数微调
对于70B(700亿)参数的模型:
- 核心部分:
- 12 * 70 = 840 GB
- 总需求:
- 远超1TB,需要大规模的GPU集群
- 大约需要14张80GB的A100显卡(1120GB)
不同微调方法的显存对比:
根据经验数据,不同的微调方法对7B模型的显存需求如下:
| 方法 | bits | 7B模型显存需求 |
|---|---|---|
| 全参数微调 | 16 | 160GB |
| Freeze | 16 | 20GB |
| LoRA | 16 | 16GB |
| QLoRA | 8 | 10GB |
| QLoRA | 4 | 6GB |
可以看到,全参数微调的显存需求远高于参数高效微调方法(PEFT)。
降低显存需求的技术
为了降低全参数微调的显存需求,可以采用以下技术:
- 梯度检查点(Gradient Checkpointing):通过时间换空间,显著减少激活值的显存占用
- 混合精度训练:使用FP16/BF16代替FP32
- 优化器选择:使用Adafactor或者8-bit Optimizers等内存优化型优化器
- 模型并行:如张量并行TP,流水线并行PP
- ZeRO优化:如DeepSpeed的ZeRO stage 1-3
- LOMO优化器:复旦大学提出的低内存优化器,可讲65B模型微调显存降低至8* 24GB GPU可行。
实际建议
- 小模型(<= 7B):可以在单卡或者多卡上进行全参数微调
- 中等规模(7B-30B),需要多卡并行 + DeepSpeed ZeRO
- 大模型(>=30B):建议考虑参数高效微调方法(LoRA等)或使用大型GPU集群。
全参数微调虽然效果通常优于参数高效微调方法,但对硬件资源要求极高,需要根据实际需求和资源情况权衡选择。
2.15 为什么SFT之后感觉LLM傻了
SFT之后模型出现性能下降或者变傻的现象,时实际应用中常见的挑战,结合最新研究和实践,以下是主要原因以及解决方案
核心原因解析
- 灾难性遗忘
- 模型在适应新任务时可能覆盖预训练阶段学到的通用知识。例如,医疗领域微调后可能丧失基础数学能力
- 机制:参数更新冲突导致旧任务知识被新任务梯度覆盖。
- 数据质量问题
- 领域偏差:微调数据集中于特定领域,如法律术语,削弱了通用对话能力
- 标注错误:错误标签引导模型学习错误模式,如医学问答中混淆症状关联性
- 低多样性:数据缺乏场景覆盖(如客服数据仅含有正式用语,忽略口语表达)
- 训练策略不当
- 过拟合:小数据集+高参数量导致模型死记硬背训练样本。例如,1万条数据训练7B模型时验证集损失骤升
- 学习率失调:过高学习率破坏预训练特征,过低则收敛缓慢。
- 任务适配性不足
- 基座模型选择错误(如用Chat模型处理非对话任务),或微调任务与预训练目标差异过大(如代码生成模型微调文学创作)
解决方案与实践建议
5. 确保数据质量:使用多样化且高质量的微调数据集,以确保其具有代表性和有效性
1. 通过IFD(Instruction-Following Difficulty)指标筛选高价值数据,仅用5%数据即可超越全量训练效果
2. 多样性保障:采用self-instruct方法构造多样化指令数据,ROUGE-L相似度阈值设为0.7,也可混合通用与领域数据(建议比例8:2),缓解领域偏移。
6. 正则化技术:采用正则化方法(如Dropout,权重衰减)来防止模型过拟合
7. 学习率调整:使用适当的学习率,通常微调时的学习率应该低于预训练阶段的学习率
8. 逐层微调:逐步解冻并微调模型的层,而不是一次性微调所有层,这可以避免灾难性遗忘。
9. 数据增强:通过数据增强技术增加微调数据的多样性,从而帮助模型更好的泛化。
2.16 SFT指令微调数据如何构建
构建SFT的微调数据需要以下步骤:
- 收集原始数据:首先,需要收集与目标任务相关的原始数据,这可以是对话数据,分类数据,生成任务数据等,具体取决于您的任务类型。确保数据集具有代表性和多样性,以提高模型的泛化能力。
- 标注数据:对原始数据进行标注,为每个样本提供正确的标签或者目标输出。标签的类型取决于任务,可以是分类标签,生成文本,对话回复等,确保标注的准确性和一致性。
- 划分数据集:将标注数据划分为训练集,验证集和测试集,大部分用于训练,一小部分用于验证模型的性能和调整超参数,最后一部分用于最终评估模型的泛化能力
- 数据预处理:根据任务的要求,对数据进行预处理,这可能包括文本清洗,分词,去除停用词等处理步骤,确保数据格式和特征适合模型的输入要求。
2.17 提升sft的prompt的代表性有什么好的方法
提升**监督微调(Supervised Fine-Tuning, SFT)**中的提示(prompt)代表性是确保模型在特定任务上表现良好的重要环节。有效的提示可以帮助模型更好地理解任务,从而提高性能。以下是一些提升提示代表性的有效方法:
1. 数据集多样性
- 多样化训练数据:
- 确保用于微调的数据集涵盖了任务的多种场景和变体。通过多样化的数据源(如不同领域、话题等),可以增强模型对各种输入的适应性。
- 合成数据生成:
- 使用数据增强技术或生成对抗网络(GANs)生成多样化的输入数据,以丰富训练集的内容。
2. 提示设计优化
- 上下文设定:
- 提供足够的上下文信息,使模型能够理解任务的背景。例如,在问答任务中,可以提供问题和相关文本的组合。
- 明确的指令:
- 使用清晰且具体的提示来引导模型的行为。例如,避免使用模糊的指令,确保提示明确表达期望的输出。
- 示例提示:
- 使用示例(few-shot 或 one-shot)来引导模型。例如,先给出几个输入及其对应的输出示例,让模型学习如何生成合适的响应。
3. 使用模板化提示
- 模板化设计:
- 设计标准化的提示模板,确保在不同的输入中保持一致性。这有助于模型快速适应任务。例如,对于文本分类任务,可以使用“这段文本属于哪个类别?”这样的模板。
- 灵活的占位符:
- 在模板中使用占位符,允许根据不同的输入动态生成提示。这样可以提高提示的适应性和代表性。
4. 反馈循环
- 人类反馈:
- 在模型输出的基础上进行人类评估,收集反馈并优化提示。通过迭代的方式逐步改进提示的设计。
- 自动化评估:
- 使用现有的评价指标(如BLEU、ROUGE等)对模型输出进行自动评估,识别哪些提示更有效,并进行相应调整。
5. 领域知识融入
- 使用领域特定知识:
- 在提示中融入领域特定的术语和概念,以提高在特定领域任务中的表现。例如,对于医学领域的任务,可以使用医学术语来构建提示。
- 专家指导:
- 请教领域专家,获取他们对提示设计的建议,确保提示的专业性和针对性。
6. 动态调整
- 在线学习:
- 根据模型的实时表现动态调整提示。通过监控模型的输出,对提示进行优化以适应当前的任务需求。
- 实验不同提示:
- 在微调过程中,尝试不同的提示设计,比较其效果,选择最佳的提示形式。
7. Prompt Tuning
- 提示微调(Prompt Tuning):
- 直接对提示的参数进行微调,而不是对整个模型进行微调。通过专门优化提示,可以在保持模型大部分参数不变的同时,提高性能。
8. 使用先进的技术
- Prompt Engineering:
- 结合最新的提示工程技术,比如使用变换器(Transformers)模型的特性来生成更高质量的提示。
- 基于模型的提示生成:
- 使用一个预训练模型来自动生成或优化提示,以确保提示的质量和适应性。
结论
提升 SFT 中提示的代表性是一个持续的过程,涉及数据多样性、提示设计、反馈循环、领域知识等多个方面。通过上述方法,可以有效地优化提示,增强模型在特定任务上的表现。选择合适的方法并结合具体任务的需求将有助于更好地实现目标。
3 领域模型微调
3.1 领域模型Continue Pretrain数据选取?
领域继续预训练和微调的区别:
领域继续预训练:
- 在特定领域(如医学,法律,金融等)的数据集上进行训练,以进一步定制模型的表示。
- 目标是使得模型适应特定领域的术语,语法,上下文和知识
微调: - 在特定任务(如文本分类,问答,命名实体识别等)上对模型进行训练,只对部分层进行更新。
- 目标是优化模型在特定任务上的性能。
在领域模型继续预训练过程中,数据选取是一个关键的步骤,以下是常见的数据选取方法:
- 领域相关数据:首先,可以收集与目标领域相关的数据。这些数据可以从互联网上爬取的,来自特定领域的文档或者公司内部的数据等。这样的数据可以提供领域相关的语言和知识,有助于模型在特定领域上的表现。
- 领域专家标注:如果有领域专家可以用,可以请他们对领域相关的数据进行标注。标注可以是分类,命名实体识别,关系抽取等任务,这样可以提供有监督的数据用于模型的训练。
- 伪标签:如果没有领域专家或者标注数据生成的成本较高,可以使用一些自动化的方法生成伪标签,例如,可以使用预训练的模型对领域相关的数据进行预测,将预测结果作为伪标签,然后使用这些伪标签进行模型的训练
- 数据平衡:在进行数据选取时,注意数据的平衡性,如果某个类别的数据样本较少,可以考虑使用数据增强手段或者对该类别进行过采样,以平衡各个类别的数据量
- 数据质量控制:在进行数据选取时,需要对数据的质量进行控制,可以使用一些质量评估指标,如数据的准确性,一致性等,来筛选和过滤数据。
- 数据预处理:在进行数据选取之前,可能需要对数据进行一些预处理,如分词,去除停用词,标准化等,以准备好输入模型进行训练。
在数据选取过程中,需要根据具体任务和需求进行适当的调整和定制。选择合适的数据可以提高模型在特定领域上的性能和泛化能力。
3.2 领域数据训练后,通用能力往往会有所下降,如何缓解模型遗忘通用能力?
当使用领域数据进行训练后,模型往往会出现遗忘通用能力的问题,以下是缓解模型遗忘通用能力的方法:
- 保留通用数据:在进行领域数据训练时,仍然需要保留一部分通用数据用于模型训练,这样可以确保模型仍然能够学习到通用的语言和知识,从而保持一定的通用能力。
- 增量学习:使用增量学习的方法,将领域数据与通用数据逐步交替进行训练,这样在学习新领域的同时,保持对通用知识的记忆。
- 预训练和微调:在领域数据训练之前,可以使用大规模通用数据进行预训练,获得一个通用的基础模型,然后在领域数据上进行微调,以适应特定领域的任务。这样可以在保留通用能力的同时提升领域任务的性能。
- 强化学习:使用强化学习的方法,通过给模型设置奖励机制,鼓励模型在领域任务上表现好,同时保持一定的通用能力。
- 领域适应技术:使用领域适应技术,如领域自适应和领域对抗训练,帮助模型在不同领域之间进行迁移学习,从而减少遗忘通用能力的问题。
- 数据重采样:在进行领域数据训练时,可以使用数据重采样的方法,使得模型在训练过程中能够更多的接触到通用数据,从而缓解遗忘通用能力的问题。
综合使用上述方法,可以在一定程度上缓解模型遗忘通用能力的问题,使得模型既能够适应特定领域的任务,有能够保持一定的通用能力,
3.3 领域模型Continue PreTrain,如何让模型在预训练过程中就能学习到更多的知识?
在领域模型的Continue PreTrain过程中,可以采取一些策略来让模型在预训练过程中学习到更多的知识。以下是一些方法:
- 多任务学习:在预训练过程中,可以引入多个任务,使得模型能够学习到更多的知识。这些任务可以是领域相关的任务,也可以是通用的语言理解任务。通过同时训练多个任务,模型可以学习到更多的语言规律和知识。
- 多领域数据:收集来自不同领域的数据,包括目标领域和其他相关领域的数据。将这些数据混合在一起进行预训练,可以使得模型在不同领域的知识都得到学习和融合。
- 大规模数据:使用更大规模的数据进行预训练,可以让模型接触到更多的语言和知识。可以从互联网上爬取大量的文本数据,或者利用公开的语料库进行预训练。
- 数据增强:在预训练过程中,可以采用数据增强的技术,如随机遮挡、词替换、句子重组等,来生成更多的训练样本。这样可以增加模型的训练数据量,使其能够学习到更多的知识和语言规律。
- 自监督学习:引入自监督学习的方法,通过设计一些自动生成的标签或任务,让模型在无监督的情况下进行预训练。例如,可以设计一个掩码语言模型任务,让模型预测被掩码的词语。这样可以使模型在预训练过程中学习到更多的语言知识。
3.4 进行SFT操作的时候,基座模型选用Chat还是Base?
在进行sft时,基座模型的选择可以根据具体情况来决定,与之前的sft操作不同,这次的目标时在特定的监督任务上进行微调,因此选择基座模型时需要考虑任务的性质和数据集的特点。
如果监督任务时对话生成相关的,比如对话回复或者对话情感分类等,那么选择chat模型作为基座模型更合适
如果监督任务时单论文本生成或者非对话生成任务,那么base模型作为基座模型更合适。
3.5 领域模型微调 指令&数据输入格式的要求?
领域模型微调是指使用预训练的通用语言模型(如bert,gpt等)对特定领域的数据进行微调,以适应该领域的任务需求,以下时领域模型微调的指令和数据输入格式的要求:
指令:
- 定义任务:明确所需要的任务类型,如文本分类,命名实体识别,情感分析等
- 选择预训练模型:根据任务需求选择合适的预训练模型,如bert,gpt等
- 准备微调数据:收集和标注与领域任务相关的数据,确保数据集具有代表性和多样性。
- 数据预处理:根据任务的要求,对数据进行预处理,例如分词,去除停用词等
- 划分数据集:将数据集划分为训练集验证集和测试机,用于模型的训练,验证和评估
- 模型微调:使用预训练模型和微调数据对模型进行微调,调整超参数并进行训练。
- 模型评估:使用测试集评估微调后的模型的性能,计算适当的评估指标,如准确率和召回率等。
- 模型应用:将微调后的模型用于实际任务,在新的输入上进行预测和生成。
数据输入格式要求: - 输入数据应该以文本形式提供,每个样本对应一行
- 对于分类任务,每个样本应该包含文本和标签,可以使用制表符或者逗号将文本和标签分隔开
- 对于生成任务,每个样本只需要包含文本即可。
- 对于序列标注任务,每个样本应该包含文本和对应的标签序列,可以使用制表符或者逗号将文本和标签序列分隔开
- 数据集应该以常见的文件格式(如文本文件,csv文件,json文件等)保存,确保数据的格式和模型的输入的要求一致。
根据具体的任务和模型要求,数据输入格式可能会有所不同,在进行领域模型微调之前,建议仔细阅读多使用模型的文档和示例代码,医疗界具体的数据输入格式要求。
3.6 领域模型微调 领域评测集如何构建?
构建领域评测集的过程可以参考以下步骤:
- 收集数据:首先需要收集与目标领域相关的数据。这可以包括从互联网上爬取文本数据、使用已有的公开数据集或者通过与领域专家合作来获取数据。确保数据集具有代表性和多样性,能够涵盖领域中的各种情况和语境。
- 标注数据:对收集到的数据进行标注,以便用于评测模型的性能。标注可以根据任务类型来进行,如文本分类、命名实体识别、关系抽取等。标注过程可以由人工标注或者使用自动化工具进行,具体取决于数据集的规模和可行性。
- 划分数据集:将标注好的数据集划分为训练集、验证集和测试集。通常,训练集用于模型的训练,验证集用于调整超参数和模型选择,测试集用于最终评估模型的性能。划分数据集时要确保每个集合中的样本都具有代表性和多样性。
- 设计评测指标:根据任务类型和领域需求,选择合适的评测指标来评估模型的性能。例如,对于文本分类任务,可以使用准确率、召回率、F1值等指标来衡量模型的分类性能。
- 进行评测:使用构建好的评测集对微调后的模型进行评测。将评测集输入模型,获取模型的预测结果,并与标注结果进行比较,计算评测指标。
- 分析和改进:根据评测结果,分析模型在不同方面的表现,并根据需要进行模型的改进和调整。可以尝试不同的超参数设置、模型架构或优化算法,以提高模型的性能。
3.7 领域模型词表扩增是不是有必要的?
领域模型的词表扩增可以有助于提升模型在特定领域任务上的性能,但是否有必要取决于具体的情况。以下是一些考虑因素:
- 领域特定词汇:如果目标领域中存在一些特定的词汇或术语,而这些词汇在通用的预训练模型的词表中没有覆盖到,那么词表扩增就是必要的。通过将这些领域特定的词汇添加到模型的词表中,可以使模型更好地理解和处理这些特定的词汇。
- 领域特定上下文:在某些领域任务中,词汇的含义可能会受到特定上下文的影响。例如,在医学领域中,同一个词汇在不同的上下文中可能具有不同的含义。如果领域任务中的上下文与通用预训练模型的训练数据中的上下文有较大差异,那么词表扩增可以帮助模型更好地理解和处理领域特定的上下文。
- 数据稀缺性:如果目标领域的训练数据相对较少,而通用预训练模型的词表较大,那么词表扩增可以帮助模型更好地利用预训练模型的知识,并提升在目标领域任务上的性能。
3.8 如何训练自己的大模型?
- 数据收集和准备:首先,需要收集与目标任务和领域相关的大规模数据集。这可以包括从互联网上爬取数据、使用公开数据集或者与合作伙伴合作获取数据。然后,对数据进行预处理和清洗,包括去除噪声、处理缺失值、标准化数据等。
- 模型设计和架构选择:根据任务的特点和目标,选择适合的模型架构。可以基于已有的模型进行修改和调整,或者设计全新的模型。常见的大模型架构包括深度神经网络(如卷积神经网络、循环神经网络、Transformer等)和预训练语言模型(如BERT、GPT等)。
- 数据划分和预处理:将数据集划分为训练集、验证集和测试集。训练集用于模型的训练,验证集用于调整超参数和模型选择,测试集用于最终评估模型的性能。进行数据预处理,如分词、编码、标记化、特征提取等,以便输入到模型中。
- 模型训练:使用训练集对模型进行训练。训练过程中,需要选择合适的优化算法、损失函数和学习率等超参数,并进行适当的调整和优化。可以使用GPU或者分布式训练来加速训练过程。
- 模型调优和验证:使用验证集对训练过程中的模型进行调优和验证。根据验证集的性能指标,调整模型的超参数、网络结构或者其他相关参数,以提升模型的性能。
- 模型评估和测试:使用测试集对最终训练好的模型进行评估和测试。计算模型的性能指标,如准确率、召回率、F1值等,评估模型的性能和泛化能力。
- 模型部署和优化:将训练好的模型部署到实际应用中。根据实际需求,对模型进行进一步的优化和调整,以提高模型的效率和性能。
3.9 指令微调的好处?
指令微调(Instruction fine-tuning)是一种在预训练模型上进行微调的方法,其中模型接受指令或者约束来生成特定的输出,指令微调有以下几个好处:
- 控制生成输出:指令微调能够使得模型能够根据指定的指令或者约束生成特定的输出,这对于需要精确控制模型生成结果的任务非常有用,例如自然语言生成任务中的文本摘要,翻译或者对话系统
- 可解释性和可控性:通过指令微调,可以将任务的要求以指令的形式传达给模型。这增加了模型的可解释性和可控性,使得用户能够更好的理解和干预模型的生成过程
- 避免不符合要求的输出:通过指令微调,可以避免模型生成不符合要求或者偏离期望的输出,通过明确的指令或者约束,模型能够更好的遵循任务的要求,并生成符合期望的结果。
- 提高任务性能:指令微调可以针对具体任务进行优化,使得模型在该任务的性能得到提升。通过引入任务特定的指令或者约束,模型可以更好的适应特定任务的需求,并生成更准确,更合理的输出
- 灵活性和可扩展性:指令微调是一种灵活且可扩展的方法,允许在不同任务和场景中进行微调,通过调整和修改指令或者约束,可以适应不同的任务需求,并在多个任务上进行微调。
需要注意的是,指令微调需要提供明确的指令或者约束,并对模型进行适当的调整和微调,在实践中,需要根据具体任务和应用场景来决定是否采用指令微调以及如何设计和实施指令。
3.10 预训练和微调是在哪个阶段注入知识的?
预训练和微调两个阶段都可以注入知识,但它们注入知识的方式和范围略有不同。
在预训练阶段,模型通过大规模的未标注数据进行训练,从中学习语言的统计特征,语义知识和语言规律,预训练的目的是让模型建立起对语言的基本理解和概念,并学习到一般性的语言表示,这种预训练过程注入了通用的语言知识,并可以迁移到各种下游任务中。
在微调阶段,预训练的模型通过在特定任务上使用带标注的数据进行微调,并适应具体任务的要求,在微调过程中,模型通过接触任务特定的数据和标签,进一步调整和优化模型的参数,使其更好的适应任务的特定特征和要求,微调阶段注入的是与任务相关的知识和信息。
综上所述,预训练阶段主要注入通用的语言知识和表示能力,而微调阶段则将这种能力与具体任务相结合,使模型在任务上表现更好,预训练和微调两个阶段的结合,可以有效的提高模型的性能和泛化能力。
3.11 想让模型学习某个领域或者行业的知识,是应该预训练还是应该微调?
如果想让模型学习到某个特定领域或者行业的知识,一般建议使用微调的方法。
预训练模型通常是在大规模通用数据上进行预训练,以学习通用的语言知识和表示能力,虽然预训练模型可以在各种任务上表现出色,但它们的训练并未针对特定领域或者行业进行优化。因此,如果希望模型具备特定领域的专业知识,微调是更合适的选择。
在微调阶段,可以使用特定领域的数据来微调预训练模型,使其适应该领域的任务和语境,通过在特定领域的数据集上进行微调,模型可以学习到该领域的专业术语,实体关系,特定语义和上下文等,微调过程可以使模型更好的理解和处理与特定领域相关的文本数据,从而提高模型在该领域任务上的性能。
需要注意的是,微调需要在预训练模型的基础上进行,因此首先选择合适的预训练模型,然后再特定领域上微调,微调过程中,可以根据任务需求和数据情况,调整微调的超参数,如学习率,微调步数等。
3.12 多轮对话任务如何微调模型?
在多轮对话任务中,微调模型的目标是使其能够更好地理解和生成连续的对话内容,并具备上下文理解和一致性回复的能力。下面是一种常见的微调模型的方法:
- 数据准备:收集或创建适用于多轮对话任务的数据集,包括对话文本和相应的标签或回复。确保数据集中包含上下文信息和对话的连续性。
- 构建输入输出格式:将对话数据转换为适合模型输入的格式。通常情况下,输入可以是包含多个对话轮次的上下文文本,输出可以是下一轮对话的回复或标签。
- 模型选择:选择适合多轮对话任务的预训练模型,如DialoGPT、BERT等。这些模型已经在大规模对话数据上进行了预训练,并具备一定的对话理解和生成能力。
- 微调模型:使用多轮对话数据集对预训练模型进行微调。微调的过程通常包括以下步骤:
- 初始化模型参数:将预训练模型的参数加载到模型中。
- 定义损失函数:根据任务要求,定义适当的损失函数,如交叉熵损失函数或生成模型中的对抗损失函数。
- 进行反向传播和参数更新:根据损失函数,通过反向传播算法计算梯度,并更新模型参数。
- 重复训练步骤:重复进行微调步骤,直到模型在验证集上达到满意的性能。
- 超参数调优:根据任务需求和数据情况,调整微调过程中的超参数,如学习率、批大小、微调步数等。可以使用验证集来评估模型性能并选择最佳的超参数配置。
- 评估和测试:使用测试集对微调后的模型进行评估和测试,评估模型在多轮对话任务上的性能和表现。
需要注意的是,微调多轮对话模型时,除了常规的微调方法,还可以采用一些特定的技巧,如引入对话历史的注意力机制、使用特定的对话策略进行训练等,以进一步提升模型在多轮对话任务中的性能。
3.13 微调后的模型出现能力劣化,灾难性遗忘是怎么回事?
灾难性遗忘是指在模型微调过程中,当模型在新任务上进行训练时,可能会忘记之前学习到的知识,导致在旧任务上的性能下降,这种现象常见于神经网络模型的迁移学习或者连续学习场景中。
在微调大语言模型时,灾难性遗忘可能出现的原因包括:
- 数据分布差异:微调过程中使用的新任务数据与预训练数据或者旧任务数据的分布存在差异,如果新任务的数据分布与预训练数据差异较大,模型坑会过渡调整以适应新任务,导致旧任务上的性能下降。
- 参数更新冲突:微调过程中,对新任务进行训练时,模型参数可能会被更新,导致之前学习到的知识被覆盖或者丢失,新任务的梯度更新可能会遇旧任务的梯度更新发生冲突,导致旧任务的知识被遗忘。
为了解决灾难性遗忘问题,可以尝试一下方法: - 经验回放:在微调过程中,使用一个缓存区来存储旧任务的样本,然后将旧任务的样本和新任务的样本混合在一起进行训练,这样可以保留旧任务的知识,减少灾难性遗忘的发生
- 弹性权重共享:通过引入正则化项,限制模型参数的变动范围,以保护之前学习到的知识,这种方法可以在微调过程中平衡新任务和旧任务之间的重要性
- 增量学习:将微调过程分为多个阶段,每个阶段只微调一部分参数,这样可以逐步引入新任务,减少参数更新的冲突,降低灾难性遗忘的风险。
- 多任务学习:在微调过程中,同时训练多个相关任务,以提高模型的泛化能力和抗遗忘能力,通过共享模型参数,可以在不同任务之间传递知识,减少灾难性遗忘的影响。
综上所述,灾难性遗忘是在模型微调过程中可能出现的问题,通过合适的方法和技术,可以减少灾难性遗忘的发生,保留之前学习到的知识,提高模型的整体性能。
3.14 预训练和SFT操作有什么不同
大语言模型的预训练和有监督微调(Supervised Fine-Tuning)是两个不同的操作,它们在目标、数据和训练方式等方面存在一些区别。
目标:
- 预训练的目标是通过无监督学习从大规模的文本语料库中学习语言模型的表示能力和语言知识。预训练的目标通常是通过自我预测任务,例如掩码语言模型(Masked Language Model,MLM)或下一句预测(Next Sentence Prediction,NSP)等,来训练模型。
- 有监督微调的目标是在特定的任务上进行训练,例如文本分类、命名实体识别等。在有监督微调中,模型会利用预训练阶段学到的语言表示和知识,通过有监督的方式调整模型参数,以适应特定任务的要求。
数据:
- 在预训练阶段,大语言模型通常使用大规模的无标签文本数据进行训练,例如维基百科、网页文本等。这些数据没有特定的标签或任务信息,模型通过自我预测任务来学习语言模型。
- 在有监督微调中,模型需要使用带有标签的任务相关数据进行训练。这些数据通常是人工标注的,包含了输入文本和对应的标签或目标。模型通过这些标签来进行有监督学习,调整参数以适应特定任务。
训练方式:
- 预训练阶段通常使用无监督的方式进行训练,模型通过最大化预训练任务的目标函数来学习语言模型的表示能力。
- 有监督微调阶段则使用有监督的方式进行训练,模型通过最小化损失函数来学习任务相关的特征和模式。在微调阶段,通常会使用预训练模型的参数作为初始参数,并在任务相关的数据上进行训练。
总的来说,预训练和有监督微调是大语言模型训练的两个阶段,目标、数据和训练方式等方面存在差异。预训练阶段通过无监督学习从大规模文本数据中学习语言模型,而有监督微调阶段则在特定任务上使用带有标签的数据进行有监督学习,以适应任务要求。
3.15 样本量规模增大,训练出现OOM错误怎么办?
当在大语言模型训练过程中,样本量规模增大导致内存不足的情况出现时,可以考虑出一下几种解决方案:
- 减少批量大小:将批量大小减小可以减少每个训练步骤中需要的内存量,较小的批量大小可能会导致训练过程中的梯度估计不稳定,但可以通过增加训练步骤的数量来弥补这一问题
- 分布式训练:使用多台机器或者多个GPU进行分布式训练可以讲训练负载分散到多个设备上,从而减少单个设备上的内存需求,通过分布式训练,可以将模型参数和梯度在多个设备之间进行同步和更新。
- 内存优化技术:使用一些内存优化技术可以减少模型训练过程中的内存占用。例如,使用混合精度训练可以减少模型参数的内存占用;使用梯度累积可以减少每个训练步骤中的内存需求
- 减少模型规模:如果内存问题仍然存在,可以考虑减少模型的规模,例如减少模型的层数,隐藏单元的数量等,虽然这可能导致模型性能的一定损失,但是可以在一定程度上减少内存需求。
- 增加硬件资源:如果条件允许,可以考虑增加硬件资源,例如增加内存容量或者使用更高的内存的设备。这样可以提供更多的内存空间来容纳更大规模的训练数据。
- 数据处理和加载优化:优化数据处理和加载过程可以减少训练过程中的内存占用。例如,可以使用数据流水线技术来并行加载和处理数据,减少内存中同时存在的数据量。
综上所述,当在大语言模型训练中遇到内存不足的问题时,可以通过减少批量大小,分布式训练,内存优化技术,减少模型规模,增加硬件资源或者优化数据处理等方式来解决,具体的解决方案需要根据具体情况进行选择和调整。
4 PEFT
4.1 介绍一下PEFT是啥,如何微调?
Parameter-Efficient Fine-tuning 是一种微调策略,旨在仅训练少量参数使模型适应下游任务。对大规模PLM(pre-trained language models)进行微调的成本往往高的令人望而却步。在这方面,PEFT方法只是微调了少量(额外的)模型参数,从而大大降低了计算和存储成本。最近最先进行PEFT技术实现了与完全微调相当的性能。
PEFT通过冻结预训练模型的某些层,并仅微调特定于下游任务的最后几层来实现这种效率。这样,模型就可以适应新的任务,计算开销更少,标记的例子也更少。尽管PEFT是一个相对较新的概念,但自从引入迁移学习以来,更新最后一层模型已经在计算机视觉领域得到了实践,即使在NLP中,静态和非静态词嵌入的实验也很早就进行了。
参数高效微调旨在提高预训练模型(如Bert 和RoBertTa)在各种下游任务上的性能,包括情感分析,命名实体识别和问答。它在数据和计算资源有限的低资源设置中实现了这一点,它只修改模型参数的一小部分,并且不容易过拟合。
参数高效的微调在计算资源有限或者涉及大型预训练模型的情况下特别有用。在这种情况下,PEFT可以在不牺牲性能的情况下提供一种更有效的方法来微调模型。然而需要注意的是,PEFT有时可能会达到与完全微调不同的性能水平,特别是在预训练模型需要进行重大修改才能在新任务上表现良好的情况下。
高效微调技术可以粗略的分为以下三类:增加额外参数-A,选取一部分参数更新S,引入重参数化。而在增加额外参数这类方法中,又主要分为类适配器(Adapter-like)方法和软提示(sofrt prompts)两个小类。
4.2 为什么需要适配器微调Adapter-tuning?
adapter是在预训练模型每层中插入用于下游任务的参数(针对每个下游任务,仅增加3.6%的参数),在微调时将模型主体冻结,仅训练特定于任务的参数,从而减少了训练时的算力开销。
技术原理:
- 作者设计了一种新的Adapter结构,并将其嵌入Transformer的结构里面
- 针对每一个Transformer层,增加两个Adapter结构(分别是多头注意力的投影之后和第二个feed-forward层之后)
- 在训练时,固定住原来预训练的参数不变,只对新增的Adapter结构和Layer Norm层进行微调,从而保证了训练的高效性
- 每当出现新的下游任务,通过添加Adapter模块来产生一个易于扩展的下游模型,从而避免了全量微调和灾难性遗忘的问题。
4.3 适配器微调Adapter-tuning的一些细节?
每个Adapter模块主要有两个前馈feed forward子层组成:
- 第一个前馈子层将Transformer块的输出作为输入,将原始输入维度d(高维特征)投影到m(低维特征),通过控制m的大小来限制Adapter模块的参数量,通常情况下,m《d。
- 然后,中间通过一个非线性层
- 在输出阶段,通过第二个前馈子层(up- project)还原输入维度,将m(低维特征)重新映射回d(原来的高维特征),作为Adapter模块的输出
同时,通过一个跳跃链接(skip-connenction)来将Adapter的输入重新加到最终的输出中去,这样可以保证,即便Adapter一开始的参数初始化接近0,Adapter也由于skip connection的设置而接近于一个恒等映射,从而确保训练的有效性。
通过实验发现,只训练少量参数的Adapter方法的效果可以媲美全量微调,这也验证了Adapter是一种高效的参数训练方法,可以快速的将语言模型的能力迁移到下游任务中去。
Adapter通过引入0.5%-5%的模型参数可以达到不落后全量微调模型1%的性能。
5 LoRA系列
5.1 什么是LoRA?
LoRA是一种参数高效微调技术,主要是用于大型预训练模型的微调,它通过在模型的权重矩阵中引入低秩矩阵来实现对模型的调整,从而减少训练参数的数量,降低计算和存储成本。
LoRA的核心思想是,大型语言模型在进行特定任务的微调时,并不必要更新所有参数。通过仅对模型中一小部分参数进行微调,可以显著减少所需要的计算资源,同时保持或者提升模型性能。
在具体实现上,LoRA通过在预训练模型的权重矩阵上添加一个可学习的低秩矩阵,来实现对模型的微调,这个低秩矩阵由两个较小的矩阵相乘的到,这两个矩阵在训练过程中进行更新,而原始的预训练权重则保持不变。
冻结一个预训练模型的矩阵参数,并选择用A和B矩阵来替代,在下游任务时只更新A和B矩阵。
5.2 LoRA的思路是什么?
LoRA的核心思想:
1 冻结原模型:保持预训练模型参数不变,不直接修改“大脑”
2 添加轻量补丁:插入两个小型矩阵A和B(秩r远小于原参数维度),仅训练这些新参数
3 合并输出:工作时将原模型输出与补丁输出相加,实现专业适配。
为什么有效?
1 大模型任务在下游任务中需要的调整其实都是“低维度”的(就像高维空间中的点在低维平面上)
2 通过低秩分解,用极少的参数(通常<1%原模型参数)就能捕捉任务特定模式
3 训练后可将AB矩阵合并回原模型,推理时零开销。
1 旁路增加与低秩分解:
- 在原模型的旁边加一个额外的路径,称为旁路,使用两个低秩矩阵分解来近似更新量;
- 首先将输入通过一个降维矩阵A,然后通过一个升维矩阵B进行还原
- 这使得我们能够用更小的参数更新来捕捉必要的信息,从而减少计算开销
2 训练策略: - 在微调过程中,原模型的参数保持不变,专注于训练降维和升维矩阵A和B
- 这种方式避免了对所有模型参数的训练,只更新额外的旁路,降低了计算复杂度和内存需求。
3 推理阶段整合 - 在推理时,将训练好的旁路矩阵BA与原模型参数进行相加,从而无需改变原有计算图,这种设计不增加额外的实时计算开销
4 初始化策略 - 降维矩阵A采用高斯分布(正态分布)来初始化,以赋予其随机特性
- 而升维矩阵B初始化为0矩阵,这样开始训练时不会影响原有模型的输出,确保训练稳定性。
5 可插拔的任务切花: - 通过不同的A和B配置,可快速适应新的任务情景。
- 当前任务可表示为W0 + B1A1,只需要移除或者替换旁路中的LoRA的部分即可切换任务,例如使用B2A2,实现快速的模型适应。
优势对比:
| 方法 | 参数量 | 训练成本 | 推理开销 | 适用场景 |
|---|---|---|---|---|
| 全参数微调 | 100% | 极高 | 无 | 数据充足、资源丰富 |
| LoRA | 0.1%-1% | 低 | 无 | 资源有限、快速适配 |
| Adapter | 3%-10% | 中 | 有 | 需要模块化设计 |
5.3 LoRA的特点是什么?
- 将B A矩阵加到W上可以消除推理延迟;
- 可以通过可插拔的形式切换到不同的任务;
- 设计的比较好,简单且效果好
5.4 QLoRA是什么?
QLoRA是LoRA的量化版本,结合了量化和低秩适配两种技术,旨在减少模型微调过程中的内存占用和计算成本,同时尽量保持模型性能。
在QLoRA中,首先对模型的权重进行4位量化,这意味着模型的每个权重都被表示位4位的树枝,显著减少了模型的内存占用。量化后的模型参数以一种称为NormalFloat(NF4)的数据类型存储,这种数据类型特别适合表示正态分布的数据,并且可以比传统的4位整数或者浮点数提供更好的量化效果。
接下来,QLoRA利用LoRA技术,通过在模型中引入可训练的低秩矩阵来进一步微调模型。这些低秩矩阵作为适配器,被添加到模型的特定层中,并且只有这些适配器的参数在微调过程中被更新,而模型的原始参数保持不变。这样做的好处是,可以针对特定任务微调模型的行为,而不需要对整个模型进行昂贵的更新。
此外,QLoRA还采用了一种称为双重量化的技术,对量化过程中使用的缩放因子(scale factor)和偏移量(offset)进行再次量化,从而进一步减少内存占用。
QLoRA的另一个关键技术是利用NVIDIA的统一内存进行分页优化。这种方法可以有效地管理内存使用,特别是在处理长序列数据时,可以避免内存峰值过高的问题。
Rank是矩阵中线性无关行或者列的最大数目。在LoRA中,通过引入低秩矩阵,可以减少模型的参数数量,从而降低计算和存储成本。
5.5 QLoRA的思路和流程是怎么样的?
QLoRA是什么?想象你要微调一个超级大的语言模型(比如650亿参数),但你的显卡只有24GB显存(比如RTX 3090)。传统方法需要780GB显存,就像用自行车拉火车——根本不可能!QLoRA就是解决这个问题的"魔法工具包",它能让你用家用显卡微调超大模型,效果还和全量微调差不多。
核心原理:
- 4位压缩:把模型参数压缩成超级精简版(原大小的1/8),就像把高清电影转成流畅画质,但关键信息不丢。
- 外挂训练:冻结压缩后的模型,只训练新增的"小补丁"(LoRA模块),类似给固定骨架加可调节关节。
- 无损还原:训练时临时把4位参数恢复成16位精度计算,保证数学计算的准确性 。
5.6 QLoRA在LoRA基础上的四大改进
4位智能压缩(NF4量化)
- 传统问题:直接4舍5入压缩会丢失关键信息,就像把彩色照片粗暴转黑白。
- QLoRA方案:用统计学方法(分位数量化),根据权重分布特点智能分配压缩档位。好比把照片按明暗分成16档,确保暗部细节不丢失 。
- 示例:对于正态分布的权重,QLoRA会让靠近0的密集区域分配更多档位,边缘稀疏区域分配较少档位 。
双重压缩(Double Quantization)
- 传统问题:量化时需要存储缩放系数,这些系数本身也占空间。
- QLoRA方案:对缩放系数再压缩一次!就像把zip压缩包再打个rar包,显存占用从0.5bit/参数降到0.127bit/参数 。效果:65B模型节省3GB显存。
分页优化器(Paged Optimizer)
- 传统问题:训练时偶尔会显存爆炸,就像春运火车站突然涌入大量乘客。
- QLoRA方案:在显存不够时,自动把部分数据暂存到内存,需要时再调回。类似机场的应急分流通道 。
计算优化
- 关键设计:存储用4位,计算时恢复成16位。就像把压缩文件解压后使用,既省硬盘又不影响CPU计算 。流程:4位存储 → 实时解压 → 16位计算 → 4位存储 。
效果对比(以65B模型为例)
| 指标 | 传统微调 | LoRA | QLoRA |
|---|---|---|---|
| 显存占用 | 780GB | 160GB | 48GB |
| 训练速度 | 1x | 1.2x | 0.7x |
| 性能保留率 | 100% | 98% | 99.3% |
为什么这些改进有效?
- 正态分布特性:大模型权重天然符合正态分布,QLoRA的NF4正好匹配这个规律 。
- 异常值处理:分块量化避免单个异常值影响整体精度 。
- 硬件友好:4位存储+16位计算完美适配GPU的Tensor Core 。
通俗类比
把QLoRA想象成乐高改装大师:
- 原模型是拼好的巨型乐高城堡(不可拆)
- NF4量化是把城堡拍成高清照片(轻量存档)
- LoRA是外挂可动部件(只改这些部件)
- 双重压缩是把照片存成zip+密码(更省空间)
- 需要玩的时候按图纸恢复局部(16位计算)
这样既不用拆原城堡,又能低成本改造!
5.7 LoRA矩阵的标准初始化方式
LoRA(Low-Rank Adaptation)通过引入两个低秩矩阵A和B来微调预训练模型,其初始化遵循以下规则:
矩阵A:采用随机高斯分布初始化(如Kaiming初始化),通常从均值为0、方差较小的正态分布中采样。例如:
Python
nn.init.normal_(self.lora_A, mean=0, std=0.02) # 小随机数初始化这种初始化方式为模型提供初始的随机方向,便于梯度更新时捕捉任务特定特征。
矩阵B:初始化为全0矩阵。例如:
Python
nn.init.zeros_(self.lora_B) # 全0初始化这是LoRA实现中的默认设置,Hugging Face的PEFT库等主流工具均采用此方式。
初始化为全0的原因
矩阵B初始化为0的核心目的是:
- 保证训练初期的稳定性: 初始状态下,LoRA的更新项 ΔW=BAΔW=BA 为0(因为B=0),模型行为与原始预训练模型完全一致。这避免了随机初始化可能带来的初始扰动,防止破坏预训练学到的知识。
- 梯度更新的对称性打破: 虽然B初始为0,但A的随机初始化会通过反向传播自然引导B的更新方向。若B也随机初始化,可能导致初始更新方向混乱,影响收敛。
- 与学习率的协同作用: 理论分析表明,B=0的初始化允许使用更大的学习率(相比A=0的方案),加速收敛且不易引发输出不稳定。实验证明,这种初始化在大多数任务中表现更优。
其他初始化方案的对比
- A=0 & B随机: 虽然数学上 BA=0BA=0 仍成立,但实际训练中会导致梯度更新效率降低,且需更小的学习率来维持稳定性,效果通常不如标准方案。
- A/B均随机: 可能加速初期收敛,但需精细调整方差和学习率,否则易引发训练不稳定。
初始化对训练动态的影响
- 默认方案(A随机+B=0): 梯度从A流向B,形成“渐进式学习”,适合大多数任务。
- 反向方案(A=0+B随机): 梯度从B流向A,可能因初始噪声导致训练波动。
总结
LoRA将B初始化为0是为了稳定训练起点并简化超参数调优,而A的随机初始化则提供探索方向。这种组合在实践中被证明是效率与稳定性的最佳平衡。
5.8 如何使用PEFT库中的Lora?
Parameter-Efficient Fine-Tuning (PEFT) 是一种微调大型预训练模型(如语言模型)的技术
PEFT库(参数高效微调)是一个库,用于高效的将大型预训练模型适配到各种下游应用,而无需微调模型的所有参数,因为这样做成本过高。PEFT方法仅微调少量(额外)模型参数,同时产生与完全微调模型相当的性能。这使得在消费硬件上训练和存储大型语言模型LLm变得更加容易。
PEFT与Transformers,Diffusers和Accelerate库集成,提供更快更简单的方法来加载,训练和使用大型模型进行推理。
PEFT库使用方法可以概括为以下几个步骤:
1 安装PEFT库,pip install peft
5.9 如何配置LoraConfig?
每个PEFT方法由一个PeftConfig类定义,存储构建PeftModel的所有重要参数,以LoRA为例,需要指定任务类型,是否用于推理,低秩矩阵的维度等参数:
- 1
- 2
fromimport False8320.1一 核心参数配置
- 基础参数
- r(秩):控制低秩矩阵的维度,默认值为8,较小的r(如4-16)适合简单任务,较大的r(如64)适合复杂任务,但会增加计算量。
- lora_alpha:缩放因子,默认值为8,建议设为r的1-4倍(如r=8时设为16),用于平衡低秩矩阵的影响。
- lora_dropout:防止过拟合的Dropout率,常用0.05-0.1
- 模块选择
- target_modules:指定应用LoRA的模型层,如Transformer的q_proj(查询矩阵)和v_proj(值矩阵)。不同模型层可能不同,需要通过print(model)查看,示例:target_modules = [“q_proj”,“v_proj”]
- 任务类型
- task_type:根据任务选择,如:
- CAUSAL_LM:自回归生成(如GPT)
- SEQ_2_SEQ_LM:序列到序列任务(如T5)
- TOKEN_CLS:标注任务
- task_type:根据任务选择,如:
二 高级参数优化
- 初始化与正则化
- init_lora_weights:
- True:LoRA矩阵B初始化为0,A为随机高斯分布,确保训练前不改变原始模型输出。
- “gaussian”或者“eva”:更复杂的初始化策略,适合特定场景。
- bias:可选“none”(默认),“all”或者“lora_only”,控制偏执项是否参与训练。
- init_lora_weights:
- 动态调整
- rank_pattern和alpha_pattern:对不同层设置不同r和alpha,例如:
- 1
- 2
"model.layers.10.*"16# 第10层使用更高秩 "model.layers.1.*"32# 第1层使用更大alpha适用于深层模型的关键层微调。
3. 显存优化
1. modules_to_save:指定额外需训练的全参数层(如分类头classifier),与LoRA层结合使用。
2. use_rslora:设为True时,缩放因子改为alpha/sqrt®,可能提升稳定性。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
fromimport 16# 低秩维度 32# 缩放因子 "q_proj""v_proj""o_proj"# 目标层 0.05# Dropout率 "none"# 不训练偏置 "CAUSAL_LM"# 自回归任务 "lm_head"# 额外训练输出层 "gaussian"# 高斯初始化 True# 启用稳定缩放三 实践建议
- 模型适配
- 使用print(model)查看层名,确保target_modules命名正确。例如,ChatGLM的查询层名为query_key_value
- 参数调优
- 小数据集:降低r(如4-8)和alpha(如8-16),增加dropout(如0.1)
- 多任务训练,通过rank_pattern分层配置,关键任务层分配更高秩。
- 工具链合成
- 结合prepare_model_for_int8_training 实现8位量化,减少显存占用。
五 常见问题
参数冲突:避免同时设置target_modules 和 layers_to_transform,可能导致重复适配。
效果不佳:检查task_type是否匹配任务,如分类任务设为CAUSAL_LM
通过以上配置,可高效微调大模型,典型场景下仅需训练0.1%-1%的参数量。
- 结合prepare_model_for_int8_training 实现8位量化,减少显存占用。
5.10 模型加载PEFT策略
加载要微调的基础模型,使用get_peft_model()函数包装基础模型和peft_config以创建PeftModel
- 1
- 2
- 3
- 4
fromimport fromimport "bigscience/mt0-large"训练模型
现在可以用Transformers的Trainer、Accelerate,或任何自定义的PyTorch训练循环来训练模型。例如,使用Trainer类进行训练,例如使用Trainer类进行训练:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
fromimport "your-name/bigscience/mt0-large-lora" 1e-3 32 2 0.01 "train" "test"5.11 微调需要了解的知识-模型显存占用的部分有哪些?
模型参数
- 存储内容:模型的权重矩阵(如全连接层,卷积核,embedding层等)
- 显存计算:参数量* 参数精度(如FP32占4字节,FP16占2字节)
- 示例:7B参数的模型在FP16下占用14GB显存
- 特点:静态占用,与输入数据无关
梯度(Gradients)
- 存储内容:反向传播时计算的参数梯度,用于优化器更新权重。
- 显存计算:与参数量相同(FP16梯度占2字节/参数)
- 优化器影响:如使用Adam需存储梯度,SGD则无需额外状态
优化器状态(Optimizer States)
- 存储内容:优化器维护的中间变量(如Adam的一阶动量、二阶动量)。
- 显存计算:
- Adam:每个参数需额外8字节(FP32状态)
- SGD:仅需梯度,无额外状态
- 示例:7B模型使用Adam时,优化器状态占用约56GB(7B×8字节)
中间激活值(Activations)
- 存储内容:前向传播中每层的输出(特征图),用于反向传播计算梯度。
- 显存计算:与输入数据(batch size、序列长度)强相关,公式为:
- 1
- 2
5 6070- KV Cache(推理专用)
- 存储内容:推理时缓存注意力层的Key-Value矩阵,加速自回归生成。
- 显存计算:
4blh(s+n)(l=层数,s=输入序列长度,n=生成序列长度) - 优化方法:MQA/GQA减少多头KV Cache的冗余存储
- 临时缓存与框架开销
- 存储内容:框架的临时缓冲区、通信缓存、显存碎片等。
- 显存占比:通常<5%,但可能随batch size增大而显著
- 显存占用分布示例(训练 vs 推理)
| 组件 | 训练显存占比(Adam) | 推理显存占比 |
|---|---|---|
| 模型参数 | 20% | 80%-90% |
| 梯度 | 20% | - |
| 优化器状态 | 30% | - |
| 中间激活值 | 30%-60% | <10% |
| KV Cache | - | 5%-20% |
5.12 模型显存占用优化策略?
训练阶段:
- 使用混合精度(FP16/BF16)减少参数和梯度显存
- 激活重计算+ZeRO分片(如Deepspeed)优化中间激活和优化器状态
推理阶段:
- 量化(INT8/INT4)压缩模型参数
- 动态调整KV Cache长度
通过合理配置上述策略,可显著降低显存需求。例如,7B模型全参数训练需112GB显存(FP32),而QLoRA微调仅需2.3GB
5.13 prefix类的微调方式有哪些?
prefix类的微调包括以下几种:
prefix tuning
在prefix tuning之前的工作主要是人工设计离散的模版或者自动化搜索离散的模板。
对于人工设计的模板,模板的变化对模型最终的性能特别敏感,加一个词,少一个词或者变动位置都会造成非常大的变化。
而对于自动化搜索模版,成本也比较高,同时,以前这种离散化的token搜索出来的结果可能并不是最优的,除此之外,传统的微调范式利用预训练模型去对不同的下游任务进行微调,对每个任务都要保存一份微调后的模型权重,一方面微调整个模型耗时较长;另一方面也会占用很多存储空间。
技术原理:
基于以上,prefix tuning提出固定预训练语言模型,为语言模型添加可训练,任务特定的前缀,这样就可以为不同任务保存不同的前缀,微调成本也小
prefix Tuning在输入token之前构造一段任务相关的virtual tokens作为prefix,然后训练的时候只更新prefix那部分的参数,而PLM中的其他部分参数固定。
prompt tuning
大模型全量微调对每一个任务训练一个模型,开销和部署成本都比较高,同时,离散的prompts方法,成本比较高,并且效果不太好。
除此之外,之前的prefix tuning在更新参数的时候还是有些复杂。
技术原理
基于此,作者提出了prompt tuning,通过反向传播更新参数来学习prompts,而不是人工设计prompts;同时冻结模型原始权重,只训练prompts参数,训练完之后,用同一个模型可以做多任务推理。
prompt tuning,该方法可以看作是prefix tuning的简化版本,它给每个任务定义了自己的prompt,然后拼接到数据上作为输入,但是只在输入层加入prompt tokens,并且不需要加入多层感知器MLP 进行调整来解决难训练的问题。
model tuning需要为每个下游任务制作整个预训练模型的任务特定副本,并且必须分批进行推理
prompt tuning只需要为每个任务存储一个特定于任务的小提示,并使用原始预训练模型进行混合任务推理。
通过实验发现,随着预训练模型参数量的增加,prompt tuning的方法会逼近全参数微调的结果。
5.14 prompt tuning和prefix tuning在微调上的区别是什么?
他们都是在自然语言处理任务中对预训练模型进行微调的方法,但它们在实现细节和应用场景上有所不同。
以下是他们之间的主要区别:
参数更新位置:prompt tuning通常只在输入层添加参数,而prefix tuning在每一层都添加了参数
参数数量:prefix tuning通常比prompt tuning有更多的可学习参数(因为它为模型的每一层都添加了前缀)
适用任务:prompt tuning更适合于分类任务,而prefix tuning更适合于生成任务(因为它可以在不同层次上调整模型的行为)
训练效率:prompt tuning通常有更高的训练效率。
P-tuning
背景:
1 大模型的prompt构造方法严重影响到下游任务的效果
比如:gpt-3采用人工构造模版来做上下文学习,但人工设计的模版的变化特别敏感,加一个词或者少一个词,或者变动位置都会造成比较大的变化。
进来的自动化搜索模版工作成本也比较高,以前这种离散化的token的搜多出来的结果可能不是最优的,导致性能不稳定。
基于此,设计了一种连续可微的virtual token,该方法将prompt转换为可以学习的embedding 层,并对prompt embedding进行一层处理。
相比prefix tuning,p-tuning加入了可微的virtual token,但仅限于输入层,没有在每一层都加:
另外,virtual token的位置也不一定是前缀,插入的位置是可选的。
这里的出发点实际是把传统人工设计模版中真实token替换成可微的virtual token。
P-tuning v2
之前的prompt tuning和p tuning等方法存在两个主要的问题
一,缺乏模型参数规模和任务通用性。
- 缺乏规模通用性:
- prompt tuning论文中表明当模型参数规模超过10B时,提示优化可以与全量微调相媲美,但是对于那些较小的模型(从100M到1B),提示优化和全量微调的表现有很大的差异,这大大限制了提示优化的适用性。
- 缺乏任务普遍性:
- 尽管prompt tuning和p tuning在一些NLU基准测试中表现出优势,但提示调优对硬序列标记任务(即序列标注)的有效性尚未得到验证。
第二,缺少深度提示优化
在prompt tuning 和p-tuning中,连续提示只被插入transfomrer第一层的输入embedding序列中。
在接下来的transformer层中,插入连续提示的位置的embedding是由之前的transformer层计算出来的,这可能导致两个可能的优化挑战。
- 尽管prompt tuning和p tuning在一些NLU基准测试中表现出优势,但提示调优对硬序列标记任务(即序列标注)的有效性尚未得到验证。
- 由于序列长度的限制,可调参数的数量是有限的。
- 输入embeddinembedding对模型预测只有相对间接的影响。
P-tuning v2方法在每一层都加入了prompts tokens 作为输入,2️而不仅仅是加入到输入层,这带来两个方面的好处: - 更多的可学习参数(从p-tuning 和prompt tuning 的0.01%增加到0.1%-3%)
- 加入到更深层结构中的prompt能给模型预测带来更直接的影响。
总结
1 prefix tuning
- 在每一个transformer层都带上一些virtual token作为前缀,以适应不同的任务。
- 优化多层prefix
- 与fine-tuning比肩
2 prompt tuning - 该方法可以看作是prefix tuning的简化版本,针对不同的任务,仅在输入层引入virtual token形式的软提示(soft prompt)
- 优化单层prefix
- 大尺寸模型下与fine-tuning比肩
3 p-tuning - 将prompt转换为可以学习的embeddinembedding层,相比prefix tuning,仅在输入层加入的可微的virtual token;另外,virtual token的位置也不一定是前缀,插入的位置时可选的。
- 优化单层prefix
- 大尺寸模型下与fine-tuning比肩
4 p tuning v2
- 该方法在每一个transformer层都加入了prompt token作为输入,引入多任务学习,针对不同任务采用不同的提示长度
- 优化多层prefix
- 小尺寸和大尺寸模型下均与fine-tuning比肩。
分别用通俗易懂的语言介绍prefix tuning ,prompt tuning ,p-tuning,p- tuning v2
如何学习AI大模型 ?
“最先掌握AI的人,将会晚掌握AI的人有竞争优势,晚掌握AI的人比完全不会AI的人竞争优势更大”。在这个技术日新月异的时代,不会新技能或者说落后就要挨打。
老蓝我作为一名在一线互联网企业(保密不方便透露)工作十余年,指导过不少同行后辈。帮助很多人得到了学习和成长。
我是非常希望可以把知识和技术分享给大家,但苦于传播途径有限,很多互联网行业的朋友无法获得正确的籽料得到学习的提升,所以也是整理了一份AI大模型籽料包括:AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、落地项目实战等免费分享出来。
👉点击即可获取大模型学习包2026年最新版👈
- AI大模型学习路线图
- 100套AI大模型商业化落地方案
- 100集大模型视频教程
- 200本大模型PDF书籍
- LLM面试题合集
- AI产品经理资源合集
大模型学习路线
想要学习一门新技术,你最先应该开始看的就是学习路线图,而下方这张超详细的学习路线图,按照这个路线进行学习,学完成为一名大模型算法工程师,拿个20k、15薪那是轻轻松松!
视频教程
首先是建议零基础的小伙伴通过视频教程来学习,其中这里给大家分享一份与上面成长路线&学习计划相对应的视频教程。文末有整合包的领取方式
技术书籍籽料
当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,这里也分享一份我学习期间整理的大模型入门书籍籽料。文末有整合包的领取方式
大模型实际应用报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。文末有整合包的领取方式
大模型落地应用案例PPT
光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。文末有整合包的领取方式
大模型面试题&答案
截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。文末有整合包的领取方式
领取方式
这份完整版的 AI大模型学习籽料我已经上传CSDN,需要的同学可以微⭐扫描下方CSDN官方认证二维码免费领取!