Datawhale self-llm 实战:Qwen1.5-7B-Chat LoRA 微调接入 SwanLab 实验管理

发布时间:2026/9/20 8:41:40
Datawhale self-llm 实战:Qwen1.5-7B-Chat LoRA 微调接入 SwanLab 实验管理
大模型人工智能教程本地部署微调【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址https://gitcode.com/datawhalechina/self-llm点击查看免费下载本教程是《开源大模型食用指南》self-llm中 Qwen1.5 模型系列的第 8 篇在前序 LoRA 微调训练的基础上为 Qwen1.5-7B-Chat 的指令微调流程引入 SwanLab 实验管理平台实现训练过程的云端可视化跟踪、指标比较与团队协作。读者学完后将掌握一套数据格式化 → LoRA 微调 → SwanLab 可视化 → 权重加载推理的完整实战链路并能在未来任何基于 transformers peft 的微调任务中复用同样的实验管理方案。配套的 Notebook 版本见 08-Qwen1.5-7B-chat LoRA微调接入实验管理.ipynb不含实验管理的纯 LoRA 微调版本见 04-Qwen1.5-7B-chat Lora 微调.md两者可对照学习。环境配置本文基础环境如下---------------- ubuntu 22.04 python 3.12 cuda 12.1 pytorch 2.3.0 ----------------本文默认学习者已安装好以上 PyTorchCUDA环境如未安装请自行安装。仓库还在 AutoDL 平台提供了 Qwen1.5 环境镜像该镜像适用于本仓库除 Qwen-GPTQ 和 vLLM 外的所有部署环境。首先通过pip换源加速下载并安装依赖包各依赖版本与 Notebook 中实际运行验证的版本保持一致# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install modelscope1.16.1 pip install transformers4.43.2 pip install accelerate0.32.1 pip install peft0.11.1 pip install datasets2.20.0本节教程将微调数据集放置在仓库根目录 dataset/huanhuan.json实际训练时按你自己的数据存放路径读取即可。指令集构建LLM 的微调一般指指令微调Instruction Tuning过程。所谓指令微调是指我们使用的微调数据形如{ instruction:回答以下用户问题仅输出答案。, input:11等于几?, output:2 }其中instruction是用户指令告知模型其需要完成的任务input是用户输入是完成用户指令所必需的输入内容output是模型应该给出的输出。核心训练目标是让模型具备理解并遵循用户指令的能力。因此在指令集构建时应针对目标任务针对性地构建任务指令集。例如本节以模拟甄嬛对话风格的个性化 LLM 为目标该数据集源自 Chat-嬛嬛 项目构造的指令形如{ instruction: 你是谁, input:, output:家父是大理寺少卿甄远道。 }在 dataset/huanhuan.json 中可以看到这类对话样本的完整形态例如{ instruction: 皇上驾到, input: , output: 皇上万福金安。 }Notebook 中通过pd.read_json读取该 JSON 文件并转为 HuggingFaceDataset对象代码路径 08-Qwen1.5-7B-chat LoRA微调接入实验管理.ipynb 第 34-36 行from datasets import Dataset import pandas as pd df pd.read_json(./huanhuan.json) ds Dataset.from_pandas(df)格式化后数据集共包含 3729 条训练样本字段为instruction、input、output。数据格式化LoRA 训练的数据需要经过格式化、编码之后再输入给模型。熟悉 PyTorch 模型训练流程的同学知道我们需要将输入文本编码为input_ids将输出文本编码为labels编码之后的结果都是多维向量。首先定义一个预处理函数用于对每一个样本编码其输入、输出文本并返回一个编码后的字典def process_func(example): MAX_LENGTH 384 # 分词器会将一个中文字切分为多个token因此需要放开一些最大长度保证数据的完整性 input_ids, attention_mask, labels [], [], [] instruction tokenizer(f|im_start|system\n现在你要扮演皇帝身边的女人--甄嬛|im_end|\n|im_start|user\n{example[instruction] example[input]}|im_end|\n|im_start|assistant\n, add_special_tokensFalse) # add_special_tokens 不在开头加 special_tokens response tokenizer(f{example[output]}, add_special_tokensFalse) input_ids instruction[input_ids] response[input_ids] [tokenizer.pad_token_id] attention_mask instruction[attention_mask] response[attention_mask] [1] # 因为eos token咱们也是要关注的所以 补充为1 labels [-100] * len(instruction[input_ids]) response[input_ids] [tokenizer.pad_token_id] if len(input_ids) MAX_LENGTH: # 做一个截断 input_ids input_ids[:MAX_LENGTH] attention_mask attention_mask[:MAX_LENGTH] labels labels[:MAX_LENGTH] return { input_ids: input_ids, attention_mask: attention_mask, labels: labels }这里有几个关键设计labels掩码指令部分的 token 在labels中对应位置置为-100损失函数计算时会忽略-100的位置因此模型只学习助手回复部分的内容避免把 system / user 提示也当成生成目标attention_mask补 1末尾拼接了pad_token_idQwen1.5 的 pad token 即|endoftext|由于 EOS token 也需要被模型关注所以对应的 attention mask 补充为 1MAX_LENGTH 384截断BPE 分词器会把一个汉字拆成多个 token中文对话拼接后序列较长需要放宽最大长度并做截断保证数据完整性。随后使用Dataset.map批量处理并移除原始列tokenized_id ds.map(process_func, remove_columnsds.column_names)Notebook 中展示了格式化结果的验证第 198-222 行tokenizer.decode(tokenized_id[0][input_ids])还原出带|im_start|/|im_end|特殊 token 的完整训练文本而tokenizer.decode(list(filter(lambda x: x ! -100, tokenized_id[1][labels])))只解码出答案部分印证了 labels 掩码的正确性。Qwen1.5 采用的 ChatML Prompt Template 格式如下|im_start|system You are a helpful assistant.|im_end| |im_start|user 你是谁|im_end| |im_start|assistant 我是一个有用的助手。|im_end|加载 tokenizer 与半精度模型模型以半精度形式加载如果显卡较新可以用torch.bfloat16加载Notebook 实测模型 dtype 为torch.bfloat16。对于自定义模型一定要指定trust_remote_codeTruetokenizer AutoTokenizer.from_pretrained(./qwen/Qwen1.5-7B-Chat/, use_fastFalse, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained(./qwen/Qwen1.5-7B-Chat/, device_mapauto, torch_dtypetorch.bfloat16)从 Notebook 第 9 个单元格打印的模型结构可以看到Qwen1.5-7B-Chat在 transformers 4.43.2 中实际对应Qwen2ForCausalLM由 32 层Qwen2DecoderLayer组成每层包含self_attnQwen2Attentionq_proj、k_proj、v_proj输入输出均为 4096 维带 biaso_proj输出 4096 维无 bias并配备Qwen2RotaryEmbedding旋转位置编码mlpQwen2MLPgate_proj、up_proj将 4096 维映射到 11008 维down_proj映射回 4096 维激活函数为 SiLUinput_layernorm/post_attention_layernorm均为Qwen2RMSNorm。这个结构直接决定了下方LoraConfig中target_modules的取值——Qwen1.5 的全部 7 个线性投影层都是 LoRA 的可注入目标。定义 LoraConfigLoraConfig类中可以设置很多参数但主要的参数不多。需要特别注意的是LoRA 的缩放系数不是r秩而是lora_alpha / r。在本配置中缩放即为32 / 8 4倍。config LoraConfig( task_typeTaskType.CAUSAL_LM, target_modules[q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj], inference_modeFalse, # 训练模式 r8, # Lora 秩 lora_alpha32, # Lora alaph具体作用参见 Lora 原理 lora_dropout0.1 # Dropout 比例 )各参数要点task_type模型类型因果语言模型填TaskType.CAUSAL_LMtarget_modules需要训练的模型层名字主要是 attention 与 MLP 中的投影层。不同模型的层名不同可以传数组、字符串或正则表达式。对 Qwen1.5 而言结合上文模型结构7 个投影层q_proj / k_proj / v_proj / o_proj / gate_proj / up_proj / down_proj全部纳入rLoRA 的秩控制低秩矩阵的维度秩越大可学习参数量越多lora_alpha缩放超参数最终缩放因子为lora_alpha / rlora_dropoutLoRA 分支的 Dropout 比例用于缓解过拟合。将配置应用到模型并统计可训练参数from peft import LoraConfig, TaskType, get_peft_model model get_peft_model(model, config) model.print_trainable_parameters()Notebook 实测输出为trainable params: 19,988,480 || all params: 7,741,313,024 || trainable%: 0.2582052933143348即在约 77.4 亿总参数中仅约 2000 万参数0.26%参与训练——这正是 LoRA 高效微调的核心价值以极小的可训练参数量完成领域适配显存与训练成本大幅低于全量微调。自定义 TrainingArguments 参数TrainingArguments的源码对每个参数的作用都有说明这里讲解几个常用项output_dir模型输出路径per_device_train_batch_size单设备 batch_sizegradient_accumulation_steps梯度累加步数。如果显存较小可以把batch_size调小、梯度累加调大logging_steps多少步输出一次 lognum_train_epochs训练轮数gradient_checkpointing梯度检查点。一旦开启模型必须执行model.enable_input_require_grads()Notebook 第 10 个单元格有对应调用并注释开启梯度检查点时要执行该方法。args TrainingArguments( output_dir./output/Qwen1.5, per_device_train_batch_size4, gradient_accumulation_steps4, logging_steps10, num_train_epochs3, save_steps100, learning_rate1e-4, save_on_each_nodeTrue, gradient_checkpointingTrue )提示Notebook 实际运行中可以看到一条日志——use_cacheTrueis incompatible with gradient checkpointing. Settinguse_cacheFalse...即开启梯度检查点后 Trainer 会自动关闭 KV cache 以节省显存这是预期行为无需额外处理。接入 SwanLab 实现模型实验管理配置完训练参数后推荐使用模型实验管理工具记录实验的训练情况这样就不需要一直盯着服务器命令行的打印结果。SwanLab 是一个开源的 AI 实验跟踪工具提供跟踪、比较和协作实验的平台。接入流程只有三步第一步安装 SwanLabpip install swanlab第二步注册账号并获取 API-Key前往 SwanLab 官方网站注册账号手机注册即可然后进入个人设置界面获取 API-Key这是将训练数据上传到云端的关键凭证第三步确认框架集成支持SwanLab 已对主流开源框架做了集成其中就包括 HuggingFace Transformers 的 Trainer官方文档给出了SwanLabCallback的接入示例使用 Trainer 训练引入 SwanLab 后只需要实例化一个回调类再将其传入Trainer的callbacks列表即可实现微调训练的实验追踪from swanlab.integration.huggingface import SwanLabCallback swanlab_callback SwanLabCallback(projecthf-visualization) trainer Trainer( modelmodel, argsargs, train_datasettokenized_id, data_collatorDataCollatorForSeq2Seq(tokenizertokenizer, paddingTrue), callbacks[swanlab_callback], ) trainer.train()训练启动后会要求输入 SwanLab 的 API-Key只需要输入在个人设置界面获取的 API-Key 即可。Notebook 的示例运行记录显示trainer.train()单元格输出训练进度条推进到[134/699]、Epoch 0.57/3每 10 步打印一次训练损失例如 Step 10 的 loss 为 4.1535到 Step 130 已波动下降至 2.9357 左右。这些数值会同步被 SwanLab 记录供后续在云端查看与分析。提示DataCollatorForSeq2Seq(tokenizertokenizer, paddingTrue)负责在批内按最长序列做动态 padding保证同 batch 内 input_ids 长度一致是序列到序列训练的标准配套组件。查看训练进展SwanLab 支持在 Jupyter 界面中直接开启看板方便随时了解训练情况无需离开 Notebook 环境。Notebook 运行trainer.train()后单元格内会直接渲染出实验卡片、图表、日志与环境信息等面板并显示Tracking run with swanlab version 0.3.8之类的跟踪信息当然也可以直接登录 SwanLab 官网在个人账号下查看。图表视图会以折线图形式汇总展示train/loss、train/grad_norm、train/learning_rate、train/epoch等关键指标随训练步数的变化支持多指标对比分析与多实验横向比较相比裸用命令行盯日志这种方式的好处在于训练结束后指标曲线、超参配置、环境信息等实验元数据都被持久化在云端方便事后复盘、对比不同超参数组合的效果也便于团队成员协作共享实验结果。加载 LoRA 权重推理训练好之后可以使用如下方式加载 LoRA 权重进行推理from transformers import AutoModelForCausalLM, AutoTokenizer import torch from peft import PeftModel mode_path ./qwen/Qwen1.5-7B-Chat/ lora_path lora_path # 替换为你的 LoRA 权重保存路径如 ./output/Qwen1.5/checkpoint-100 # 加载tokenizer tokenizer AutoTokenizer.from_pretrained(mode_path) # 加载模型 model AutoModelForCausalLM.from_pretrained(mode_path, device_mapauto, torch_dtypetorch.bfloat16) # 加载lora权重 model PeftModel.from_pretrained(model, model_idlora_path, configconfig) prompt 你是谁 messages [ {role: system, content: 现在你要扮演皇帝身边的女人--甄嬛}, {role: user, content: prompt} ] text tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) model_inputs tokenizer([text], return_tensorspt).to(cuda) generated_ids model.generate( model_inputs.input_ids, max_new_tokens512 ) generated_ids [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0] print(response)要点说明PeftModel.from_pretrained(model, model_idlora_path, configconfig)将训练好的 LoRA 低秩适配权重叠加到基座模型上基座模型权重本身不变tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue)会自动套用 Qwen1.5 的 ChatML 模板并追加 assistant 生成提示generated_ids切片去掉了输入部分的 token只保留新生成的内容配合skip_special_tokensTrue得到干净的回复文本。总结至此我们完成了从环境搭建、指令数据构建、数据格式化、LoRA 配置到 SwanLab 可视化训练与推理验证的完整闭环。核心收获有三点LoRA 高效微调范式通过get_peft_model仅注入约 0.26% 的可训练参数约 2000 万 / 77.4 亿即可在单一任务模拟甄嬛对话风格上实现领域适配训练成本显著低于全量微调一键接入实验管理SwanLabCallback作为 HuggingFace Trainer 的标准回调callback机制成员只需实例化并传入callbacks[swanlab_callback]即可自动采集 loss、learning_rate、grad_norm 等指标并上传云端训练期间与训练结束后的复盘都无需值守命令行全程可复现本文所有代码与 Notebook 输出均可对照 08-Qwen1.5-7B-chat LoRA微调接入实验管理.ipynb 逐步验证数据文件位于 dataset/huanhuan.json。这一微调 实验管理的组合方案同样适用于仓库内其他模型的 LoRA/QLoRA 微调流程例如 07-Qwen2.5-7B-Instruct Lora 微调 SwanLab可视化记录版.md当你需要批量实验、对比超参数或与团队共享训练成果时SwanLab 的实验管理能力将带来直接的效率提升。赞分享大模型人工智能教程本地部署微调【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址https://gitcode.com/datawhalechina/self-llm点击查看免费下载相关推荐Datawhale self-llm 实战Baichuan2-7B-Chat LoRA 高效微调全流程指南transformers peftDatawhale self llm 实战Baichuan2 7B Chat LoRA 高效微调全流程指南transformers peft 本篇技术大模型人工智能教程本地部署微调Datawhale self-llm 实战基于 transformers 与 peft 的 Atom-7B-Chat LoRA 指令微调全流程Datawhale self llm 实战基于 transformers 与 peft 的 Atom 7B Chat LoRA 指令微调全流程 本文是《开源大大模型人工智能教程本地部署微调Datawhale self-llm 实战基于 PEFT 对 XVERSE-7B-Chat 进行 LoRA 高效微调全流程指南Datawhale self llm 实战基于 PEFT 对 XVERSE 7B Chat 进行 LoRA 高效微调全流程指南 导读 本指南基于《开源大模型食大模型人工智能教程本地部署微调创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考