几个月前,我们团队接到一个任务:把通用大模型训练成能回答金融合规问题的行业模型。模型基座选了开源通用大模型,初期大家觉得提示词写细一点就行,结果一测就露馅:合同条款里的“留置权”“代位求偿”这些术语,模型能聊个大概,但一旦落到具体业务场景,经常给出似是而非的答案。后来我们把路线从“微调”改成了Continued Pre-Training(继续预训练,简称CPT),用一批内部脱敏语料让模型把领域资料“通读”了一遍,效果才明显拉开差距。
这篇文章想把这条路线完整拆开讲一遍:什么时候该做继续预训练,数据怎么准备,训练参数怎么定,以及训练中最容易踩的坑。适合想在企业里落地行业模型的算法工程师和技术负责人,也适合正在评估“通用大模型+行业数据”技术路线的决策者。
1. 先判断要不要走CPT:通用大模型为什么在行业场景失灵
1.1 通用模型在行业场景的三块短板
通用大模型的优势是知识覆盖面广,但这个“广”往往是以“专”为代价的。第一个短板是行业术语理解不到位。拿我们金融场景举例,模型可能知道“抵押”是什么意思,但面对“浮动抵押”“最高额抵押”这类带有精确法律边界的词,它经常把几个概念搅在一起。第二个短板是业务规则缺失,很多行业知识并不在公开互联网上,比如企业内部的风控口径、审批流程、产品说明书,通用模型根本没机会读到。第三个短板是输出风格与业务不匹配,行业文档讲究术语严谨、格式固定,而通用模型默认用“普及式”口吻回答,拿去直接交付会被业务方打回来。
这不是提示词工程能解决的问题。提示词相当于让一个只看过《百科全书》的人现场翻报纸答题,没读过的知识就是答不出来。所以企业如果想把大模型用在自己的垂直领域,本质上是给模型补数据、补知识。这个“补”的动作,就是继续预训练的核心价值。
1.2 三条路线对比:微调、LoRA与Continued Pre-Training
很多团队一上来就提“微调”,把行业问答对丢给模型做监督训练。这没有错,但得先分清楚阶段。我把常见方案列成了表格,方便对比:
| 路线 | 训练阶段 | 训练数据 | 主要学习目标 | 成本 | 适用场景 |
|---|---|---|---|---|---|
| 全参数微调 | SFT阶段 | 指令-回答对 | 学习输出格式、对齐人类偏好 | 较高 | 已有行业知识,只缺表达方式 |
| LoRA等参数高效微调 | SFT阶段 | 指令-回答对 | 在低成本下调整行为 | 低 | 快速验证、单卡试点 |
| Continued Pre-Training | 预训练阶段 | 大规模无标注文本 | 注入行业知识、术语、文档风格 | 最高 | 模型明显缺少领域知识 |
关键区别在于:微调学的是“怎么说话”,继续预训练学的是“懂什么”。行业模型如果直接在通用模型上做指令微调,模型只是表面上学会了问答格式,遇到没见过的知识仍然会一本正经地编。CPT则是让模型在大量行业文本上继续做“预测下一个词”的自监督学习,把领域里的概念、事实、逻辑关系写进参数里。
需要说清楚,CPT通常不是终点。做完CPT之后,一般还要接着做指令微调或对齐,才能变成好用的对话模型。它更像是介于通用预训练和业务微调之间的必经之路。
1.3 什么样的企业场景真正需要CPT
不是所有项目都需要继续预训练。我判断的依据是三条:
一是模型在领域知识上的错误率高到影响可用性。可以提前做一个小样本测试,把20个典型行业问题丢给基座模型,如果回答里出现术语混淆、事实错误,就有必要做CPT。二是企业手里有大量未标注的领域文本。注意,这里说的是“未标注文本”,不是问答对。光有一两千个问答对,做SFT就够了;但如果手里有上千万篇合同、研报、产品手册,不用起来就太浪费了。三是业务要求私有化部署和知识不外传。通用模型的公共知识无法覆盖企业内部资料,而行业模型又必须能回答这些私有知识,CPT就是把私有知识内化到模型参数里的重要路径。
如果三条都满足,这条路值得认真考虑。如果只满足最后一条,也许用RAG(检索增强生成)先把文档库接上去更划算。CPT解决的是“知识内化”,RAG解决的是“知识外挂”,两者不冲突,但预算有限时得先排优先级。
2. 数据准备:行业模型的护城河其实在数据
2.1 行业语料从哪里找
很多团队把数据准备简单理解成“收集文档、切分文本”,实际操作中最大的工作量恰恰在这里。行业语料按来源大概分四类:企业内部文档(合同、报告、制度、工单)、公开行业数据(监管公告、行业白皮书、专业文献)、外部专业数据库(期刊、论文、专利)、以及知识库沉淀(FAQ、案例库、合规问答)。优先级的逻辑是:离业务越近的数据越值钱。
但原始数据不能直接用。以金融行业为例,一份年报PDF可能几百页,里面有大量表格、图表、页眉页脚,直接抽取出来塞给模型,噪声比有效信息还多。我的经验是先做数据治理:PDF先转文本,再用规则清洗掉页眉页脚、乱码、摘要式重复内容;表格最好格式化保留,否则会丢失关键数据关系;图片里的文字需要OCR,但OCR结果一定要抽样检查,错误率高会让模型学到错误符号。
另外必须提醒一句,企业内部数据涉及脱敏和权限问题。我们当时和合规部门定了一个原则:能用脱敏后的数据,绝不用原始数据;人名、身份证号、手机号这些字段在做CPT之前全部打码。模型训练完也不会泄露具体隐私,但数据来源的合法合规性是企业的底线,这一步不能省。
2.2 清洗与过滤:宁可少,不要脏
行业文本清洗是决定CPT效果好坏的第一道关。不要迷信“喂得越多越好”,脏数据会让模型学到错误的语言习惯,后期很难纠正。
我常用的清洗流程分五步:
- 格式清洗:统一全角半角、去除控制字符、修复断裂段落;
- 噪声过滤:去除广告、导航、无意义重复、乱码文本,长度低于50字的片段直接丢弃;
- 文档去重:网页正文经常一模一样的内容反复出现,用SimHash或MinHash做近似去重,这一步能砍掉至少20%的冗余数据;
- 质量打分:用一个简单的分类器或者规则,给每个文档打质量分,论文、教材、监管文件优先保留,论坛口水文降权;
- 敏感信息过滤:用正则和实体识别把身份证、电话号码、邮箱等替换成占位符。
质量打分这里可以多说一句。我们最初只做了格式和去重,结果训练后模型回答里经常出现“哈哈哈”“小编觉得”这类口语噪声。后来加了质量打分,把各类文档按“专业度”加权采样,回答风格立刻正经了很多。行业数据清洗的目标不是变成PDF原样,而是要让模型学到“行业内的人在正式场合怎么说话”。
2.3 数据配比、去重与token预算
模型既要学行业知识,又不能把通用能力忘光,所以CPT的数据配比非常关键。我们的经验是:行业语料和通用语料按70:30到80:20之间混合,通用语料用来稳住模型的基础语言能力。纯行业语料训练出来的模型,在专业问答上的确很犀利,但一旦用户闲聊或者问常识性问题,就开始胡言乱语,这就是没有保留通用知识的典型症状。
token预算方面,得先算一算。一个中型企业如果准备了20GB干净文本,按中文约1.5字/token算,大约有100亿token。对7B到13B量级的模型,这个量级是合理的;如果预算少于10亿token,CPT的收益可能不明显,不如考虑RAG。这里我建议的做法是先小规模验证:用1亿token做一次短训练,看领域测试集效果有没有提升,再决定要不要上全量数据。
另外还有一个容易被忽略的动作:训练集和验证集的去重。我见过团队拿同一份合同既训练又评测,结果loss曲线漂亮得不行,实际业务一测原形毕露。做训练/验证切分时,必须按文档ID去重,甚至按相似度去重,否则评估结果会虚高。
3. 训练参数与运行环境:让模型“温和”地学新知识
3.1 计算资源与框架选型
CPT比SFT要贵得多,这是很多团队没有心理准备的。一个7B模型,在8张A100(80G)的机器上训练100亿token,通常需要跑一周以上;如果用4090这种卡,就得几十张并行。这里给一个粗略的经验值:训练速度约等于总token数除以(单卡吞吐×卡数),单卡吞吐量受模型大小和上下文长度影响很大。
框架方面,熟练的团队可以直接用DeepSpeed或Megatron-LM,这两个框架对大规模并行训练支持得最好。如果团队更熟悉Transformers,也可以基于Trainer改造,但要仔细处理梯度累积和分布式采样。中小团队不要一上来就自己写分布式逻辑,DeepSpeed ZeRO-2/ZeRO-3已经够用。我们的做法是:基座模型用HuggingFace格式,训练框架用DeepSpeed,配置好ZeRO-3和FlashAttention,稳定性和速度都满意。
有一个建议:训练前先跑一个极小数据量的冒烟测试,确认数据加载、模型结构、保存逻辑都正确,再启动全量训练。不然跑了两天发现数据管道有bug,损失是灾难性的。
3.2 关键超参:学习率、上下文长度、batch size
CPT和普通预训练在超参上有个显著差异:学习率要低,而且得用带衰减的调度器。通用预训练一般用3e-4这类高学习率,但CPT是在一个已经收敛的模型上继续学习,学习率太高会把原有参数冲乱,表现成通用能力断崖式下跌。我们通常把峰值学习率设在1e-5到5e-5之间,7B模型一般取2e-5,13B模型取更低,比如1e-5。
上下文长度也直接影响数据采样。行业文档往往有长依赖,比如一份合同里的定义条款可能在后面反复引用,因此上下文长度建议从4096起步,有条件直接上8192。但注意,上下文越长,显存占用和训练成本越高。我们要做的不是盲目加长,而是先分析行业语料的长度分布,如果大部分核心信息集中在500字以内,4096就够用;如果经常需要跨章节引用,再考虑8192。
batch size看的是“总token数”,不是sample数量。经验上,单步更新的token数控制在2M到4M比较合适。举个例子,如果上下文长度是4096,global batch size是512,那么单步就是512×4096约200万token。梯度累积步数要配合设备数量计算,这个值太大则收敛慢,太小则噪声大。
3.3 训练脚本与断点续训
下面是基于DeepSpeed训练CPT时的关键配置片段,我简化成可以照着改的形式:
# 以7B模型为例,单机8卡A100,DeepSpeed ZeRO-3 deepspeed train_cpt.py \ --model_name_or_path base_model_path \ --train_data_path train_data.jsonl \ --valid_data_path valid_data.jsonl \ --output_dir cpt_model_output \ --per_device_train_batch_size 4 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 16 \ --learning_rate 2e-5 \ --lr_scheduler_type cosine \ --warmup_ratio 0.05 \ --max_length 4096 \ --num_train_epochs 1 \ --fp16 \ --deepspeed ds_config_zeRO3.json这里有几个细节值得注意。num_train_epochs通常设为1,因为CLP是“读一遍”数据,而不是像SFT那样反复多轮;如果数据吞吐不错,也可以改成按token数控制训练步数。warmup比例5%是为了让学习率缓慢上升,避免在训练初期对模型造成冲击。
断点续训是必做的工程能力。训练跑到一半宕机太常见了,如果没做checkpoint保存,等于前面成本全部作废。DeepSpeed的checkpoint除了保存权重,还必须保存优化器和随机种子状态,否则恢复后收敛曲线可能不连续。我的习惯是每200步存一个临时checkpoint,最后再保留最好的几个版本。
4. 训练过程监控:别只看loss,还要盯住“通用能力”
4.1 loss和困惑度怎么看
训练loss下降是正常的,但loss并不是唯一指标,甚至不是最重要的指标。CPT场景下,我更关注验证集上的loss(或困惑度Perplexity)。如果训练loss持续下降,验证loss却开始回升,说明模型已经开始死记训练数据,这时要考虑提前停止或降低学习率。
这里有一个容易犯错的地方:不要拿训练语料里的同一批文档做验证。前面提到过,训练/验证集必须按文档去重。验证集应当是模型没见过的行业文本,困惑度才有参考意义。我建议在验证集里同时加一份通用中文语料,用来观察通用能力的变化。
困惑度的大致量级因模型而异,不要跟网上别人的数值硬比。更重要的是看相对变化:行业验证集的ppl在下降,说明模型确实在吸收领域知识;通用验证集ppl如果大幅上升,说明灾难性遗忘已经很严重。两个曲线画在一张图上,比单看loss直观得多。
4.2 灾难性遗忘与通用能力下降
灾难性遗忘是CPT绕不开的话题。模型在行业语料上越学越深,通用知识和对话能力就可能被“覆盖”。表现形式很多:问它“中国的首都是哪里”还在,但问“帮我解释一下什么是机器学习”开始支支吾吾;或者写代码、做数学题的能力明显变弱。
应对遗忘,除了在数据配比里保持30%左右的通用语料,还可以做“回放式训练”,把一批高多样性的通用数据随机混入每个batch,而不是放在某个固定阶段。另外还有一种技巧:按比例混合历史checkpoint数据或者旧版模型生成的通用样本,但这是相对进阶的做法,数据安全审查要更严格。
另一个实用手段是控制训练步数。CPT不是训得越久越好,我们的经验是,当行业验证集ppl进入平台期,再继续训练往往只带来遗忘而没有额外收益。可以设定“早停”:跟踪通用验证集ppl,如果连续N个checkpoint上涨超过一定阈值(比如5%),就回滚到上一个checkpoint。
4.3 构建行业评估集与回归测试
没有评估集就没有方向感。我强烈建议在CPT启动前,至少准备三套评测数据:
- 领域知识测试:100到300道行业选择题或问答题,覆盖术语定义、业务规则、合规要求;
- 领域生成测试:给定合同片段、研报片段,让模型生成摘要或续写,人工打分;
- 通用能力回归:通用知识问答、基础数学、逻辑推理、指令遵循等样本。
每一套评测集都要固定下来,训练到不同步数时跑一遍,形成回归曲线。很多团队只在训练前和训练后各测一次,中间出了问题根本不知道是哪一步引入的。我们用了一份包含200条金融问题的手工标注集,训练过程中每500步测一次,及时发现了第3000步左右通用能力衰减超标的问题,立刻回滚了一个checkpoint,避免了白费后面的算力。
有一点要特别提醒:评测集数据绝对不要混进训练数据,否则评测结果就是自欺欺人。评测数据要由不参与数据清洗的人维护,并且和训练语料做一遍相似度检查。
5. 从checkpoint到可用模型:评估、微调与部署
5.1 行业任务评测怎么做
CPT完成后,先别急着接前端。我们内部的流程是:先跑一遍领域测试集,再跑通用回归,然后专门抽几个资深业务人员做盲评。盲评很重要,因为自动指标像ppl下降,并不能说明回答让业务人员满意。
行业任务评测建议拆成多个维度:
- 术语准确率:回答里专业术语是否使用正确;
- 知识覆盖率:是否提到核心知识要点;
- 格式合规率:是否遵循行业文档结构;
- 无关信息比例:有没有夹带编造的内容。
每个维度都打分,和基座模型做对比。如果CPT之后术语准确率从40%提升到70%,那这个训练就是值的;如果只提升了5%,就要怀疑是数据量不足,还是数据质量有问题。这里没有统一及格线,目标是“比基座好,适合业务用”。
5.2 基座能力回测与“回退”机制
很多团队做完CPT只测行业任务,忽略基座能力,等上线才发现模型变“傻”了。我们每次训练完都要跑一遍通用回归测试,包括数学、代码、常识问答、指令遵循,然后和基座模型对比。如果通用能力下降但行业能力提升明显,可以接受;如果两边都没提升,那就是训练配置有问题。
更稳妥的做法是保留基座模型和多个checkpoint,线上先跑A/B测试。CPT模型在行业问题上的表现如果明显优于基座,才切换。用户问通用问题时,可以设计路由策略:行业问题走行业模型,通用问题走通用模型。这样可以充分扬长避短,而不是把两个优势做减法。
5.3 后续SFT、对齐与推理部署
CPT产出的模型本质上还是一个“更懂行业知识的基座模型”,不一定适合直接对话。所以CPT之后,通常还要做一轮指令微调。这里就要用到第一批标注好的行业问答对了,让模型学会把知识组织成自然的业务回答。缺少这步,你可能会遇到“知识变多了,但答非所问”的情况。
部署时可以做量化压缩。7B模型用INT8或者INT4量化,显存占用能下降一半以上,推理速度也能提升不少。如果用了vLLM这类推理框架,要注意和训练框架的模型格式兼容。如果CPT过程中扩展了词表,部署时也要同步替换tokenizer和embedding层,否则会出现乱码或推理错误。
如果企业有持续更新的行业文档,CPT也可以做成定期增量任务,比如每个月用一个相对低的学习率在新增数据上继续训练一轮。要注意的是,增量训练前要把新数据和老数据按比例混合,避免模型在新数据上过度拟合。
6. 常见问题与排查技巧实录
6.1 问题速查表
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 训练loss不降 | 数据噪声太多;学习率太低;数据管道错误 | 抽样检查数据;调大学习率到5e-5;用小样本跑通验证 |
| 验证loss快速回升 | 过拟合;验证集与训练集重叠 | 提前停止;检查去重;降低训练轮数至1轮 |
| 行业知识有提升,但通用能力断崖下降 | 通用语料配比太低;学习率太高 | 提高通用语料到30%以上;学习率降到1e-5;回滚checkpoint |
| 模型回答出现乱码或重复词 | 词表扩展后embedding没有同步;分词器配置错误 | 检查tokenizer与模型词表;用旧词表重新训练 |
| 100万token训练后效果不明显 | 数据量不足;行业数据太单一 | 扩充语料来源;考虑先接入RAG做对比实验 |
| 训练中途OOM | 上下文过长;batch size过大;ZeRO配置不对 | 降低per_device_batch_size;开启FlashAttention;检查ZeRO阶段设置 |
6.2 三个真实的踩坑记录
第一个坑是数据里混了不该有的测试集。我们一开始图省事,从公开数据集里找了一批“行业问答”加进训练语料,结果评测用的题目正好来自同一个源头,指标漂亮得离谱。幸好上线盲评时发现有业务人员质疑“模型太会背题了”,最后追查才发现。后来定了一条铁律:训练语料和评测语料必须完全隔离,并且由两个不同的人维护。
第二个坑是学习率取太高,导致模型通用能力崩了。第一轮全量CPT,我们按普通预训练的经验设了1e-4,训练到两千步时,发现通用测试准确率断崖式下跌,行业能力也没涨多少。后来回滚到2e-5重新训练,通用能力几乎没有受损,行业指标反而更好。低学习率不是保守,是CPT的物理规律。
第三个坑是上下文长度引起的数据偏差。我们当时把上下文设为8192,但很多行业文本实际只有几百字,结果模型学会了在一大段padding里“找位置”,行业文档的长依赖能力没提升多少,训练速度还慢了许多。后面根据语料长度分布把大部分数据截断到2048,只有长文档才保留完整上下文,成本直接降了一截。
6.3 给新手的实操建议
如果你所在团队第一次做CPT,我的建议是不要一上来就上7B以上的模型。先用一个小模型,比如1B到3B规模,配几千万token数据,把数据清洗、训练脚本、评估流程完整跑一遍。这轮“流程演练”花不了多少算力,但能帮你把坑都提前踩一遍。流程跑通后再换大模型,会省心很多。
还有一个小技巧:训练时准备一份“回退样本集”,里面放50条领域老手认定必对的问题,比如行业基本概念、高频业务规则。每次checkpoint保存后都跑一遍这50条,如果正确率掉到阈值以下,立刻触发告警。这套机制比单纯依赖loss曲线更能直接反映业务价值的波动。
我个人的体会是,CPT不是一个“锦上添花”的动作,而是企业把公共大模型变成私有行业资产的必经之路。它不便宜,也不简单,但一旦把数据、参数、评估这套循环跑通,后续知识更新的边际成本会越来越低。希望这份实战指南能让你的团队少走几步弯路。