跳到主要内容大语言模型 LLM 微调策略详解 | 极客日志PythonAI算法
大语言模型 LLM 微调策略详解
本文详细介绍了大语言模型(LLM)的微调策略,重点阐述了参数高效微调(PEFT)技术。文章首先分析了微调的应用场景,包括语言学习、可控输出、角色定制及小参数模型优化。随后深入探讨了 PEFT 的三大类别:基于添加、选择和重新参数化的方法,并具体讲解了适配器(Adapters)、低秩适配(LoRA)和 IA3 的原理与优势。文中还提供了基于 Hugging Face 库的 LoRA 实战代码示例,帮助开发者理解如何在实际环境中实施微调。最后总结了微调考量的关键因素,为技术选型提供参考。
暗影行者1 浏览 大语言模型(LLM)借助大规模数据集进行训练,能够在零样本或少样本提示下完成多种任务。随着检索增强生成(RAG)方法的兴起,这些通用模型越来越多地被组织用于各种应用,从简单的聊天机器人到更复杂的智能自动化代理。尽管像 GraphRAG 这样的技术已经被开发出来,用于基于实体跨文档提取关系,但由于基础模型缺乏足够的上下文,这些技术可能无法完全满足每个领域的特定需求。这一局限性导致每月都有新的模型不断被推出。
对于领域特定的模型,可以在现有 LLM 架构的基础上调整其权重,使其学习特定领域的上下文信息,这一过程被称为微调(fine-tuning)。在本文中,我们将探讨语言模型的微调过程,分析微调的多种类型、涉及的关键考虑因素,并举例介绍一种几乎无需编码的开源工具。
什么是微调
为了更好地理解微调,我们用一个类比来说明。想象你是一名学生,正在为一场科学考试做准备。你从课堂上获得了扎实的基础知识。随着考试临近,你开始专注于即将考查的特定主题。你通过练习题检验自己的理解,然后根据表现重新审视相关的学习材料。与此同时,你可能会向朋友寻求指导、查阅在线资源或重温关键主题。
这一过程与微调非常相似:我们利用一个经过预训练的模型(就像拥有扎实基础的学生),让它专注于特定任务(复习特定主题),评估其表现(通过练习测试),并反复迭代,直到根据性能指标实现最佳结果。正如一个学生能够在特定领域达到精通一样,我们也可以开发一个在某些领域或多个领域都表现卓越的语言模型。最终,这一过程的成效取决于所选模型、具体任务以及所使用训练数据的质量。
微调应用场景
在深入探讨微调之前,让我们通过一些场景分析它为何必要。
1. 语言学习与多模态支持
以下是两个 Llama 版本在回答泰米尔语问题时的对比。基础版本的 Llama 模型难以理解请求的语言,而经过微调的模型则能够流利地用泰米尔语响应。这一能力来自微调过程,使模型能够学习并识别新语言中的模式。
简单的 RAG 应用无法有效地将新上下文与现有知识联系起来。在需要模型整合和学习多样化上下文的情况下,微调显得尤为重要。
![图:基础模型与微调后模型在多语言任务上的表现对比]
2. 可控输出与安全
大模型开发中的一个重要挑战是大模型的可控输出。假设一个税务助手 AI 突然开始回答心理健康相关的问题。这种多功能性固然令人惊叹,但也可能带来风险,尤其是在涉及敏感领域时。
即使通过指令限制模型不回答特定问题,也存在以下问题:
- 提示注入攻击(Prompt Hacking):用户可以通过操纵输入绕过限制。
- 上下文窗口问题:大模型的上下文窗口有限,尽管像 Llama 3.1 提供 128k 的上下文窗口,但过多的指令仍然会占用实际内容的空间。
有效的提示模板可以有所帮助,但无法涵盖所有可能的细微差别。即使上下文窗口变大,也不能完全解决问题,这使得微调成为更可靠的选择。例如,Meta 推出的 LlamaGuard 是一个经过微调的 Llama 版本,用于防止有害响应并强化聊天安全。
3. 角色定制与风格对齐
新闻媒体通常报道相同的新闻,但每个渠道的视角和风格都不同。想象一个辅助写作的聊天助手,通过多个来源收集信息。如果您使用预训练模型(如 ChatGPT),通过设计有效的用户指令和系统提示可以生成有用的新闻摘要。然而,这些内容可能并不完全符合您组织的风格或准则。
通过使用您团队撰写的新闻文章对模型进行微调,可以确保生成的内容始终符合您的组织语调和标准。此外,许多初创企业正在开发企业级 AI 角色,简化重复性任务。
4. 小参数但智能
实现卓越表现并不总需要庞大的模型。参数规模较小的模型(甚至仅有几百万参数)通常能够以更高的效率完成特定任务,同时节约运行成本。这一策略显著降低了模型运行和维护的成本。
本文将探讨一种称为**参数高效微调(PEFT)**的技术。这一方法利用矩阵分解将大模型转换为更小、更易管理的形式,从而避免使用全部参数以完成目标任务。
微调考量
- 数据充足性:是否拥有足够的数据用于有效训练模型?通常需要高质量的对齐数据(Instruction Data)。
- 硬件可用性:是否有必要的硬件用于训练和运行模型?全量微调需要大量 GPU 显存。
- RAG 策略:问题是否可以通过现有 LLM API 和 RAG 方法解决?如果仅需更新知识库,RAG 可能更优。
- 上线时间:您需要多快将服务投入使用?微调周期较长,需预留训练时间。
这些考虑因素将帮助您判断是否应采用微调方法,或者通过现有 API 结合打造统一产品。
参数高效微调 (PEFT)
参数高效微调(PEFT)是一种技术,其核心思想是并非需要更新大型语言模型(LLM)的所有参数才能实现最佳性能。通过冻结大多数参数,仅优化一小部分关键参数,可以显著减少微调所需的计算资源和时间。
想象一间教室里有一名学生,在许多学科中表现优秀,但在某些特定领域需要提高。与其彻底重建整个课程,老师会在这些领域提供有针对性的额外练习。这种方法效率更高,因为它基于学生现有的知识,集中资源在最需要的地方。同样,在 PEFT 中,我们仅优化最具影响力的权重。
通过冻结大多数参数、继续使用残差连接(residual connections)、并应用适当的正则化技术,这些模型能够保留其已有知识,从而避免灾难性遗忘(catastrophic forgetting)。例如,像 GaLore 这样的方法使得在个人计算机上微调大型模型(如 Llama-3)成为可能,从而让高级语言建模更易于实现。
- 基于添加 (Addition-based):通过在现有模型中添加新的可训练参数模块来实现微调。这些新增模块通常会减少对原始模型参数的修改,从而提高训练效率。
- 基于选择 (Selection-based):从基础模型中选择一个参数子集进行微调,而不是对整个模型的所有参数进行优化。这种方法通过专注于最相关的参数,显著降低计算成本。
- 基于重新参数化 (Reparametrization-based):使用替代表示形式对模型进行微调。例如,通过将权重矩阵分解为低秩表示,仅优化分解后的小部分参数。
接下来,我们将探讨几种代表性的 PEFT 技术,需注意的是,这些技术并非相互排斥,可以结合使用。
适配器(Adapters)
适配器属于**基于添加(Addition-based)**的 PEFT 方法。它们是添加到现有 Transformer 架构中的前馈模块,用于减少全连接层之间的参数空间。
假设一个全连接层将 256 维输入降维到 16 维,然后下一个全连接层将其重新升维回 256 维。计算其参数数量为:256 x 16 + 16 x 256 = 8192
相比之下,单个全连接层直接将 256 维输入映射到 256 维输出需要:256 x 256 = 65536
通过这种方式,适配器模块显著减少了参数数量。在适配器微调中,仅对适配器模块、层归一化(Layer Norms)和最终输出层进行训练,而不是调整整个模型的所有参数。这使得训练更快且更高效。
低秩适配 (LoRA)
这是一种**重新参数化(Reparameterization)**的方法,通过采用语言模型的替代表示形式进行微调。该技术通过将注意力层中的大权重矩阵分解为两个较小的矩阵,显著减少了微调过程中需要调整的参数数量。与直接分解矩阵不同,它从分解后的表示(伪分解)中进行学习。
相比于向模型添加新参数,LoRA 方法专注于这种替代表示形式。一般共识是根据训练数据量和模型规模设置秩(rank)r,以缓解过拟合问题并有效管理模型预算。同时,研究表明 LoRA 的特性是'学得少,忘得少',这也是预期的结果。
假设我们有两个矩阵 A 和 B,分别包含 100 和 500 个参数。那么,总的权重参数数量 WA 和 WB 为:
WA x WB = 100 * 500 = 50000
现在假设秩(rank)为 5,新生成的权重矩阵 WA 和 WB 分别为:
WA = 100 x 5 = 500,WB = 500 x 5 = 2500
相比原始的 50,000 个参数,这减少了 94%。
通过抑制和放大内部激活的注入式适配器 (IA3)
IA3 是另一种基于添加的微调方法,涉及三个阶段:向量添加、重新缩放(抑制/放大)以及下游任务的微调。在微调过程中,学习到的向量用于对模型中相应的元素进行重新缩放。这种缩放可以根据学习向量的值来**抑制(减少)或放大(增加)**激活值。通过这种方式,模型在特定任务中调整其表现。最终,这些重新缩放的向量在下游任务中微调,随着微调过程的进行,向量不断更新以优化模型性能。
- 键值重新缩放向量(Key Rescaling Vector):该向量与自注意力层中的键(keys)相乘。
- 值重新缩放向量(Value Rescaling Vector):该向量与自注意力层以及编码器 - 解码器注意力层中的值(values)相乘。
- 中间激活重新缩放向量(Intermediate Activation Rescaling Vector):该向量与位置前馈网络中的中间激活相乘。
这种方法可以简单理解为,模型在处理输入数据时,会针对不同的任务'调整音量'。'音量大'意味着放大激活值,'音量小'意味着抑制激活值,从而灵活地适应任务需求。比如,在文本分类任务中,模型可能需要放大与关键主题词相关的激活值,而抑制无关词的激活值,以确保准确地分类。同样地,在机器翻译任务中,模型可能会放大与句子语法结构相关的激活值,而对不影响翻译质量的冗余信息进行抑制。通过这种方式,IA3 不仅能够以最少的参数调整完成对任务特定需求的适配,还能提高计算效率,减少过拟合风险,保持模型整体性能。
LoRA 实战代码示例
为了更直观地理解 LoRA 的应用,以下提供一个基于 Hugging Face peft 库的 LoRA 微调代码示例。此示例展示了如何加载预训练模型、配置 LoRA 参数并进行训练。
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
import torch
model_name = "meta-llama/Llama-2-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_4bit=True,
device_map="auto"
)
model = prepare_model_for_kbit_training(model)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
training_args = TrainingArguments(
output_dir="./lora_finetuned_model",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
num_train_epochs=3,
fp16=True,
logging_steps=10,
save_strategy="epoch"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
tokenizer=tokenizer
)
trainer.train()
上述代码展示了如何使用 peft 库快速集成 LoRA。关键点在于 target_modules 的选择,通常选择 Attention 层的 Query 和 Value 投影矩阵能获得较好的效果。通过 print_trainable_parameters() 可以查看可训练参数量占总参数的比例,验证 PEFT 的效率。
总结
大模型微调是提升模型在特定领域表现的关键手段。从全量微调到参数高效微调(PEFT),技术的演进使得在有限的计算资源下实现高性能成为可能。LoRA 和 Adapters 等方法通过冻结主干参数,仅训练少量附加参数,大幅降低了显存需求和训练时间。在实际应用中,开发者应根据数据规模、硬件条件和业务需求选择合适的微调策略。未来,随着更多高效微调算法的出现,大模型的定制化部署将更加普及和便捷。
通过本文的介绍,希望读者能够对 LLM 微调策略有更深入的理解,并在实际项目中灵活运用这些技术。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online