把一个通用基座模型训练成领域专家,最直接的办法就是在海量领域语料上继续做预训练,也就是持续预训练(Continual Pre-Training,CPT)。医疗和法律是两个典型的知识密集型领域,术语密度高、推理链条长、语料形态特殊,非常适合用CPT来做领域注入。但CPT有一个绕不开的坑:模型学得越专注,通用能力丢得越快,这就是灾难性遗忘(Catastrophic Forgetting)。本文结合实践经验,聊聊领域数据怎么准备、训练怎么配比、遗忘怎么防,帮你把领域大模型调得既专业又不失底色。

一、医疗与法律领域语料的构建与配比
CPT的效果上限由数据质量决定,医疗和法律领域尤其如此。医疗方面可用的语料包括医学教科书、临床指南、药品说明书、PubMed摘要与全文、中文医学百科、脱敏后的电子病历等;法律方面则有法律法规原文、司法解释、裁判文书、合同模板、法学教材和实务问答。这些语料的特点是文本结构差异极大,裁判文书动辄上万字,而药品说明书则是短条目式文本,如果不做处理直接混合训练,模型学到的东西会非常不均衡。
数据清洗是第一道关。医疗语料中要重点处理脱敏问题,患者姓名、住院号、身份证号必须彻底清除;法律语料中要剔除乱码文书和重复率极高的模板化文本。经验上,对裁判文书做MinHash去重后,数据量通常能压缩到原来的三到五成,但信息量几乎不损失。此外建议对长文档做结构感知的切分,保留章节标题层级信息,可以用特殊标记或者拼接摘要的方式让模型感知文档结构。
配比是CPT成败的关键。纯领域数据训练听起来很纯粹,但实践反复证明这样做遗忘最严重。主流做法是通用数据与领域数据混合,常见比例从1:1到4:1(通用比领域)都有人用,具体取决于领域语料的规模。下面是一个典型的数据配比示例:
domain_ratio_config = {
"medical_corpus": 0.35, # 医疗领域语料(指南/教材/脱敏病历)
"law_corpus": 0.15, # 法律领域语料(法规/裁判文书)
"general_web": 0.30, # 通用网页数据(回放用)
"code_and_math": 0.10, # 代码与数学,保住推理能力
"instruction_data": 0.10, # 指令数据,对齐能力不丢失
}
# 训练时按epoch重新采样,保证每个batch内分布稳定
# 领域数据可过采样2-3个epoch,通用数据只过1个epoch另外一个细节是课程式安排:前几个epoch可以领域数据占比稍高,后期逐步提高通用数据比例,让模型在收尾阶段重新校准通用分布,这比全程固定比例的效果通常更好。
二、灾难性遗忘的成因与训练策略层面的缓解
灾难性遗忘的根源在于神经网络的参数共享机制。预训练时模型参数在通用数据分布上达到一个较优解,CPT阶段持续用领域分布的梯度更新参数,原本编码通用知识的参数被覆盖性改写。领域数据分布越窄、学习率越大、训练轮数越多,遗忘越严重。理解了这一点,就能推导出一系列缓解手段。
首先是学习率策略。CPT的学习率绝不能沿用预训练的峰值学习率,一般取预训练峰值的十分之一到五分之一,并配合较快的衰减。以7B模型为例,预训练峰值学习率如果是3e-4,CPT阶段从2e-5到5e-5起步是常见选择。学习率小意味着参数更新幅度小,对原有知识表征的扰动自然就小。其次是训练轮数控制,领域语料过两到三个epoch通常就够了,超过五个epoch往往出现领域过拟合叠加通用能力崩塌的双重问题。
其次是回放机制(Replay)。在训练流中掺入通用数据,本质上是在优化目标里保留对旧分布的约束。回放数据不必与原始预训练集完全一致,用高质量的通用子集即可,重点覆盖百科、新闻、代码、数学这几类与通用能力强相关的分布。再进一步,可以给不同来源的数据设置不同的损失权重,让领域数据主导知识注入,回放数据负责稳住底盘:
loss_weight_map = {
"medical_corpus": 1.0,
"law_corpus": 1.0,
"general_web": 0.8, # 回放数据权重稍低,避免与领域数据抢梯度
"code_and_math": 1.0, # 推理能力相关,权重保持
}
# 每步根据batch内token来源分别计算加权损失
weighted_loss = sum(loss_weight_map[src] * loss_for(src) for src in batch)还有一个容易被忽视的策略是暖启动与分阶段训练。如果目标模型要同时覆盖医疗和法律两个领域,一次性混合两个领域训练的效果,往往不如先医疗后法律、每个阶段都掺通用数据的串行方案,或者干脆训两个领域专家模型再用模型合并的方式整合。串行多领域CPT时,前一阶段的数据也要以一定比例进入后一阶段的回放池,否则第一个领域的知识同样会被冲掉。
三、参数层面的防遗忘方法:从正则化到LoRA
训练策略之外,参数层面的方法能更结构性地约束遗忘。第一类是正则化方法,代表是EWC(弹性权重固化)。它先在基座模型上用通用数据估计费雪信息矩阵,找出对通用任务重要的参数,训练时对这些参数施加二次惩罚项,重要参数更新幅度被压小,通用知识得以保留。EWC在中小模型上效果明确,但在超大模型上费雪矩阵估计成本高,实践中常用对角近似或者抽样估计来降低开销。
# EWC核心思想伪代码
fisher = estimate_fisher(base_model, general_data) # 通用数据上的参数重要性
for step in cpt_training:
loss = ce_loss(domain_batch)
for name, p in model.named_parameters():
# 对重要参数施加弹性约束,theta_0为初始参数
loss += lam * (fisher[name] * (p - theta_0[name]) ** 2).sum()
loss.backward()第二类是参数隔离方法,LoRA是最实用的代表。CPT阶段冻结基座权重,只在注意力层注入低秩适配矩阵训练,基座参数原封不动,通用能力理论上零损失。LoRA用于CPT时rank要设得比微调时大,常见取64到256,领域知识量大的场景rank越高注入容量越足。训练完成后既可以把LoRA权重合并回基座得到独立的领域模型,也可以保留为可插拔模块,一个基座挂多个领域适配器,按需切换。
第三类是MoE路由方案。将部分前馈层改造为专家结构,新增的领域专家在CPT阶段训练,原有参数作为共享专家冻结或低学习率微调。推理时路由器根据输入自动分配,领域问题走领域专家,通用问题走共享路径,遗忘问题从架构上被绕开。代价是训练和推理成本都显著上升,一般只在有充足算力和长期领域布局时选择。
四、评估体系:怎么知道模型没有学废
防遗忘不能凭感觉,必须建立双轨评估。领域侧用医疗和法律的专业基准,比如医学选择题评测、临床问答集合、法律条文理解与案例分析任务,确认领域知识确实注入成功。通用侧则用MMLU、C-Eval、通用问答和代码生成等基准,与CPT前的基座模型逐项对比,任何一项跌幅超过三到五个百分点就要警惕。
建议每个checkpoint都跑一轮轻量双轨评测,画出领域指标与通用指标随训练步数的变化曲线。理想状态是两条曲线同步上升后趋稳;如果通用曲线持续下滑,说明配比或学习率需要回调。训练完成后还应该做一轮人工盲测,把CPT前后的模型输出混在一起,由领域专家判断专业性、由普通用户判断通用对话质量,避免评测集过拟合带来的虚假繁荣。
综合来看,一套稳妥的CPT流水线是:高质量领域语料加去重清洗,通用数据按比例回放,小学习率加快速衰减,两到三个epoch封顶,视算力选择LoRA或全量加正则化,最后用双轨评测闭环验证。把这几个环节做扎实,医疗法律领域模型的遗忘问题可以控制在可接受范围内,得到一个真正可用的领域专家。