大模型微调方法详解:LoRA、QLoRA与全量微调选型实战 📅 发布时间:2026/9/13 9:08:19 👁 浏览次数: 1. 从零理清微调到底在干嘛六种方法怎么来的先说结论微调不是玄学选方法本质就两个问题——你手里有多少显存以及你想改掉模型的多少“认知”。我第一次带团队做项目时看到“全量微调、LoRA、QLoRA”这几个词还以为是对立关系后来才反应过来它们更像是“改作业”的三种尺度把整本书重写一遍、在书上贴便利贴、还是连课本都压缩成红宝书再贴便利贴。搞清楚这个比喻后面一切就顺了。大模型微调的本质是在一个已经用海量文本“学过一遍”的模型基础上用你的领域数据再做一次定向训练让它更贴合你的任务。比如让通用模型学会给外卖评论打星、学会生成特定风格的小红书文案、学会回答你公司的产品问题。所谓“六种微调方法”并不是六个互不相干的闭门绝技而是从“改多少参数”这个维度分出来的六条路径全量微调、Adapter、Prompt Tuning、Prefix Tuning、LoRA、QLoRA。其中全量微调是“老一派”LoRA 和 QLoRA 是当下最热的“显存救星”剩余几种则是 PEFTParameter-Efficient Fine-Tuning参数高效微调家族里的经典思路。这篇内容不是教科书而是我“踩完坑之后写给自己团队”的选型笔记。有基础的人可以直接跳到第 3 节的资源账本和第 5 节的排查实录刚开始接触的人建议从头读我不会堆公式只在必要的地方给你讲透“为什么”。1.1 一次微调里真正烧显存的是哪几块很多人以为微调就是“把模型放到显卡里跑一下”结果一跑就 OOM一脸懵。显存到底被谁吃掉了我在实际项目里总结就四个大头模型参数本身、梯度、优化器状态、中间激活值。模型参数模型有多少个参数加载到显存里就要占多少空间。以 7B 模型为例用 BF16 精度加载每个参数占 2 字节单是这个干模型就得吃掉约 14GB。梯度和优化器状态训练时模型要反向传播算梯度每个参数对应一份梯度Adam 优化器还要保存一阶动量、二阶动量这些状态在混合精度下通常按 FP324字节或 BF162字节存储。业内粗略估算全量微调时每个参数可能需要约 16 字节的额外开销。激活值就是前向传播过程里每层留下来的中间张量。它跟序列长度、batch size 直接挂钩这也是为什么你把序列从 2048 改成 8192显存会瞬间翻倍。所以“全量微调为什么吃显存”就不再神秘了7B 模型全参数训练参数梯度优化器状态粗略就要超过 100GB再加上激活值单卡 A10080GB根本喘不过气。而 LoRA 这类方法因为只训练极少参数绕开了大部分梯度与优化器状态把显存需求瞬间打下来。1.2 六种方法按“改多少参数”排队我习惯把这六种方法按“需要训练的参数规模”排个队方法核心思路训练参数量占比参考全量微调Full Fine-tuning所有原始权重都参与更新100%Adapter在 Transformer 层里插入小网络固定原权重约 1%Prompt Tuning只在输入端学习一组“提示向量”冻结模型约 0.01%Prefix Tuning在每层 Transformer 前加可学习的“前缀”约 0.1%~1%LoRA冻结原权重在权重旁加低秩矩阵约 0.1%~1%QLoRALoRA 的升级版基底模型用 4bit 量化后冻结约 0.1%~1%基座更省显存这张表建议你收藏起来后面选型时经常要回来对比。注意 Prompt Tuning 和 Prefix Tuning 虽然训练参数量极少但对“任务形态”比较挑不是所有场景都适合而 LoRA 和 QLoRA 之所以流行是因为它们同时兼顾了“效果好”和“显存友好”是这几年实战中性价比最高的两条路。2. 用同一个例子把六种方法逐一说通光讲概念容易飘。我给团队做技术分享时喜欢用一个固定任务把六种方法挨个演示一遍用 Qwen2.5-7B-Instruct 做一个小型文本分类任务让模型判断一条外卖评论是好评还是差评。我们用 5000 条带标签的评论做训练集希望微调后模型在没见过的评论上也能判对。这个任务很小但它能清晰展示每种方法到底动了模型的哪一部分。你完全可以把例子里的“判断好评差评”替换成“生成合同条款”“写周报摘要”“识别图片里的商品”原理是一样的。2.1 任务设定让 7B 模型学会给外卖评论打分通用模型其实已经能判断评价好坏你直接问它“这个评论是好评吗”它也能答但准确率不稳定而且有时候会啰嗦一大堆。我们真正想要的是让它变成“一个稳定、简短、可靠的分类器”。所以微调数据我做成这样的格式用户输入“这家店送餐超快汉堡还是热的”模型输出“好评”。每一条都是一段用户指令加一段标准回答。你可能会问这不就是在做指令微调SFT吗对绝大多数开源模型的微调都是这个路子先准备好输入输出对然后让模型在训练中学会模仿这些回答。选 7B 模型的原因也很实际它比 13B 更容易在消费级显卡上跑效果又比 3B 好不少是“够得着、能跑动、效果不糊”的黄金档位。整个项目里我最想让你体会的一点是方法不同训练时“可以动的参数”完全不同可最终目标都一样。2.2 全量微调把整本书背下来再重新记笔记全量微调是所有方法里最“正统”的把模型的每一层、每一个权重都当作可训练参数用你的数据做梯度更新。用例子说话评论“外卖好吃但包装破了”全量微调时模型会调整注意力层、前馈网络层里所有参数这一轮更新后它不仅更懂“好吃好评”还捎带手改动了它对“包装”话题的底层理解这些改动可能帮你也可能帮倒忙。全量微调的优势是上限高当你有足够多、足够干净的数据时它能把模型“掰”得最彻底。缺点也明显显存开销巨大7B 模型少说要 100GB 的显存普通玩家根本玩不转训练出来的权重动辄十几个 GB部署和分发都是麻烦事。另一个隐形风险是“灾难性遗忘”你只拿外卖评论去训它它可能忘了怎么写诗、怎么算数——因为全量更新把旧知识也洗掉了。实战中除非我有 100GB 以上的显存、接近或超过 10 万条训练数据否则我不会优先选全量微调。2.3 Adapter在书里插“补充页”Adapter 的思路是在原始模型的每一层里“插”一个小型神经网络模块通常是两层带瓶颈结构的 MLP训练时只更新这些小模块原始权重全部冻结。你可以把它想象成在一本教科书里临时塞了几页“补充页”考试时只看补充页就行。放在外卖评论任务里训练时模型结构是这样的评论输入后每个 Transformer 层先走原来的计算再额外过一遍插进去的 Adapter 小网络小网络的输出再和原结果合并。最终只有这些小网络的参数被更新而 Qwen 原来的“语文功底”完全不变。这个方案的好处是显存明显低于全量微调能和全量微调一样把所有中间层的激活值保留下来效果比纯 Prompt 类方法更稳。但它的缺点是推理阶段有额外耗时——每个 Transformer 层都多了一段计算而且实际工程里适配器模块要自己写还要处理合并权重的问题现在用的人相对少。LoRA 流行后Adapter 更多被当作“历史经典方案”来学习。2.4 Prompt Tuning / Prefix Tuning只给模型加“小抄”这两个方法都属于“软提示”思路它们的共同点是不修改模型权重而是往输入或隐藏状态里加一些“可学习的小向量”。Prompt Tuning 最简单在模型的输入序列前面拼上几十个“虚拟 token”这些 token 不是真实词而是随机初始化的一串嵌入向量。训练中只更新这些向量帮你把“外卖评论分类”这个任务挤成一种“条件反射”。它极致省显存7B 模型甚至用 8GB 显存就能训。但它的局限也很明显只在输入端做文章对深层语义变化的控制力偏弱。我做外卖评论任务时试过效果不如 LoRA因为一个 0.01% 参数的软提示很难完全“教会”模型输出格式。Prefix Tuning 是 Prompt Tuning 的加强版——它不只是输入端加向量而是在每一层 Transformer 的输入前都拼上一段可学习的前缀相当于在每一章书页边都贴上“小抄”。这样控制力强了不少但训练参数量和实现复杂度也跟着起来了。如果你手头卡特别弱、数据又少可以先用 Prompt Tuning / Prefix Tuning 跑通全流程观察 loss 变化和任务适配性但真要追求稳定效果我还是建议直接上 LoRA。这也算是我自己反复折腾后得出的经验。2.5 LoRA只训练两张小巧的“备忘卡”LoRA 是当下最主流的微调方法它的思路是原始权重冻结不动但在权重旁边并联一对低秩分解矩阵。矩阵乘法里一个大权重 W 的更新量 ΔW 可以用两个小矩阵 A、B 的乘积近似AB 的维度远小于 W训练时只更新 A、B。回到外卖评论例子Qwen 的注意力权重是 4096×4096 级别的矩阵LoRA 会为它加一个 4096×16 和 16×4096 的分解矩阵可训练参数只有原来一个权重的千分之几。训练时前向计算是“原权重输出 低秩矩阵输出”反向传播只算两个小矩阵的梯度。我最初接触 LoRA 时最大的疑惑是“只改这么点参数能学会吗”实测下来对于大多数“风格迁移、格式统一、指令遵循”类任务LoRA 的表现已经接近全量微调因为它本质上是在模型原有能力基础上做“软修正”。7B 模型用 LoRA 训练单卡 24GB比如 RTX 4090就能跑得很舒服而且训练完的适配器文件通常只有几十到两百 MB部署时换个模型文件就行。它的主要“坑”在于需要你合理选择作用模块target_modules和秩rank。比如只去 LoRA 注意力层的q_proj, v_proj是默认玩法但遇到任务需要改变深层语义理解时不改o_proj, gate_proj效果就会打折扣。这些细节我后面实操部分细讲。2.6 QLoRA把课本压缩成红宝书再加小抄QLoRA 是 LoRA 的“省显存加强版”核心创新是把冻结的基底模型用 4bit 量化后再去做 LoRA 微调。4bit 的意思是把每个参数从 2 字节压缩到 0.5 字节7B 模型的显存占用直接从约 14GB 降到约 3.5GB。它不是简单粗暴地砍精度。QLoRA 引入了几样硬核技术NF4 数据类型一种专门为 4bit 设计的分布感知量化、双重量化把量化常数再量化一次、以及分页优化器显存不够时暂时挪到 CPU 内存。训练时基底模型始终处于 4bit 冻结状态只有 LoRA 适配器用正常精度更新。放在我那个 5000 条外卖评论任务里用 QLoRA 甚至在 12GB 显存的 3060 上就能跑。速度确实比 LoRA 慢一些因为每步都要反量化但换来的是“低端卡也能微调大模型”的体验。QLoRA 论文里用单块 48GB 显存训 65B 模型放到普通玩家手里就是“24GB 显卡微调 13B 模型”也没压力。对于绝大多数人和绝大多数业务场景我的建议非常简单没有多卡 A100 就别碰全量微调直接 QLoRA 起步等熟悉了再根据数据量决定要不要升 LoRA。这就是你对付显存焦虑和效果焦虑的最优解。3. 资源账本显存、速度和效果到底差多少道理讲完了接下来用实际行动数据说话。很多人最关心的就是同一台机器上这几种方法到底谁吃显存最少、谁训得最快、谁效果最好。我根据自己跑过的 7B 模型项目整理了一张“参考账本”配置不同会有浮动但数量级不会差太远。3.1 7B模型三种主流方法的显存对照方法基底模型精度训练参数量训练显存参考典型显卡单步速度参考适配器文件大小全量微调BF16约 7B110GB2-4×A100 80GB快14GBLoRABF16约 0.1B约 18-24GBRTX 4090 24GB较快约 50-200MBQLoRA4bit NF4约 0.1B约 10-16GBRTX 3060 12GB偏慢约 50-200MBPrompt TuningBF16约 1M约 8-12GBRTX 3090/4090快约 1MB注意LoRA 的显存估算里我默认序列长度 2048、batch size 1、开了梯度检查点gradient checkpointing。如果你把序列拉到 8192显存会明显上涨因为你存的激活值变多了。全量微调的 110GB 也是“理论起步值”实际训练中加上激活值7B 模型 4 张 80G 卡都比较紧张。速度方面要单独说一句QLoRA 不一定比 LoRA 慢太多因为瓶颈往往在数据加载和反向传播但如果你的显卡算力很强比如 40904bit 反量化确实会拖慢计算。实测下来同样 4090 上跑 7B 模型QLoRA 单步时间大约是 LoRA 的 1.3 到 1.6 倍。所以如果显卡显存够24GB 以上我更推荐直接上 LoRA只有显存吃紧时才用 QLoRA。3.2 什么场景适合什么方法选型决策清单我在团队里定过一个“默认选型规矩”说白了就是按数据量和显存两步走数据量少于 1000 条别想全量LoRA / QLoRA 都够用。数据太少时全量微调很容易过拟合模型会死记硬背训练集测试全崩。数据量 1 万条以上、任务和预训练能力差距不大首选 LoRA如果显存不够就 QLoRA。数据量几万条、任务形态有明显变化比如让模型学会全新输出格式可以考虑 LoRA 稍大秩比如 rank64或者 Adapter。数据量巨大且资金充足、任务变化极大才考虑全量微调并且要准备评估脚本和回放数据来对抗遗忘。只想快速试效果先用 QLoRA 默认参数跑一遍记录 loss 是否下降再逐步调整。还有一个经常被忽略的判断标准你要的是“懂你的语料”还是“懂你的格式”如果只是希望模型回答问题时带点你公司的语气、会用表格输出、会调用你的 API 风格LoRA 和 QLoRA 完全够用如果希望模型掌握一套全新的知识体系比如行业专有术语、新学科知识那数据量和训练轮数都得加码必要时还得混合全量微调。4. 实操一把用 LLaMA-Factory 跑通 QLoRA 微调理论说再多不如亲手跑一遍。下面是我近期最常用的一套流程用 LLaMA-Factory 在单卡 24GB 环境下对 Qwen2.5-7B-Instruct 做 QLoRA 微调完成外卖评论分类任务。不说废话直接按步骤来。这套流程同样可以平移到 3B、13B、甚至 VLM 模型比如 qwen-vl-4b只要把模型路径和数据集格式改一下就行。4.1 环境准备与数据组织首先确认你的环境CUDA 版本建议 11.8 以上PyTorch 2.x显卡驱动能支撑你的算力。LLaMA-Factory 是我测试下来对新手最友好的训练工具一条命令就能启动 WebUI不用手写 Trainer 模板。数据要整理成 Alpaca 格式一个 JSON 文件里是对象组成的数组每个对象至少包含instruction用户指令和output标准答案[ { instruction: 判断这条外卖评论是好评还是差评。评论这家店送餐超快汉堡还是热的。, output: 好评 }, { instruction: 判断这条外卖评论是好评还是差评。评论等了四十分钟可乐还是漏的。, output: 差评 } ]然后修改 LLaMA-Factory 的data/dataset_info.json把你的数据集注册进去{ comment_classify: { file_name: comment_classify.json, columns: { prompt: instruction, response: output } } }到这里你会发现整个微调的数据准备其实很简单核心就是“用户说什么期望模型回什么”。如果你的任务需要多轮对话也可以用 ShareGPT 格式但单轮指令格式是入门最快的方式。4.2 训练参数怎么给才不翻车我默认使用命令行方式也方便记录和复现。以 QLoRA 为例核心参数长这样llamafactory-cli train \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --stage sft \ --finetuning_type lora \ --quant_bit 4 \ --quant_method bitsandbytes \ --dataset comment_classify \ --template qwen \ --lora_rank 32 \ --lora_alpha 64 \ --target_modules all \ --per_device_train_batch_size 4 \ --gradient_accumulation_steps 2 \ --learning_rate 2e-4 \ --num_train_epochs 3 \ --lr_scheduler_type cosine \ --logging_steps 10 \ --save_steps 500 \ --output_dir outputs/comment_lora \ --fp16每个参数背后都有讲究。lora_rank 32意味着低秩矩阵的维度是 32秩越大可学习参数越多拟合能力越强但也不是越大越好rank64 以上在某些任务上会开始过拟合。lora_alpha 64是缩放系数一般设为 rank 的 1~2 倍它控制 LoRA 权重的“用力程度”。target_modules all表示对所有线性层都加 LoRA稳妥如果显存吃紧可以改成q_proj,v_proj。学习率 2e-4 是 LoRA 类方法常用的起点比全量微调的 1e-5 高一个数量级因为可训练参数少、更不容易震荡。fp16在 4090 这类卡上问题不大如果是 A 系列卡可以换成bf16数值更稳。4.3 微调后的验证是不是真的“学会了”训练完不要急着高兴先做三件事第一看 loss 曲线。如果 loss 一直下降并且最终平稳说明模型在学如果 loss 震荡或者直接起飞先回去调学习率。第二跑一遍验证集的硬样本比如故意挑几条包含“包装破但好吃”“味道一般但送得快”这样矛盾的评论看模型会不会被绕晕。第三直接和原始模型对比同一个 prompt 分别扔给微调前和微调后的模型看输出是否更贴近你想要的格式。测试时用 LLaMA-Factory 自带的命令行推理最方便llamafactory-cli chat \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --adapter_name_or_path outputs/comment_lora \ --template qwen \ --finetuning_type lora然后输入“这家店送餐超快汉堡还是热的”如果模型干脆利落地回了一句“好评”而不是写一大段感受那说明这次微调基本成了。我特别强调“格式统一”这件事因为微调最常见的收获不是让模型“变聪明”而是让模型“学会按你的规矩办事”。这也是为什么用 LoRA 就够了——你要改变的不是它的底层逻辑而是它的回答风格和任务模式。5. 踩坑实录微调翻车现场与排查思路这几年我用 LLaMA-Factory 做过不少微调项目也带团队踩过不少坑。下面这些问题几乎每个新手都会遇到至少一个我把排查思路和解决办法整理成一份“避坑速查”希望能帮你少走几天弯路。5.1 微调后模型变笨问题出在哪最诡异的现象是loss 明明在降但模型回答反而更差了甚至原来会的题也不会了。这大概率是“灾难性遗忘” “过拟合”的混合症状。我的排查顺序是先降低学习率看是否震荡然后减少训练轮数3 轮是经验值7B 模型训 5 轮以上小数据集基本都会过拟合最后检查数据质量如果你的数据集里 90% 都是差评样本模型自然会把“好评”学歪。还有个容易被忽略的点全量微调比 LoRA 更容易遗忘因为它动了所有参数。用 LoRA/QLoRA 时基底模型是冻结的相当于“旧知识被锁住了”遗忘问题会轻很多。这算是 LoRA 这类方法的隐藏优点。5.2 LoRA“没生效”的几个检查点训练完加载 adapter 后模型输出跟原始模型一模一样这种情况我遇到过不下三次。排查思路如下训练日志里确认是否确实冻结了基底模型看trainable params占比是否真的只有 0.1%~1%。检查--adapter_name_or_path是否指向了正确的输出目录很多人输出目录写错加载了旧 adapter。确认推理时也带了--finetuning_type lora有些工具默认不加载 adapter。看训练时的 loss 数值是否明显低于预训练模型直接推理的 loss如果 loss 一开始就低得离谱可能是数据集格式错误模型在“抄答案”。核心教训是微调不是“点一下训练按钮就完事”你得时刻确认训练对象是谁、加载对象是谁。最简单的方法就是训练完立刻拿一个训练集里的样本去测如果连训练集都答不对那问题一定出在训练环节如果训练集答对了但测试集不行才是泛化问题。5.3 显存不够/训练太慢的常规解法显存不够时不要一上来就换显卡。按优先级调整先开gradient_checkpointing能省 50% 左右的激活值显存。再降per_device_train_batch_size配合梯度累积来保持稳定 batch size。然后检查max_length序列长度很多人默认 4096你的任务根本用不到这么长改成 1024 或 2048 能省出一大截显存。如果还不行再用 4bit 量化QLoRA甚至把基底模型换成更小的 3B/4B 版本。训练太慢的话除了换卡外还可以优化把flash_attention打开用torch.compile加速检查数据加载是不是变成了瓶颈多线程加载比单线程好太多。另外注意QLoRA 在算力一般的卡上确实会比 LoRA 慢不少如果你已经用了 24GB 以上显存且跑的是 7B 模型直接换成 LoRA 往往速度反而更好。结尾我的默认选择我自己最近做新项目时默认流程已经固定在“QLoRA 起步LoRA 进阶全量兜底”这个节奏上。第一次跑通微调时总觉得全量微调才是正经方案后来被显存和遗忘问题教育了几次才意识到大多数业务场景里我们要的不是“把模型彻底改写”而是“教会模型在新任务上懂规矩”。这个认知转变后我的训练效率高了很多。最后再分享一个小技巧无论你选哪种方法微调完一定要保留好“原始模型 LoRA 适配器”的组合不要图方便直接发布合并后的权重。因为万一新任务效果不好你可以随时卸载适配器回到原始模型不丢底牌同时适配器文件小在团队里协作、上生产、版本管理都轻松得多。项目多了之后你会发现能快速切换的适配器比一颗锁死的“魔改大模型”值钱多了。