4.1 垂直领域实战之数据构建与训练:以医疗问答为完整范例 读者读完这一节,应该能拿走一条可复用的「垂直领域微调作战线」:先想清楚这个领域要改模型的哪一类能力,再从真实业务流里捞出对的语料、按 SFT 的格式洗干净、配上能约束输出的模板,最后用一个保守但够用的训练配置把它训出来并过三道验收门。这一节用医疗问答做完整范例,是因为它几乎集齐了所有垂直领域的典型难题——数据敏感、必须讲事实、答错有代价、且标注语料稀缺。把医疗这条线走通,换到法律、客服、金融都是同一套打法。 4.1.1 为什么医疗是 LoRA 微调的「甜区」 先把话说在前头:医疗场景绝不适合用全量微调去「暴力改造」一个通用大模型,反而特别适合 LoRA/QLoRA 这种「精准用工」的路子。原因有四: 第一,数据极其敏感。
读者读完这一节,应该能拿走一条可复用的「垂直领域微调作战线」:先想清楚这个领域要改模型的哪一类能力,再从真实业务流里捞出对的语料、按 SFT 的格式洗干净、配上能约束输出的模板,最后用一个保守但够用的训练配置把它训出来并过三道验收门。这一节用医疗问答做完整范例,是因为它几乎集齐了所有垂直领域的典型难题——数据敏感、必须讲事实、答错有代价、且标注语料稀缺。把医疗这条线走通,换到法律、客服、金融都是同一套打法。
先把话说在前头:医疗场景绝不适合用全量微调去「暴力改造」一个通用大模型,反而特别适合 LoRA/QLoRA 这种「精准用工」的路子。原因有四:
第一,数据极其敏感。病历、诊断、用药记录里全是受保护的健康信息,这类数据基本出不了医院内网,你不可能把它们拿去训练一个从头训起的大模型,更不可能上传到第三方。LoRA 的价值在于——基座 GLM-5.2 是开源可本地部署的,适配器只在你自己的机器上训练,原始语料从头到尾不离开内网,合规风险天然低一截。
第二,强领域知识、弱标注规模。医疗有大量专业术语、用药逻辑、诊疗路径,通用模型「知道一点但不准」;但你手里的标注问答对往往只有几千到几万条,远不够全量微调。LoRA 恰好在「小数据 + 强领域」的区间内性价比最高。
第三,答错有代价,必须可控。医疗回答不能瞎编。LoRA 只动几百万参数,基座的通用常识被完整保留,意味着「模型不会因为你加了医疗适配器就丧失基本判断力」,这比大幅改写权重更安全、更可预测。
第四,多场景可拆分。导诊、健康科普、用药咨询、病历结构化是性质不同的任务。用一个基座挂多个医疗子适配器(导诊一个、科普一个、结构化一个),比训一个大杂烩模型干净得多——这一点在 4.2 会展开讲多场景切换。
把领域拆开看,「要改模型的能力」其实只有三类:知识注入型(把术语体系、用药逻辑灌进去)、格式约束型(病历结构化、按模板出报告)、风格/角色型(用温和、专业的口吻做健康科普)。医疗里三类全占,所以它是练手的绝佳范本。
新手最大的误区是「先去找一堆现成数据集,再想怎么用」。正确的顺序是反过来的:先定义你要解决的业务问题,再去你的真实业务流里捞对应的语料。医疗场景里,语料通常来自这四口井:
捞出来之后,要统一成 SFT 需要的「指令-回答」对(instruction-input-output 或纯 instruction-output)。下面是一份医疗 SFT 样本的骨架:
{ "instruction": "根据以下患者主诉,给出需要进一步询问的关键症状和初步分诊建议。", "input": "患者男,32岁,发热两天,体温38.5℃,伴咳嗽、乏力,无明显呼吸困难。", "output": "建议补充询问:1)是否接触过呼吸道感染患者或近期去过疫区;2)咳嗽是否带痰及痰色;3)有无胸闷、血氧下降。初步分诊:若精神状态好、无呼吸急促,可居家观察并多饮水;若出现持续高热>3天、呼吸急促、血氧<93%,应及时线下就诊。" }
注意这里 output 的写法:它给的是「建议进一步询问 + 分诊」,而不是替医生下诊断。医疗垂直模型最危险的越界就是「直接给确诊结论」,所以数据构造时就要把边界写进样本——模型学会的是「辅助分诊与信息收集」,而非「替代医生」。这条边界要贯穿所有样本,否则训出来的模型会养成乱下诊断的坏习惯。
通用语料清洗是「去重、去噪、去空」,医疗清洗还要多加一道安全与事实门。我建议按这张流水线过一遍:
几个踩坑点必须说:
数据干净了,接下来是模板。医疗任务的失败,一半坏在「模型答得没错但格式没法用」。解决办法是在系统提示和样本结构里就把输出格式定死。
一个病历结构化任务的模板可以这样设计:
系统提示:你是某三甲医院的病历结构化助手。只输出 JSON,字段固定为 age/sex/complaint/duration/vitals/suspect。不得输出任何解释性文字。若某项信息缺失,填"未提及"。 用户输入:患者女,45岁,反复上腹疼痛一周,伴反酸,进食后加重。 期望输出: { "age": "45", "sex": "女", "complaint": "上腹疼痛、反酸", "duration": "1周", "vitals": "未提及", "suspect": "未提及" }
模板设计的三条原则:
数据、模板齐了,落到训练配置。下面是一份 QLoRA 4-bit 训练医疗适配器的示例配置(写法基于 PEFT + transformers 的 SFTTrainer,API 为公开稳定接口,具体模块命名以智谱官方文档为准):
from peft import LoraConfig, get_peft_model from transformers import BitsAndBytesConfig bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype="bfloat16", ) lora_config = LoraConfig( r=16, lora_alpha=32, # alpha/r = 2,稳妥起点 target_modules=["q_proj","k_proj","v_proj","o_proj", "gate_proj","up_proj","down_proj"], # 医疗偏知识注入,FFN 也挂上 lora_dropout=0.05, bias="none", task_type="CAUSAL_LM", ) model = get_peft_model(model, lora_config) model.print_trainable_parameters() # 确认真实命中层与可训练参数量
训练超参给一个医疗场景的保守起点(非铁律):学习率 2e-4、轮次 3~5、批次按显存调、warmup 比例 0.03、加 cosine 调度。为什么保守?因为医疗样本少、错答案代价高,宁可不收敛到完美,也不要学飞。如果训练后发现「模型太保守、答不出专业内容」,再小步把学习率提到 3e-4 或轮次加到 6;如果发现「开始编造罕见病用药」,立刻降学习率并复查拒答样本比例。
训练跑完不等于能用。医疗适配器必须过三道门:
只有三道门全过,才进灰度。上线后仍保留「低置信度转人工/转医生」的开关——这是医疗场景不可省的护栏。走完这一节,你已经拥有了一条从数据到上线的完整医疗微调链路;下一节把它抽象成可迁移的方法,套到法律、客服两个场景,并讲清楚多场景怎么共用一个基座。
很多团队把「训完上线」当成结束,这是浪费。LoRA 最被低估的价值恰恰是——适配器天然适合做持续学习,而且回滚几乎零成本。医疗线上每天都会产生三类高价值信号:医生在后台纠正过的模型误答、用户反复追问暴露的模型盲区、以及触发拒答后转人工的真实疑难。这些日志比任何离线构造的语料都珍贵,因为它们来自真实分布。
回流的链路很简单:线上日志先走一遍 4.1.3 的脱敏与事实门(这一步医疗绝不能省),由医生标注「对/错/边界」并修正输出,再并入增量数据集;之后用 resume_from_checkpoint 在上一版适配器基础上做小步增量训练,而不是从零重训——这能避免新数据把旧能力冲掉。重训完必须重新过 4.1.6 的三道门,灰度通过后再替换线上版本,同时永远保留上一版适配器文件作为回滚支点。因为 LoRA 只动几百万参数,存十个历史版本也不过几百 MB,这种「训错就退一步」的底气,是全量微调给不了的。
走完这一节,你已经拥有了一条从数据到上线的完整医疗微调链路;下一节把它抽象成可迁移的方法,套到法律、客服两个场景,并讲清楚多场景怎么共用一个基座。