近两年“大模型微调”相关的讨论热度一直很高,但大多数教程停留在“跑通脚本”的层面。真正动手做过的朋友应该都有感触:同样一套开源框架,有人微调出的模型业务表现立竿见影,有人却把 7B 模型训得连原本的通顺对话都不会了。这种差异不在算力,而在微调背后的思路是否成体系。这篇内容我想把微调这条链路从头到尾拆开讲——从“通才”基座到“专才”业务的最后一公里,重点放在那些常规文档里不会写、但实践中几乎必踩的决策点和坑上。无论你正准备做领域知识增强,还是已经在训练中反复折腾,这篇文章应该都能给你一些可落地的参考。
1. “最后一公里”到底差在哪:基座模型真实的能力边界
很多人有个误解,觉得基座模型已经是“通才”,微调就是把新知识填进去。实际上基座模型的“通才”更接近一个接受过通识教育的应届生——基础能力扎实,但不懂你的行业行话、不知道你的输出规范、不理解你业务里的隐藏约束。微调解决的不是“让他变聪明”,而是“让他适配岗位”。
1.1 知识和行为的区别:微调真正改变的是什么
大模型训练分为预训练和微调两个阶段,两者的目标完全不同。预训练阶段模型在海量文本上学的是语言规律、知识储备和通用的推理模式;微调阶段模型面对的是经过整理的、带有明确“输入-输出”映射关系的业务样本,学的是特定任务下的行为模式。
举个例子。我去年帮一家制造企业做过设备运维问答模型。基座模型本身能写出通顺的自然语言,也能解释“什么是轴承过热”,但当用户问“出现 SP-16 报警,主轴转速骤降,该怎么办”时,基座模型的回答要么泛泛而谈,要么给出和该企业维修手册不一致的操作建议。经过几百条真实维修案例微调后,同一个模型回答同样的问题,会主动按“停机检查 → 查看驱动连接 → 按手册参数复位 → 上报流程”这个企业标准流程来作答。
这里的本质是:微调重塑了模型在特定输入条件下的条件概率分布,让模型学会了“遇到这类输入,应该走这种应答路径”。所以微调不适合用来灌输大规模事实知识——那是 RAG 和继续预训练的事。它最适合做的是三件事:领域术语绑定、输出格式控制、业务规则对齐。
1.2 哪些任务适合微调,哪些任务不应该微调
把任务分清楚,能帮你省一大笔训练预算。我的分类标准大致是这样:
| 任务类型 | 是否适合微调 | 理由 |
|---|---|---|
| 固定格式输出(JSON、工单、SQL) | 适合 | 输出模式高度一致,SFT 很容易学 |
| 领域术语和回复风格对齐 | 适合 | 样本量需求小,几百条就能见效 |
| 私有知识注入(最新文档、企业资料) | 不适合纯微调 | 知识密度高且更新频繁,应优先考虑 RAG |
| 复杂推理能力提升(数学、代码调试) | 效果有限 | 模型推理上限由基座决定,微调很难跳出基座天花板 |
| 完全没见过的新语言/新模态 | 不适合常规 SFT | 需要继续预训练或专门的指令数据 |
把“不该微调的任务”硬塞进 SFT,最常见的表现就是训完的模型回答看起来专业,但一问到需要推理的细节就一本正经胡说八道。这不是微调没效果,是你选错了工具。
2. 动手前绕不开的三个选择题:基座、方案、数据
每次有人来问“我准备微调一个模型,怎么开始”,我都会先反问三个问题:你跑业务的机器显存多大?输出场景对延迟多敏感?手里有多少条高质量数据?这三个问题直接决定了模型选型、训练方案和数据策略。
2.1 基座模型选择:不是越大越好,是够用且能落地
基座模型参数量与显存需求、推理成本、部署难度强相关。以 7B 级别模型为例,用 QLoRA 方式微调,一张 16GB 显存的消费级显卡就能跑起来,推理时量化到 GGUF Q4 格式也就 5GB 左右,普通办公电脑都能运行。14B 模型通常需要 24GB 以上显存微调,推理成本高一截。72B 以上的模型,微调和部署基本要上多卡方案,适合预算充足、对回答质量要求极高的场景。
我的建议是:先用能轻松部署的最小基座跑通业务闭环,再用更大模型做对比。年初有个团队用 Qwen2.5-7B 做客服知识库微调,当时担心 7B 不够用,后来发现针对几百条高频问答,7B 模型的效果已经满足了业务需求,部署成本还比 14B 方案省了接近一半的机器预算。
基座选择上,中文业务场景优先考虑 Qwen 系列;代码生成和英文场景 Llama 系表现更稳;如果希望微调后保留比较强的推理能力,DeepSeek 系列蒸馏版模型也可以作为候选。选定基座后还要注意一点:尽量使用官方 Chat/Instruct 版本,这类模型的对话格式和指令遵循能力已经调好,微调时只需要在这个基础上做领域适配,比从 Base 模型开始省力得多。
2.2 全量微调、LoRA、QLoRA:怎么选才不浪费
训练方案的选择本质上是在“效果上限”和“成本下限”之间做取舍。三者对比可以看下面这个表:
| 方案 | 可训练参数量 | 7B 模型显存参考 | 适用场景 |
|---|---|---|---|
| 全量微调 | 100% 参数 | 约 56GB 以上,单卡 A100/H100 或四卡 3090 | 数据量极大、任务行为需要彻底改变、训练语料包含大量新知识 |
| LoRA | 约 0.1%~1% 参数 | 约 24GB,一张 3090/4090 即可 | 大部分领域化场景,性价比最高 |
| QLoRA | LoRA 参数量级 | 约 16GB,消费级显卡也能玩 | 低成本验证、数据量不大、硬件受限场景 |
全量微调在大多数领域任务里其实是不必要的。原因很简单:微调本质上是在基座模型已经学好的能力之上做“行为校准”,全量更新不仅训练时间长、显存压力大,还有更高的灾难性遗忘风险——很可能把模型原有的通用能力冲掉。LoRA 只更新一小部分附加参数,恰好能做到“保留通识、定向调整”。
QLoRA 相比 LoRA 的核心区别在于把基座权重做了 4bit NF4 量化后再挂 LoRA 适配器,训练时只反量化当前需要的部分权重,因此显存需求大幅降低。从实测效果看,QLoRA 相比 LoRA 的精度差距通常很小,绝大多数业务任务上几乎无法感知差异。硬件条件允许时我会优先用 LoRA,条件不够时 QLoRA 是相当可靠的替代方案。
2.3 数据策略提前定:你要的是“像”还是“准”
微调数据的组织方式取决于你的业务目标,这两者是有冲突的。如果目标是让模型回复风格、话术习惯像某些优秀员工,几百条高质量样本就能见效;如果目标是让模型在特定任务上准确率高、输出稳定,数据质量的要求完全不同,需要成对覆盖边界情况,甚至要刻意构造“这种问题不能乱答”的负样本。
动手前先把这个目标写下来。我见过不少项目失败的原因就是“既想要风格、又想要准确率”,结果数据集里混着聊天记录和标准工单,训练完模型两头不讨好。风格类数据要有上下文、话题跳跃,适合机动性强的回复;准确率类数据要有标准字段、固定流程、可验证的输出。两类数据混在一个数据集里训,模型学到的规则出现冲突,行为就会“四不像”。
3. 数据集工程:微调真正的分水岭
如果让我说哪个环节决定了微调项目成败,答案不是模型选型、不是训练框架,而是数据集。数据集的格式、数量、质量和清洗方式,每一项都会直接反映在训练曲线上。很多“我微调模型效果很差”的求助,最后排查下来问题都出在数据上。
3.1 从业务资料到训练样本:格式选择与转换
目前主流开源训练框架普遍支持两种微调数据格式:Alpaca 风格和 ShareGPT 风格。Alpaca 风格适合单轮指令任务,字段通常包含instruction、input、output;ShareGPT 风格适合多轮对话,使用conversations数组保存对话历史。
以设备运维场景为例,一条 Alpaca 风格样本长这样:
{ "instruction": "你是一名设备运维助手。请根据故障描述,给出排查步骤和预防建议。", "input": "设备型号:CNC-850;故障:主轴转速在加工中突然下降,伴随异常振动,报警代码 SP-16。", "output": "故障类型:主轴驱动异常。排查步骤:1. 停机检查主轴驱动器和电机连接线,确认接线无松动;2. 查看数控系统报警日志,确认 SP-16 触发条件;3. 检查主轴编码器反馈值是否漂移;4. 复位驱动器参数并重新校准主轴原点。预防建议:每两周检查一次动力线接头紧固情况,重点检查加工振动大的工序段。" }如果你需要多轮场景,就改用 ShareGPT 格式,每一条human和gpt消息组成一轮。多轮数据尤其适合客服、导购、技术答疑这类上下文连续的场景。
关键心得是:output 宁可写得详细,不要写得简略。模型在微调阶段就是在学“给这个输入,应该产出这种长度的回答”。如果 output 普遍只有一句话,模型就会学得比基座还懒;如果 output 结构严谨、分步骤,模型输出质量会肉眼可见地提升。所以整理数据时不要偷懒——这是回报率最高的工作。
3.2 清洗与去重:别把脏数据送进训练管线
数据清洗步骤看起来枯燥,却是排查训练事故的第一现场。我在处理一份从生产环境导出的客服对话数据时,发现里面混杂了大量同义词替换后的重复样本,还有一个字段把客户情绪标注成了反义(正样本全变成负样本)。如果直接训练,轻则损失曲线无法收敛,重则模型学到错误映射,上线后定向出错。
建议至少做这几步清洗:
- 精确去重和近似去重:完全相同的文本直接删除,高相似度的用 minhash 近似去重,避免单一高频样本把模型带偏。
- 字段规范性检查:用脚本统计每条样本的字段完整度,缺失字段直接丢弃。
- 编码与换行检查:中文场景里隐性繁体、全半角混乱、非法换行符都可能引入噪声,统一转换成 UTF-8 并规范化标点。
- 敏感内容过滤:这是我认为最重要也最容易被忽略的一步。训练数据里一旦混入诱导模型输出有害内容的投毒样本,模型上线后会成为安全隐患。务必在训练前做一轮敏感词与 prompt 注入模式的筛查,把带风险的样本直接剔除。
- 人工抽检:机器清洗完,至少人工过一遍 50~100 条样本,确认标注一致性和术语统一性。
清洗完成后我习惯做一个分布统计:看看每个意图类别的样本数量、每条样本的平均长度、output 的平均长度。这些统计指标能帮你发现数据偏差——如果某个类别的样本是另一个类别的 20 倍,模型很容易对少数类别产生“识别盲区”。
3.3 数据量、多样性与混合策略
微调到底需要多少数据,这是高频问题。我的经验是:单任务的格式对齐任务,300~500 条高质量样本就能有明显效果;多任务场景,需要每个任务至少 500 条;如果涉及领域风格的迁移,建议总量在 2000~5000 条之间。超过这个范围,继续增加数据的边际收益通常低于整理数据的成本。
比数量更重要的是多样性。同一类任务如果只有 20 种说法,模型只能学会 20 种模板,换个提问方式就开始飘。构造数据时要有意识地覆盖同义改写、问题边界、否定表达、多轮追问等变体,让模型学到“这类问题的应对模式”,而不是“这几个固定句式的死答案”。
还有一个实操经验:在领域数据中适当混合通用开放域数据。全领域训练数据会直接造成通用能力退化,最常见的表现是模型只会回答领域问题,闲聊一句就卡壳。我一般按领域数据:通用数据 = 7:3 到 8:2 的比例混合,既保留领域专长,也保住基本对话能力。通用数据可以直接复用公开的 SFT 数据集的子集,不必自己造。
4. LoRA 为什么这么能打:低秩适配的原理与调参边界
既然前面把 LoRA 说成性价比之王,这里就把它的原理说透。理解原理不是为了背公式,是为了在调参出问题时知道往哪个方向找原因。
4.1 低秩更新的直觉理解与矩阵本质
LoRA 的核心假设其实很朴素:模型做微调时,权重变化矩阵 ΔW 的“有效自由度”很低,也就是它落在某个低秩子空间里。就好像公司全员大调整,但真正影响业务方向的其实只是几个核心决策人,其余岗位的变化可约可不约。
形式化一点,微调后的权重为 W_new = W_old + ΔW,LoRA 把 ΔW 分解成两个低秩矩阵的乘积:ΔW = B × A。其中 A 和 B 都是远小于 W 的矩阵,训练时冻结 W_old,只更新 A 和 B。假设 7B 模型的某个线性层权重是 4096×4096,用秩 r=16 做 LoRA,新增参数量是 4096×16 + 16×4096 ≈ 13 万,只占原层参数量的 0.4% 左右。整个模型的训练参数量因此被压缩到极低水平,显存和优化器状态开销随之大幅下降。
为什么这个低秩假设成立?大量语言模型微调的实测经验表明,微调过程中的权重更新主要集中在一个维度很低的子空间内。换个直觉说法就是:模型本来就是用一个比较紧凑的表征来理解世界的,你在微调阶段教它的那点“新规矩”,不需要推到全世界,只需要在几个核心表征维度上微调就够。
4.2 关键超参数怎么定:r、alpha、学习率与目标模块
LoRA 的核心超参是r和alpha。r是秩,决定低秩矩阵的表达能力;alpha是缩放因子,控制更新项对原权重的影响强度。时常见到的设置是 r=16、alpha=32,这是一个很稳的起点,适合大多数任务。
调参经验是这样:任务越复杂、需要学习的模式越精细,r可以适当增大到 32 或 64;但r不是越大越好,过大的r会增加过拟合风险,也会让训练显存开销上升。alpha一般取r的 1~2 倍,也可以保持alpha=r同时调低学习率。两者与学习率的组合效果比单独调某一个更有意义——alpha/r影响更新强度,学习率影响优化步伐,跑的时候三个一起观察才不会误判。
目标模块的选择同样关键。默认情况下 LoRA 注入到注意力层的q_proj、k_proj、v_proj、o_proj,这对绝大多数任务够用。如果想让模型“更听话”,可以额外把 MLP 层的gate_proj、up_proj、down_proj也加入训练,这样效果有提升,但训练时间也变长。能不能全注入?可以,但没必要——注意力层和 MLP 层同时全量低秩化,训练显存和耗时上涨明显,而收益通常只体现在极少数对细节要求极高的任务里。
4.3 QLoRA 与精度取舍:什么时候用 4bit 训练
QLoRA 在 LoRA 基础上增加了一个关键改动:基座权重用 4bit NF4 量化存储,训练时只把当前计算需要的权重反量化到 16bit,同时用双重量化压缩优化器状态。这套设计让 7B 模型微调显存需求从约 24GB 降到约 16GB,一块消费级显卡就能跑,是个人开发者和预算有限团队的首选。
不过量化训练有一个代价:基座权重的信息精度被压缩到 4bit,少量任务对权重精度敏感,QLoRA 训练出的效果可能比标准 LoRA 低一点。如果你对效果有极高要求且显存足够,优先 LoRA;如果显存紧张、数据量不算特别大,QLoRA 能帮你省下的硬件成本相当可观。另一个实用技巧是:训练完成合并 LoRA 权重后,可以再对合并结果做一步简单的量化部署(例如 GGUF 格式),推理时损耗通常低于训练时量化损耗,因为推理量化发生在合并后的完整权重上。
5. 用 LLaMA-Factory 完整跑通一次 Qwen 微调
前面讲了不少理论,现在流水账式地记录一次实战。我用的是 LLaMA-Factory,理由很简单:它把数据处理、训练、对话测试、模型导出集成在一个项目里,配置通过 YAML 管理,可复现性比手写训练脚本强得多。这个框架现在社区生态好、踩坑资料多,适合不想重复造轮子的团队。
5.1 环境准备与显存预算
环境这块说多了都是泪,直接给一份能用的清单。训练机我用的是单张 4090 24GB,跑 QLoRA 训练 7B 模型毫无压力;如果你只有 16GB 显存的卡,QLoRA 方案也能跑,只是 batch size 要更保守。软件环境建议:
- Python 3.10 或 3.11
- CUDA 12.x,配套 torch 2.x(注意 torch 版本与 CUDA 版本匹配)
- 安装 LLaMA-Factory:
git clone项目后用pip install -e .方式安装,依赖会自动装好 - 模型权重从 Hugging Face 或 ModelScope 下载,建议提前下载到本地路径,训练过程中反复下载不仅慢,还可能因为断网中断
我第一次跑的时候没注意 CUDA 和 torch 的版本兼容问题,启动训练直接报错,排查了半天是 torch 编译版本不支持当前显卡驱动。现在的习惯是先在机器上python -c "import torch; print(torch.cuda.is_available())",确保 CUDA 可用再进下一步。
5.2 数据准备与训练配置
假设我们已经把设备运维数据整理成equipment_sft.json,放在 LLaMA-Factory 的data目录下,并在dataset_info.json中注册数据集名equipment_sft。接下来写训练配置:
model_name_or_path: /models/Qwen2.5-7B-Instruct template: qwen stage: sft finetuning_type: lora lora_rank: 16 lora_alpha: 32 dataset_dir: data dataset: equipment_sft cutoff_len: 1536 learning_rate: 2e-4 num_train_epochs: 3.0 per_device_train_batch_size: 1 gradient_accumulation_steps: 16 lr_scheduler_type: cosine optim: adamw_torch bf16: true output_dir: outputs/equipment_lora几个关键参数解释一下。per_device_train_batch_size设成 1 是为了应对显存限制,靠gradient_accumulation_steps把有效 batch size 凑到 16,梯度累积的逻辑类似“攒够一批再更新一次”,能同时兼顾稳定性和显存占用。cutoff_len控制样本最长长度,按业务数据的最长长度加一点余量,一般 1536 够用,太长会撑爆显存,太短会截断有效内容。bf16在有支持的卡上优先开启,比fp16更稳定;如果硬件不支持 bf16,再退到 fp16 并做好损失监控。
启动训练的命令很简洁:
CUDA_VISIBLE_DEVICES=0 llamafactory-cli train configs/equipment_lora.yaml训练过程我会保留一条命令窗口专门观察损失值。正常的 SFT 损失走势是在前几百步显著下降,然后缓慢走平,最后阶段可能出现小范围波动。如果损失一直不降,或者降到一半突然跳高,大概率是数据或超参出了问题,不要盲目加大训练轮次去“撞运气”。
5.3 训练时长、显存监控与 LoRA 合并
以 7B 模型、2000 条数据、3 个 epoch 为例,单卡 4090 上 QLoRA 训练大约需要 1.5~3 小时,标准 LoRA 会稍长一些。训练过程中用nvidia-smi持续观察显存占用,如果接近显存上限且开始出现 OOM,优先调低per_device_train_batch_size,然后再考虑减小cutoff_len。
训练完成后,LoRA 权重保存在outputs/equipment_lora目录下。这时模型还不能直接部署,因为 LoRA 适配器是附加在基座上的,需要用合并脚本把适配器权重融合回基座。命令大致如下:
llamafactory-cli export \ --model_name_or_path /models/Qwen2.5-7B-Instruct \ --adapter_name_or_path outputs/equipment_lora \ --template qwen \ --finetuning_type lora \ --export_dir outputs/equipment_merged \ --export_size 4 \ --export_legacy_format false合并完成后,equipment_merged目录就是一个可以直接部署的全量模型。合并前记得确认已经训练收敛,合并过程本身不可逆,反复合并再重新训练很浪费时间。
6. “微调崩了”的完整排查:一次视觉模型损失爆炸的经历
热榜上有条词条是“目标检测模型微调崩了”,看到这个词条我就想起两个月前帮一个朋友排查的视觉模型训练事故。那种“loss 曲线一开始正常,训练 200 步后突然冲高,然后直接 NaN”的经历,遇到过的朋友应该知道有多崩溃。把整个排查链路写下来,下次你遇到类似问题可以按图索骥。
6.1 现象描述与第一反应
朋友的场景是视觉语言模型的微调,输入是车载摄像头画面,任务是提取驾驶员行为要素。训练到 200 步左右,损失从正常下降趋势突然高频震荡,随后训练日志里出现nan,训练进程整体失效。
第一反应不要急着动训练参数,先把停下来的训练日志完整看一遍。我当时的排查顺序是这样的:
- 确认数据和标注的映射关系。检查数据加载器是否可能读到错位样本。结果发现数据集中有个小批量样本的 JSON 坐标字段用错坐标系——把检测框的宽高写反了,同一批次里既有正确注标又有错误注标,模型在尝试学习互相矛盾的映射时,梯度产生剧烈冲突。
- 检查学习率是否过大。把学习率从 2e-4 降到 2e-5 后重跑,发现损失仍有跳变但不至于发散,说明学习率不是主因,但确实够大。
- 检查混合精度设置。训练配置用的 fp16,查看日志发现 loss 在变成 NaN 前已经出现多次
inf更新。fp16 的指数位有限,梯度过大时容易溢出成 inf,再回传就直接变成 NaN。 - 固定 loss 函数输入。在损失函数里临时加断言,当输入出现 NaN 时就打印对应样本索引,最终定位到那批坐标错误的样本确实能从数据层面稳定复现出数值异常。
6.2 根因与修复:数据错了,框架背锅
最终结论很简单:数据错了,不是框架的问题。那批标注错误的样本,让模型在某个 batch 里同时看到“同样的视觉特征对应不同标签”,创造了无法收敛的梯度条件;而 fp16 的低精度放大了异常梯度的数值扩散,让 loss 从“不合理”迅速演变成“NaN”。
修复动作分三步:清洗异常标注样本;把混合精度从 fp16 切到 bf16;学习率从 2e-4 降到 1e-5 重新训练。重跑后损失曲线恢复正常下降,最终效果也达到业务预期。
这个案例的通用意义在于:“微调崩了”绝大多数时候不是框架或显卡的锅,而是数据管线里的某个低级错误叠加数值精度问题。排查时应该先看数据、再看精度、最后才调参数。
7. 从训练到上线:模型导出、量化部署与效果验收
训练收敛、LoRA 合并完成,只相当于完成了 60% 的工作。接下来的导出、量化、部署、评测,每一步都可能让前面的成果打折扣。很多团队把模型训练得不错,却在部署和评测环节翻了车。
7.1 量化导出:GGUF 格式与 Ollama/vLLM 部署
合并后的模型是 fp16 格式,7B 权重大约占 14GB 磁盘,直接部署到普通业务机上压力不小。实践中我通常把它量化成 GGUF 格式。GGUF 是 llama.cpp 生态的量化格式,支持 4bit、5bit、8bit 等不同精度的量化。我常用的量化配置是 Q4_K_M,7B 模型体积约 5GB 左右,单机 CPU 或普通显卡都能流畅运行。
用 Ollama 部署私有化模型非常顺滑,引入 Modelfile 定义模型行为和对话模板:
FROM ./equipment_merged.gguf TEMPLATE "{{ if .System }}<|im_start|>system {{ .System }}<|im_end|> {{ end }}<|im_start|>user {{ .Prompt }}<|im_end|> <|im_start|>assistant " PARAMETER temperature 0.3 PARAMETER top_p 0.9执行:
ollama create equipment-7b -f Modelfile ollama run equipment-7b如果你的场景是高并发的在线服务,vLLM 是更好的选择。vLLM 的 PagedAttention 机制显存利用率比传统推理高很多,适合多路并发。7B 量化模型部署在 24GB 显卡上可以承载几十路并发请求。当然 vLLM 更偏“服务化”,要接 API 网关、管理并发策略,复杂度比 Ollama 高,适合有一定工程能力的团队。
7.2 效果验收:别让训练损失曲线骗了你
损失值收敛只是最低标准。我看过太多“训练损失降到很低”的模型,实际业务效果却不及预期。现在的习惯是准备一套固定的评测样本,训练前后各测一遍。评测维度通常包含这样几个:
| 评测维度 | 做法 | 通过标准 |
|---|---|---|
| 领域回答准确率 | 挑选 100 条业务专家标注的高难样本,对比基座模型与微调模型的输出 | 微调模型正确率显著高于基座 |
| 输出格式符合率 | 用程序解析模型输出的 JSON、表格等结构化内容 | 100% 可解析且字段完整 |
| 通用能力回退 | 跑通用问答抽查,覆盖闲聊、常识、推理 | 与基座模型差距不超过 3% |
| 安全与边界 | 输入与业务无关或诱导性问题 | 模型稳定拒绝或按边界话术回复,不泄露训练数据特征 |
这里重点说“通用能力回退”和“安全与边界”。微调模型最隐蔽的问题就是“局部学得太死、整体变笨”。我用过的最有效手段是让模型回答一组固定通用问题,把微调前后的回答逐一对照。如果微调后连“介绍你自己”都开始复读领域话术,说明灾难性遗忘已经严重,需要在数据混合比例上补充更多通用样本。安全与边界方面,训练前已做过敏感数据清洗,评测时再做一轮边界验证,确保模型对越权话题能安全兜底。
7.3 上线后持续观察:把微调变成可迭代的事情
模型一旦上线,微调工作并没有结束。我建议接好推理日志,按周维度观察几个指标:拒绝率、无意义输出比例、用户反馈关键词、格式解析失败率。任何一个指标异常,都值得回到数据集去看是不是新出现的业务问题没被覆盖。
现在很多团队已经习惯一个月做一轮增量微调,把上一阶段积累的高质量用户反馈数据整理进训练集,配合 RAG 一起使用。微调和 RAG 从不冲突:RAG 负责把最新、最细的知识带到上下文,微调负责让模型更稳定地使用这些知识并遵守业务输出规范。两者结合,才是领域大模型落地最稳的姿势。
我自己的习惯是每次微调前先保存一份固定的评测样本集,里面 20 条高难业务样本、20 条通用对话样本,每次训练完先跑这份评测再谈上线。这样做还有一个隐藏好处:如果哪次微调后效果比上次差,这份固定评测能最快暴露“是哪一类能力退化了”,而不是靠记忆去猜。这个习惯帮我避免了很多次“看起来训练成功了、实际却被业务方打回”的情况,建议你也试试。