
简介这份资源面向希望借助 LoRA 微调提升研发效率的算法工程师与 AI 应用开发者围绕 LlamaAlpaca LoRA与 ChatGLMChatGLM Tuning两条技术路线展开覆盖用户故事生成、测试代码生成、代码辅助生成、文本转 SQL、文本生成代码等典型研发场景适合具备一定深度学习基础、想动手实践轻量微调的中高级读者。压缩包共 93 个文件约 53.46MB以 jsonl 数据集、ipynb 训练笔记、md 说明文档、pdf 参考资料和 py 脚本为主另含少量 json、csv、txt 及图片素材便于按模块查阅与复现。目前已有 442 人学习下载。资源内含 Alpaca LoRA 与 ChatGLM 微调的完整训练流程、多场景数据集与脚本以及文本转 SQL、文本生成代码等示例可帮助读者快速搭建实验环境、理解数据构造与训练配置并对照排错思路完成自己的 LoRA 微调实践。1. 从一张 24G 显存卡说起这套 LoRA 训练资源到底能跑什么手里只有一张 24G 显存的卡想微调一个 7B 级别的大模型全量参数更新基本没戏——光是优化器状态就能把显存吃干净。这时候 LoRALow-Rank Adaptation就是那个能让你在单卡上把活干完的方案冻结原模型权重只在注意力层的部分矩阵旁边挂两个小矩阵训练参数量降到原来的千分之一量级显存占用和训练时间都跟着塌下来。这套《AI 研发提效研究自己动手训练 LoRA》资源核心就是围绕 Llama走 Alpaca LoRA 那条线和 ChatGLM 两个主流底座把数据准备、训练脚本、参数配置、权重合并这一整条链路拆开给你看。适合谁手上有业务数据想做领域适配的算法工程师、想搞懂 LoRA 微调到底改了哪些层的研发、以及被全量微调显存劝退想找轻量方案的人。它不是那种只贴一段trainer.train()就完事的教程而是把 Alpaca 格式数据怎么转、target_modules 怎么选、rank 设多少不翻车这些实操细节都摆出来了。2. Alpaca LoRA 训练链路拆解数据格式、脚本与参数落点2.1 为什么选 Alpaca 格式而不是直接喂原始文本Alpaca LoRA 这条线最省心的地方在于数据格式统一。它要求每条样本是instruction、input、output三个字段训练脚本里的 prompt template 会把它拼成一段带指令前缀的文本再送进模型。你如果直接拿原始对话日志或者纯文本去训模型学到的只是「续写」而不是「按指令回答」这是很多人训完发现模型不听话的根因。常见做法是把业务数据先整理成 JSON 数组每条一个对象。下面这个转换脚本我一般会先跑一遍把脏数据挡在训练之前import json # 原始业务数据假设是 question/answer 两列 raw [ {question: LoRA 的 rank 设多少合适, answer: 一般 8 到 64任务越复杂越大}, {question: ChatGLM 支持 LoRA 吗, answer: 支持target_modules 要改成 query_key_value}, ] alpaca_data [] for item in raw: alpaca_data.append({ instruction: item[question], input: , # 没有额外上下文就留空字符串别写 None output: item[answer] }) with open(train_alpaca.json, w, encodingutf-8) as f: json.dump(alpaca_data, f, ensure_asciiFalse, indent2) print(f共转换 {len(alpaca_data)} 条样本)逻辑说明input字段留空字符串而不是None因为 Alpaca 的模板拼接时会对input做判空传None在某些版本里会拼出None字样污染训练文本。ensure_asciiFalse保证中文不被转义成\uXXXX否则你打开文件看到的是一堆编码排查数据问题时很痛苦。参数上indent2只是给人看的训练读取时不关心缩进。2.2 训练脚本的关键参数rank、alpha、target_modulesAlpaca LoRA 的训练入口通常是一个finetune.py核心参数集中在命令行或者配置字典里。下面这段是我从资源里提炼出来的典型调用方式python finetune.py \ --base_model decapoda-research/llama-7b-hf \ --data_path ./train_alpaca.json \ --output_dir ./lora-out \ --lora_r 8 \ --lora_alpha 16 \ --lora_dropout 0.05 \ --target_modules q_proj,k_proj,v_proj,o_proj \ --batch_size 4 \ --micro_batch_size 2 \ --num_epochs 3 \ --learning_rate 3e-4 \ --cutoff_len 512逻辑说明lora_r是低秩矩阵的秩8 是保守起点任务复杂可以往上加到 32 或 64但显存和过拟合风险同步上升。lora_alpha一般设成2 * r它控制 LoRA 权重缩放alpha 相对 r 越大LoRA 分支对原模型的影响越强。target_modules是决定「挂在哪」的关键Llama 系用q_proj/k_proj/v_proj/o_projChatGLM 系要换成query_key_value选错了训练照样跑但效果约等于没微调——这是血泪经验里最常见的一条。micro_batch_size和batch_size的关系是梯度累积实际 batch 等于batch_size显存按micro_batch_size走。24G 卡上 7B 模型micro_batch_size2比较稳再大容易 OOM。cutoff_len是截断长度超过 512 的长样本会被砍掉尾部如果你的任务依赖长上下文这里要往上调但显存也跟着涨。2.3 训练完怎么验证合并权重与推理自测LoRA 训完产出的是一个几十兆的 adapter 权重不是完整模型。要单独用得先合并回底座from peft import PeftModel from transformers import LlamaForCausalLM, LlamaTokenizer base LlamaForCausalLM.from_pretrained(decapoda-research/llama-7b-hf) tokenizer LlamaTokenizer.from_pretrained(decapoda-research/llama-7b-hf) model PeftModel.from_pretrained(base, ./lora-out) model model.merge_and_unload() # 合并 LoRA 权重进底座 model.save_pretrained(./merged-model) tokenizer.save_pretrained(./merged-model)逻辑说明merge_and_unload()把 LoRA 的 A、B 矩阵乘回原权重之后模型就是一个普通 Llama推理时不再需要 peft 依赖。合并前建议先不合并直接推理几条确认 adapter 确实起作用了再合并否则合并完发现效果不对你连是哪一步出的问题都分不清。验证时用训练集里没出现过的指令问几条看回答风格是否贴合你的数据而不是看 loss 降没降——loss 降了但回答跑偏的情况太常见了。3. ChatGLM 的 LoRA 差异target_modules 与数据模板怎么改3.1 ChatGLM 的层命名和 Llama 不是一回事把 Alpaca LoRA 的脚本直接套到 ChatGLM 上第一个翻车点就是target_modules。Llama 的注意力是分开的q_proj/k_proj/v_proj/o_projChatGLM 用的是融合的query_key_value你如果照抄 Llama 的配置脚本不会报错但 LoRA 挂不到任何有效层上训练 loss 几乎不动。正确做法是# ChatGLM 的 LoRA 配置片段 from peft import LoraConfig lora_config LoraConfig( r8, lora_alpha16, target_modules[query_key_value], # ChatGLM 专用 lora_dropout0.05, biasnone, task_typeCAUSAL_LM )逻辑说明target_modules传列表ChatGLM 的每一层 Transformer block 里那个融合 QKV 的线性层名字就是query_key_value。biasnone表示不训练偏置项LoRA 论文里验证过训 bias 收益很小还增加参数量。task_type设成因果语言模型PEFT 库靠它决定怎么包装前向。3.2 ChatGLM 的 prompt 模板要单独写ChatGLM 有自己的对话格式通常是[Round 1]\n\n问...\n\n答...这种。你如果还用 Alpaca 的### Instruction:模板模型也能训但和它预训练时的格式对不上收敛会慢效果也打折。资源里给的做法是自定义一个preprocess函数def preprocess_chatglm(example): # ChatGLM 对话模板 prompt f[Round 1]\n\n问{example[instruction]}\n\n答{example[output]} # tokenize 并构造 labelslabels 和 input_ids 对齐 tokenized tokenizer( prompt, truncationTrue, max_length512, paddingmax_length ) tokenized[labels] tokenized[input_ids].copy() return tokenized逻辑说明labels直接复制input_ids意味着整段文本都参与 loss 计算。如果你想只对「答」的部分算 loss需要把「问」对应的 label 位置设成-100这样模型只学回答不学问句复述。max_length512和训练参数里的cutoff_len保持一致避免 tokenize 和训练截断两套标准。paddingmax_length在样本长度差异大时会浪费算力样本长度接近的话可以改longest。3.3 两个底座训练成本对比项目Llama Alpaca LoRAChatGLM LoRAtarget_modulesq_proj,k_proj,v_proj,o_projquery_key_value数据模板### Instruction / ### Response[Round 1] 问/答7B 单卡显存micro_bs2约 18-20G约 16-18Gadapter 体积r8约 20-40MB约 15-30MB合并方式merge_and_unloadmerge_and_unload这张表不是让你背是让你在换底座时知道哪些地方必须改。显存数字是 24G 卡上的经验值具体和你用的精度fp16/bf16、序列长度强相关bf16 比 fp16 省一点且更稳。4. 避坑与排查LoRA 训练里最容易翻车的五件事4.1 loss 不降或者降得极慢现象训练跑起来了日志里 loss 在 2.5 附近晃几个 epoch 下来几乎不动。原因九成是target_modules配错了LoRA 挂到了不存在的层名上PEFT 会静默跳过等于没加 adapter。解决训练前打印一下model结构确认你写的模块名在named_modules()里能搜到或者训完看 adapter 权重文件大小如果只有几 KB基本就是没挂上。4.2 显存 OOM 但 batch 已经很小现象micro_batch_size降到 1 还是 OOM。原因cutoff_len设太大或者用了 fp32 加载模型。解决先把cutoff_len从 1024 降到 512 试再把加载精度改成 bf16torch_dtypetorch.bfloat16。还有一个隐蔽原因是梯度检查点没开在TrainingArguments里加gradient_checkpointingTrue能省不少显存代价是训练慢 20% 左右。4.3 训完模型胡言乱语现象合并权重后推理模型输出重复、乱码或者答非所问。原因学习率太大把原模型能力冲垮了LoRA 虽然只训小矩阵但 lr 设到 1e-3 以上照样能把底座带偏。解决LoRA 的 lr 一般从 1e-4 到 3e-4 起步别用全量微调那种 2e-5 也别用 1e-3。另外检查数据里有没有大量空 output 或者超短样本脏数据会让模型学到「输出空字符串」这种退化解。4.4 adapter 加载了但推理没变化现象PeftModel.from_pretrained加载成功推理结果和底座一模一样。原因加载时adapter_name对不上或者推理时没调model.set_adapter()。解决加载后打印model.peft_config确认 adapter 在列推理前显式model.set_adapter(default)。多 adapter 场景下不设活动 adapterPEFT 可能用底座原始前向。4.5 中文数据训完输出英文现象明明喂的是中文指令数据模型回答夹英文。原因底座本身中文能力弱比如原版 LlamaLoRA 参数量太小拉不回来。解决换中文底座ChatGLM 或者中文增强的 Llama或者把lora_r提到 32 以上、target_modules加上gate_proj/up_proj/down_proj这些 FFN 层让 LoRA 有更大容量去适配中文。但注意挂 FFN 层后参数量和显存都会明显上升。5. 进阶技巧用 rank 和 target_modules 组合控制微调强度LoRA 调参里最值得花时间琢磨的是r和target_modules的组合它直接决定你是在「轻推」还是「重训」模型。我一般按任务类型分三档来设这套分档在 Llama 和 ChatGLM 上都适用任务类型lora_rtarget_modules说明风格/语气适配4-8仅 q_proj,v_proj改动最小保留底座能力领域知识注入16-32q,k,v,o_proj平衡容量与过拟合复杂指令跟随32-64注意力 FFN 层容量大需更多数据和正则风格适配那档比如你只是想让模型说话更像客服r4挂q_proj和v_proj就够了训 1-2 个 epochadapter 只有几兆。领域知识注入那档比如医疗、法律问答r16起步四个注意力投影都挂上数据量建议至少几千条否则容易过拟合到训练集那几百条上。复杂指令跟随那档把 FFN 的gate_proj/up_proj/down_proj也加进target_modules参数量会翻几倍但模型对复杂指令的遵循能力提升明显代价是显存和训练时间都上一个台阶。验证微调强度是否合适我习惯用「留出指令集」而不是看 loss。具体做法是从业务数据里切 5% 出来不参与训练训完后用这批指令让模型回答人工看三条格式对不对、内容有没有编、风格贴不贴。三条里两条不过就说明 rank 或 target_modules 需要调而不是继续加 epoch。加 epoch 只会让模型把训练集背得更死留出集上的表现反而可能下降。还有一个容易被忽略的点是 adapter 的复用。同一份底座上可以挂多个 LoRA adapter推理时按场景切换不用为每个任务存一份完整模型。PEFT 支持load_adapter加载多个set_adapter切换。我一般会把客服风格、领域知识、指令跟随各训一个 adapter部署时按请求路由到对应 adapter显存里只放一份底座。这个用法在资源里没展开但它是 LoRA 相比全量微调最实用的优势之一值得你训完第一个 adapter 后顺手试一下。从那以后我每次开训前都强制走一遍先打印 target_modules 确认挂载点、再跑 10 步看 loss 有没有动、最后留出 5% 数据当后悔药。这三步花不了十分钟但能挡掉后面几小时的无效训练。希望帮到你。本文还有配套的精品资源点击获取