微调实操:LoRA 与 QLoRA 的单卡路线
一句话定位:通用模型不贴身时,用 LoRA 低秩补丁做参数高效微调、用 QLoRA 把底座压到 4-bit,一张消费级显卡就能把模型掰到你的任务上——本文讲原理取舍、数据准备、一条可照做的实操线与效果评估。前置:训练三段流水线——LoRA 的低秩账本在那篇立过,本文直接复用。
先看看全量微调的账单
模型什么都会,就是不懂你:你的领域黑话、你的输出格式、你那套业务规则,它一概没有。把模型掰到贴身,最直接的办法是全量微调——所有参数都在训。
可全量的账单吓人。沿用并行训练篇的「三样大件」口径(权重 + 梯度 + 优化器状态,16 字节/参数),微调一个 7B 模型就是 112 GB 起步——单卡消费级显卡连零头都装不下。
个人与小团队就没有路了吗?
有,而且已经成熟:LoRA 冻住原模型、只训一个低秩小补丁,QLoRA 再把冻结的底座压到 4-bit——7B 的活儿一张 24 GB 卡从容干完,论文口径下效果追平 16-bit 全量微调。这条单卡路线怎么走,本文从头讲到尾。
全景图:微调五步流水线
微调是一个工程流程,不是一条命令。全流程五步:定目标、备数据、配补丁、训与盯、评与归——每步都有各自的坑,先看地图:
图 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 字节加补丁件):
图 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 个点,要拿去和任务分一起权衡是否上线;任务尺则用留出的任务评估集(微调数据绝不入集)验证提升真实存在。两把尺子都过关才发布;退化严重时的手段按轻到重排:减轮次、减秩、混入通用数据,而不是调学习率硬顶。
参考与延伸
- LoRA 论文(2021-06):低秩适应的奠基出处,「内在秩假设」与 GPT-3 175B 实验口径 — arxiv.org/abs/2106.09685
- QLoRA 论文(2023-05):NF4 量化底座 + LoRA,65B 单卡 48 GB 的官方口径 — arxiv.org/abs/2305.14314
- LIMA 论文(2023-05):千条精选数据完成对齐的「少而精」证据 — arxiv.org/abs/2305.11206
- LLaMA-Factory 官方仓库:本文实操线的框架,含基座支持矩阵与 WebUI — github.com/hiyouga/LLaMA-Factory
下一站:本地部署与量化——模型调好了,怎么在自己机器上又快又省地跑起来。