三者改动的是三个不同的东西
把一次生成写成条件分布 P(y | x; θ),x 是输入上下文,θ 是权重。三条路线各自动一个变量:
| 路线 | 改动对象 | 模型权重 | 知识来源 |
|---|---|---|---|
| 提示词工程 | x | 不变 | 靠上下文现场提供 |
| RAG | x(拼接检索结果) | 不变 | 外部库,运行时拉取 |
| 微调 | θ | 改变 | 烘进权重,静态快照 |
这张表是后面所有判断的基础。提示词和 RAG 都不碰权重,所以它们无法让模型”学会”任何东西——只能把模型已经具备的能力引导出来,或者把材料递到它眼前。微调碰了权重,代价是知识从此变成不可版本化、不可删除、不可按条追溯的东西。
混淆这两类改动,是绝大多数项目走弯路的起点。
各自的硬边界
提示词的边界在于容量和稳定性。上下文窗口有限,塞不下一整本手册;few-shot 示例越多,模型越容易被示例的边缘特征带偏(比如示例里恰好都是三位数编号,输出就开始编三位数)。长对话下指令还会漂移,前二十轮守规矩,后面开始自由发挥。
RAG 的边界在于它只管知识,不管行为。检索到的片段每次都不一样,模型的行为也就跟着上下文浮动。想靠 RAG 保证”每次都输出同样的六字段 JSON、字段顺序固定、枚举值不超范围”,做不到——因为决定格式的是模型,不是检索结果。格式稳定性、语气一致性、领域术语习惯,这三类需求 RAG 帮不上忙,反而可能因为上下文长度变化加剧不稳定。
微调的边界则在于事实时效。训练语料是一个时间切片,微调完的那一刻起,知识就开始过期。价格、库存、政策条款、人员信息,任何高频变动的事实都不该进权重。更麻烦的是,把知识烘进权重后无法做权限控制:一个用户能问到的东西,所有用户都能问到。
还有一条容易忽略的:微调有灾难性遗忘。在窄域数据上训几轮,通用推理能力可能明显下滑,而且掉得不均匀——可能代码能力还在,多步算术先塌了。没有覆盖全能力的评测集,这种退化是看不见的。
知识更新频率是第一个分岔点
| 知识更新频率 | 稳定性要求 | 合适路线 |
|---|---|---|
| 小时/天级变动 | 事实必须准确 | RAG |
| 月/季度级 | 事实 + 固定格式 | RAG 为主 + 轻量微调 |
| 年级或静态 | 领域术语、文体 | 微调 |
| 不变(纯行为) | 格式、风格、任务拆解 | 微调 |
| 一次性验证 | 探索阶段 | 提示词 |
判断顺序是先看知识会不会变,再看要不要改行为。知识会变 → 知识部分走 RAG,没有例外。行为要改 → 先试提示词,提示词在长尾输入上守不住 → 再上微调。
LoRA 与全参微调的资源量级差异
全参微调的显存大头不是参数本身,是优化器状态。Adam 类优化器对每个参数保存一阶动量和二阶动量,加上 fp32 主权重和梯度,经验上每 1B 参数的训练显存在十几 GB 量级。一个 7B 模型全参微调,显存需求大约在 100 GB 往上,单卡放不下,得上多卡并行或者 ZeRO 分片。梯度本身还要一份,激活值随 batch 和序列长度线性增长。
LoRA 的思路是冻结主干 W,只学一个低秩增量:
h = W x + ΔW x = W x + B A x
A ∈ R^(r×d), B ∈ R^(d×r), r << d
r 取 8、16、32 这类值。对一个 d=4096 的矩阵,r=16 时增量参数约为 2×4096×16 ≈ 13 万,相比原矩阵 1600 万,量级上不到百分之一。主干不需要梯度、不需要优化器状态,显存需求掉到接近纯推理再加一点点,训练稳定,多任务切换时换 adapter 即可。
代价是表达上限。LoRA 能很好地对齐风格、格式、领域词汇这类低秩变化;要注入大量新知识、或者要做大幅度的能力重塑,低秩增量会欠拟合,这时候得加大 r 或者干脆全参。还有一个实操细节:rank 和 alpha 要配合调,alpha/r 决定实际缩放系数,只加 r 不调 alpha 有时反而训不动。
量化版(4-bit 主干 + LoRA adapter)能进一步把显存压到单卡 24 GB 可以跑 7B 量级模型的程度,代价是量化噪声带来的一点性能损失和调参复杂度。
混合方案怎么搭
最常见的有效组合是”RAG 给事实,微调给行为”:
[系统指令: 固化在权重里的格式与语气约束]
↓
[检索器: 从知识库取 top-k 片段]
↓
[拼装: 片段带来源编号塞进上下文]
↓
[模型: 按微调过的格式规范输出,并标注引用编号]
这样拆分之后,两边各自可迭代:知识更新只动检索库,几分钟生效;格式调整只动 adapter,重训一次。互不干扰。
搭的时候有几个坑。微调数据里千万别塞大量事实性问答——那会把知识烘进权重,既污染行为训练的目标,又制造幻觉来源。微调数据应该只示范”如何回答”,事实内容留空或明显占位,让模型学会去引用检索到的片段而不是去回忆。
另外一个坑是顺序:先调 RAG 还是先微调。建议先把检索质量调到可接受(召回率测出来),再在这个检索结果上做微调。顺序反了的话,微调是在”坏检索”的条件下对齐行为,检索修好之后行为反而失配。
决策树
需求进来
├─ 涉及外部/私有/高频变动的知识?
│ ├─ 是 → 必须 RAG。知识不准进权重。
│ └─ 否 → 往下
├─ 只是想让输出格式/风格稳定?
│ ├─ 是 → 提示词 + 结构化输出约束先试
│ │ └─ 长尾输入上守不住 → LoRA 微调
│ └─ 否 → 往下
├─ 需要新能力(新任务类型、新语言、新推理模式)?
│ ├─ 是 → 微调(先 LoRA,不够再全参)
│ └─ 否 → 提示词就够了
└─ 有没有评测集?
└─ 没有 → 先建评测集,否则无法判断上面任何一步是否奏效
微调数据要多少条
这是个没有定值但可以估算范围的问题。格式与风格类对齐,几百到两三千条高质量样本往往就能看到明显效果,因为这类变化是低秩的、模式单一的。任务能力类(学会新的任务分解方式、新的输出协议)通常需要更多,量级上在数千到数万。
决定效果的不是条数,是覆盖度和一致性。三百条覆盖全部输入形态的样本,效果好过三万条全是同一种模板的样本。一致性指的是标注标准要统一:同一类输入在不同样本里给了不同的处理方式,模型学到的是噪声,表现为输出时好时坏、无法预测。人工标注时先让两个人各标五十条算一致性,一致性不达标就回去改标注规范,这步省不得。
数据清洗里最该做的是去重和长度分布检查。重复样本会让模型对特定表述过拟合;长度分布过于集中会让模型对超出该长度的输入表现突降。
建评测集要排在选型之前
三条路线的取舍本质上是实验问题,没有评测集就只能靠感觉。最小可行的评测集是二三十条覆盖长尾的真实输入,配人工标注的期望输出,加上一个能自动跑的判定脚本(格式类用解析校验,事实类用关键词或 LLM 打分)。有了它,”提示词够不够””LoRA 值不值””RAG 召回够不够”才有答案。
没有评测集就上微调,是最贵的那种试错:训完不知道变好还是变差,回滚也回不去。
评论(2)
这个方案我们试过,主要成本在后期维护。
这类内容太少了,大部分人都只写「成功案例」。
请 登录 后参与评论。