在大模型落地到真实业务时,经常会遇到一个问题:基础模型能力很强,但并不一定适合当前场景。它可能不熟悉某个行业的表达习惯,不能稳定遵循业务输出格式,也可能在客服、代码审查、合同分析、工单分类这类垂直任务上表现不够一致。

要解决这类问题,常见有两条路线:一条是 RAG,把外部知识检索出来放进上下文,让模型基于资料回答;另一条是微调,用特定任务数据继续训练模型,让模型的行为、表达方式和任务能力更贴近目标场景。

微调本身也有不同层次:从更新全部参数的 Full Fine-tuning,到只训练少量增量参数的 LoRA、QLoRA。前者能力上限更高,但成本更大;后者更轻量、更易落地,也因此成为很多团队适配垂直场景时最常用的方法。这一篇,我们就从全量微调讲到 LoRA,看清楚大模型到底是如何被“定制”的。

为什么需要微调

预训练模型已经学到了大量通用知识和语言能力,但通用能力不等于业务可用。真实业务里,模型经常会遇到几类问题:

  1. 领域语言不熟:金融、法律、医疗、工业、研发体系里有大量专有术语和表达习惯;
  2. 输出格式不稳:业务系统需要固定 JSON、表格、SQL、配置、工单字段,而模型可能自由发挥;
  3. 任务风格不一致:客服、投研、代码审查、故障排查,对回答风格和判断标准要求不同;
  4. 小模型能力不足:为了成本和延迟,业务可能希望用较小模型完成特定任务;
  5. RAG 不能解决所有问题:RAG 能提供知识,但不一定改变模型的行为模式。

可以把大模型适配业务的方式分成几类:

大模型适配

从上图可以看出,Prompt、RAG、微调和后训练解决的问题不同,微调更偏向改变模型行为和任务分布。微调适合解决的问题,通常不是“今天文档更新了模型不知道”,而是:

  • 模型已经大概会做,但做得不稳定、不专业、不符合业务要求。

例如以下这些场景,微调的主要作业是:

  1. 客服助手:统一回答风格、话术、拒答边界;
  2. 代码模型:适配项目代码风格、框架模式、测试规范;
  3. 金融研报:学会领域表达、结构化摘要和风险提示;
  4. 法律文档:适配条款分析、审查格式和谨慎表达;
  5. 数据分析:稳定生成 SQL、图表解释和结论模板;
  6. 工单系统:输出固定字段、分类、优先级和处理建议。

一句话概括:RAG 主要给模型补知识,微调主要改变模型做事的方式。

微调路线:从全量更新到参数高效

微调的核心思想很直接:在已有基础模型之上,用特定数据继续训练,让模型更适配目标任务。但从技术上看,微调可以拆成两个维度:

  1. 训练目标:模型要学什么,比如继续预训练、指令监督微调 SFT、偏好对齐;
  2. 参数更新方式:训练时更新哪些参数,比如 Full Fine-tuning、LoRA、QLoRA、Adapter。

这里需要注意的是:SFT 和 LoRA 不是同一层概念。SFT 更关注“用什么数据、学什么行为”,LoRA 更关注“用什么方式更新参数”。一次 SFT 训练,既可以用全量微调实现,也可以用 LoRA 实现。

微调可以从训练目标和参数更新方式两个维度理解

Full Fine-tuning:更新全部参数

Full Fine-tuning 是最直接的微调方式:模型中的所有可训练参数都会参与更新。

1
θ_new = θ_old - η × ∇L(θ)

其中 θ 表示模型参数,L 表示训练 loss。对于 Transformer 来说,这意味着 Embedding、Attention 投影矩阵、FFN / MLP 矩阵、LayerNorm、输出层等参数都可能被更新。它的优势是适配能力强,模型可以充分学习新的任务分布。但代价也很明显:

  1. 显存占用高:不仅要存模型权重,还要存梯度、优化器状态和激活值;
  2. 训练成本高:所有参数都参与反向传播;
  3. 部署成本高:每个场景都可能需要保存一份完整模型;
  4. 过拟合风险高:小数据场景下容易损伤原模型通用能力;
  5. 安全边界可能被破坏:训练数据不干净时,模型可能学到错误行为。

所以 Full Fine-tuning 更适合数据量大、任务重要、算力充足、需要深度领域适配的场景。

SFT:让模型学会按指令完成任务

SFT,全称 Supervised Fine-Tuning,监督微调。它通常使用“指令 - 输入 - 输出”形式的数据,让模型学习在给定指令下生成期望答案。

1
2
3
4
5
{
"instruction": "请总结下面这段故障日志的原因",
"input": "...日志内容...",
"output": "故障原因是数据库连接池耗尽,建议检查连接泄露和最大连接数配置。"
}

SFT 的目标不是单纯让模型继续学习领域文本,而是让模型学会:

  1. 理解用户指令;
  2. 按任务要求回答;
  3. 遵循固定格式;
  4. 使用特定领域表达;
  5. 避免不符合业务规则的输出。

很多垂直模型训练,本质上都是围绕 SFT 展开的:构造高质量指令数据,再选择 Full Fine-tuning 或 LoRA / QLoRA 等方式进行训练。

PEFT:只训练少量新增参数

Full Fine-tuning 成本太高,因此业内出现了很多参数高效微调方法,也就是 PEFT,Parameter-Efficient Fine-Tuning。它们的共同思想是:

  • 冻结大部分原模型参数,只训练少量新增参数或增量参数。

常见方法包括:

方法 核心思想 特点
Adapter 在 Transformer 层中插入小模块 只训练 Adapter,便于多任务切换
Prefix Tuning 在注意力层前加入可训练 prefix 参数少,但表达能力受限
LoRA 给线性层增加低秩增量矩阵 当前最常用,成本低,效果稳定
QLoRA 量化基础模型,再训练 LoRA 显存更低,适合资源受限场景

Adapter 可以理解为在原模型层旁边插入一个小的可训练模块:

1
原模型层 -> Adapter 小模块 -> 输出

它的好处是不同业务场景可以保存不同 Adapter,不需要复制完整模型。但它会改变推理结构,部署上需要额外适配。

LoRA 则更进一步:不改变主干结构,只给关键线性层增加低秩增量,因此在工程上更轻量,也更容易成为主流方案。

LoRA 与 QLoRA 的核心原理

LoRA 原理

LoRA 是最常见的参数高效微调方法之一。它的核心思想是:冻结原模型参数,只训练一小组新增的低秩矩阵

在 Transformer 里,很多参数都集中在线性层中,比如 Attention 的 q_projv_projo_proj,以及 FFN / MLP 的投影矩阵。全量微调会直接更新这些大矩阵,而 LoRA 不直接改原矩阵 W,而是在旁边学习一个增量:

1
W' = W + ΔW

为了让这个增量足够轻量,LoRA 不训练完整的 ΔW,而是把它拆成两个更小的矩阵:

1
ΔW = B × A

也就是说,原模型负责保留通用能力,LoRA 只学习当前任务需要补上的那部分变化。

LoRA 不更新原权重,只训练低秩增量矩阵

LoRA 能省参数,是因为原矩阵可能是一个很大的 4096 × 4096 矩阵,而 LoRA 只训练两个很窄的小矩阵。比如 rank r = 8 时,新增参数大约只有原矩阵的 0.39%。这也是 LoRA 能显著降低显存和训练成本的核心原因。

LoRA 的优势是显存低、训练快、易管理、可插拔;同一个基础模型可以挂载不同 LoRA adapter,适配不同业务任务。但它也有代价:rank 太小可能学不动,rank 太大成本会上升,注入层选错会影响效果,数据质量差时 LoRA 也会稳定学到错误模式。

QLoRA:进一步降低显存门槛

QLoRA 可以理解为 LoRA 的低显存版本。它的核心思路是:基础模型权重量化 + LoRA 增量训练。具体做法是:

  1. 把基础模型权重量化到低比特,比如 4-bit;
  2. 冻结量化后的基础模型;
  3. 只训练 LoRA adapter 参数;
  4. LoRA 参数通常仍用 FP16 / BF16 训练。

在实际实现中,QLoRA 还常结合 NF4 量化、Double Quantization 和 Paged Optimizer 等技术,进一步降低显存占用和训练峰值。这里可以先简单理解为:QLoRA 用低比特保存基础模型权重,用少量 LoRA 参数完成任务适配。

QLoRA 通过量化基础模型并只训练 LoRA 参数

QLoRA 省显存的原因是:基础模型的大部分权重用低比特存储,训练时只需要为 LoRA 参数保存梯度和优化器状态。

方法 基础模型权重 训练参数 显存压力
Full Fine-tuning FP16 / BF16 全部参数 最高
LoRA FP16 / BF16 LoRA 参数 中等
QLoRA 4-bit 量化 LoRA 参数 更低

QLoRA 很适合单机训练、中小团队垂直场景适配、多业务 adapter 管理,以及对训练成本非常敏感的场景。但它也不是免费午餐:量化会带来数值误差,训练对学习率、batch size、rank 更敏感;长上下文训练时,activation 仍然会占用大量显存;基础模型质量也仍然决定最终上限。

简单总结一下:LoRA 让微调从“更新整个模型”变成“学习少量增量”,QLoRA 则进一步通过低比特量化降低显存门槛。

数据与训练流程

微调最容易被误解的一点是:只要把业务数据丢进去训练,模型就会变好。实际不是这样。微调效果很大程度取决于数据质量,而不是数据数量。一个典型的微调流程如下图所示:

微调的训练流程

从图片也可以看出,微调并不是一次训练动作,而是一套围绕数据、训练、评测和迭代的工程流程。

数据怎么构造

常见微调数据可以分成几类:

数据类型 作用 示例
指令数据 提升任务遵循能力 问题 -> 标准回答
领域语料 适配领域语言和知识分布 金融研报、法律条款、技术文档
格式样本 稳定输出结构 JSON、SQL、表格、工单字段
失败样本 修复模型常见错误 历史 bad case -> 正确答案
偏好数据 学习回答优劣偏好 answer A 优于 answer B
安全样本 强化拒答和边界 越权问题、敏感内容、注入攻击

这里要注意:领域语料和指令数据的训练方式不完全一样。如果只是金融研报、法律条款、技术文档这类原始文本,更适合做继续预训练或领域自适应预训练,让模型熟悉领域语言和知识分布;如果是“问题 - 答案”“指令 - 输出”形式的数据,则更适合做 SFT,让模型学会在具体任务中如何回答(领域微调更关注“懂不懂这个领域”,指令微调更关注“会不会按要求做事”)。

数据质量比数据数量更重要

微调数据常见问题包括:

  1. 答案本身不准确;
  2. 指令和答案不匹配;
  3. 格式混乱;
  4. 同一个问题多种冲突答案;
  5. 混入过期知识;
  6. 包含隐私或敏感信息;
  7. 样本分布和线上真实问题不一致。

如果用低质量数据微调,模型不会变聪明,只会更稳定地学会错误模式。所以生产级微调通常需要:

  1. 数据去重;
  2. 质量评分;
  3. 隐私脱敏;
  4. 格式统一;
  5. 难例增强;
  6. 训练集、验证集、测试集隔离;
  7. 微调后做回归评测。

训练参数关注什么

LoRA / QLoRA 微调时,常见关键参数包括:

参数 含义 影响
rank r 低秩矩阵维度 越大表达能力越强,但参数更多
alpha LoRA 缩放系数 影响 LoRA 增量强度
target modules 注入哪些层 常见为 q_proj、v_proj、o_proj、MLP
learning rate 学习率 过大容易学坏,过小收敛慢
batch size 批大小 影响稳定性和显存
epochs 训练轮数 太多容易过拟合
max length 最大序列长度 影响长样本训练成本

微调不是参数越大越好,也不是训练越久越好。更重要的是:训练后是否在目标任务上变好,同时不破坏原有能力和安全边界。

微调的边界与生产落地

微调适合解决“模型行为”问题,比如输出格式不稳定、领域表达不专业、任务风格不符合业务要求。它不适合承载频繁变化的业务知识,也不适合替代可追溯的文档检索。

问题类型 更适合的方案
知识频繁更新、需要引用来源 RAG
输出格式、回答风格、领域表达不稳定 微调 / LoRA
简单格式约束和任务提示 Prompt / 上下文工程
多步骤任务执行 Agent + 工具
上线质量验证 Eval + 安全检查

RAG 解决知识问题,微调解决行为问题

微调上线前必须重新评测:目标任务是否提升、通用能力是否退化、输出格式是否稳定、幻觉是否增加、安全边界是否被破坏。即使是 LoRA,也可能改变模型行为。

微调需要和评测、安全、线上反馈形成持续迭代闭环

一句话概括:微调让模型更会做某类任务,LoRA 让这种适配更轻量;但真正落地,还需要评测、安全和数据回流一起配合。