
几个月前我们团队接到一个任务把通用大模型训练成能回答金融合规问题的行业模型。模型基座选了开源通用大模型初期大家觉得提示词写细一点就行结果一测就露馅合同条款里的“留置权”“代位求偿”这些术语模型能聊个大概但一旦落到具体业务场景经常给出似是而非的答案。后来我们把路线从“微调”改成了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亿tokenCPT的收益可能不明显不如考虑RAG。这里我建议的做法是先小规模验证用1亿token做一次短训练看领域测试集效果有没有提升再决定要不要上全量数据。另外还有一个容易被忽略的动作训练集和验证集的去重。我见过团队拿同一份合同既训练又评测结果loss曲线漂亮得不行实际业务一测原形毕露。做训练/验证切分时必须按文档ID去重甚至按相似度去重否则评估结果会虚高。3. 训练参数与运行环境让模型“温和”地学新知识3.1 计算资源与框架选型CPT比SFT要贵得多这是很多团队没有心理准备的。一个7B模型在8张A10080G的机器上训练100亿token通常需要跑一周以上如果用4090这种卡就得几十张并行。这里给一个粗略的经验值训练速度约等于总token数除以单卡吞吐×卡数单卡吞吐量受模型大小和上下文长度影响很大。框架方面熟练的团队可以直接用DeepSpeed或Megatron-LM这两个框架对大规模并行训练支持得最好。如果团队更熟悉Transformers也可以基于Trainer改造但要仔细处理梯度累积和分布式采样。中小团队不要一上来就自己写分布式逻辑DeepSpeed ZeRO-2/ZeRO-3已经够用。我们的做法是基座模型用HuggingFace格式训练框架用DeepSpeed配置好ZeRO-3和FlashAttention稳定性和速度都满意。有一个建议训练前先跑一个极小数据量的冒烟测试确认数据加载、模型结构、保存逻辑都正确再启动全量训练。不然跑了两天发现数据管道有bug损失是灾难性的。3.2 关键超参学习率、上下文长度、batch sizeCPT和普通预训练在超参上有个显著差异学习率要低而且得用带衰减的调度器。通用预训练一般用3e-4这类高学习率但CPT是在一个已经收敛的模型上继续学习学习率太高会把原有参数冲乱表现成通用能力断崖式下跌。我们通常把峰值学习率设在1e-5到5e-5之间7B模型一般取2e-513B模型取更低比如1e-5。上下文长度也直接影响数据采样。行业文档往往有长依赖比如一份合同里的定义条款可能在后面反复引用因此上下文长度建议从4096起步有条件直接上8192。但注意上下文越长显存占用和训练成本越高。我们要做的不是盲目加长而是先分析行业语料的长度分布如果大部分核心信息集中在500字以内4096就够用如果经常需要跨章节引用再考虑8192。batch size看的是“总token数”不是sample数量。经验上单步更新的token数控制在2M到4M比较合适。举个例子如果上下文长度是4096global batch size是512那么单步就是512×4096约200万token。梯度累积步数要配合设备数量计算这个值太大则收敛慢太小则噪声大。3.3 训练脚本与断点续训下面是基于DeepSpeed训练CPT时的关键配置片段我简化成可以照着改的形式# 以7B模型为例单机8卡A100DeepSpeed 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不是一个“锦上添花”的动作而是企业把公共大模型变成私有行业资产的必经之路。它不便宜也不简单但一旦把数据、参数、评估这套循环跑通后续知识更新的边际成本会越来越低。希望这份实战指南能让你的团队少走几步弯路。