ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

持续预训练实战指南:让大模型真正懂行业知识

2026/9/12 19:15:18 拓冰建站 浏览量
持续预训练实战指南:让大模型真正懂行业知识 1. 为什么企业做行业模型往往卡在了“微调”这一步先聊一个我常被问到的问题企业拿到一个开源大模型比如 Qwen、LLaMA、DeepSeek 系列直接做指令微调SFT跑了一堆业务数据进去结果上线之后发现模型回答得挺流畅但一到具体业务细节就开始一本正经地胡说八道尤其涉及行业专有名词、内部流程、设备型号、历史案例时错的非常离谱。这个现象太典型了。很多团队把“行业模型 微调”画了等号但实际上SFT 擅长教模型“怎么说话”——也就是指令遵循、输出格式、语气风格它并不擅长教模型“懂这个领域”。行业知识的沉淀靠的是模型在预训练阶段见过的语料。如果模型压根没见过你们公司的设备维护手册、临床诊疗路径、招投标条款、法务判例那你指望用几千条问答对就让它顿悟根本不现实。这时候就需要另一条技术路线Continued Pre-Training中文一般叫持续预训练或者领域增量预训练。它的思路很直接在通用大模型的基础上用大量领域无标注文本继续做自回归训练把行业知识嵌入模型参数相当于让一个读过万卷书的通才再去集中啃你们公司的内部档案室。这样训练出来的模型才是真正意义上的“行业模型”而不是一个“换了副行业嘴脸的通用模型”。这篇文章我会按照一个实际项目的完整路径从数据准备、基座选择、训练参数、评测闭环、上线部署几个角度把 Continued Pre-Training 这件事讲透。适合正在做行业大模型落地的算法工程师、技术负责人以及准备从 RAG 方案往模型内化知识方向走一步的团队参考。2. 先别急着训练几个前置判断决定了项目死活2.1 继续预训练和微调、RAG 到底该怎么选继续预训练不是万能药它的成本比微调高一个量级而且很多人其实根本不需要它。我在项目里一般先做一道选择题只想让模型学会按格式输出、学会工具调用用 SFT成本低见效快。知识是动态变化的、需要随时更新的比如实时的库存价格、每日资讯用 RAG 更合理因为不需要频繁重训模型。业务场景高度依赖长期稳定的领域知识体系比如企业内部制度、行业技术标准、历史数据规律而且这些知识是相对静态的、有深度的那才轮到 Continued Pre-Training 上场。补充一点很多项目其实是“混合架构”用 CPT 让模型具备领域底座用 SFT 教它怎么回答再在外面挂一个 RAG 解决最新、最碎片的信息。这个组合在工业界已经比较成熟不是“CPT 和 RAG 二选一”而是分层解决问题。2.2 数据决定上限语料从哪里来、怎么洗CPT 的核心资产只有一个数据。模型参数量再大没有高质量的领域语料训练完也是空壳。数据来源我按优先级排列企业内部结构化沉淀历史工单、维修记录、质检报告、客服对话、合同档案这些最珍贵因为外面买不到。行业公开语料行业标准文件、技术白皮书、专业期刊、论文摘要、设备说明书注意版权风险一般用于训练问题不大但不能拿去商用转售。网络公开数据行业垂直网站、百科、论坛精华帖量大但噪音多需要重点清洗。合成数据用通用大模型把碎片化的内部资料改写成规范的段落、QA 对再过滤一遍适合数据量不足的冷启动场景。数据清洗是整个流程里最脏最累、最容易被低估的环节。我建议按这个顺序做格式统一把所有 PDF、Word、HTML 全部转成纯文本统一编码。正文抽取去掉页眉页脚、导航、广告、重复模板信息这一步误杀率很高建议人工抽检。规则清洗去 HTML 标签、去超链接、去乱码、去连续空白把全角半角统一。去重MD5 精确去重一遍再用 MinHash 做近似去重阈值可以设在 0.8 左右也就是两段文本 80% 相似就删掉一条。质量过滤用长度、符号占比、重复率这几个指标做粗筛也可以用一个小分类模型判断文本是不是“通顺的正式文本”把口语化碎片、乱码文本扔掉。这里有一个体会很多人以为清洗的目的是把数据变干净其实真正的目的是控制训练信号的“信噪比”。领域语料里如果混了大量口水话模型学到的不是领域知识而是口水话。我们曾经因为偷懒跳过近似去重结果模型在生成时反复出现同一段话排了好久才发现是语料里重复段落太多教训很深。2.3 语料配比不是领域数据越多越好继续预训练最常见的一个误区既然要提高领域能力那就全喂领域数据越多越好。实际操作中如果只用领域数据训练模型会很快退化怎么退化的两个方向一个是对通用知识的记忆开始遗忘常识问答变差另一个是生成文本的多样性降低说话越来越“领域腔”甚至出现重复。比较稳的做法是领域语料和通用语料混合训练。通用语料可以从开源数据集里抽一部分比如中文 Wikipedia、悟道、Skypile 的采样子集。混合比例我见过从 1:1 到 1:10 都有取决于领域数据的体量和质量。经验法则是领域数据量很小低于 2GB通用语料可以占到 60%~70%主要是防止遗忘。领域数据量大且质量高10GB 以上领域语料可以提到 50% 左右让模型充分吸收。如果领域数据特别垂直比如医疗影像报告、电力巡检记录还要考虑适当增加对应数据的上采样次数。还有一个参数叫“数据重复次数”epoch领域数据通常可以训练 2~4 个 epoch通用数据 1 个 epoch 以内。具体我们在后面训练配置里再细说。3. 基座模型选型与词表扩展别什么都往上套3.1 基座模型该选 Base 还是 Chat很多人一上来就选 Chat 版模型做继续预训练这是个隐患。Chat 版是经过 SFT 和偏好对齐的它的生成风格已经被“驯化”过用领域语料继续训练时模型会处于一种别扭的状态既想保持对齐后的交互风格又要吸收新的领域知识结果往往是两边都不到位。我做 CPT 的经验是优先选 Base 版模型也就是没有经过指令微调的原始预训练模型。市面上主流开源模型基本都会同时发布 Base 版和 Chat/Instruct 版比如 Qwen 的 Qwen2.5-7B-Base、DeepSeek 的 DeepSeek-V3-Base直接用 Base 版做领域继续预训练训练完再自己接 SFT。如果团队的 SFT 能力比较弱也可以选 Chat 版做 CPT但学习率要调得更低训练步数也要更短防止灾难性遗忘。3.2 参数量级怎么选7B、14B 还是 72B参数量级没有绝对标准核心看算力预算和部署资源。我的经验是7B 级适合快速验证流程单机多卡4×A100/8×A100就能跑迭代快适合先跑通全链路。13B~14B 级性价比比较高的区间领域能力比 7B 明显增强部署成本也在可控范围。70B 级以上需要多机多卡或者依赖大算力集群建议在数据量和评测体系都很完善之后再上否则资源浪费严重。有一个容易被忽视的点模型在继续预训练阶段的“吸收效率”和 Base 模型本身的预训练充分程度有关。如果基座本身已经很强比如 Qwen 系列CPT 只需要少量高质量领域数据就能有明显效果如果基座模型本身比较弱你喂再多的领域数据也补不齐它的基础能力短板。选基座的时候先跑几个通用基准测试确认它的“底子”是健康的。3.3 词表要不要扩展领域语料里如果大量出现特有字符——比如化学分子式、特殊符号、代码片段、日文假名——而基座模型原本的词表没有覆盖这些 token那每个字符都会被拆成好几个 token训练和推理都会变慢而且模型不容易学到这些词的语义。解决办法是扩展词表。实际操作分三步用领域语料训练一个新的 SentencePiece/BPE 词表或者做词表合并。把新增 token 的 embedding 随机初始化或者用基座已有相似 token 的 embedding 做初始化。调整模型的 config 中 vocab_size 字段把 embedding 层和 LM head 的维度同步扩展。这种做法在跨语言、代码、生物医学领域比较多见效果也确实明显。但要提醒一下词表扩展会引入大量随机初始化的 embedding这些参数一开始是“没学过”的模型需要额外的训练步数把新 token 学会。如果只是扩展几百个 token 影响不大扩展到成千上万个训练成本要预算进去。对于一般的中文行业语料如果基座本来就是中文友好的模型比如 Qwen词表扩展的优先级不算高可以先用原始词表跑一版看效果。4. Continued Pre-Training 核心实操流程4.1 数据格式设计不是把文本拼在一起就行继续预训练用的是自回归语言建模目标每个样本就是一段文本模型要预测下一个 token。数据组织上我不建议把一整个文档直接塞成一个超长样本。更常见的做法是把文档切块chunk每块控制在模型上下文窗口范围内比如 4096 token 或 8192 token。切块时要遵守两条原则按语义边界切不要硬切。优先在段落、章节标题、句号之后切断尽量避免把一句话拦腰截断。相邻块之间可以保留少量重叠比如 100~200 token 的重叠减少切块带来的上下文断裂感。构造训练样本的时候通常会用特殊标记分隔文档。比如用|endoftext|作为文档结束标记或者用自定的|doc_start|和|doc_end|包裹每一块。不同预训练框架的模板不完全一样用 Hugging Face 的AutoTokenizer时tokenizer 自带的 eos_token 就能当分隔符。我自己在实践中比较喜欢在每段样本前面加一个User:之类的字段标记吗不是CPT 阶段不需要这种对话格式它就是纯文本预训练不需要加角色前缀。一个可以直接参考的数据切块脚本伪代码from datasets import load_dataset from transformers import AutoTokenizer def tokenize_function(examples, tokenizer, max_length4096, stride128): text examples[text] return tokenizer( text, truncationTrue, max_lengthmax_length, stridestride, return_overflowing_tokensTrue, ) dataset load_dataset(json, data_filesyour_domain_data.jsonl) tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-7B-Base) tokenized dataset.map( lambda x: tokenize_function(x, tokenizer), batchedTrue, remove_columnsdataset.column_names, ) # 再把切出来的碎片拼成最终的训练集落盘到磁盘缓存 tokenized.save_to_disk(./data/tokenized_domain)这个脚本里 tokenizer 的return_overflowing_tokensTrue是切块的开关stride控制重叠长度。实际跑数据预处理时建议把 token 化结果先落盘缓存避免每次训练前重新切一遍。4.2 训练参数配置照着这份表调基本不会翻车继续预训练和从零预训练不同它是在一个成熟的模型上继续学所以学习率要比预训练小很多否则会把原有参数冲坏。我常用的配置大致是这样参数推荐范围说明学习率1e-5 ~ 3e-57B 以下可稍高70B 要更低主要是防遗忘不是追求快速收敛Batch Size128~512按 token 数算总 batch size 越大越稳梯度噪音小最大序列长度4096 或 8192取决于显存和场景需要训练步数领域数据过 1~3 个 epoch领域数据不宜训太多遍Warmup 步数前 1%~3% 的步数让学习率先升后降避免一开始就把参数扰动太大权重衰减0.01~0.1防止过拟合梯度裁剪1.0防止个别大梯度把模型带崩优化器AdamW标配学习率调度cosine 衰减末端降到峰值的 10%稳定收尾具体到训练框架可以选用 Hugging Face 的Trainer或transformersdeepspeed也可以直接用Megatron-LM、TinyLlama之类的预训练框架。规模在 7B~14B 时用 DeepSpeed ZeRO-2 或 ZeRO-3 就够规模到 70B建议上张量并行加流水线并行。一个容易忽视的参数是lr_scheduler_type的末端值。很多框架默认把学习率衰减到 0在 CPT 场景下我习惯把末端设为峰值的 10%给模型一个“收尾稳定”的过程能明显减少训练末尾 loss 抖动。4.3 训练流程与中间检查点选择我习惯把 CPT 训练拆成两个阶段第一阶段是“预热吸收”用较低学习率1e-5训练少量步数比如几百步主要让模型开始接触领域数据格式这个阶段 loss 下降不明显是很正常的不用慌。第二阶段是“稳定吸收”提高学习率到 2e-5 左右正常训练直到领域数据过完 1~2 个 epoch。这一步如果 loss 曲线出现明显回升大概率是数据里有问题比如混入了超长重复文本要停下来检查。训练过程中建议每 500 步保存一个 checkpoint。别只看 lossloss 低不代表生成质量好。我一般会把 checkpoint 直接接到评测集上跑看代表性任务的指标变化再选定最终版本。很多团队图省事直接选最后一个 checkpoint这不一定是最优解因为最后一个 checkpoint 往往遗忘最严重倒数第几个反而更均衡。4.4 显存与算力评估你最需要关心的硬成本续预训练不是零成本。拿 7B 模型举例如果用 DeepSpeed ZeRO-2单卡 80GB 显存大约 4~8 张卡能跑起来。如果不是 A100/H100而是消费级显卡比如 4090 24GB7B 模型需要至少 4~8 张 4090 才能比较舒服地跑而且要用 ZeRO-3 加 CPU offload。14B 模型建议至少 8×A10080GB。70B 模型就要 16~32 张 A100 起步了还得搭并行策略普通团队别轻易尝试。训练时长方面7B 模型、10GB 领域训练数据、4096 上下文、8×A100通常需要 10~20 个小时具体看 batch size 和框架优化程度。14B 大约是这个时间的 2 倍。先拿小参数量模型跑通全链路确认数据、代码、评测都稳定了再上大模型这是最省钱的路径。5. 训练过程中的监控、踩坑与调优5.1 训练损失Loss怎么看CPT 阶段最需要关注的不是损失降不降而是时时刻刻防“灾难性遗忘”。损失在降、模型也在学但原有的通用能力可能已经被破坏。所以我的习惯是每训练一段就停下来跑一遍通用基准测试比如 C-Eval、MMLU 的一小部分题目看通用能力衰减是否在可接受范围。如果发现通用任务成绩大幅下滑有几种恢复手段降低学习率给模型更小的更新步幅。提高通用语料在 batch 中的占比。提前停止训练回到上一个 checkpoint。loss 不降反而是小事。如果学习率没问题、数据也没问题loss 不降通常意味着你的领域文本风格基座已经学得很好了继续训练收益有限这时候该做的是缩小学习率和步数而不是盲目加量。5.2 灾难性遗忘不是不可逆但处理要提前灾难性遗忘是 CPT 的头号公敌。这里分享一个我在项目里用过的组合策略每次训练集采样时从通用语料池里按固定概率插入通用样本比如 30%。通俗点说就是不要让模型这顿饭只吃领域菜每四口里搭一口家常菜才能保证它对通用世界的记忆不丢。另外训练过程中可以做“持续评测”每 200 步跑一次固定的领域测试集和通用测试集画两条曲线对比。领域指标向上、通用指标平缓或小波动是理想状态如果领域上升的同时通用大幅下跌立刻停下调参。我们当时就是这样发现训练一上来就崩的原因——领域数据里有一批损坏的 HTML 残片导致 loss 暴涨模型直接性情大变。5.3 显存 OOM、数据加载卡死几个高频问题的排查这里把常见问题整理成速查表都是我实际踩过的现象大概率原因排查与解决方法训练时 OOM单样本长度过长、batch size 过大先降 batch size还不行就用梯度累积再不行就开启序列并行或 ZeRO-3数据加载卡死tokenize 阶段在 CPU 上做成了瓶颈数据预处理阶段提前 tokenize 并落盘或增加 dataloader 的 num_workersloss 突然变 NaN数据里有超长重复文本或异常 token检查数据集是否有空样本、乱码样本降低学习率开启梯度裁剪通用能力下降明显遗忘比率太高提高通用语料占比、降低学习率、提前停生成内容开始重复啰嗦领域语料重复度太高加强近似去重降低训练 epochCPU 内存爆了加载大模型时 CPU offload 内存不够换更大的内存机器或减少 offload 策略OOM 这个坑值得多说一句。7B 模型用 8×A100 看起来绰绰有余但如果你把 max_length 拉到 8192batch size 又设成 32照样 OOM。先算一下 token 总量batch_size x seq_len x 每 token 的显存占用大约 0.5MB~1MB视模型和优化器而定。算完之后才发现表面上 batch_size 是 32实际上已经相当于 32768 token超预算了。一般小模型建议总 token 数控制在 16K~32K 以内稳一点。5.4 训练中途如何选 checkpoint盯着评测指标不是盯着 loss继续预训练的 finished checkpoints 不是越靠后越好。我一般这样选训练完成后把所有 checkpoint 分别在验证集上跑一遍业务指标。选“领域指标增益最大、通用指标下降最小”的那个。这个点往往在训练中段而不是最后。如果业务指标整体增长都有限检查是不是数据量不够而不是继续盲目加步数。这个环节最好做成半自动写一个脚本对每个 checkpoint 做批量推理输出到同一个评测表格里。没有评测体系的 CPT 项目就是在盲飞。6. 训练完不等于能用上线前还要做这些6.1 CPT SFT 偏好对齐的完整链路CPT 训练完的模型输出往往很“原始”——它能读懂领域文本能续写一段报告但它不会听你的指令“把这段内容总结成三句话”。所以实际落地时CPT 只是第一步后面通常还要接 SFT、甚至偏好对齐DPO 等。推荐的完整流程是先用领域数据做 CPT把知识底座打好。再用一批高质量的“指令-回答”数据做 SFT教模型输出格式和交互风格注意这时的训练目标是可以加系统提示词的。可选如果场景要求非常高再用偏好数据做 DPO让模型学会少说废话、避免幻觉式编造。这个链路和我们开头说过的“企业做行业模型”很对应前面 CPT 管“懂不懂”后面 SFT/DPO 管“会不会答”。两者不能互相替代。6.2 上线前的检查清单模型训练完要真正跑在业务里我建议至少过一遍这个清单推理性能CPT 后的模型会不会比原模型推理慢如果扩展了词表检查新增 token 的 embedding 热加载是否正确。量化兼容性很多企业上线需要量化INT8/INT4。CPT 后的模型在量化后效果是否依然稳定先做量化验证再上生产。提示词适配检查模型对“你是一个某某专家”这类提示词的反应看看它是否真的能切换到对应角色。安全性测试跑一遍红队测试集确认模型没有被领域语料带偏生成内容仍然可控合规。回滚方案保存好每一个 checkpoint 元数据配置好版本号防止线上效果不及预期时能快速回滚到上一个稳定版本。业务效果对照把 CPT 前和 CPT 后的模型接进线上业务做 A/B 对比。一句老话离线指标只是参考线上效果才是唯一标准。6.3 再聊一个接地气的部署思路CPT 和 RAG 怎么搭配很多人问我CPT 之后是不是就不需要 RAG 了我的回答是看数据类型。CPT 是让模型把静态知识记住RAG 是让模型随时查动态资料。对于企业知识库这种高频变化的资产RAG 仍然是更灵活的方案但对那些 80% 时间不变的核心领域知识CPT 可以让模型回答得更自然不需要每次都靠检索拼接上下文。最终项目里经常是两层结构先 RAG 抓最新的信息再让 CPT 后的模型用自己的领域直觉去理解和生成。这么搭配比单独用任何一端都顺。我个人在实际操作里还有一个体会CPT 项目最大的坑从来不是技术而是预期管理。很多老板以为训练完模型就“什么都懂”实际上一段 GPT 水平的通用底座加上几个 G 的领域数据能做到的是“有明显领域感、在常见问题上更专业”而不是“百科全书式无所不知”。把这个预期在项目启动时就对齐好后面每一步都会轻松不少。最后再分享一个小技巧如果你第一次接触 CPT先把流程跑通比什么都重要。拿 0.5B 或 1.5B 的小模型配 1GB 领域数据完整走一遍“数据清洗 训练 评测 SFT”的链路把每个环节的坑都踩一遍再上 7B 或更大规模的模型。这样既能控制成本也能让你对模型每一步的变化有体感。等小模型跑出了确定性的收益再考虑扩算力、扩数据那时候你已经知道每一步该看什么指标、该调什么参数了。