ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Qwen1.5-7B-Chat LoRA 微调接入 SwanLab 实验管理:基于 transformers + peft 的完整实操指南

Qwen1.5-7B-Chat LoRA 微调接入 SwanLab 实验管理:基于 transformers + peft 的完整实操指南 Qwen1.5-7B-Chat LoRA 微调接入 SwanLab 实验管理基于 transformers peft 的完整实操指南【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm本文基于《开源大模型食用指南》仓库中 Qwen1.5 LoRA 微调接入实验管理文档完整演示如何用transformers、peft对 Qwen1.5-7B-Chat 进行 LoRA 指令微调并通过开源实验跟踪工具 SwanLab 对训练过程进行云端可视化监控。读完本文你将掌握指令微调数据集构建、数据格式化、LoRA 配置、Trainer 训练、SwanLab 回调接入以及 LoRA 权重加载推理的完整链路并能在训练过程中实时查看 loss、学习率等关键指标无需守在服务器命令行前盯日志。环境配置本文基础环境如下---------------- ubuntu 22.04 python 3.12 cuda 12.1 pytorch 2.3.0 ----------------本文默认学习者已安装好以上 PyTorch(cuda) 环境如未安装请自行安装。首先pip换源加速下载并安装依赖包# 升级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考虑到部分同学配置环境可能会遇到一些问题本仓库在 AutoDL 平台准备了 Qwen1.5 的环境镜像该镜像适用于本仓库除 Qwen-GPTQ 和 vllm 外的所有部署环境可直接创建 AutoDL 实例使用。本节教程将微调数据集放置在根目录 dataset/huanhuan.json该数据集由仓库随附包含 3729 条甄嬛风格的对话样本notebook 中Dataset(num_rows: 3729)可印证每条样本均为instruction/input/output三元组结构。指令集构建LLM 的微调一般指指令微调过程。所谓指令微调是指我们使用的微调数据形如{ instruction:回答以下用户问题仅输出答案。, input:11等于几?, output:2 }其中instruction是用户指令告知模型其需要完成的任务input是用户输入是完成用户指令所必须的输入内容output是模型应该给出的输出。即我们的核心训练目标是让模型具有理解并遵循用户指令的能力。因此在指令集构建时我们应针对目标任务针对性构建任务指令集。例如本节示例目标是构建一个能够模拟甄嬛对话风格的个性化 LLM因此构造的指令形如{ instruction: 你是谁, input:, output:家父是大理寺少卿甄远道。 }从仓库的 dataset/huanhuan.json 可以看到真实数据的风格例如instruction: 娘娘。对应output: 你放心本宫到任何时候都不会自轻自贱委屈了这孩子。。全部指令数据集位于根目录可在训练前自行查看和替换。数据格式化LoRA 训练的数据需要经过格式化、编码之后再输入给模型。熟悉 PyTorch 模型训练流程的同学知道我们一般需要将输入文本编码为input_ids将输出文本编码为labels编码之后的结果都是多维向量。首先定义一个预处理函数对每个样本编码其输入、输出文本并返回编码后的字典def process_func(example): MAX_LENGTH 384 # Llama分词器会将一个中文字切分为多个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中-100的作用指令部分system 与 user 内容的 token 对应位置填入-100这是 PyTorch 交叉熵损失约定俗成的忽略标记训练时只有 assistant 回复部分的 token 会参与 loss 计算保证模型只学习如何回复而非如何提问。pad_token_id的收尾序列末尾拼接tokenizer.pad_token_id作为结束符占位同时attention_mask对应位置补1让模型在注意力计算时关注到该位置因为 eos token 也需要被关注。MAX_LENGTH 384中文场景下分词器会将一个中文字切分为多个 token因此适当放开最大长度以保证数据完整性超长样本统一截断。add_special_tokensFalse避免在每个片段前重复添加特殊 token特殊标记由模板中的|im_start|、|im_end|手动控制。Qwen1.5采用的 Prompt Template 格式如下|im_start|system You are a helpful assistant.|im_end| |im_start|user 你是谁|im_end| |im_start|assistant 我是一个有用的助手。|im_end|在 对应的 notebook 中数据集通过pandas.read_json读取后转为Dataset再经ds.map(process_func, remove_columnsds.column_names)得到tokenized_id。你可以在 notebook 中用tokenizer.decode(tokenized_id[0][input_ids])验证格式化结果解码后形如|im_start|system 现在你要扮演皇帝身边的女人--甄嬛|im_end| |im_start|user 小姐别的秀女都在求中选唯有咱们小姐想被撂牌子菩萨一定记得真真儿的——|im_end| |im_start|assistant 嘘——都说许愿说破是不灵的。|endoftext|加载 tokenizer 和半精度模型模型以半精度形式加载如果你的显卡比较新可以用torch.bfloat16形式加载。对于自定义模型一定要指定trust_remote_code参数为True。tokenizer 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 的加载输出可以看到Qwen1.5-7B-Chat 的 tokenizer 为Qwen2Tokenizer词表大小 151643并注册了|im_start|、|im_end|、|endoftext|三个特殊 token模型结构为Qwen2ForCausalLM包含 32 层Qwen2DecoderLayer每层由Qwen2Attentionq/k/v/o 四个投影与Qwen2MLPgate/up/down 三个投影中间维度 11008构成lm_head输出维度与词表一致151936。这一结构直接决定了下方LoraConfig.target_modules应传入哪些层名。在开启梯度检查点后还需要执行model.enable_input_require_grads()否则部分模块在 checkpoint 重放时可能因输入无梯度而报错。定义 LoraConfigLoraConfig类中可以设置很多参数但主要的参数并不多下面简单讲解感兴趣的同学可以直接阅读 peft 源码task_type模型类型自回归语言模型填TaskType.CAUSAL_LM。target_modules需要训练的模型层的名字主要是 attention 部分的层不同模型对应的层名不同可以传入数组、字符串也可以使用正则表达式。Qwen1.5 对应的是注意力四投影加 MLP 三投影。rLoRA 的秩具体可参考 LoRA 原理。lora_alphaLoRA alpha具体作用参见 LoRA 原理。LoRA 的缩放因子不是r秩而是lora_alpha / r。在本节的LoraConfig中lora_alpha32、r8因此缩放为 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 比例 )对照 notebook 的输出可以验证get_peft_model(model, config)之后model.print_trainable_parameters()打印出trainable params: 19,988,480 || all params: 7,741,313,024 || trainable%: 0.2582052933143348即在 77 亿参数的模型中仅约 2000 万参数0.26%参与训练这正是 LoRA 高效微调的核心价值——以极小的显存和训练代价实现模型适配。若想进一步提高适配能力可增大r若显存紧张可适当调低r与lora_dropout对训练动态的影响较小但过高的 dropout 会降低收敛速度。自定义 TrainingArguments 参数TrainingArguments类的源码对每个参数的作用都有说明这里介绍几个常用的output_dir模型的输出路径。per_device_train_batch_size单卡 batch size。gradient_accumulation_steps梯度累加。如果显存比较小可以把batch_size设置小一点、梯度累加步数增大一些两者乘积决定等效 batch size。logging_steps每隔多少步输出一次 log。num_train_epochs训练轮数。gradient_checkpointing梯度检查点。一旦开启模型必须执行model.enable_input_require_grads()。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 )结合上述参数等效 batch size 为4 × 4 16每 10 步记录一次日志、每 100 步保存一次 checkpointsave_on_each_nodeTrue在多节点训练时每个节点都会保存权重。notebook 训练输出显示总步数为 699 步[134/699 ... Epoch 0.57/3]loss 从约 4.15 逐步下降到 2.8 左右可作为参考训练预期。另外需要注意的是开启gradient_checkpointing后 Transformers 会自动将use_cache置为Falsenotebook 中有对应 warning这是训练阶段的正常行为不影响微调后的推理。利用 SwanLab 实现模型实验管理配置完参数后推荐使用模型实验管理工具记录实验训练情况这样就不需要守在服务器命令行前盯着打印结果了。SwanLab 是一款开源、轻量级的 AI 实验跟踪工具提供跟踪、比较和协作实验的平台支持云端看板与图表可视化。SwanLab 的使用流程非常简单只需三步第一步安装库pip install swanlab第二步注册账号并获取 API-Key前往 SwanLab 官方网站注册账号通过手机注册即可然后进入个人设置界面获取 API-Key这是将本地实验数据上传到云端的关键凭证。第三步在代码中接入回调目前 SwanLab 已经对十几个主流的开源框架做了集成通过几行代码即可实现日志记录其中就包括对 HuggingFace Transformers Trainer 的支持。官方文档的集成列表中可以看到 Transformers 等框架均有对应的集成方案从仓库中的其他微调示例也可以印证 SwanLab 的两种典型接入方式在 MiniCPM-o LoRA 微调参考代码 中通过from swanlab.integration.transformers import SwanLabCallback引入回调并额外使用swanlab.Image/swanlab.log记录多模态预测样本最后调用swanlab.finish()结束记录在 DeepSeek-V4-Flash LoRA 训练脚本 中通过命令行参数--swanlab-project、--swanlab-experiment控制是否启用 SwanLab并动态构造SwanLabCallback(project..., experiment_name...)传入 Trainer 的callbacks。使用 Trainer 训练引入 SwanLab 后只需实例化一个回调类再将其传入 Trainer即可实现微调训练的实验追踪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 即可首次登录后凭证会被保存后续实验无需重复输入。回调机制的工作方式是SwanLabCallback挂接在 Trainer 的训练循环上自动捕获超参数TrainingArguments 与模型配置以及每一步的train_loss、learning_rate、grad_norm、epoch等指标并同步上传到云端项目hf-visualization下。注意notebook 示例中同时展示了swanlab.integration.huggingface与swanlab.integration.transformers两种导入路径前者为历史命名、后者为当前推荐路径二者本质一致按你安装的 SwanLab 版本选择即可。查看训练进展SwanLab 支持在 Jupyter 界面中直接开启看板方便实时了解训练情况当然也可以直接登录官网在个人账号下查看。云端看板会以曲线图形式展示train_loss训练损失、train_grad_norm梯度范数、total_learning_rate学习率、train_epoch训练轮次等多个维度的指标变化帮助你快速判断模型是否收敛、是否存在梯度爆炸或学习率异常等问题除了看曲线SwanLab 还支持将多次实验放在同一项目下进行对比方便在调整r、learning_rate、batch_size等超参数后比较各次实验的效果差异——这正是实验管理工具相比裸命令行打印的核心价值。加载 LoRA 权重推理训练好之后可以使用如下方式加载 LoRA 权重进行推理from transformers import AutoModelForCausalLM, AutoTokenizer import torch from peft import PeftModel mode_path ./qwen/Qwen1.5-7B-Chat/ lora_path lora_path # 加载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)推理要点说明加载路径lora_path指向训练时output_dir下保存的 checkpoint如./output/Qwen1.5/checkpoint-100训练脚本会在其中保存 LoRA adapter 权重与配置mode_path指向原始基座模型路径。apply_chat_template自动将messages列表按 Qwen1.5 的 chat 模板格式化为上述|im_start|风格文本并设置add_generation_promptTrue追加 assistant 起始标记保证与训练时的数据格式一致。skip_special_tokensTrue解码时剔除|endoftext|等特殊 token只保留纯文本回复。小结本文完整走通了数据构建 → 数据格式化 → 模型半精度加载 → LoRA 配置 → 训练参数配置 → SwanLab 实验追踪 → Trainer 训练 → 权重加载推理的整条链路。核心要点可归纳为LoRA 高效微调通过target_modules精准命中 Qwen1.5 的 q/k/v/o 与 gate/up/down 七个投影层仅 0.26% 参数参与训练即可完成风格化适配数据格式化是成败关键-100掩码、pad_token_id收尾、MAX_LENGTH截断三个细节直接决定模型能否正确学习只见回复、不见提问SwanLab 三步接入pip install swanlab→ 注册获取 API-Key →SwanLabCallback传入 Trainercallbacks即可获得云端 loss / lr / grad_norm 曲线与多实验对比能力。完整的可运行代码位于同目录的 08-Qwen1.5-7B-chat LoRA微调接入实验管理.ipynb可配合本仓库的 基础 LoRA 微调文档 对照学习。如果你希望进一步了解 Qwen1.5 的 FastApi 部署、LangChain 知识库接入或 vLLM 推理也可在本仓库 models/Qwen1.5 目录下找到对应教程。【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表