spaCy & LLM:为开发者打造的NLP工具包

6 阅读5分钟

演讲概述

  • 第一部分:spaCy:一个为开发者设计的、用于自然语言处理的工具包。
  • 第二部分:spacy-llm:将大型语言模型集成到结构化的NLP流程中。

spaCy:为开发者赋能的生产力工具

spaCy 流程

采用模块化的流程方法进行语言分析,将非结构化文本转换为像spaCy的Doc对象这样的结构化数据对象。

spaCy:赋能开发者

  • 快速原型:通过预训练模型、内置功能和合理的默认设置,快速理解业务应用并分析NLP解决方案的 downstream 需求。
  • 定制解决方案:通过实现自定义模型和算法、强大的配置系统以及迭代微调,来满足特定业务场景。

预训练模型使用示例

# 下载预训练模型
$ python -m spacy download en_core_web_trf
# 加载模型并进行实体识别
nlp = spacy.load("en_core_web_trf")
doc = nlp(text)
for ent in doc.ents:
    print(ent.text, ent.label_)
# 可视化实体
displacy.serve(doc, style="ent")

规则匹配器应用

通过定义模式来匹配文本结构,例如提取“治疗组”信息。

from spacy.matcher import Matcher
matcher = Matcher(nlp.vocab)
pattern = [
    {"LOWER": "patients"},
    {"POS": {"IN": ["SYM", "NUM", "PUNCT"]}, "OP": "+"},
    {"LOWER": "received"},
    {"POS": {"IN": ["ADJ", "NOUN", "NUM", "ADP", "SYM"]}, "OP": "+"}
]
matcher.add("TreatmentGroup", [pattern])
matches = matcher(doc, as_spans=True)
for span in matches:
    print(span.text)

规则匹配器帮助探索数据并理解任务复杂性,可通过弱标记引导标注过程。

训练监督模型

通常需要针对特定领域和业务场景训练监督模型,例如:

  • NER与SpanCat:识别患者群体、药物、剂量、频率、结果等。
  • 关系抽取:找出患者群体、治疗和结果之间的正确关系。

配置化训练

通过配置文件(.cfg)捕获所有训练设置,实现序列化和可复现性。

$ python -m spacy init config my_config.cfg --lang en --pipeline ner,spancat

配置文件中可以定义流程组件、训练参数和模型架构。

[nlp]
lang = "en"
pipeline = ["tok2vec","ner","spancat"]
batch_size = 1000

[training]
seed = 342
dropout = 0.1
max_steps = 20000

[components.spancat]
factory = "spancat"
spans_key = "sc"
# ... 其他配置

训练命令如下,系统会自动保存最佳模型。

$ python -m spacy train my_config.cfg --output ./my_output
# 加载训练好的最佳模型
nlp = spacy.load("my_output/model-best")
doc = nlp(text)

spacy-llm:将LLM集成到结构化NLP流程

生产环境中使用ChatGPT的挑战

  • 没有API
  • 不支持批处理
  • 缺乏鲁棒性
  • 无数据隐私保障
  • 不可复现
  • “黑盒”问题

spacy-llm 解决方案

将LLM集成到生产就绪的结构化NLP流程中。

  • 后端支持
    • 外部API,如某机构OpenAI、Cohere、Anthropic。
    • 开源模型,如Dolly v2、OpenLLaMa、StableLM(通过HuggingFace hub)。
    • 支持编写自定义后端。
  • 任务支持
    • 定义发送给LLM的提示词。
    • 解析LLM的响应,并将其转换为spaCy的Doc对象上的结构化注解。
    • 支持为特定用例编写自定义任务。

spacy-llm:赋能开发者

  • 快速原型:通过内置后端/模型、内置任务和合理默认设置。
  • 定制解决方案:通过实现自定义任务和后端、强大的配置系统和迭代微调。

使用内置NER功能

配置文件定义使用某机构OpenAI的GPT-3.5-turbo模型进行零样本命名实体识别。

[nlp]
lang = "en"
pipeline = ["llm"]

[components]
[components.llm]
factory = "llm"

[components.llm.backend]
@llm_backends = "spacy.REST.v1"
api = "OpenAI" 
[components.llm.backend.config]
model = "gpt-3.5-turbo"

[components.llm.task]
@llm_tasks = "spacy.NER.v2"
labels = "Drug,Dose"
from spacy_llm.util import assemble
nlp = assemble("my_config.cfg")
doc = nlp(text)

轻松切换后端与任务

通过修改配置文件,可以轻松地将任务从NER切换到文本分类,或将后端从某机构OpenAI的GPT模型切换到开源的Dolly模型。

编写自定义任务

通过定义指令和解析逻辑,创建自定义任务。

INSTRUCTION = """ Summarize the trial results in a structured fashion like so:
Patient group: <name>
Number of patients in the group: <number>
Treatment drug or substance: <drug>
Treatment dose: <drug>
... """

class TrialSummaryTask:
    def generate_prompts(self, docs):
        # 为每个文档生成提示词
        pass
    def parse_responses(self, docs, responses):
        # 解析LLM的响应并添加到Doc对象中
        pass

@registry.llm_tasks("hedgy.TrialSummary.v1")
def make_trial_task():
    return TrialSummaryTask()

解析函数可以将LLM的自由文本输出解析成结构化字段,并作为Doc对象的实体供下游流程使用。

从原型到生产的技术权衡

需要考虑的性能特征

  • 准确性
  • 推理速度
  • 内存使用
  • 可靠性/可复现性
  • 可维护性
  • 可定制性
  • 运行成本
  • 注解/实现成本
  • 计算能力
  • 原型速度
  • 可解释性
  • 数据隐私

性能权衡(1):规则/模式 vs 监督学习 vs 大型语言模型

三种技术在不同维度(如准确性、速度、成本、可解释性)上各有优劣。

性能权衡(2):闭源LLM vs 开源LLM

  • 闭源LLM:通常性能强大,但存在数据隐私风险、供应商锁定和API调用成本。
  • 开源LLM:提供了更好的数据隐私和可定制性,但可能需要更多的计算资源和技术 expertise 来部署和维护。

从原型到生产的演进路径

从使用LLM进行快速原型验证开始,然后根据业务需求,逐步用监督学习、规则等进行替换、集成或微调。

混合架构的应用示例

示例1:LLM辅助标注

利用LLM的零样本预测生成初始标注,然后通过人工筛选和校正,快速构建用于训练监督模型的训练数据和用于评估的测试数据。

示例2:文本预处理

在将文本发送给第三方LLM之前,使用本地的NER系统识别并替换个人身份信息,避免敏感数据泄露。

示例3:输入文本过滤

先使用文本分类器筛选出包含特定主题或实体的句子,再发送给LLM,从而降低成本和优化提示词。

示例4:LLM响应后处理

利用规则或实体链接系统,对LLM返回的自由文本响应进行规范化处理,将其连接到知识库,提高下游流程的鲁棒性。

总结

  • NLP从文本中解锁信息,并以结构化形式提供给下游业务应用。
  • 大型语言模型具有强大的文本生成/理解能力。
  • 使用LLM进行NLP应用原型设计变得非常容易。
  • 在构建生产级流程时,需要考虑可定制性、鲁棒性、推理成本、网络延迟等因素。
  • spaCy是一个为开发者编写的生产级NLP框架。
  • 其最新扩展spacy-llm允许将LLM轻松集成到结构化NLP流程中。
  • LLM辅助标注可以快速引导训练/评估数据的构建。FINISHED