
Datawhale self-llm 实战GLM-4.1V-Thinking 多模态大模型 LoRA 微调与 SwanLab 可视化全流程【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm导读本文是 Datawhale《开源大模型食用指南》self-llm仓库中 models/GLM-4.1V-Thinking 目录下的实战教程基于 transformers、peft 框架对智谱 AI 的GLM-4.1V-9B-Thinking视觉语言模型进行 LoRA 高效微调并使用开源实验跟踪工具SwanLab记录训练指标、对比实验结果。文中以沐雪猫娘风格化对话数据集为案例覆盖数据构建、格式化编码、LoRA 参数配置、训练监控到微调后推理的完整链路。读者完成后将掌握多模态 VLM 的 LoRA 微调标准流程并能独立复现一套个性化角色 视觉理解的双能力模型。一、GLM-4.1V-Thinking 模型与微调思路GLM-4.1V-Thinking 是智谱 AI 基于 GLM-4-9B-0414 基座模型推出的开源视觉语言模型VLM引入了思考Thinking范式模型在给出最终答案前会先生成一段think思考过程再以answer标签包裹最终回答。据仓库 01-GLM-4 1V-Thinking vLLM部署调用.md 描述该模型通过课程采样强化学习RLCSReinforcement Learning with Curriculum Sampling全面提升能力在 10B 参数级别的视觉语言模型中具备竞争力支持图片、视频、PDF/PPT 文档等多种模态输入。与纯文本 LLM 微调不同GLM-4.1V-Thinking 是多模态模型因此在 LoRA 微调时有两点关键差异模型加载类不同需使用transformers提供的Glm4vForConditionalGeneration加载而非常见的AutoModelForCausalLM对话模板包含思考标记数据格式化时需要在|assistant|之后插入think/think占位标记引导模型学习先思考、后回答的输出结构。本文的微调目标是让模型通过supervised-finetuningSFT有监督微调获得理解并遵循用户指令的能力具体落地为赛博猫娘风格的个性化对话——用大量风格化人物设定对话数据微调得到一个说话带喵、符合角色设定的模型。二、数据集构建SFT 数据格式与猫娘数据集有监督微调SFT的数据格式如下{ instruction: 回答以下用户问题仅输出答案。, input: 11等于几?, output: 2 }instruction用户指令告知模型需要完成的任务input用户输入是完成任务所必需的输入内容output模型应给出的标准输出。有监督微调的核心目标是让模型具备理解并遵循用户指令的能力。一个有趣的实践方向是通过大量风格化人物设定的对话数据微调出一个拥有对应特色对话风格的模型。本教程选用魔搭ModelScope平台上开源的沐雪猫娘化数据集muice-dataset-train.catgirl进行演示其样本结构在标准三字段基础上还包含可选的history字段{ instruction: 沐雪的功能是什么, input: , output: 喵~本雪的主要功能是让你开心喵用可爱的猫娘之力治愈你的心灵喵呜~, history: [] }数据读取与转换拿到 JSON 数据文件后先导入依赖库并将 JSON 读取为 HuggingFacedatasets的Dataset对象便于后续.map()批量处理from datasets import Dataset import pandas as pd from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq, TrainingArguments, Trainer # 将JSON文件转换为CSV格式并加载为 Dataset df pd.read_json(/root/autodl-tmp/LLaMA-Factory/data/muice-dataset-train.catgirl.json) # 注意修改为你的实际路径 ds Dataset.from_pandas(df)仓库 dataset/huanhuan.jsonl 中存放的甄嬛对话数据集如{instruction:你是谁,input:,output:我是甄嬛家父是大理寺少卿甄远道。}采用完全相同的instruction/input/output三字段结构可作为理解该格式的补充参考在 models/DeepSeek-V4-Flash/01-DeepSeek-V4-Flash-LoRA.py 中也能看到同样的处理逻辑——用instruction input拼接作为用户输入、output作为监督标签。三、数据格式化适配 GLM-4.1V 思考模板LoRA 训练的数据需要经过格式化、编码后才能输入给模型将输入文本编码为input_ids将输出文本编码为labels编码结果均为向量。我们定义一个预处理函数process_func对每个样本同时编码其输入、输出文本并返回编码字典def process_func(example): MAX_LENGTH 1024 # 设置最大序列长度为1024个token input_ids, attention_mask, labels [], [], [] # 初始化返回值 # 适配chat_template instruction tokenizer( f[gMASK]sop|system|\n现在你要扮演皇帝身边的女人--甄嬛 f|user|\n{example[instruction] example[input]} f|assistant|\nthink/think\n, add_special_tokensFalse ) response tokenizer(f{example[output]}, add_special_tokensFalse) # 将instruction部分和response部分的input_ids拼接并在末尾添加eos token作为标记结束的token input_ids instruction[input_ids] response[input_ids] # 注意力掩码表示模型需要关注的位置 attention_mask instruction[attention_mask] response[attention_mask] # 对于instruction使用-100表示这些位置不计算loss即模型不需要预测这部分 labels [-100] * len(instruction[input_ids]) response[input_ids] 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 }对这段代码的关键设计逐一拆解chat_template 拼接GLM 系列模型的对话模板以[gMASK]sop开头依次包含|system|系统提示、|user|用户消息、|assistant|助手回复三段。think/think是 GLM-4.1V-Thinking 的思考占位符训练时模型会学习在这对标签之间生成推理过程add_special_tokensFalse避免重复添加特殊 tokenlabels 掩码机制对instruction部分的 token 用-100填充损失函数如ForCausalLMLLoss会自动跳过-100位置即只对模型回答部分计算损失让模型学习怎么回答而不是怎么复述问题。这一提示部分屏蔽、答案部分监督的构造方式与 DeepSeek-V4-Flash LoRA 脚本 中labels [-100] * prompt_length input_ids[prompt_length:]的逻辑完全一致MAX_LENGTH 截断MAX_LENGTH 1024超过最大序列长度的部分直接截断防止显存溢出。对比说明在 models/GLM-4/05-GLM-4-9B-chat Lora 微调.md 的纯文本 GLM-4 微调中process_func末尾还需拼接[tokenizer.pad_token_id]补齐序列本文针对 GLM-4.1V-Thinking 的版本则未强制补齐交由DataCollatorForSeq2Seq(paddingTrue)在 batch 内动态 padding。四、加载模型与 TokenizerGLM-4.1V-Thinking 是多模态模型必须使用transformers的专用类Glm4vForConditionalGeneration加载from transformers import Glm4vForConditionalGeneration import torch # 记得将模型路径替换为自己本地的模型路径 tokenizer AutoTokenizer.from_pretrained(ZhipuAI/GLM-4.1V-9B-Thinking) model Glm4vForConditionalGeneration.from_pretrained( ZhipuAI/GLM-4.1V-9B-Thinking, torch_dtypetorch.bfloat16, device_mapauto, attn_implementationsdpa )参数说明torch_dtypetorch.bfloat16以 BF16 半精度加载兼顾显存占用与训练稳定性尤其适用于 Ampere 及以上架构的显卡device_mapauto让 accelerate 自动将模型权重分配到可用设备单卡或多卡attn_implementationsdpa使用 PyTorch 原生的 SDPAScaled Dot-Product Attention加速注意力计算避免依赖手动编译 flash-attn。环境前提GLM-4.1V-Thinking 对图像、视频的数量及大小有限制且 PyTorch 版本需在 2.2 以上。仓库部署文档 01-GLM-4 1V-Thinking vLLM部署调用.md 中记录的试验环境为 PyTorch 2.5.1 / Python 3.12 / CUDA 12.4 / 单卡 A800-80GB可供参考。模型下载既可使用modelscope的snapshot_download也可使用huggingface-cli download详见该文档模型下载一节。五、LoraConfigLoRA 核心参数详解LoraConfig是 peft 库中配置 LoRA 的核心类常用参数如下参数含义本教程取值task_type模型类型绝大部分decoder_only模型都是因果语言模型TaskType.CAUSAL_LMTaskType.CAUSAL_LMtarget_modules需要注入 LoRA 的模块名主要是 attention 与 MLP 部分不同模型命名不同[q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj]rLoRA 的秩决定低秩矩阵的维度较小的r意味着更少的可训练参数8lora_alpha缩放参数与r共同决定 LoRA 更新强度实际缩放比例为lora_alpha / r32缩放比为 4lora_dropout应用于 LoRA 层的 dropout 比例用于防止过拟合0.1inference_modeFalse表示训练模式Falsefrom peft import LoraConfig, TaskType, get_peft_model 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 alpha实际缩放比例 32/8 4 倍 lora_dropout0.1 # Dropout 比例 )几点实践提示target_modules覆盖了q/k/v/o四个注意力投影层与gate/up/down三个 MLP 全连接层。GLM-4.1V 与 GLM-4 系列的层命名风格一致q_proj、k_proj、v_proj等这与纯文本 GLM-4 微调中的query_key_value旧式命名不同务必以当前模型的实际权重文件为准LoRA 的低秩思想不直接微调全部权重而是为待训练层注入低秩分解矩阵r决定秩冻结原参数、只训练注入部分从而大幅降低可训练参数量。训练前可用model.print_trainable_parameters()打印可训练参数占比参见 DeepSeek-V4-Flash LoRA 脚本 中的用法通过get_peft_model(model, config)将配置应用到模型上即得到 LoRA 化模型。六、TrainingArguments训练超参数配置TrainingArguments中本教程用到的参数如下参数含义本教程取值output_dir模型与 checkpoint 的输出路径./output/glm4_1V-Thinking_loraper_device_train_batch_size单卡 batch size4gradient_accumulation_steps梯度累积步数等效 batch size 4×4164logging_steps每多少步打印一次日志2num_train_epochs训练轮数3save_steps每多少步保存一次 checkpoint10learning_rate学习率1e-4save_on_each_node多节点训练时每个节点都保存Truegradient_checkpointing梯度检查点用计算换显存Truereport_to指标上报目标设为none交由 SwanLab 回调接管nonefrom transformers import TrainingArguments args TrainingArguments( output_dir./output/glm4_1V-Thinking_lora, # 输出路径 per_device_train_batch_size4, # batch_size gradient_accumulation_steps4, # 梯度累积 logging_steps2, num_train_epochs3, # epoch save_steps10, learning_rate1e-4, # 学习率 save_on_each_nodeTrue, gradient_checkpointingTrue, report_tonone, )结合 DeepSeek-V4-Flash LoRA 脚本 的源码可以看到两个必须配套的细节开启gradient_checkpointing后必须关闭 KV cache脚本中显式执行model.config.use_cache False。训练日志中常见的警告use_cacheTrue is incompatible with gradient checkpointing. Setting use_cacheFalse正是 transformers 在自动处理这一冲突说明 use_cache 仅服务于推理阶段、与训练无关开启梯度检查点后需执行model.enable_input_require_grads()由于梯度检查点会重算前向需要让输入层保留梯度同时在显存紧张时可调小per_device_train_batch_size、增大gradient_accumulation_steps以保持等效 batch size 不变。七、实例化 SwanLabCallback训练可视化SwanLab 是一款面向 AI 研究者的开源训练可视化工具提供训练曲线可视化、超参数自动记录、多实验对比与团队协同能力。它与 transformers 的集成方式是向Trainer传入SwanLabCallback回调无需改造训练逻辑即可自动记录超参数和训练指标。import swanlab from swanlab.integration.transformers import SwanLabCallback swanlab.login(api_keyyour apikey, saveTrue) # 记得替换为自己账号的apikey # 实例化SwanLabCallback swanlab_callback SwanLabCallback( projectself-llm, experiment_nameglm4.1v-lora-catgirl )使用要点swanlab.login(api_key..., saveTrue)首次使用需在 SwanLab 官网注册账号并获取 API KeysaveTrue将登录凭据保存到本地后续训练无需重复登录project实验所属项目名用于归类多个实验如本仓库统一使用self-llmexperiment_name本次实验的名称如glm4.1v-lora-catgirl便于在同一项目下区分不同实验在Trainer中通过callbacks[swanlab_callback]传入回调即可仓库 DeepSeek-V4-Flash-LoRA.py 的build_swanlab_callback函数展示了完全相同的封装模式且按未指定 project 则不启用回调的方式保证脚本可独立运行。训练完成后即可在 SwanLab 面板中查看训练过程中的指标曲线。从训练日志可以看到本实验共 243 步、训练 3 个 epoch[243/243 04:51, Epoch 3/3]训练损失从第 2 步的 18.28 逐步下降到第 10 步的 11.53整体呈现稳定下降趋势说明模型正在收敛训练日志中还出现了loss_typeNone ... Using the default loss: ForCausalLMLLoss的提示表明模型配置未指定自定义损失函数时默认采用因果语言建模损失这与前文-100标签掩码的机制相互印证。八、使用 Trainer 训练并保存 LoRA 权重SFT 训练本身与纯文本 LLM 一致用DataCollatorForSeq2Seq做动态 padding 对齐 batch将tokenized_id对数据集应用process_func后的结果传入Trainerfrom transformers import DataCollatorForSeq2Seq, Trainer tokenized_id ds.map(process_func, remove_columnsds.column_names) trainer Trainer( modelmodel, argsargs, train_datasettokenized_id, data_collatorDataCollatorForSeq2Seq(tokenizertokenizer, paddingTrue), callbacks[swanlab_callback], ) trainer.train()训练完成后挑选效果最佳的 checkpoint位于output_dir下保存 LoRA 权重与 tokenizerlora_path ./output/glm4_1V-Thinking_lora/checkpoint-180 trainer.model.save_pretrained(lora_path) tokenizer.save_pretrained(lora_path)九、加载 LoRA 权重进行推理训练完成后挑选效果最佳的 LoRA 权重前面定义的输出路径下加载权重与沐雪打招呼from transformers import AutoTokenizer, AutoProcessor, Glm4vForConditionalGeneration import torch from peft import PeftModel mode_path ZhipuAI/GLM-4.1V-9B-Thinking # 本地glm4.1V-Thinking的模型路径 lora_path output/glm4_1V-Thinking_lora/checkpoint-180 # 修改为你的 lora 输出对应 checkpoint 地址 # 加载tokenizer与processor tokenizer AutoTokenizer.from_pretrained(mode_path) processor AutoProcessor.from_pretrained(mode_path, use_fastTrue) # 加载基座模型 model Glm4vForConditionalGeneration.from_pretrained(mode_path, device_mapauto, torch_dtypetorch.bfloat16, trust_remote_codeTrue) # 加载lora权重 model PeftModel.from_pretrained(model, model_idlora_path)注意多模态模型推理需要同时加载AutoProcessor负责将图像/视频/文本统一处理为模型输入与AutoTokenizertrust_remote_codeTrue允许执行模型仓库内的自定义代码。与纯文本对话不同多模态消息的content是一个类型化列表用type: text/type: image区分文本与图像messages [ { role: user, content: [ { type: text, text: 你是谁 } ], } ] inputs processor.apply_chat_template( messages, tokenizeTrue, add_generation_promptTrue, return_dictTrue, return_tensorspt ).to(model.device) generated_ids model.generate(**inputs, max_new_tokens8192) output_text processor.decode(generated_ids[0][inputs[input_ids].shape[1]:], skip_special_tokensFalse) print(output_text)微调后的模型输出截取如下可以看到模型已经学会了喵系回答风格并且遵循了think - answer的思考结构喵呜~本雪是AI猫猫喵专门用喵星人的智慧帮助大家解决各种问题喵~记得给本雪小鱼干当礼物喵喵~/thinkanswer喵呜~本雪是AI猫猫喵专门用喵星人的智慧帮助大家解决各种问题喵~记得给本雪小鱼干当礼物喵喵~/answer十、视觉理解能力测试多模态 LoRA 的额外验证由于 GLM-4.1V-Thinking 是多模态模型微调不仅保留其文本风格化能力还可验证其视觉理解能力在 LoRA 权重下是否依然生效。构造同时包含图像与文本的消息messages [ { role: user, content: [{ type: text, text:假设你是一只猫娘。}], }, { role: user, content: [ { type: image, url: https://cdn.colorhub.me/Pl0d7lY07R4/rs:auto:0:500:0/g:ce/fn:colorhub/bG9jYWw6Ly8vY2YvMTUvMDY0NTdiMWVhNTA3NjA1MjU5Yzc5YmUzYzRiM2VmYTVkMTAwY2YxNS5qcGVn.webp }, { type: text, text: 本雪觉得它怎么样呀 } ], } ] inputs processor.apply_chat_template( messages, tokenizeTrue, add_generation_promptTrue, return_dictTrue, return_tensorspt ).to(model.device) generated_ids model.generate(**inputs, max_new_tokens8192) output_text processor.decode(generated_ids[0][inputs[input_ids].shape[1]:], skip_special_tokensFalse) print(output_text)模型以猫娘口吻描述了画面内容这个皮革看起来很舒服喵就像本雪的毛一样柔软喵~……说明 LoRA 微调后模型同时保留了视觉感知与风格化表达两种能力。需要注意的是由于未对重复生成做抑制max_new_tokens8192较大模型出现了内容循环重复的现象实际使用时建议配合repetition_penalty与top_k/temperature等采样参数进行控制。关于多模态输入的硬性限制仓库部署文档 01-GLM-4 1V-Thinking vLLM部署调用.md 给出了明确说明输入类型最大允许数量支持格式图片10 张Gradio/ 300APIJPG, JPEG, PNG, GIF, BMP, TIFF, WEBP视频1 个MP4, AVI, MKV, MOV, WMV, FLV, WEBM, MPEG, M4V文档1 个 PDF 或 1 个 PPTPDF, PPT, PPTX内部转换为图片十一、完整流程回顾与避坑清单完整链路数据instruction/input/output三字段 →pd.read_json→Dataset格式化process_func按[gMASK]sop...|assistant|\nthink/think\n模板编码-100屏蔽指令部分损失模型Glm4vForConditionalGeneration.from_pretrained(..., torch_dtypetorch.bfloat16, device_mapauto, attn_implementationsdpa)LoRALoraConfig(r8, lora_alpha32, lora_dropout0.1, target_modules七层投影)get_peft_model训练TrainingArgumentsTrainer(callbacks[swanlab_callback])SwanLab 全程可视化推理PeftModel.from_pretrained加载最优 checkpointprocessor.apply_chat_templatemodel.generate输出。避坑清单PyTorch 版本GLM-4.1V-Thinking 要求 PyTorch ≥ 2.2环境过旧会报算子不兼容错误gradient_checkpointing与use_cache二者互斥训练时需设置model.config.use_cache Falsecheckpoint 路径推理时lora_path必须指向训练实际保存的 checkpoint如checkpoint-180不同步数/数据量下编号不同多模态输入限制图片/视频/文档的数量与格式有硬性上限超过会报错重复生成max_new_tokens设置过大时注意配合repetition_penalty等采样参数数据路径所有模型路径、数据路径均需替换为本地实际路径。相关资源关联文档03-GLM-4 1V-Thinking LoRA 及 SwanLab 可视化记录.md部署前置教程01-GLM-4 1V-Thinking vLLM部署调用.md、02-GLM-4 1V-Thinking Gradio部署.md同仓库 SwanLab 可视化实践Qwen2-VL Lora 微调 SwanLab 可视化记录版、DeepSeek-V4-Flash LoRA 及 SwanLab 可视化记录可复用训练脚本参考DeepSeek-V4-Flash-LoRA.py相同三字段格式的示例数据集dataset/huanhuan.jsonl【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考