v3.0版本的新特性
新功能
本节概述了最重要的新功能和改进。API文档中还包含了额外的废弃说明。本版本引入的新方法和函数都标有v3.0标签。
基于Transformer的管道
spaCy v3.0 采用了全新的基于transformer的流程,将spaCy的准确率提升至当前最先进水平。您可以使用任何预训练的transformer来训练自己的流程,甚至通过多任务学习在多个组件间共享一个transformer。spaCy的transformer支持与PyTorch和HuggingFace transformers库互操作,让您能够为流程访问数千个预训练模型。
| Pipeline | Parser | Tagger | NER |
|---|---|---|---|
en_core_web_trf (spaCy v3) | 95.1 | 97.8 | 89.8 |
en_core_web_lg (spaCy v3) | 92.0 | 97.4 | 85.5 |
en_core_web_lg (spaCy v2) | 91.9 | 97.2 | 85.5 |
完整流程准确率基于 OntoNotes 5.0语料库(在开发集上报告)。
| 命名实体识别系统 | OntoNotes | CoNLL '03 |
|---|---|---|
| spaCy RoBERTa (2020) | 89.8 | 91.6 |
| Stanza (StanfordNLP)1 | 88.8 | 92.1 |
| Flair2 | 89.7 | 93.1 |
命名实体识别准确率在
OntoNotes 5.0和
CoNLL-2003语料库上的表现。更多结果请参阅
NLP-progress。项目模板:
benchmarks/ner_conll03。1.
Qi et al. (2020)。2.
Akbik et al. (2018)。
全新训练基于Transformer的pipeline
| 包 | 语言 | 转换器 | 标记器 | 解析器 | 命名实体识别 |
|---|---|---|---|---|---|
en_core_web_trf | English | roberta-base | 97.8 | 95.2 | 89.9 |
de_dep_news_trf | German | bert-base-german-cased | 99.0 | 95.8 | - |
es_dep_news_trf | Spanish | bert-base-spanish-wwm-cased | 98.2 | 94.6 | - |
fr_dep_news_trf | French | camembert-base | 95.7 | 94.4 | - |
zh_core_web_trf | Chinese | bert-base-chinese | 92.5 | 76.6 | 75.4 |
全新训练流程与配置系统
spaCy v3.0 引入了一个全面且可扩展的系统,用于配置训练运行。单个配置文件即可描述训练运行的每个细节,没有隐藏的默认值,使得重新运行实验和跟踪变更变得容易。您可以使用快速启动小工具或init config命令开始使用。无需在命令行提供大量参数,您只需将config.cfg文件传递给spacy train。训练配置文件包含训练管道的所有设置和超参数。某些设置也可以是注册的函数,您可以替换和自定义这些函数,从而轻松实现自己的自定义模型和架构。
使用任意框架的自定义模型
spaCy的新配置系统使得自定义不同流程组件使用的神经网络模型变得简单。您还可以通过spaCy的机器学习库Thinc实现自己的架构,该库提供了各种层和实用工具,以及对PyTorch、TensorFlow和MXNet等框架的轻量级封装。组件模型都遵循相同的统一Model API,每个Model也可以作为更大网络的子层使用,让您能够自由地将不同框架的实现组合到单个模型中。
使用项目管理工作流全流程
spaCy项目让您能够管理和共享针对不同使用场景和领域的端到端spaCy工作流,并协调训练、打包和部署自定义流程。您可以从克隆预定义的项目模板开始,根据需求进行调整,导入数据,训练流程,将其导出为Python包,将输出上传到远程存储,并与团队共享结果。
spaCy项目还能轻松与其他工具集成,包括用于数据版本控制的DVC、用于创建标注数据的Prodigy、用于构建交互式应用的Streamlit、用于生产环境模型部署的FastAPI、用于并行训练的Ray、用于实验跟踪的Weights & Biases等数据科学和机器学习生态系统中的工具!
使用Ray进行并行和分布式训练
Ray 是一个快速简单的框架,用于构建和运行分布式应用。您可以使用Ray在一台或多台远程机器上训练spaCy,从而可能加速训练过程。该Ray集成由一个轻量级扩展包spacy-ray提供支持,如果它安装在相同环境中,会自动将ray命令添加到您的spaCy CLI中。然后您可以运行spacy ray train进行并行训练。
新增内置管道组件
spaCy v3.0 包含多个新的可训练和基于规则的组件,您可以将其添加到流程中并根据您的用例进行定制:
| 名称 | 描述 |
|---|---|
SentenceRecognizer | Trainable component for sentence segmentation. |
Morphologizer | Trainable component to predict morphological features. |
Lemmatizer | Standalone component for rule-based and lookup lemmatization. |
AttributeRuler | Component for setting token attributes using match patterns. |
Transformer | Component for using transformer models in your pipeline, accessing outputs and aligning tokens. Provided via spacy-transformers. |
TrainablePipe | Base class for trainable pipeline components. |
Multi-label TextCategorizer | Trainable component for multi-label text classification. |
全新优化的管道组件API
定义、配置、复用、训练和分析管道组件现在变得更加简单便捷。@Language.component和@Language.factory装饰器允许您注册组件,定义其默认配置和元数据,例如它分配和需要的属性值。任何自定义组件都可以在训练过程中包含进来,从现有训练好的管道中获取组件让您能够混合搭配自定义管道。nlp.analyze_pipes方法会输出关于当前管道及其组件的结构化信息,包括它们分配的属性、在训练期间计算的分数以及是否有任何必需属性未被设置。
依赖关系匹配
全新的DependencyMatcher允许您使用Semgrex运算符在依存句法分析中匹配模式。它遵循与基于词符的Matcher相同的API。添加到依存匹配器的模式由字典列表组成,每个字典描述一个待匹配词符及其与模式中现有词符的关系。
类型提示与基于类型的数据验证
spaCy v3.0 正式停止对 Python 2 的支持,现在需要 Python 3.6+ 版本。这也意味着代码库可以充分利用 type hints。spaCy 纯 Python 实现的用户接口 API(与 Cython 相对)现在都带有类型提示。新版本的 spaCy 机器学习库 Thinc 也具备全面的 type support,包括模型和数组的自定义类型,以及可用于类型检查模型定义的自定义 mypy 插件。
对于数据验证,spaCy v3.0采用了
pydantic。它还支持Thinc的配置系统的数据验证功能,
允许您注册带有类型参数的自定义函数,在配置中引用它们,
并在参数值不匹配时查看验证错误。
新增方法、属性和命令
以下方法、属性和命令是spaCy v3.0中的新增内容。
| 名称 | 描述 |
|---|---|
Token.lex | Access a token’s Lexeme. |
Token.morph | Access a token’s morphological analysis. |
Doc.spans | Named span groups to store and access collections of potentially overlapping spans. Uses the new SpanGroup data structure. |
Doc.has_annotation | Check whether a doc has annotation on a token attribute. |
Language.select_pipes | Context manager for enabling or disabling specific pipeline components for a block. |
Language.disable_pipe, Language.enable_pipe | Disable or enable a loaded pipeline component (but don’t remove it). |
Language.analyze_pipes | Analyze components and their interdependencies. |
Language.resume_training | Experimental: continue training a trained pipeline and initialize “rehearsal” for components that implement a rehearse method to prevent catastrophic forgetting. |
@Language.factory, @Language.component | Decorators for registering pipeline component factories and simple stateless component functions. |
Language.has_factory | Check whether a component factory is registered on a language class. |
Language.get_factory_meta, Language.get_pipe_meta | Get the FactoryMeta with component metadata for a factory or instance name. |
Language.config | The config used to create the current nlp object. An instance of Config and can be saved to disk and used for training. |
Language.components, Language.component_names | All available components and component names, including disabled components that are not run as part of the pipeline. |
Language.disabled | Names of disabled components that are not run as part of the pipeline. |
TrainablePipe.score | Method on pipeline components that returns a dictionary of evaluation scores. |
registry | Function registry to map functions to string names that can be referenced in configs. |
util.load_meta, util.load_config | Updated helpers for loading a pipeline’s meta.json and config.cfg. |
util.get_installed_models | Names of all pipeline packages installed in the environment. |
init config, init fill-config, debug config | CLI commands for initializing, auto-filling and debugging training configs. |
init vectors | Convert word vectors for use with spaCy. |
init labels | Generate JSON files for the labels in the data to speed up training. |
project | Suite of CLI commands for cloning, running and managing spaCy projects. |
ray | Suite of CLI commands for parallel training with Ray, provided by the spacy-ray extension package. |
新增和更新的文档
向后不兼容性
一如既往,我们尽量将破坏性变更控制在最低限度,重点放在支持新功能、修复问题或提升可用性所必需的改动上。以下部分列出了面向用户的API相关变更。如需了解如何重写代码的具体示例,请查阅迁移指南。
API变更
- 管道包符号链接、
link命令和快捷名称现已弃用。由于可能存在多种不同的训练管道而不仅限于单一的"英文模型",因此您应当始终明确使用完整包名称如en_core_web_sm。 - 管道的
meta.json现在仅用于提供元信息,如包名称、作者、许可证和标签。它不再用于构建处理管道。所有这些都在config.cfg中定义,该文件还包含用于训练管道的所有设置。 train、pretrain和debug data命令现在仅接受config.cfg文件。Language.add_pipe现在接受组件工厂的字符串名称而非组件函数。- 自定义管道组件现在需要使用
@Language.component或@Language.factory装饰器进行装饰。 Language.update、Language.evaluate和TrainablePipe.update方法现在都接受批量的Example对象,而不是Doc和GoldParse对象, 或原始文本和标注字典。begin_training方法已更名为initialize,现在接受一个返回Example对象序列的函数来初始化模型,而不是接受元组列表。Matcher.add和PhraseMatcher.add现在仅接受模式列表作为第二个参数(而不是可变数量的参数)。on_match回调变为可选的关键字参数。Doc标志如Doc.is_parsed或Doc.is_tagged已被Doc.has_annotation取代。spacy.gold模块已更名为spacy.training。PRON_LEMMA符号和作为代词词元指示符的-PRON-已被移除。- 语言数据中的
TAG_MAP和MORPH_RULES已被更灵活的AttributeRuler替代。 Lemmatizer现在是一个独立的流水线组件,默认情况下不提供词元,也不会自动在基于查找和基于规则的词元之间切换。您现在可以显式地将其添加到流水线中,并在初始化时设置其模式。- 现在,各种函数和方法中的关键字参数被明确声明为仅限关键字参数。这些参数在API参考文档中统一使用keyword-only标签进行标注。
textcat管道组件现在仅适用于互斥类别的分类 - 即每个输入句子或文档只能预测一个类别。要进行多标签分类,请改用新的textcat_multilabel组件。
移除或重命名的API
| 已移除 | 替代方案 |
|---|---|
Language.disable_pipes | Language.select_pipes, Language.disable_pipe, Language.enable_pipe |
Language.begin_training, Pipe.begin_training, … | Language.initialize, Pipe.initialize, … |
Doc.is_tagged, Doc.is_parsed, … | Doc.has_annotation |
GoldParse | Example |
GoldCorpus | Corpus |
KnowledgeBase.load_bulk, KnowledgeBase.dump | KnowledgeBase.from_disk, KnowledgeBase.to_disk |
KnowledgeBase.get_candidates | KnowledgeBase.get_alias_candidates |
Matcher.pipe, PhraseMatcher.pipe | not needed |
gold.offsets_from_biluo_tags, gold.spans_from_biluo_tags, gold.biluo_tags_from_offsets | training.biluo_tags_to_offsets, training.biluo_tags_to_spans, training.offsets_to_biluo_tags |
spacy init-model | spacy init vectors |
spacy debug-data | spacy debug data |
spacy profile | spacy debug profile |
spacy link, util.set_data_path, util.get_data_path | not needed, symlinks are deprecated |
以下方法、属性和参数在v3.0版本中已被移除。其中大部分早已被弃用,许多在之前版本中就会报错。它们大多属于内部实现。如果您一直在使用较新的spaCy v2.x版本,那么您的代码不太可能依赖这些内容。
| 已移除 | 替代方案 |
|---|---|
Doc.tokens_from_list | Doc.__init__ |
Doc.merge, Span.merge | Doc.retokenize |
Token.string, Span.string, Span.upper, Span.lower | Span.text, Token.text |
Language.tagger, Language.parser, Language.entity | Language.get_pipe |
keyword-arguments like vocab=False on to_disk, from_disk, to_bytes, from_bytes | exclude=["vocab"] |
n_threads argument on Tokenizer, Matcher, PhraseMatcher | n_process |
verbose argument on Language.evaluate | logging (DEBUG) |
SentenceSegmenter hook, SimilarityHook | user hooks, Sentencizer, SentenceRecognizer |
从v2.x迁移
下载并加载训练好的管道
像en这样的符号链接和快捷方式已被弃用一段时间,现在不再受支持。spacy提供了许多不同的训练管道,具有不同的功能,而不仅仅是一个“英语模型”。要下载和加载一个包,您应该始终使用其全名——例如,en_core_web_sm。
自定义管道组件与工厂
自定义管道组件现在必须使用
@Language.component 或
@Language.factory 装饰器显式注册。对于接收Doc并返回它的简单函数,您只需添加
@Language.component 装饰器并为其分配名称:
无状态函数组件
对于使用设置和/或共享nlp对象初始化的类组件,您可以使用@Language.factory装饰器。同时请确保用于初始化工厂的方法具有两个命名参数:nlp(当前的nlp对象)和name(组件实例的字符串名称)。
有状态的类组件
除了装饰你的类,你也可以添加一个工厂函数,该函数接收参数nlp和name并返回你的组件实例:
使用工厂函数的有状态类组件
@Language.component 和 @Language.factory 装饰器现在会自动处理向组件工厂添加条目的操作,因此spaCy知道如何从其字符串名称重新加载组件。您不再需要手动写入Language.factories了。
向管道添加组件
nlp.add_pipe 方法现在接收组件工厂的字符串名称而非可调用组件。这使得spaCy能够追踪和序列化已添加的组件及其设置。
nlp.add_pipe 现在还会返回管道组件本身,因此您可以访问其属性。nlp.create_pipe 方法现在主要用于内部实现,通常您不需要在代码中使用它。
如果需要从现有训练好的管道中添加组件,现在可以使用nlp.add_pipe的source参数。这将检查组件是否兼容,并负责移植所有配置。在训练过程中,您还可以在config中引用现有训练好的组件,并决定是否应该用更多数据来更新它们。
使用设置配置流水线组件
由于现在使用字符串名称添加管道组件,您不再需要直接实例化组件类。要配置组件,您现在可以在nlp.add_pipe上使用config参数。
config对应config.cfg中的组件设置,并将覆盖组件定义的默认配置。
添加匹配模式
Matcher.add、
PhraseMatcher.add和
DependencyMatcher.add方法现在仅接受
模式列表作为第二个参数(而非可变数量的参数)。on_match回调变为可选的关键字参数。
在分词器异常中迁移属性
分词器异常现在只允许设置ORTH和NORM值作为词符属性的一部分。其他属性如TAG和LEMMA的异常应移至AttributeRuler组件中:
迁移标签映射和形态规则
不再需要在语言数据中定义tag_map和morph_rules,spaCy v3.0现在通过一个独立且更灵活的管道组件AttributeRuler来管理映射和例外情况。具体示例请参阅使用指南。如果您有v2.x格式的标签映射和形态规则,可以在训练前通过配置文件的[initialize]区块将它们加载到属性标尺中。
使用Lexeme表
要从头开始训练模型时使用像lexeme_prob这样的表,您需要在配置文件的initialize块中添加一个条目。以下是现有训练管道的示例配置:
config.cfg (节选)
AttributeRuler 还提供了两个便捷的辅助方法
load_from_tag_map 和
load_from_morph_rules,它们允许
您加载现有的标签映射或形态规则:
迁移文档标志
在v3.0版本中,Doc的标志位Doc.is_tagged、Doc.is_parsed、Doc.is_nered和
Doc.is_sentenced已被弃用,取而代之的是
Doc.has_annotation方法,该方法引用的是
词符属性符号(与Matcher模式中使用的符号相同):
训练流程和模型
要训练您的流水线,现在您基本上应该始终使用spacy train命令行界面。除非您确实需要,否则不必再自己编写训练脚本。训练命令现在使用一个灵活的配置文件来描述所有训练设置和超参数,以及您要使用的流水线、组件和架构。--code参数允许您传入包含自定义注册函数的代码,这些函数可以在配置中引用。要开始使用,请查看快速入门小工具。
二进制 .spacy 训练数据格式
spaCy v3.0 使用了一种新的
二进制训练数据格式,该格式通过序列化
DocBin创建,表示一组Doc
对象。这意味着您可以使用与其输出相同的格式来训练spaCy管道:带标注的Doc对象。这种二进制格式在存储效率方面极为出色,特别是在打包多个文档时。您可以使用spacy convert命令转换现有的JSON格式数据,该命令会输出.spacy文件:
训练配置
开始使用训练配置的最简单方法是使用init config命令或快速启动小工具。您可以定义需求,它将自动生成一个包含最佳匹配默认设置的初始配置。
如果您已经从我们的快速启动小工具导出了初始配置,您可以使用init fill-config命令来填充所有默认值。然后您可以使用自动生成的config.cfg进行训练:
修改分词器设置
如果您在v2版本中使用基础模型配合spacy train来自定义分词器设置,您的修改可以在[initialize.before_init]回调函数中提供。
编写一个已注册的回调函数来修改分词器设置,并在配置中指定此回调:
functions.py
训练时,使用--code选项提供上述函数:
训练步骤需要使用--code选项来调用你在[initialize]块中注册的函数,但由于这些回调函数仅在初始化阶段需要,因此最终生成的管道包中无需包含它们。不过,为了让其他人更容易复现你的训练设置,你可以选择将这些初始化回调函数与管道包一起打包,或者单独发布它们。
通过Python API进行训练
对于大多数使用场景,您无需再编写自己的训练脚本。相反,您可以使用spacy train配合配置文件,如有需要还可添加自定义的注册函数。您甚至可以注册回调函数,在训练前通过修改nlp对象生命周期的不同阶段来实现完全定制。
如果您决定使用Python中的内部训练API,只需对脚本进行少量修改即可将其从spaCy v2.x转换为v3.x。Example.from_dict类方法接收一个参考Doc和一个标注字典,类似于spaCy v2.x中的"简单训练风格":
迁移Doc和GoldParse
迁移简单训练风格
Language.update、
Language.evaluate 和
TrainablePipe.update 方法现在都接受批量的
Example 对象,而不是 Doc 和 GoldParse 对象,
或原始文本和标注字典。
训练循环
Language.begin_training 和 TrainablePipe.begin_training 已被重命名为
Language.initialize 和
TrainablePipe.initialize,这些方法现在接受一个
返回 Example 对象序列的函数来初始化模型,
而不是元组列表。数据示例用于初始化
可训练管道组件的模型,包括验证网络、
推断缺失形状 和
设置标签方案。
打包训练好的管道
spacy package 命令现在会自动构建Python包的可安装.tar.gz源码发行版,因此您不再需要手动执行此步骤。要禁用此行为,可以设置--build none。您还可以选择通过设置--build wheel来构建二进制wheel(安装效率更高),或者通过设置--build sdist,wheel同时构建源码发行版和wheel。
数据工具与黄金模块
spacy.gold模块已更名为spacy.training,转换工具现在遵循x_to_y的命名格式。这主要影响内部实现,但如果您一直在使用以下跨度偏移转换工具:
offsets_to_biluo_tags、
biluo_tags_to_offsets或
biluo_tags_to_spans,您需要更改名称和导入方式:
插件维护者的迁移说明
感谢所有通过开发和维护众多出色的插件和扩展为spaCy生态系统做出贡献的人。我们已尽力让您能够轻松升级您的包以适配spaCy v3.0。插件最常见的用途是提供管道组件和扩展属性。在迁移您的插件时,请仔细检查以下内容:
- 使用
@Language.factory装饰器注册您的组件并为其分配名称。这允许用户通过名称引用您的组件,并序列化引用它们的管道。移除所有手动添加到Language.factories的条目。 - 确保您的组件工厂至少接受两个命名参数:
nlp(当前的nlp对象)和name(所添加组件的实例名称,以便您可以识别同一组件的多个实例)。 - 将文档中所有引用
nlp.add_pipe的地方更新为使用字符串名称而非组件函数。
在Jupyter笔记本中使用GPU
在Jupyter笔记本中,请在与spacy.load相同的单元格内运行prefer_gpu、require_gpu或require_cpu,以确保模型加载到正确的设备上。
由于与contextvars相关的错误(参见错误报告),GPU设置可能无法在多个单元格间正确保留,导致模型被加载到错误的设备上或仅部分加载到GPU。