通过参加昇思学习营的LoRA微调实战课程,我深入理解了LoRA技术在模型微调中的应用。LoRA通过仅训练少量参数,显著降低了计算资源需求,同时保持了模型性能。课程中的实践操作,如数据预处理、LoRA配置和训练过程,让我掌握了实际操作技能。
本次课程代码,基于MindSpore和MindNLP框架,使用LoRA(参数高效微调)方法对DeepSeek-R1-Distill-Qwen-1.5B模型进行微调的完整流程,目标是让模型模仿特定风格(如《甄嬛传》甄嬛口吻)进行对话。
一、环境与依赖导入
# MindNLP核心组件:模型、分词器、训练工具、数据集、生成配置、PEFT(LoRA)
# 模型保存与回调相关工具
# 魔乐社区数据集下载工具
- 导入了MindNLP中用于模型加载、数据处理、训练控制的核心模块,以及PEFT(参数高效微调)相关的LoRA工具。
disable_multi_thread():禁用多线程以避免训练中的资源冲突,提升微调稳定性。
二、数据集下载与加载
# 从魔乐社区下载《甄嬛传》风格对话数据集(huanhuan.json)
om_hub_download:从华为魔乐社区下载公开的huanhuan数据集(包含模仿甄嬛口吻的对话数据)。load_dataset:使用MindNLP的数据集加载工具读取JSON文件,返回可处理的数据集对象。
三、分词器初始化与数据预处理
1. 分词器配置
- 分词器的作用是将文本转换为模型可识别的token ID,这里适配了
DeepSeek-R1-Distill-Qwen-1.5B模型的词表。
2. 数据处理函数(核心)
def process_func(instruction, input, output):
MAX_SEQ_LENGTH = 64 # 定义最长序列长度(根据数据特点调整)
input_ids, attention_mask, labels = [], [], []
# 构建对话模板:模拟"User提问-Assistant回答"格式
# User部分:instruction(指令)+ input(补充信息)
formatted_instruction = tokenizer(f"User: {instruction}{input}\n\n", add_special_tokens=False)
# Assistant部分:output(目标回答,即甄嬛风格的回复)
formatted_response = tokenizer(f"Assistant: {output}", add_special_tokens=False)
# 拼接输入:User文本 + Assistant文本 + 终止符(eos_token)
input_ids = formatted_instruction["input_ids"] + formatted_response["input_ids"] + [tokenizer.pad_token_id]
# 注意力掩码:1表示有效token,0表示填充token(User和Assistant部分均有效)
attention_mask = formatted_instruction["attention_mask"] + formatted_response["attention_mask"] + [1]
# 标签:仅对Assistant部分计算损失(User部分设为-100,训练时忽略)
labels = [-100] * len(formatted_instruction["input_ids"]) + formatted_response["input_ids"] + [tokenizer.pad_token_id]
# 截断:超过最大长度时保留前MAX_SEQ_LENGTH个token
if len(input_ids) > MAX_SEQ_LENGTH:
input_ids = input_ids[:MAX_SEQ_LENGTH]
attention_mask = attention_mask[:MAX_SEQ_LENGTH]
labels = labels[:MAX_SEQ_LENGTH]
# 填充:不足最大长度时用pad_token填充
padding_length = MAX_SEQ_LENGTH - len(input_ids)
input_ids = input_ids + [tokenizer.pad_token_id] * padding_length
attention_mask = attention_mask + [0] * padding_length # 填充部分掩码为0
labels = labels + [-100] * padding_length # 填充部分标签忽略
return input_ids, attention_mask, labels
- 核心逻辑:将原始数据(instruction/input/output)转换为模型训练所需的
input_ids(输入序列)、attention_mask(注意力掩码)和labels(损失计算标签)。 - 关键技巧:通过
labels = [-100] * len(User部分),让模型在训练时只学习Assistant的回答部分(忽略User的提问部分),确保微调聚焦于目标风格的生成。
3. 数据集格式化与裁剪
dataset.map:批量处理原始数据,生成训练所需的特征列。- 裁剪数据集是为了减少演示时间,实际微调需使用完整数据。
四、模型加载与LoRA配置
1. 基础模型加载
AutoModelForCausalLM:加载支持文本生成的预训练模型,FP16版本可减少显存占用。
2. LoRA参数高效微调配置
- LoRA核心思想:冻结预训练模型的大部分参数,仅在关键层(如注意力Q/K/V投影、FFN层)添加低秩矩阵旁支,通过训练旁支参数实现微调。
- 优势:相比全参数微调,参数量减少99%以上,显存需求大幅降低,同时保持相近效果。
五、训练配置与回调函数
1. 自定义回调函数(保存LoRA权重)
- 作用:训练过程中仅保存LoRA的适配器权重(
adapter_model),而非完整的预训练模型,大幅减少存储占用。
2. 训练超参数配置
Trainer是MindNLP封装的训练控制类,自动处理训练循环、梯度更新、权重保存等流程。- 执行后,模型将在
huanhuan数据集上微调,学习甄嬛风格的对话生成模式,最终保存LoRA适配器权重。
总结
基于上述代码完整实现了参数高效微调的核心流程:
- 下载并预处理特定风格的对话数据集;
- 加载预训练语言模型并配置LoRA低秩适配层;
- 通过自定义训练参数和回调函数,高效训练并保存LoRA权重。
通过LoRA方法,仅需训练少量参数(约0.5%)即可让模型学习目标风格,大幅降低了硬件门槛,适合在边缘设备(如香橙派AIpro)或云端轻量环境中部署。后续可通过加载LoRA权重,让原始模型具备甄嬛风格的对话能力。