Files
wehub-resource-sync 2aaeece67c
Codestyle Check / Lint (push) Has been cancelled
Codestyle Check / Check bypass (push) Has been cancelled
Pipelines-Test / Pipelines-Test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:37:14 +08:00

241 lines
9.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# coding:utf-8
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from .knowledge_mining import WordTagTask
from .lexical_analysis import LacTask
from .utils import Customization
POS_LABEL_WORDTAG = [
"介词",
"介词_方位介词",
"助词",
"代词",
"连词",
"副词",
"疑问词",
"肯定词",
"否定词",
"数量词",
"叹词",
"拟声词",
"修饰词",
"外语单词",
"英语单词",
"汉语拼音",
"词汇用语",
"w",
]
POS_LABEL_LAC = ["n", "f", "s", "t", "v", "vd", "vn", "a", "ad", "an", "d", "m", "q", "r", "p", "c", "u", "xc", "w"]
usage = r"""
from paddlenlp import Taskflow
# WordTag精确模式
ner = Taskflow("ner")
ner("《孤女》是2010年九州出版社出版的小说,作者是余兼羽")
'''
[('《', 'w'), ('孤女', '作品类_实体'), ('》', 'w'), ('是', '肯定词'), ('2010年', '时间类'), ('九州出版社', '组织机构类'), ('出版', '场景事件'), ('的', '助词'), ('小说', '作品类_概念'), ('', 'w'), ('作者', '人物类_概念'), ('是', '肯定词'), ('余兼羽', '人物类_实体')]
'''
ner(["热梅茶是一道以梅子为主要原料制作的茶饮", "《孤女》是2010年九州出版社出版的小说,作者是余兼羽"])
'''
[[('热梅茶', '饮食类_饮品'), ('是', '肯定词'), ('一道', '数量词'), ('以', '介词'), ('梅子', '饮食类'), ('为', '肯定词'), ('主要原料', '物体类'), ('制作', '场景事件'), ('的', '助词'), ('茶饮', '饮食类_饮品')], [('《', 'w'), ('孤女', '作品类_实体'), ('》', 'w'), ('是', '肯定词'), ('2010年', '时间类'), ('九州出版社', '组织机构类'), ('出版', '场景事件'), ('的', '助词'), ('小说', '作品类_概念'), ('', 'w'), ('作者', '人物类_概念'), ('是', '肯定词'), ('余兼羽', '人物类_实体')]]
'''
# 只返回实体/概念词
ner = Taskflow("ner", entity_only=True)
ner("《孤女》是2010年九州出版社出版的小说,作者是余兼羽")
'''
[('孤女', '作品类_实体'), ('2010年', '时间类'), ('九州出版社', '组织机构类'), ('出版', '场景事件'), ('小说', '作品类_概念'), ('作者', '人物类_概念'), ('余兼羽', '人物类_实体')]
'''
# 使用快速模式,只返回实体词
ner = Taskflow("ner", mode="fast", entity_only=True)
ner("三亚是一个美丽的城市")
'''
[('三亚', 'LOC')]
'''
"""
class NERWordTagTask(WordTagTask):
"""
This the NER(Named Entity Recognition) task that convert the raw text to entities. And the task with the `wordtag`
model will link the more message with the entity.
Args:
task(string): The name of task.
model(string): The model name in the task.
kwargs (dict, optional): Additional keyword arguments passed along to the specific task.
"""
resource_files_names = {
"model_state": "model_state.pdparams",
"model_config": "config.json",
"tags": "tags.txt",
"vocab_file": "vocab.txt",
"special_tokens_map": "special_tokens_map.json",
"tokenizer_config": "tokenizer_config.json",
}
resource_files_urls = {
"wordtag": {
"model_state": [
"https://bj.bcebos.com/paddlenlp/taskflow/knowledge_mining/wordtag_v1.5/model_state.pdparams",
"c7c9cef72f73ee22c70c26ef11393025",
],
"model_config": [
"https://bj.bcebos.com/paddlenlp/taskflow/knowledge_mining/wordtag_v1.1/config.json",
"b9f307b3fa03ad98c08ecb5249c15dfa",
],
"tags": [
"https://bj.bcebos.com/paddlenlp/taskflow/knowledge_mining/wordtag_v1.1/tags.txt",
"f33feedd01d478b03bac81be19b48d00",
],
"vocab_file": [
"https://bj.bcebos.com/paddlenlp/taskflow/knowledge_mining/wordtag/vocab.txt",
"54aa6e2eeb0478c2d18a2343b008590c",
],
"special_tokens_map": [
"https://bj.bcebos.com/paddlenlp/taskflow/knowledge_mining/wordtag/special_tokens_map.json",
"58104269e4f141a258bdb2ed06aa599f",
],
"tokenizer_config": [
"https://bj.bcebos.com/paddlenlp/taskflow/knowledge_mining/wordtag/tokenizer_config.json",
"e3f2756e72e24e3bb298303fb9a171f7",
],
}
}
def __init__(self, model, task, entity_only=False, **kwargs):
super().__init__(model="wordtag", task=task, **kwargs)
self.entity_only = entity_only
if self._user_dict:
self._custom = Customization()
self._custom.load_customization(self._user_dict)
else:
self._custom = None
def _decode(self, batch_texts, batch_pred_tags):
batch_results = []
for sent_index in range(len(batch_texts)):
sent = batch_texts[sent_index]
indexes = batch_pred_tags[sent_index][self.summary_num : len(sent) + self.summary_num]
tags = [self._index_to_tags[index] for index in indexes]
if self._custom:
self._custom.parse_customization(sent, tags, prefix=True)
sent_out = []
tags_out = []
partial_word = ""
for ind, tag in enumerate(tags):
if partial_word == "":
partial_word = sent[ind]
tags_out.append(tag.split("-")[-1])
continue
if tag.startswith("B") or tag.startswith("S") or tag.startswith("O"):
sent_out.append(partial_word)
tags_out.append(tag.split("-")[-1])
partial_word = sent[ind]
continue
partial_word += sent[ind]
if len(sent_out) < len(tags_out):
sent_out.append(partial_word)
pred_words = []
for s, t in zip(sent_out, tags_out):
pred_words.append({"item": s, "wordtag_label": t})
result = {"text": sent, "items": pred_words}
batch_results.append(result)
return batch_results
def _simplify_result(self, results):
simple_results = []
for result in results:
simple_result = []
if "items" in result:
for item in result["items"]:
if self.entity_only and item["wordtag_label"] in POS_LABEL_WORDTAG:
continue
simple_result.append((item["item"], item["wordtag_label"]))
simple_results.append(simple_result)
simple_results = simple_results[0] if len(simple_results) == 1 else simple_results
return simple_results
def _postprocess(self, inputs):
"""
The model output is the tag ids, this function will convert the model output to raw text.
"""
results = self._decode(inputs["short_input_texts"], inputs["all_pred_tags"])
results = self._auto_joiner(results, self.input_mapping, is_dict=True)
results = self._simplify_result(results)
return results
class NERLACTask(LacTask):
"""
Part-of-speech tagging task for the raw text.
Args:
task(string): The name of task.
model(string): The model name in the task.
kwargs (dict, optional): Additional keyword arguments passed along to the specific task.
"""
def __init__(self, model, task, entity_only=False, **kwargs):
super().__init__(task=task, model="lac", **kwargs)
self.entity_only = entity_only
def _postprocess(self, inputs):
"""
The model output is the tag ids, this function will convert the model output to raw text.
"""
lengths = inputs["lens"]
preds = inputs["result"]
sents = inputs["text"]
final_results = []
for sent_index in range(len(lengths)):
tags = [self._id2tag_dict[str(index)] for index in preds[sent_index][: lengths[sent_index]]]
sent = sents[sent_index]
if self._custom:
self._custom.parse_customization(sent, tags)
sent_out = []
tags_out = []
parital_word = ""
for ind, tag in enumerate(tags):
if parital_word == "":
parital_word = sent[ind]
tags_out.append(tag.split("-")[0])
continue
if tag.endswith("-B") or (tag == "O" and tags[ind - 1] != "O"):
sent_out.append(parital_word)
tags_out.append(tag.split("-")[0])
parital_word = sent[ind]
continue
parital_word += sent[ind]
if len(sent_out) < len(tags_out):
sent_out.append(parital_word)
result = []
for s, t in zip(sent_out, tags_out):
if self.entity_only and t in POS_LABEL_LAC:
continue
result.append((s, t))
final_results.append(result)
final_results = self._auto_joiner(final_results, self.input_mapping)
final_results = final_results if len(final_results) > 1 else final_results[0]
return final_results