如何加快spaCy框架下波斯语NER任务的训练速度
问题描述
我有一个空白spaCy模型,最初通过Training Pipelines & Models配置组件生成配置文件时,选择的参数如下:
Language = Arabic
Components = ner
Hardware = CPU
Optimize for = accuracy
后续我将配置文件中如下配置项:
[nlp] lang = "ar"
修改为:
[nlp] lang = "fa"
修改原因是目前波斯语没有可用的预训练GPU(transformer)模型。
以accuracy为优化目标的训练模式运行速度很慢,我拥有40万条训练记录,当前使用的完整配置文件如下:
[paths] train = null dev = null vectors = null [system] gpu_allocator = null [nlp] lang = "fa" pipeline = ["tok2vec","ner"] batch_size = 1000 [components] [components.tok2vec] factory = "tok2vec" [components.tok2vec.model] @architectures = "spacy.Tok2Vec.v2" [components.tok2vec.model.embed] @architectures = "spacy.MultiHashEmbed.v2" width = ${components.tok2vec.model.encode.width} attrs = ["ORTH", "SHAPE"] rows = [5000, 2500] include_static_vectors = true [components.tok2vec.model.encode] @architectures = "spacy.MaxoutWindowEncoder.v2" width = 256 depth = 8 window_size = 1 maxout_pieces = 3 [components.ner] factory = "ner" [components.ner.model] @architectures = "spacy.TransitionBasedParser.v2" state_type = "ner" extra_state_tokens = false hidden_width = 64 maxout_pieces = 2 use_upper = true nO = null [components.ner.model.tok2vec] @architectures = "spacy.Tok2VecListener.v1" width = ${components.tok2vec.model.encode.width} [corpora] [corpora.train] @readers = "spacy.Corpus.v1" path = ${paths.train} max_length = 0 [corpora.dev] @readers = "spacy.Corpus.v1" path = ${paths.dev} max_length = 0 [training] dev_corpus = "corpora.dev" train_corpus = "corpora.train" [training.optimizer] @optimizers = "Adam.v1" [training.batcher] @batchers = "spacy.batch_by_words.v1" discard_oversize = false tolerance = 0.2 [training.batcher.size] @schedules = "compounding.v1" start = 100 stop = 1000 compound = 1.001 [initialize] vectors = ${paths.vectors}
请问可以采取哪些措施加快整个训练流程的速度?
可行加速方案
1. 硬件层面优先启用GPU
- 当前配置
gpu_allocator = null为纯CPU运行模式,是速度慢的核心诱因。如果有NVIDIA显卡,安装对应CUDA版本的cupy依赖后,将该项改为gpu_allocator = "cupy"即可调用GPU训练,同参数下速度通常是CPU的5~15倍。 - 若只能用CPU训练,启动训练时通过
--n-threads参数指定等于CPU物理核心数的线程数,不要绑定超线程逻辑核心,减少线程上下文切换的额外开销。
2. 精简模型结构,平衡精度与速度
当前是accuracy优先的大模型配置,适当调小参数后精度损失通常可控制在1%以内,速度提升明显:
- 压缩tok2vec编码器:将
[components.tok2vec.model.encode]段的depth = 8改为depth = 4,width = 256改为width = 128,maxout_pieces = 3改为maxout_pieces = 2,编码器计算量可下降60%以上。 - 缩小嵌入层规模:当前嵌入层仅使用
ORTH、SHAPE两个属性,将rows = [5000, 2500]调整为rows = [2000, 1000]即可,40万条样本的NER任务不需要过大的哈希嵌入表,过大的表对精度提升边际收益极低。 - 无高质量波斯语预训练词向量时,将
include_static_vectors = true改为false,省掉词向量查表、拼接的额外计算开销。
3. 优化数据与批次配置,提升硬件利用率
- 调整批次增长策略:当前
compound = 1.001的增长速率过于平缓,训练前期长时间处于小批次状态,硬件利用率极低。将compound = 1.001改为compound = 1.01,stop = 1000改为stop = 2000,让批次大小快速提升到合理区间。 - 过滤超长样本:将训练、验证集配置里的
max_length = 0改为max_length = 200(波斯语NER任务的有效实体几乎都分布在200词以内的句子中),直接丢弃异常长文本,避免单条样本拖慢整个批次的计算。 - 训练前提前将标注数据转换为spaCy二进制
.spacy格式,不要直接读取JSON等原始标注格式,减少数据加载阶段的IO和解析开销。
4. 调整训练流程,减少无效计算
- 降低验证评估频率:默认配置每100步跑一次全量验证集,40万样本规模下验证开销极高。在
[training]段添加eval_frequency = 500,每500步做一次验证即可,不影响精度判断的前提下省掉大量重复计算。 - 开启提前停止:在
[training]段配置patience = 500,验证集精度连续500步不提升就自动终止训练,避免无意义的迭代。 - 调参阶段先抽取10%~20%的样本做小批量测试,确定最优参数组合后再跑全量数据,不要每次调参都加载全量40万样本训练。
内容的提问来源于stack exchange,提问作者miladjurablu
相关产品推荐
相关产品推荐

