如何对spaCy已训练的model-best、model-last模型开展预训练?
spaCy已训练模型二次训练/续预训练说明
首先明确结论:spaCy完全支持对已训练完成的模型(包括训练产出的model-best、model-last,以及官方发布的预训练模型)进行二次训练、增量微调甚至无监督领域续预训练,不需要从头初始化模型权重,能大幅节省训练算力,同时让模型更好适配垂直场景数据。
场景1:基于标注数据做增量微调(最常用)
这个场景适用于你有新的标注数据,想在之前训好的模型基础上继续优化任务效果(比如补充了新的NER实体类型、新增了文本分类类别),步骤如下:
- 准备训练配置文件:可以直接复用你第一次训练模型用的
config.cfg,修改两个核心参数:- 把
[paths.train]、[paths.dev]替换为新的训练集、验证集路径 - 在
[training]配置块下添加init_from = "./旧模型存放路径"(比如你之前训好的model-best存放在./output/model-best就填这个路径),这个参数是核心,配置后spaCy启动训练时会自动加载旧模型的词表、管道组件、所有权重参数,不会随机初始化
- 把
- 调整超参数避免知识遗忘:续训时不要用和第一次训练相同的学习率,建议把
[training.optimizer.learn_rate]降到初始训练值的1/51/10,比如初始训练用`1e-3`,续训就改成`1e-4`2e-4;如果新标注数据量很小,可以把不需要更新的管道组件设置frozen = true,只训练需要更新的组件头,进一步降低过拟合、旧知识遗忘的概率。 - 启动训练:执行和常规训练完全一致的命令即可:
训练结束后输出目录下的新python -m spacy train config.cfg --output ./output_newmodel-best、model-last就是续训完成的模型。
场景2:对已训练模型做无监督领域续预训练
这个场景适用于你有大量垂直领域无标注文本,想先让模型在领域语料上做无监督预训练适配领域分布,再用少量标注数据微调下游任务,步骤如下:
- 预处理无监督语料:把领域文本整理成jsonl格式,每行对应一段文本,格式为
{"text": "单段领域文本内容"},可以用spacy内置命令转成预训练支持的二进制格式。 - 生成预训练配置:执行命令初始化预训练专用配置:
注意必须加python -m spacy init config pretrain_config.cfg --lang zh --pipeline ner,textcat --pretrain--pretrain参数,生成配置后同样把[training.init_from]指向你已有的旧模型路径,指定预训练的初始化权重来源。 - 启动无监督预训练:执行预训练命令:
预训练过程会在无标注语料上用语言模型目标优化模型表示层权重,输出目录会按训练轮次保存预训练权重。python -m spacy pretrain pretrain_config.cfg ./pretrain_output --paths.data ./你的领域无标注数据集路径 - 下游微调:预训练完成后,微调配置里把
[paths.init_tok2vec](如果是Transformer模型就对应修改Transformer组件的权重加载路径)指向预训练产出的最佳权重文件,再用标注数据执行常规spacy train命令即可,最终得到的就是完成领域预训练适配的下游模型。
注意事项:
- 续训/续预训练时要保证新旧模型使用的spaCy大版本一致,比如spaCy 3.x训练的模型不要用spaCy 2.x加载,否则会出现权重不兼容报错。
- 二次预训练的学习率建议比增量微调更低,避免破坏模型已经学到的通用语义表示。
- 如果只需要更新模型的部分组件,直接把不需要更新的组件设置为冻结状态即可,能大幅降低训练显存占用、缩短训练时间。
内容的提问来源于stack exchange,提问作者ROHIT kumar
相关产品推荐
相关产品推荐

