工程实战 · LoRA 微调
学习舱 / 工程实战 / LoRA 微调

微调实操:LoRA 与 QLoRA 的单卡路线

整理中 深度 · 应用 更新 2026-09-22

前置 预训练全流程

微调实操:LoRA 与 QLoRA 的单卡路线

一句话定位:通用模型不贴身时,用 LoRA 低秩补丁做参数高效微调、用 QLoRA 把底座压到 4-bit,一张消费级显卡就能把模型掰到你的任务上——本文讲原理取舍、数据准备、一条可照做的实操线与效果评估。前置:训练三段流水线——LoRA 的低秩账本在那篇立过,本文直接复用。

先看看全量微调的账单

模型什么都会,就是不懂你:你的领域黑话、你的输出格式、你那套业务规则,它一概没有。把模型掰到贴身,最直接的办法是全量微调——所有参数都在训。

可全量的账单吓人。沿用并行训练篇的「三样大件」口径(权重 + 梯度 + 优化器状态,16 字节/参数),微调一个 7B 模型就是 112 GB 起步——单卡消费级显卡连零头都装不下。

个人与小团队就没有路了吗?

有,而且已经成熟:LoRA 冻住原模型、只训一个低秩小补丁,QLoRA 再把冻结的底座压到 4-bit——7B 的活儿一张 24 GB 卡从容干完,论文口径下效果追平 16-bit 全量微调。这条单卡路线怎么走,本文从头讲到尾。

全景图:微调五步流水线

微调是一个工程流程,不是一条命令。全流程五步:定目标、备数据、配补丁、训与盯、评与归——每步都有各自的坑,先看地图:

微调五步流水线:每步各有一道坑 ① 定目标 缺知识→RAG 缺举止→微调 坑:用微调解知识更新 ② 备数据 指令三件套格式 千条精选胜十万灌水 坑:脏数据教会坏习惯 ③ 配补丁 秩 8–64 起步 目标模块要给全 坑:秩贪大过拟合 ④ 训与盯 轮次 1–3,多了过拟合 盯损失曲线与样本 坑:只看 loss 不看话 ⑤ 评与归 任务分要涨 旧能力不能塌 坑:只测任务分 产出一对孪生件:底座(没动过)+ 补丁适配器(几十到几百 MB) 可挂可卸可合并;多个任务共用一个底座,各配各的适配器 训练期盯两样:损失曲线 + 抽样输出(图 2 另有显存三档账) 微调教的是举止,不是知识——知识请走检索 读法:①→⑤ 是流程次序;底条是产出的孪生件形态,显存三档账见图 2

图 1:微调五步流水线——①定目标 ②备数据 ③配补丁 ④训与盯 ⑤评与归;产出是「底座 + 适配器」孪生件

渐进拆解:补丁为什么能顶替全量

LoRA 的账直接复用:训练三段流水线立过账本——不训原权重 W,改训一个低秩增量 ΔW = B×A,A 把维度压到秩 r,B 再展开回原维度,可训参数从层内 65 亿掉到几千万(Qwen2-7B r=16 全投影口径占 0.62%)。原论文在 GPT-3 175B 上给出过 470 万参数的预算(r=1 挂 Q、V 投影,或 r=2 只挂 V)就与多种全量微调基线持平或更好。本节沿图 1 的后四步走:备数据、配补丁(原理与两个旋钮)、训与盯、评与归。

② 备数据

格式是三件套:指令(干什么)、输入(材料,可空)、输出(标准答案)。真正的重点不是量是质:行业熟知的 LIMA 实验用 1000 条精选数据就调出了可用的对齐效果——先做「数据三查」,再谈扩充。

  • 一查重复:相似样本会让模型死记套路,输出多样性掉光。
  • 二查脏污:网页乱码、错别字、口径打架都要清——模型学什么像什么,脏数据教会的是坏习惯。
  • 三查泄漏:评估题哪怕改头换面混进训练集,评估分数就是自欺。去重要在切分评估集之前做,这条纪律不能倒。

量级感:举止类任务几百到几千条高质量样本起步是常态,输出范例的风格要统一——把你的业务规则写成干净的输出范例,比堆十万条灌水数据值钱。

③ 配补丁:秩与目标模块

为什么低秩敢这么省?论文的判断叫「内在秩假设」:模型适配一个新任务时,权重真正要动的那部分信息量本来就是低维的——像给一张高清大图调色,改动的信息用几个滑块就装得下,不必重画整张图。r 是「这个任务要改多少东西」的预算,不是越大越威猛:教模型把输入改写成固定 JSON 格式,要动的口径就那么几条,r=8 的容量绰绰有余;要让模型学会一整套行业术语的表达习惯,要动的东西多,r 相应往上加。任务越「举止类」(格式、风格、套路),内在秩越低,r 就可以越小。

落地就两个旋钮:

  • 旋钮一,秩 r 怎么选:经验起步 8–64,简单格式与分类任务 8 就够,领域语料多、任务杂上 32–64;判断依据是任务评估集的分数曲线,r 翻倍收益边际递减时停手。贪大的代价是过拟合与显存上涨,且大 r 并不会把知识「装进」补丁(那是 RAG 的活儿,见边界节)。
  • 旋钮二,目标模块给谁:只挂注意力投影是早期惯例(原论文受限于实验范围只研究了注意力部分),QLoRA 论文的实验发现只挂注意力追不平 16-bit 全量微调、全挂线性层才追平——现在的共识是全线性投影(attention + MLP)一起挂。学习率要比全量大 5–10 倍(补丁是空白的,步子要迈大些),常用 1e-4 量级。

LoRA 省的是「训」的账,QLoRA 再省「放」的账:把冻结底座量化到 NF4(为正态分布权重设计的 4 比特类型)存着,LoRA 补丁照旧用高精度训。配套两件:双重量化(把量化的常数再量化一遍)、分页优化器(显存峰值时借显存外内存顶一下)。同一个 7B 模型的三档账放在一起看(估算口径:全量承并行训练篇 16 字节/参数;LoRA 为 2 字节权重加「补丁件」——即 LoRA 参数、它的优化器状态与激活等临时开销,GB 级小头;QLoRA 为 NF4 约 0.5 字节加补丁件):

微调显存三档账:同一个 7B 模型 全量微调(16 字节/参数) ≈112 GB · 卡组起步 LoRA(2 字节权重 + 补丁件) ≈20 GB · 单卡 24 GB 可训 QLoRA(NF4 约 0.5 字节 + 补丁件) ≈8 GB · 显存还能再省一档 权威口径(QLoRA 论文):65B 微调从 780 GB 级压到单张 48 GB、24 小时 省的主体不是精度,是「放」底座与「训」全参的账;效果追平 16-bit 全量微调 读法:条长 = 微调期显存占用(估算口径,随批次与序列长度浮动);橙条是全量档

图 2:7B 微调显存三档账——全量 ≈112 GB、LoRA ≈20 GB、QLoRA ≈8 GB;65B 权威口径挂 QLoRA 论文

④ 训与盯

从零手写训练循环是学习路径,生产路径用成熟框架(社区广泛使用的 LLaMA-Factory 一类):内置主流基座支持矩阵(Qwen、Llama、DeepSeek 蒸馏系)、YAML 配置、WebUI 可视化,产出的 LoRA 适配器可直接挂载推理或合并导出。本文动手段给最小配置。

训练盯两样,缺一不可:

  • 损失曲线:读法复用从零预训练篇的仪表盘经验——不降是学习率或数据有问题,骤降后贴底是轮次多了;微调常用 1–3 轮,训多必过拟合。
  • 抽样输出:每几百步亲手看几条生成结果——损失在降但输出开始复读训练集、丢通用语气,就是过拟合的前兆,比曲线更早报警。

⑤ 评与归

两把尺子都要量:

  • 任务尺:留出任务评估集(微调数据绝不入集),微调前后各跑一遍,要涨。
  • 回归尺:同一批通用能力题的前后对比——常识、推理、代码、数学按业务各来 20–50 条,或直接用 MMLU、GSM8K 这类公开基准——旧能力掉多少就是「灾难性遗忘」的程度,量法见自测第二问。

还有一条评估纪律:温度、提示词、评估脚本一次锁死存档,前后两轮对比才有效——评估口径漂了,涨跌都不可信。

退化严重时的手段按轻到重排:减轮次、减秩、混入通用数据重训。

大白话:LoRA 就是给大模型贴了张「岗位培训便签」——本体不动,只学一张几十到几百 MB 的小贴纸;QLoRA 是连放本体的柜子都压缩了。贴纸贴上去会干新活,撕下来模型原样奉还。

技术定义:LoRA(Low-Rank Adaptation,2021)以低秩分解 ΔW = B×A 表示权重增量,冻结预训练权重、只训低秩矩阵;QLoRA(2023)在其上把冻结底座量化为 NF4 四比特、配合双重量化与分页优化器,把大模型微调压进单卡显存。两者都是参数高效微调(PEFT)家族的成员。

动手:一条 YAML 跑通单卡微调

实操线的最小闭环三步:备数据、装框架、跑训练。先备数据实体——指令三件套的 JSON,一行一条样本:

{"instruction": "把订单描述转成 JSON", "input": "买了 3 箱 A4 纸", "output": "{\"item\": \"A4 纸\", \"qty\": 3}"}

把它放进框架的数据目录 data/(file_name 按相对登记文件的位置解析,放错层级照样报 dataset not found),并在 data/dataset_info.json 登记 "my_task_data": {"file_name": "my_task_data.json"},然后装框架、写配置、跑训练(配置编号对应全景图 ①–⑤):

pip install llamafactory            # 或按官方 README 从源码安装;要求 Python ≥ 3.11
llamafactory-cli train qwen_lora.yaml   # ④ 训与盯:过程里盯损失与抽样输出
model_name_or_path: Qwen/Qwen2.5-7B-Instruct   # ① 定目标:选基座(任务举止类选 Instruct 版)
stage: sft
finetuning_type: lora
lora_rank: 16                                  # ③ 秩:8–64 起步,任务复杂再升
lora_target: all                               # ③ 目标模块:全线性投影挂满
dataset: my_task_data                          # ② 数据:指令三件套,已过质量过滤
template: qwen                                 # 对话模板随基座走,别配错
cutoff_len: 2048
per_device_train_batch_size: 2
gradient_accumulation_steps: 8
learning_rate: 1.0e-4                          # ③ 比全量大 5–10 倍
num_train_epochs: 3
output_dir: saves/qwen-7b-lora                 # ⑤ 产出:适配器目录,评测后再决定挂载或合并

训完先别合并:把任务评估集与通用回归题各跑一遍(框架自带推理命令 llamafactory-cli chat 挂载适配器即可),⑤ 的两把尺子都过关再谈上线。三个数字提醒:

  • 秩 16 在多数举止类任务够用。
  • 学习率 1e-4 是 LoRA 常见起点,损失不降先查数据再动学习率。
  • 显存不够就开 4-bit 加载(QLoRA 档),配置加一行 quantization_bit: 4。

时间量级也给你个底:几千条样本、3 轮、单张 24 GB 卡,是小时级的活儿——微调真正贵的不是 GPU 时间,是写干净输出范例的人工。

边界与取舍

先过「微调 vs RAG」这道闸

判据复用蒸馏篇的三条路:缺知识上 RAG、缺举止做 SFT(监督微调)、缺能力且养不起才蒸馏。落到场景里走一遍:

场景判类走法
客服话术口径乱、输出格式飘举止类微调
产品手册问答,内容月月更新还要标注出处知识类RAG
内部代码库的表达风格小能力缺口 + 举止微调

知识频繁更新、要引用溯源、要可解释的活儿,微调是错的工具——微调教格式与套路,不负责装事实;把「产品手册更新」寄托在重训一轮上,是微调最常见的误用。

秩与数据量的匹配,不是越大越好

数据只有几百条时,大秩是过拟合加速器;评估集分数掉头向下时先减秩再查数据。r 的上限受限于「内在秩」,超过任务信息量的秩只是空转参数。

适配器挂载还是合并,按服务形态选

多任务共享底座、频繁热切换,挂载(推理时叠补丁)灵活;单一任务追求推理零开销,合并导出一次性固化。合并后模型不再可逆,留好适配器原件。还有一层次序问题:目标部署环境要跑量化(下一篇的主角)时,先量化底座再挂适配器,比「合并后整体量化」的精度更可控——次序错了,掉点都找不到原因。

坏味道预警

评估只报任务分不报回归分——任务涨三分、通用能力掉十分的模型上了线,事故都在别人发现之后。两把尺子写进发布流程,别靠自觉。

自测

合上文章先自己答,再展开对照:

LoRA 的秩怎么选?什么任务微调不如 RAG?

秩的选法:8–64 起步(简单格式与分类 8 够,领域语料多、任务杂上 32–64),用任务评估集的分数曲线决策——r 翻倍收益边际递减就停手;r 贪大的代价是过拟合与显存上涨。任务选择上,知识频繁更新、需要引用溯源、要可解释的任务微调不如 RAG——微调教的是举止(格式、风格、套路),不负责装事实,把知识寄托在重训上既贵又不可更新。判据一句话:缺知识上 RAG,缺举止做微调。

微调后旧能力退化怎么量化?

两把尺子对比量:微调前后各跑同一批通用能力题(常识、推理、代码等按业务挑几类,固定题目固定口径),分数差就是遗忘的程度——比如通用问答准确率从 85 掉到 70,就是掉了 15 个点,要拿去和任务分一起权衡是否上线;任务尺则用留出的任务评估集(微调数据绝不入集)验证提升真实存在。两把尺子都过关才发布;退化严重时的手段按轻到重排:减轮次、减秩、混入通用数据,而不是调学习率硬顶。

参考与延伸

下一站:本地部署与量化——模型调好了,怎么在自己机器上又快又省地跑起来。

本节点大纲与自测题(5 个子点 · 2 问)

大纲

  • LoRA 原理:低秩分解为什么有效
  • QLoRA 与显存账
  • 指令数据准备与质量过滤
  • LLaMA-Factory 实操线
  • 微调效果评估与回归

自测——答不上来就是缺口

  • LoRA 的秩怎么选?什么任务微调不如 RAG?
  • 微调后旧能力退化怎么量化?