self-llm 实战:基于 Hugging Face transformers 与 PEFT 对 GLM-4-9B-Chat-hf 进行 LoRA 微调

发布时间:2026/9/19 22:16:28
self-llm 实战:基于 Hugging Face transformers 与 PEFT 对 GLM-4-9B-Chat-hf 进行 LoRA 微调 self-llm 实战基于 Hugging Face transformers 与 PEFT 对 GLM-4-9B-Chat-hf 进行 LoRA 微调【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm本指南以《开源大模型食用指南》self-llm项目中的 GLM-4 模型教程为主线完整演示如何在 24G 显存显卡上基于transformers 4.46.0、peft与datasets等框架对 Hugging Face 标准化的 GLM-4-9B-Chat-hf 模型执行 LoRA 指令微调并以「甄嬛」风格对话数据集为例训练出具有特定人设的个性化大模型。读完本文你将掌握 GLM-4-9B 对话模型的下载、指令数据格式化、LoRA 参数配置、Trainer 训练、权重保存与加载推理的全链路实操能力。本文基于 models/GLM-4/05-GLM-4-9B-chat-hf Lora 微调.md 撰写配套可运行的 Notebook 位于 05-GLM-4-9B-chat-hf Lora 微调.ipynb训练数据为仓库根目录下的 huanhuan.json。前置说明为什么要用 GLM-4-9B-chat-hfGLM-4-9B 系列对话模型不含视觉模型的实现已经被 Hugging Facetransformers官方合并并标准化。自transformers 4.46.0 版本起原有的GLM4-9B-chat模型依赖trust_remote_code加载自定义代码可能无法正常使用。因此本教程使用官方标准化的ZhipuAI/glm-4-9b-chat-hf权重并强制要求transformers4.46.0这正是本文与仓库中另一篇 05-GLM-4-9B-chat Lora 微调.md 的核心差异对比项05-GLM-4-9B-chat旧版05-GLM-4-9B-chat-hf本教程模型权重ZhipuAI/glm-4-9b-chatZhipuAI/glm-4-9b-chat-hftransformers 版本4.40.04.46.0LoRA 目标模块query_key_value、dense、dense_h_to_4h、dense_4h_to_hq_proj、k_proj、v_proj、o_proj、gate_proj、up_proj、down_proj从模型结构上看可参见 Notebook 中model的打印输出标准化后的模型由ChatGLMForConditionalGeneration包装transformer内含word_embeddings词表 151552、rotary_pos_emb旋转位置编码与 40 层GLMBlock每个块包含self_attentionquery_key_value将 4096 维映射到 4608 维、dense输出投影与MLPdense_h_to_4h映射到 27392 维、dense_4h_to_h还原。这决定了 LoRA 适配器应挂载在哪一层上。环境准备在 AutoDL 上租用 24G 显存机器在 AutoDL 平台租赁一台3090 等 24G 显存的显卡机器创建实例时按如下配置选择镜像框架名称PyTorch框架版本2.1.0Python 版本3.10 (ubuntu22.04)CUDA 版本12.1实例创建完成后打开 JupyterLab 并启动其中的终端后续的环境配置、模型下载与训练演示均在终端内完成。环境配置安装依赖库在完成基本环境配置后还需安装以下第三方库本教程所有关键版本均被钉死避免版本漂移导致兼容性问题python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install modelscope1.9.5 pip install transformers4.46.0 pip install streamlit1.24.0 pip install sentencepiece0.1.99 pip install accelerate0.29.3 pip install datasets2.19.0 pip install peft0.10.0 pip install tiktoken0.7.0 MAX_JOBS8 pip install flash-attn --no-build-isolation各依赖的作用modelscope国内模型下载通道用于拉取glm-4-9b-chat-hf权重transformers4.46.0必须满足 4.46.0 及以上否则 GLM-4-9B 官方标准化实现无法正确加载peft提供LoraConfig、PeftModel等 LoRA 微调核心 APIdatasets将 JSON 指令集转换为Dataset对象并做批量预处理accelerate支撑device_mapauto的多设备自动调度与 Trainer 底层加速sentencepiece/tiktokentokenizer 分词所需的底层依赖flash-attnFlash Attention 加速库安装耗时较长约十几分钟属正常现象。注意若在 Notebook 中执行还需确认flash-attn已成功编译安装训练时若显存紧张可先不启用 flash attention。数据集准备与模型下载本教程使用仓库根目录下的 huanhuan.json共 3729 条对话样本作为微调数据集目标是让模型学会「甄嬛」风格的应答。使用modelscope的snapshot_download函数下载模型第一个参数为模型名称cache_dir为模型下载路径。在/root/autodl-tmp下新建model_download.pyimport torch from modelscope import snapshot_download, AutoModel, AutoTokenizer import os model_dir snapshot_download(ZhipuAI/glm-4-9b-chat-hf, cache_dir/root/autodl-tmp/glm-4-9b-chat, revisionmaster)保存后执行python /root/autodl-tmp/model_download.py即可完成下载模型最终会存放在/root/autodl-tmp/glm-4-9b-chat/ZhipuAI/glm-4-9b-chat目录下后续加载路径与此对应。指令集构建让模型学会遵循指令LLM 的微调一般指指令微调Instruction Tuning即训练数据形如{ instruction: 回答以下用户问题仅输出答案。, input: 11等于几?, output: 2 }字段语义instruction用户指令告知模型需要完成的任务input用户输入是完成任务所必需的输入内容output模型应当给出的标准输出。核心训练目标是让模型获得理解并遵循用户指令的能力因此指令集必须围绕目标任务针对性构建。本教程以「模拟甄嬛对话风格的个性化 LLM」为目标构造的指令形如{ instruction: 你是谁, input: , output: 家父是大理寺少卿甄远道。 }打开 huanhuan.json 可以看到全部指令数据例如{ instruction: 娘娘。, input: , output: 你放心本宫到任何时候都不会自轻自贱委屈了这孩子。 }数据格式化构造 input_ids / attention_mask / labelsLoRA 训练数据需要经过格式化、编码后才送入模型。熟悉 PyTorch 训练流程的同学都知道输入文本需编码为input_ids输出文本需编码为labels用于计算交叉熵损失编码结果均为多维向量。为此定义预处理函数process_func对每个样本编码输入、输出文本并返回编码字典def process_func(example): MAX_LENGTH 384 input_ids, attention_mask, labels [], [], [] instruction tokenizer((f[gMASK]sop|system|\n假设你是皇帝身边的女人--甄嬛。|user|\n f{example[instruction]example[input]}|assistant|\n ), add_special_tokensFalse) 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 }这段代码的关键设计点Prompt 模板GLM-4-9B-Chat 采用的模板格式为[gMASK]sop开头后接|system|系统提示、|user|用户输入、|assistant|模型回答三段式结构[gMASK]sop|system| 假设你是皇帝身边的女人--甄嬛。|user| 小姐别的秀女都在求中选唯有咱们小姐想被撂牌子菩萨一定记得真真儿的——|assistant| 嘘——都说许愿说破是不灵的。|endoftext|labels 掩码instruction部分系统提示 用户输入的 labels 置为-100在 PyTorch 交叉熵损失中-100会被自动忽略只有response模型输出部分参与损失计算这是指令微调只学回答、不学提问的标准做法结尾补 pad_token_id在input_ids、attention_mask与labels末尾各追加一个 token保证序列以 pad 符闭合截断策略MAX_LENGTH384超过则直接裁剪防止超长样本撑爆显存。在 Notebook 中通过ds.map(process_func, remove_columnsds.column_names)对整个数据集批量处理最终得到一个包含input_ids、attention_mask、labels三列、共3729 行的Dataset用tokenizer.decode可以验证模板拼接正确性如[151331, 151333, 151335]正是[gMASK] sop |system|的 token 序列。加载 tokenizer 与半精度模型模型以**半精度bfloat16**加载若显卡较新可用torch.bfloat16获得更好的数值稳定性。对于通过trust_remote_code加载的自定义实现必须将trust_remote_code置为Truetokenizer AutoTokenizer.from_pretrained(/root/autodl-tmp/glm-4-9b-chat/ZhipuAI/glm-4-9b-chat, use_fastFalse, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained(/root/autodl-tmp/glm-4-9b-chat/ZhipuAI/glm-4-9b-chat, device_mapauto,torch_dtypetorch.bfloat16, trust_remote_codeTrue)参数说明device_mapauto由 accelerate 自动将 10 个 checkpoint shard 分配到可用设备Notebook 中可见 Loading checkpoint shards: 0/10支持单卡或多卡torch_dtypetorch.bfloat16以 BF16 半精度加载单卡 24G 显存即可容纳 9.4B 参数use_fastFalse使用经典非 fasttokenizer与 GLM-4 分词器兼容性更好trust_remote_codeTrue允许执行仓库内自定义代码模型与分词器实现。加载后若启用梯度检查点gradient_checkpointingTrue还需执行model.enable_input_require_grads()为冻结权重下的输入张量保留梯度通路Notebook 中有对应调用。定义 LoraConfig挂载哪些层、秩与缩放LoraConfig可配置参数很多核心参数如下task_type模型类型因果语言模型填TaskType.CAUSAL_LMtarget_modules需要注入 LoRA 适配器的层名主要是 attention 与 MLP 中的线性层可传数组、字符串或正则表达式rLoRA 的秩rank控制低秩矩阵的维度lora_alphaLoRA 的缩放因子 alphalora_dropout适配器中的 Dropout 比例用于缓解过拟合inference_modeFalse声明当前为训练模式。需要特别澄清 LoRA 的缩放机制实际缩放系数是lora_alpha / r而不是r本身。本配置中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 比例 )注意由于本教程面向 transformers 4.46.0 标准化的glm-4-9b-chat-hftarget_modules使用的是与 LLaMA 系一致的q_proj / k_proj / v_proj / o_proj / gate_proj / up_proj / down_proj命名可对照 examples/Chat-嬛嬛/train.py 中 Llama-3.1 微调的写法两者模块名完全相同而旧版非 hf 模型使用query_key_value、dense、dense_h_to_4h、dense_4h_to_h两者不可混用。将配置应用到模型后用get_peft_model包装并打印可训练参数占比。从 Notebook 的实际运行结果看trainable params: 21,176,320 || all params: 9,421,127,680 || trainable%: 0.2248即在约 94.2 亿总参数中仅约2118 万0.22%的参数参与训练这正是 LoRA 高效微调的核心体现——冻结全部基座权重只训练注入的低秩适配器显著降低显存与算力开销。自定义 TrainingArguments训练超参TrainingArguments的源码对每个参数都有详细注释这里说明本教程用到的几个关键项output_dir模型输出checkpoint、日志路径per_device_train_batch_size单卡 batch sizegradient_accumulation_steps梯度累加步数显存较小时可调小 batch size、调大累加步数等效放大 batchlogging_steps每多少步输出一次 lognum_train_epochs训练轮数save_steps每多少步保存一次 checkpointlearning_rate学习率save_on_each_node多节点训练时每节点各自保存gradient_checkpointing梯度检查点开启后必须先执行model.enable_input_require_grads()原理是牺牲少量计算时间换取激活值不驻留显存可大幅降低显存占用。args TrainingArguments( output_dir./output/GLM4, per_device_train_batch_size1, gradient_accumulation_steps8, logging_steps50, num_train_epochs2, save_steps100, learning_rate1e-5, save_on_each_nodeTrue, gradient_checkpointingTrue )本配置下实际等效 batch size 为1 × 8 8。从 Notebook 的训练输出可见共执行932 步、2 个 epoch训练 loss 由初期的 3.84 稳步下降至 2.61 附近最终train_loss2.836训练耗时约 21 分钟说明该超参组合在 24G 显存下收敛平稳、开销可控。使用 Trainer 训练组装Trainer并开始训练trainer Trainer( modelmodel, argsargs, train_datasettokenized_id, data_collatorDataCollatorForSeq2Seq(tokenizertokenizer, paddingTrue), ) trainer.train()要点说明train_dataset传入经process_func预处理后的tokenized_iddata_collator使用DataCollatorForSeq2Seq训练时会按 batch 内最长序列做padding并自动将labels中的-100与pad_token_id对齐避免 padding 位置参与损失计算trainer.train()内部由 transformers 封装了前向、反向、优化器更新与日志记录全流程无需手写训练循环。保存 LoRA 权重训练完成后只需保存 LoRA 适配器与 tokenizer无需保存 9.4B 的完整基座权重PeftModel 保存的仅是注入的低秩矩阵体积通常在几十 MB 量级lora_path./GLM4 trainer.model.save_pretrained(lora_path) tokenizer.save_pretrained(lora_path)从 Notebook 输出可见tokenizer.save_pretrained会在./GLM4_lora目录下生成tokenizer_config.json、special_tokens_map.json、tokenizer.model、added_tokens.json等文件与适配器权重共同构成一份可独立分发的 LoRA 产物。加载 LoRA 权重推理训练完成后用PeftModel将 LoRA 适配器挂载回基座模型进行推理from transformers import AutoModelForCausalLM, AutoTokenizer import torch from peft import PeftModel mode_path /root/autodl-tmp/glm-4-9b-chat/ZhipuAI/glm-4-9b-chat lora_path ./GLM4_lora # 加载tokenizer tokenizer AutoTokenizer.from_pretrained(mode_path, trust_remote_codeTrue) # 加载模型 model AutoModelForCausalLM.from_pretrained(mode_path, device_mapauto,torch_dtypetorch.bfloat16, trust_remote_codeTrue).eval() # 加载lora权重 model PeftModel.from_pretrained(model, model_idlora_path) prompt 你是谁 inputs tokenizer.apply_chat_template([{role: system, content: 假设你是皇帝身边的女人--甄嬛。},{role: user, content: prompt}], add_generation_promptTrue, tokenizeTrue, return_tensorspt, return_dictTrue ).to(cuda) gen_kwargs {max_length: 2500, do_sample: True, top_k: 1} with torch.no_grad(): outputs model.generate(**inputs, **gen_kwargs) outputs outputs[:, inputs[input_ids].shape[1]:] print(tokenizer.decode(outputs[0], skip_special_tokensTrue))关键细节对话模板构造使用tokenizer.apply_chat_template按system / user角色消息自动套用 GLM-4 的 chat 模板add_generation_promptTrue会在末尾追加|assistant|以触发生成return_dictTrue使inputs直接可作为model.generate的 kwargs生成参数max_length2500限制最大生成长度do_sampleTrue开启采样top_k1等价于贪心解码只取概率最高的 token输出截取outputs[:, inputs[input_ids].shape[1]:]去掉输入部分只保留新生成的 token效果验证Notebook 的实际运行结果为我是甄嬛家父是大理寺少卿甄远道。说明模型已成功习得「甄嬛」人设LoRA 微调链路完整打通。总结与延伸至此一条完整的 GLM-4-9B-Chat-hf LoRA 微调链路已经跑通环境准备 → 依赖安装 → 模型下载 → 指令集构建 → 数据格式化 → 半精度加载 → LoraConfig → TrainingArguments → Trainer 训练 → 权重保存 → PeftModel 推理。全文涉及的核心文件均可从仓库直接获取教程文档与 Notebookmodels/GLM-4/05-GLM-4-9B-chat-hf Lora 微调.md、05-GLM-4-9B-chat-hf Lora 微调.ipynb训练数据集dataset/huanhuan.json同类微调参考实现examples/Chat-嬛嬛/train.pyLlama-3.1-8B-Instruct 版可对照理解 LoRA 流程的通用性旧版非 hfGLM-4 LoRA 教程05-GLM-4-9B-chat Lora 微调.md。需要留意的是本教程基于transformers4.46.0与glm-4-9b-chat-hf权重展开若更换模型版本或 transformers 版本target_modules的层名与 Prompt 模板格式均需同步核对24G 显存是单卡运行本方案的前提显存更小时可进一步调低per_device_train_batch_size并调高gradient_accumulation_steps。掌握了这条 LoRA 流水线你可以将其迁移到任意角色人设、领域指令或对话风格数据上快速定制专属大模型。【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考