ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

继续预训练(CPT)实战:从通用底座到行业大模型

继续预训练(CPT)实战:从通用底座到行业大模型 通用大模型要真正在某个行业里顶用光靠开箱即用的对话能力是不够的。企业拿到的开源基座比如Qwen、Llama、DeepSeek这类模型它们懂通用知识、能写代码、会聊天但对行业里的专业术语、内部文档风格、业务逻辑的理解往往浮于表面。这时候就需要把通用底座往行业方向再“喂”一步让模型真正吸收行业知识这一步在技术圈里叫Continued Pre-Training也就是继续预训练。很多团队一上来就想着做SFT监督微调拿几千条问答对去调结果模型在业务场景里还是露怯专业名词经常写错、长文档读不明白、行业规则一问就偏。问题不在于微调本身而在于模型压根没有建立起行业知识的基础。SFT是教模型“怎么说话”而CPT是让模型“懂行”。这篇指南就围绕CPT展开讲清楚企业怎么把通用大模型训练成行业模型包含数据怎么准备、超参怎么设、训练怎么跑、踩了哪些坑全部是实操层面的东西。1. 继续预训练企业行业模型的第一块跳板1.1 通用模型的“说明书”与行业模型的“内行话”打个比方一个刚毕业的大学生基础素质很好数理逻辑、语言表达都在线这是通用大模型的状态。但你要让他直接上手处理医疗病例、法律文书、设备维修手册他大概率会抓瞎因为里面全是行业黑话、特定格式和隐含规则。CPT干的事情就是让这个大学生去行业里“实习”一段时间阅读大量行业资料熟悉行话、格式和逻辑之后再上岗。从模型角度来看通用大模型的参数里存的是互联网级别的知识分布。继续预训练就是在大规模通用语料的基础上继续用行业文本去调整参数分布把模型对世界语言的建模能力引导到行业方向上。这个过程中模型不仅记住了更多行业词汇更重要的是学会了行业文本的上下文模式包括术语之间的关联、文档结构、常见表述逻辑。这些知识是SFT很难直接灌输进去的因为SFT的样本量太少且目标函数是“跟着指令输出”而不是“理解文本本身”。1.2 CPT和SFT到底什么关系搞清楚CPT和SFT的区别是企业决定技术路线的第一步。SFT是把模型从“会说话”训练成“会听话办事”。它的数据是“指令-回答”对训练目标是让模型看到指令后生成符合预期的回复。优点是所需数据量小、训练快、效果直接可见缺点是模型学到的知识上限受限于底座本身的知识储备。CPT则是把模型的“知识储备”直接扩容。它的数据是纯文本不需要标注成问答对训练目标和预训练一致继续预测下一个Token。模型的底座知识越扎实后面的SFT才能出效果。如果模型连行业术语和文档结构都没见过SFT只能教会模型“硬答”答出来的东西满是虚构和错误。两条路线不是二选一而是先后关系。真正规范的行业模型落地流程是先用CPT注入行业知识再在CPT基座上做SFT对齐指令最后用RLHF/DPO做偏好优化。CPT是地基SFT是装修。地基不打装修再好看也住不踏实。1.3 哪些场景最需要CPT不是所有企业都需要CPT。判断的依据是你的业务场景是否涉及大量非公开、非通用的知识或者对模型输出格式有极强的领域规范性要求。行业术语密集的领域医疗、法律、金融、能源、制造业这些行业的专业词汇在通用语料里占比极低模型根本没学过。私有文档体系企业内部有大量制度文件、技术手册、历史项目文档这些内容网上完全搜不到模型不可能凭空知道。领域文本结构特殊法律文书、病历、检修工单、科研论文都有自己的固定结构CPT能让模型学会这种结构感。长文本理解要求高行业场景经常涉及几十页甚至上百页的文档理解通用模型训练时主要处理短文本CPT时可以增加长序列训练比例来强化这个能力。反过来如果你的场景靠RAG检索增强就能解决比如从FAQ里检索答案、从知识库里查资料那CPT不一定是最优解先把RAG做好更务实。CPT适合的是“让模型内化知识”而不是“外挂知识库”。2. 数据工程CPT成败的七成在这里CPT和预训练一样数据质量决定模型天花板。我在实际项目中见过太多团队把精力全放在调参上数据却是一锅乱炖最后训出来的模型不仅没变懂行连通用能力都退化了。数据工程才是CPT的重头戏。2.1 行业语料从哪里来业内常见的数据来源可以分为三大类第一类是公共行业数据。包括行业报告、白皮书、论文、专利、标准规范、法律法规、公开数据库。这类数据量大权威性高适合做基础语料。比如做金融行业模型可以收集上市公司的年报、招股书、研报、监管政策文件做法律模型可以收集法律法规库、裁判文书、合同模板。第二类是企业私有数据。包括内部制度、操作手册、工单记录、产品文档、客服对话历史、业务报表说明。这类数据是最有价值的护城河但也是最难处理的往往格式混乱、噪音大、存在大量敏感信息。第三类是合成数据。用通用大模型生成行业相关的高质量文本再经过人工或规则过滤后加入训练集。合成数据的质量取决于生成策略我建议用“大纲扩展法”而不是“自由发挥法”先列行业知识提纲让模型按提纲写内容这样结构可控、错误率低。2.2 清洗和过滤是硬功夫原始数据必须经过严格的清洗流水线我常用的流程分五步格式标准化把PDF、Word、HTML统一转成纯文本去掉页眉页脚、目录、图片说明、乱码字符。编码清洗处理全角半角混用、特殊符号、HTML实体、Unicode异常字符。去重行业文档里重复内容特别多尤其是一篇报告被多个网站转来转去。建议先做NDCG级别的模糊去重再做MinHash去重最后按行去做精确去重。不去重的话模型会把这些重复文本背下来导致生成时大量复读。语言过滤如果做中文行业模型要把英文、日文等非目标语言语料滤掉但专业术语和代码片段可以保留。质量过滤用规则词频、句长、标点符号密度筛掉明显低质的段落再用一个质量分类器或困惑度过滤器进一步筛选。注意涉密和隐私信息必须严格过滤尤其是使用私有数据时。训练语料一旦进入模型参数再想“删除”就来不及了这会带来合规风险。上线前务必做一轮敏感信息扫描。2.3 数据配比不是行业语料越多越好CPT最常犯的错误是把行业语料比例拉到100%。结果模型确实记住了一些行业知识但通用能力崩了对话不流畅、常识性错误增多这就是灾难性遗忘。我一般建议保持一定的通用语料比例一个相对稳的起步配比是行业语料70% 通用高质量语料30%。通用语料可以从开源数据集里选比如中文维基、悟道、SkyPile等选质量高的子集即可。如果行业语料本身就包含大量通用文本比如包含新闻、百科类内容通用比例可以适当降低但不要低于20%。另外行业内细分主题之间的配比也要控制。我做能源行业模型的时候把语料分为安全生产、设备运维、电力市场、政策法规四类最初按业务量对齐结果模型在政策法规类上表现好在设备运维类上拉跨。后来调整了策略对不同主题语料做上采样把低频但关键的内容提上来效果才均衡。2.4 用困惑度筛选高质量语料困惑度Perplexity简称PPL是一个很有用的数据筛选工具。先拿一个已有的通用大模型对每条候选文本算困惑度如果一条文本的PPL偏高说明模型很难“理解”这段文字往往意味着内容质量差、逻辑混乱或者混合了多种语言。实际操作中我会用一个小型模型比如Qwen2.5-7B对筛选后的候选集算PPL然后按PPL分位数切分取PPL较低的一部分作为高置信语料PPL过高的直接丢掉中间段人工抽检确认。这个方法在小规模高质量语料构建中非常有效比单纯用规则过滤精细得多。3. 训练方案设计基座选型、超参与策略权衡3.1 基座模型怎么选CPT的起点是选基座。基座选不好后面所有功夫都可能白费。优先选开放权重且许可合规的模型比如Qwen系列、Llama系列、DeepSeek系列、Baichuan系列。关注基座的“语言基底”和“领域基础”。中文行业场景首选中文语料占比高的基座比如Qwen否则你还要在CPT阶段花大量算力学中文效率低。关注上下文长度。很多行业场景需要长文档处理选基座时尽量选原生支持8K以上上下文的版本。如果原生只支持4K后续CPT可以一并做长度外推但这会增加训练难度。关注参数量。显存和算力有限的情况下7B~14B是性价比最高的区间如果业务场景复杂且预算充足可以考虑32B~70B级别。不是非大不选而是匹配资源和需求。3.2 超参数设置照着这张表起步CPT的超参数和普通预训练基本一致但有几个位置需要注意。我整理了一份起手配置适用7B~14B量级模型的领域继续预训练读者可以在此基础上微调参数建议值说明学习率1e-5 ~ 2e-5比预训练小比SFT大。太小学不动新知识太大会破坏原有参数。批次大小256 ~ 1024按序列长度折算大batch更稳定但显存不够时可通过梯度累积补偿。序列长度4096 ~ 8192如果行业文档偏长可以逐步从4096扩展到8192。训练步数数千到数万步以行业数据量而定通常训练1~3个epoch就够。学习率调度cosine warmupwarmup占比5%~10%帮助模型平稳过渡。权重衰减0.01 ~ 0.1防止过拟合私有数据量少时用偏大值。需要注意的是学习率是整个训练里最敏感的超参。CPT的常见翻车原因就是学习率设太高导致模型把原有能力冲掉表现为通用能力断崖式下跌。起步时拿1e-5跑个几千步在验证集上观察PPL变化再决定加减。3.3 全参训练还是LoRACPT到底要不要全参训练一直是企业团队纠结的点。全参训练Full Fine-tuning直接更新所有参数知识注入能力最强效果好但显存和算力消耗大。7B模型用全参训练单卡A10080G只能勉强跑起来一般要配合DeepSpeed ZeRO Stage 2/3或者张量并行多卡并行。LoRA以及QLoRA只训练一小部分低秩参数资源占用低训练速度快。对于纯粹的“知识注入”任务LoRA矩阵的参数量有限很难把大量新知识塞进模型。但如果你的行业数据量不大比如只有5000万Token以内或者你想快速验证数据质量LoRA是性价比很高的起步方案。我的建议是项目初期用LoRA做数据验证和流程跑通确认数据质量没问题后再用全参训练做正式版本。这样做既省算力又不至于一步错步步错。3.4 训练框架选型CPT训练和SFT不同市面上开箱即用的SFT框架如LLaMA-Factory虽然也能跑CPT但灵活性和效率并不是最优解。工业界更常用以下组合Megatron-LM Tensor Parallelism适合超大模型和多机多卡场景稳定且吞吐高但配置复杂。DeepSpeed ZeRO适合小规模集群支持数据并行、梯度累积配置相对简单7B~13B级别很够用。torchrun HuggingFace Transformers适合快速验证和小规模训练代码量最少。TorchTitanMeta开源的训练框架灵活度高适合深度定制。我这里建议7B~13B模型单机多卡4~8张A100/H100直接用DeepSpeed ZeRO Stage 2或Stage 3方案最省事模型超过30B再考虑Megatron或多机方案。4. 实操流程从数据到训练到评测的全过程4.1 环境准备以8卡A10080G单机训练一个7B模型为例我推荐的环境组合如下系统Ubuntu 22.04 CUDA 12.1 PyTorch 2.1框架DeepSpeed Transformers Accelerate监控Weights Biases或TensorBoard数据存储SSD或NVMe数据量不大时即可数据量大建议用内存映射格式显存估算有个简单公式7B模型全参训练混合精度bf16下仅模型参数就需要约14GB显存加上优化器状态AdamW的fp32副本和梯度至少需要约40GB显存序列长度4096、batch size设为1时激活值还会吃掉额外显存。所以单卡80G训练7B是可行的但基本没法开新开发调试直接上多卡更稳。4.2 数据格式与打包CPT数据不需要像SFT那样搞成JSONL问答对直接用纯文本文件即可。但为了训练效率我建议将所有标注好的文本打包成统一的JSONL或二进制内存映射格式。下面是用Transformers框架训练时的数据格式示例# train_data.jsonl 格式示例每行一个文本块 {text: 根据《电力安全生产工作规程》设备检修作业前必须办理工作票明确工作负责人、工作许可人和工作班成员。作业期间工作负责人应始终在现场对工作班成员的安全进行监护...} {text: 变压器的定期试验项目包括绝缘电阻测试、介质损耗因数测试、油中溶解气体分析等。其中油中溶解气体分析能够有效发现变压器内部的潜在故障...}数据打包成标准预训练格式后可以直接用HuggingFace的datasets库加载from datasets import load_dataset from transformers import AutoTokenizer dataset load_dataset(json, data_filestrain_data.jsonl, splittrain) tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-7B) def tokenize_function(examples): return tokenizer(examples[text], truncationTrue, max_length4096) tokenized_dataset dataset.map(tokenize_function, batchedTrue, num_proc16)4.3 启动训练一份可直接改的训练脚本以下是用Transformers DeepSpeed启动CPT训练的最小脚本。实际使用中根据模型和显存调整per_device_train_batch_size和gradient_accumulation_steps。from transformers import ( AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments, DataCollatorForLanguageModeling, ) from datasets import load_dataset model AutoModelForCausalLM.from_pretrained( Qwen/Qwen2.5-7B, torch_dtypebfloat16, attn_implementationflash_attention_2, ) tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-7B) dataset load_dataset(json, data_filestrain_data.jsonl, splittrain) def tokenize_function(examples): return tokenizer(examples[text], truncationTrue, max_length4096) tokenized_dataset dataset.map(tokenize_function, batchedTrue, num_proc16) data_collator DataCollatorForLanguageModeling(tokenizertokenizer, mlmFalse) training_args TrainingArguments( output_dir./cpt_industry_model, per_device_train_batch_size1, gradient_accumulation_steps32, num_train_epochs2, learning_rate1.5e-5, warmup_ratio0.05, lr_scheduler_typecosine, optimadamw_torch, logging_steps20, save_steps500, save_total_limit3, bf16True, deepspeedds_config.json, report_towandb, ) trainer Trainer( modelmodel, argstraining_args, train_datasettokenized_dataset, data_collatordata_collator, ) trainer.train()这里DataCollatorForLanguageModeling会自动把输入按“预测下一个Token”的方式构建标签不需要手动加label。对应的ds_config.json可以这样写开启ZeRO Stage 2{ zero_optimization: { stage: 2, offload_optimizer: { device: cpu, pin_memory: true } }, bf16: { enabled: true }, train_batch_size: 32, gradient_accumulation_steps: 32, train_micro_batch_size_per_gpu: 1 }4.4 监控训练Loss曲线要这么看训练启动后第一件事是盯Loss曲线。但要分清楚CPT的Loss和SFT的Loss含义不同。SFT的Loss是“回答是否匹配标准答案”而CPT的Loss是“模型对文本预测的困惑程度”。CPT的Loss不会像SFT那样降到很低而是逐渐平稳。几个值得注意的现象如果Loss在前几百步快速下降说明基座模型对这堆行业文本确实不了解正在快速吸收新知识这是好事。如果Loss在中期出现突然的尖峰大概率是数据里混入了异常样本比如超长空白行、纯符号文本。建议暂停训练检查当前批次的数据。如果Loss长期不降先看学习率是否太低再看数据量是否太少最后看数据清洗是否到位。如果Loss已经降得很低但下游任务效果反而变差很可能是过拟合了行业语料被“背下来”了。这时候要削减epoch数或者把学习率进一步下调。除了Loss建议每隔固定步数保存checkpoint然后用验证集计算PPL。PPL的变化趋势比单看训练Loss更可靠因为训练集上的Loss会受到过拟合干扰。4.5 训练完怎么评测CPT阶段不能只看Loss必须结合下游任务做验证。评测分三层第一层是PPL评测。准备一份模型没见过的行业文本作为验证集对比CPT前后模型的PPL。PPL下降说明模型对行业文本的建模能力确实增强了。注意验证集不能出现在训练集里否则PPL参考价值大打折扣。第二层是通用能力评测。用MMLU、C-Eval、GSM8K这些公开评测集跑一遍确认模型通用能力没有明显退步。如果通用分数掉得很厉害说明学习率太高或者通用语料配比太低。第三层是业务场景评测。这是最重要的一层。挑几个核心业务场景设计典型的Prompt对比CPT前后的输出。比如做金融模型就拿“解释一下什么是表外融资”这类问题看模型答得是否专业不扯淡。这里没有标准答案需要业务专家参与打分。5. 常见问题与排查技巧实录5.1 灾难性遗忘通用能力崩了怎么办这是CPT最常遇到的问题。症状是训练完以后模型在行业问答上确实变强了但让它写一段通用文案、做一道数学题质量直线下降。排查思路按优先级来先看学习率。我踩过一次坑把学习率从1.5e-5提到5e-5跑了2000步模型通用能力直接崩了。CPT阶段学习率宁小勿大。再看数据配比。通用语料比例低于20%时通用能力大概率掉。建议把通用语料比例提到30%以上。最后看训练步数。如果训练了超过3个epoch模型开始背训练数据通用能力也会掉。控制epoch在1~2之间。5.2 训练中断和checkpoint恢复长时间训练很吃稳定性和耐心。断电、OOM、节点重启哪个都可能打断训练。我遇到过两次训练跑到一半进程被kill如果不是每500步保存一次checkpoint几天的算力就白烧了。恢复训练时把TrainingArguments里的resume_from_checkpoint设为True即可但要确认output_dir里有完整的最新checkpoint包括optimizer状态。如果只保存了模型权重没保存optimizer恢复后学习率会和原来不一致影响训练稳定性。5.3 数据重复导致模型复读私有数据往往有大量重复列表、模板文本比如每周的机器巡检记录格式一模一样只有日期不同。这种数据进训练集后模型学到的不是“理解巡检规律”而是“背下这段模板”生成时疯狂复读。对策是加强数据去重。数据处理阶段用MinHash做一道粗去重再做一道基于余弦相似度的细去重把相似度高于0.85的样本直接合并或丢弃。另外对模板化文本可以做一个正则规则把字段替换成占位符后再训练能减轻模板记忆问题。5.4 CPT之后怎么和SFT、部署衔接CPT训完的模型不是直接上线的还要走SFT对齐、偏好优化、评估、部署这一套。很多人问CPT之后做SFT需不需要重新准备SFT数据答案是之前的SFT数据可以继续用但要在新基座上重新评估一遍因为模型分布变了原本优质的数据可能不再是优质数据。部署层面行业模型上线后建议配置一个回滚策略保留CPT之前的基座模型一旦线上效果出现负向可以快速切换回来。不要一次性全量切流量先在灰度环境中对比CPT前后模型在真实业务请求上的表现再逐步放开。成本控制上如果行业数据量大CPT训练预算不小。建议先用10%的数据子集跑一次小规模验证训练观察PPL和业务指标变化确认ROI之后再做全量训练。这个“先小后大”的验证思路能帮企业省下不少冤枉钱。6. 写在最后的实操心得CPT这件事本质上不是炫技的算法竞赛而是一项系统工程。数据占比、数据质量、训练策略、评测闭环每一环都要认真对待。我在实际项目中最大的体会是CPT阶段多花一倍时间做数据清洗比训练时多烧一倍算力去弥补要划算得多。很多团队训练失败回去一查十有八九是数据问题而不是模型问题。最后再分享一个小技巧如果预算不多又想验证某个基座模型对行业语料的适配性可以先不跑完整训练而是直接拿模型对一段行业文章做PPL对比。基座本身对行业文本的PPL越高说明它越不了解这个领域CPT带来的提升空间就越大如果基座PPL已经很低说明它本身就见过不少这类语料你就要考虑是不是优先做SFT和RAG更合适。这个快速判断法能帮你在项目启动前就选对方向少走弯路。
返回列表