首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Elastic 进阶教程:在Elasticsearch中部署中文NER模型

Elastic 进阶教程:在Elasticsearch中部署中文NER模型

原创
作者头像
点火三周
修改2022-08-05 11:22:01
3.3K1
修改2022-08-05 11:22:01
举报
文章被收录于专栏:Elastic Stack专栏Elastic Stack专栏

概述

自然语言处理(NLP)是指我们可以使用软件来理解口语或书面文本中的自然语言的方式。

传统上,NLP 是使用语言规则、字典、正则表达式和机器学习来执行特定任务的,例如自动分类或文本摘要。然而,近年来,深度学习技术已经占据了 NLP 领域的大部分领域。深度学习利用了大规模数据集的可用性、廉价的计算以及在较少人工参与的情况下进行大规模学习的技术。使用transformer架构的预训练语言模型特别成功。例如,BERT 是谷歌于 2018 年发布的一种预训练语言模型。从那时起,它就成为当今大多数现代 NLP 技术的灵感来源。Elastic Stack 机器学习功能围绕 BERT 和 Transformer 模型构建。这些功能支持 BERT 的标记化方案(称为 WordPiece)和符合标准 BERT 模型接口的转换器模型。

为了合并 Transformer 模型并进行预测,Elasticsearch 使用了 libtorch,它是 PyTorch 的底层原生库。经过训练的模型必须采用 TorchScript 表示,才能与 Elastic Stack 机器学习功能一起使用。

Elastic NLP工作方式

因此,我们通常需要先将模型上传到Elasticsearch当中

然后再将模型部署到机器学习的节点上:

然后,将其作为输入输出的网关,对数据进行额外处理:

才能够让其与Elasticsearch的工作模式进行无缝结合。

我们可以通过Eland和 Kibana 提供的工具,快速完成以上步骤,具体步骤简单描述为:

  1. 选择一个训练好的模型
  2. 导入训练好的模型和词汇
  3. 在集群中部署模型
  4. 试运行

在本文中,我们将主要展示,如何将一个中文的NER模型部署到elasticsearch集群当中

Elastic机器学习模块对NER模型的限制

目前,Elastic Stack支持对以下 NLP 操作:

而NER(命名实体识别)属于信息提取这一分类,填充蒙版问答也属于这一范畴。

命名实体识别 (NER) 任务可以识别和分类非结构化文本中的某些实体(通常是专有名词)。命名实体通常是指现实世界中的对象,例如人(PERSON)、位置(LOC)、组织(ORG)和其他(MISC)由专有名称一致引用的杂项实体。

NER 是识别关键信息、添加结构和深入了解您的内容的有用工具。它在处理和探索大量文本(如新闻文章、维基页面或网站)时特别有用。它可以更容易地理解文本的主题并将相似的内容组合在一起。

因此,对于一个搜索引擎来说,NER是深度查询理解(Deep Query Understanding,简称 DQU)的底层基础信号,能应用于搜索召回、用户意图识别、实体链接、图探索等环节,NER信号的质量,直接影响到用户的搜索体验。

但很不幸的是,目前Elasticsearch仅仅兼容测试了以下几种英文的模型:

并且,在目前版本,只支持以IOB(Begin, Inside, Outside)形式打标签的模型。因此,如果我们在Huggingface上选择了一个中文的NER模型,比如这个:https://huggingface.co/uer/roberta-base-finetuned-cluener2020-chinese/

然后部署到Elasticsearch集群:

docker run -it --rm --network host elastic/eland eland_import_hub_model \
--url http://localhost:9200 -u elastic -p yourpassword \
--hub-model-id uer/roberta-base-finetuned-cluener2020-chinese --task-type ner

会有如下提示:

2022-08-05 02:54:41,792 INFO : Establishing connection to Elasticsearch
2022-08-05 02:54:41,882 INFO : Connected to cluster named 'docker-cluster' (version: 8.4.0-SNAPSHOT)
2022-08-05 02:54:41,883 INFO : Loading HuggingFace transformer tokenizer and model 'uer/roberta-base-finetuned-cluener2020-chinese'
Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 295/295 [00:00<00:00, 280kB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.76k/1.76k [00:00<00:00, 3.02MB/s]
Downloading: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 107k/107k [00:01<00:00, 74.2kB/s]
Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 112/112 [00:00<00:00, 132kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 388M/388M [19:02<00:00, 356kB/s]
Asking to pad to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no padding.
2022-08-05 03:14:18,830 INFO : Creating model with id 'uer__roberta-base-finetuned-cluener2020-chinese'
Traceback (most recent call last):
  File "/usr/local/bin/eland_import_hub_model", line 219, in <module>
    ptm.put_config(config=config)
  File "/usr/local/lib/python3.9/dist-packages/eland/ml/pytorch/_pytorch_model.py", line 78, in put_config
    self._client.ml.put_trained_model(model_id=self.model_id, **config_map)
  File "/usr/local/lib/python3.9/dist-packages/elasticsearch/_sync/client/utils.py", line 414, in wrapped
    return api(*args, **kwargs)
  File "/usr/local/lib/python3.9/dist-packages/elasticsearch/_sync/client/ml.py", line 3258, in put_trained_model
    return self.perform_request(  # type: ignore[return-value]
  File "/usr/local/lib/python3.9/dist-packages/elasticsearch/_sync/client/_base.py", line 390, in perform_request
    return self._client.perform_request(
  File "/usr/local/lib/python3.9/dist-packages/elasticsearch/_sync/client/_base.py", line 321, in perform_request
    raise HTTP_EXCEPTIONS.get(meta.status, ApiError)(
elasticsearch.BadRequestError: BadRequestError(400, 'x_content_parse_exception', '[ner] only allows IOB tokenization tagging for classification labels; provided [S_address, S_book, S_company, S_game, S_government, S_movie, S_name, S_organization, S_position, S_scene, [PAD]]')

部署中文模型的解决方案

为了解决以上问题,我们需要对模型做一些修改,使其符合当前Elasticsearch的限制。

也就是说,我们需要将目前模型的打标方式,改成elasticsearch兼容的模式:

{
  "architectures": [
    "BertForTokenClassification"
  ],
  "attention_probs_dropout_prob": 0.1,
  "hidden_act": "gelu",
  "hidden_dropout_prob": 0.1,
  "hidden_size": 768,
  "id2label": {
    "0": "O",
    "1": "B-address",
    "2": "I-address",
    "3": "B-book",
    "4": "I-book",
    "5": "B-company",
    "6": "I-company",
    "7": "B-game",
    "8": "I-game",
    "9": "B-government",
    "10": "I-government",
    "11": "B-movie",
    "12": "I-movie",
    "13": "B-name",
    "14": "I-name",
    "15": "B-organization",
    "16": "I-organization",
    "17": "B-position",
    "18": "I-position",
    "19": "B-scene",
    "20": "I-scene",
    "21": "S-address",
    "22": "S-book",
    "23": "S-company",
    "24": "S-game",
    "25": "S-government",
    "26": "S-movie",
    "27": "S-name",
    "28": "S-organization",
    "29": "S-position",
    "30": "S-scene",
    "31": "[PAD]"
  },
  "initializer_range": 0.02,
  "intermediate_size": 3072,
  "label2id": {
    "B-address": 1,
    "B-book": 3,
    "B-company": 5,
    "B-game": 7,
    "B-government": 9,
    "B-movie": 11,
    "B-name": 13,
    "B-organization": 15,
    "B-position": 17,
    "B-scene": 19,
    "I-address": 2,
    "I-book": 4,
    "I-company": 6,
    "I-game": 8,
    "I-government": 10,
    "I-movie": 12,
    "I-name": 14,
    "I-organization": 16,
    "I-position": 18,
    "I-scene": 20,
    "O": 0,
    "S-address": 21,
    "S-book": 22,
    "S-company": 23,
    "S-game": 24,
    "S-government": 25,
    "S-movie": 26,
    "S-name": 27,
    "S-organization": 28,
    "S-position": 29,
    "S-scene": 30,
    "[PAD]": 31
  },
  "layer_norm_eps": 1e-12,
  "max_position_embeddings": 512,
  "model_type": "bert",
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  "pad_token_id": 0,
  "vocab_size": 21128
}

问题是我们是直接从Huggingface将模型导入到elasticsearch的,我们如何能够对别人的模型进行修改?

很简单,参考我的上一篇博文:在Huggingface上fork repository

我们可以把模型转移到自己的仓库中,然后可自行修改配置文件。在下图中:

image.png
image.png

我们将模型搬移到自己的仓库,然后在线将congfig.json修改为符合IOB的模式。这里的修改包括:

  • S-address等标签改为B-address1
  • [PAD]标签改为B-no

然后通过自己的仓库进行重新部署:

docker run -it --rm --network host elastic/eland eland_import_hub_model \
--url http://localhost:9200 -u elastic -p yourpassword \
--hub-model-id canIjoin/datafun --task-type ner

部署后,即可在界面上进行测试:

image.png
image.png

总结

本文中,我们介绍了在Elasticsearch中NLP的工作愿意,以及在集群中部署中文NER模型的一些限制与解决的办法。

而当下,像搜索深度理解,智能推荐等需要更为精准的搜索的场景,和NLP的结合已经成为必然。而在Elasticsearch中直接实现NLP,将帮助我们以极简的架构、极低的成本,极快的速度去上线一个包含了NLP功能的搜索项目

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • Elastic NLP工作方式
  • Elastic机器学习模块对NER模型的限制
  • 部署中文模型的解决方案
  • 总结
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档