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

143 lines
4.9 KiB
Python

# Copyright (c) 2022 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.
import re
from io import BytesIO
import numpy as np
import paddle
from PIL import Image
from ..metrics import SpanEvaluator
from .image_utils import NormalizeImage, Permute, ResizeImage
resize_func = ResizeImage(target_size=224, interp=1)
norm_func = NormalizeImage(is_channel_first=False, mean=[123.675, 116.280, 103.530], std=[58.395, 57.120, 57.375])
permute_func = Permute(to_bgr=False)
def map_offset(ori_offset, offset_mapping):
"""
map ori offset to token offset
"""
for index, span in enumerate(offset_mapping):
if span[0] <= ori_offset < span[1]:
return index
return -1
def pad_image_data(image_data):
if not image_data:
image = np.zeros([3, 224, 224])
return image
# decode image
data = np.frombuffer(bytearray(image_data), dtype="uint8")
image = np.array(Image.open(BytesIO(data)).convert("RGB"))
sample = {"image": image}
# resize image
sample = resize_func(sample)
# norm image
sample = norm_func(sample)
# permute
sample = permute_func(sample)
return sample["image"]
def unify_prompt_name(prompt):
# The classification labels are shuffled during finetuning, so they need
# to be unified during evaluation.
if re.search(r"\[.*?\]$", prompt):
prompt_prefix = prompt[: prompt.find("[", 1)]
cls_options = re.search(r"\[.*?\]$", prompt).group()[1:-1].split(",")
cls_options = sorted(list(set(cls_options)))
cls_options = ",".join(cls_options)
prompt = prompt_prefix + "[" + cls_options + "]"
return prompt
return prompt
def get_relation_type_dict(relation_data, schema_lang="ch"):
def compare(a, b, schema_lang="ch"):
if schema_lang == "ch":
a = a[::-1]
b = b[::-1]
res = ""
for i in range(min(len(a), len(b))):
if a[i] == b[i]:
res += a[i]
else:
break
if res == "":
return res
if schema_lang == "ch" and res[::-1][0] == "的":
return res[::-1][1:]
elif schema_lang == "en" and res[-3:] == " of":
return res[:-3]
return ""
relation_type_dict = {}
added_list = []
for i in range(len(relation_data)):
added = False
if relation_data[i][0] not in added_list:
for j in range(i + 1, len(relation_data)):
match = compare(relation_data[i][0], relation_data[j][0], schema_lang=schema_lang)
if match != "":
match = unify_prompt_name(match)
if relation_data[i][0] not in added_list:
added_list.append(relation_data[i][0])
relation_type_dict.setdefault(match, []).append(relation_data[i][1])
added_list.append(relation_data[j][0])
relation_type_dict.setdefault(match, []).append(relation_data[j][1])
added = True
if not added:
added_list.append(relation_data[i][0])
if schema_lang == "ch":
suffix = relation_data[i][0].rsplit("的", 1)[1]
suffix = unify_prompt_name(suffix)
relation_type = suffix
else:
prefix = relation_data[i][0].split(" of ", 1)[0]
prefix = unify_prompt_name(prefix)
relation_type = prefix
relation_type_dict.setdefault(relation_type, []).append(relation_data[i][1])
return relation_type_dict
def uie_loss_func(outputs, labels):
criterion = paddle.nn.BCELoss()
start_ids, end_ids = labels
start_prob, end_prob = outputs
start_ids = paddle.cast(start_ids, "float32")
end_ids = paddle.cast(end_ids, "float32")
loss_start = criterion(start_prob, start_ids)
loss_end = criterion(end_prob, end_ids)
loss = (loss_start + loss_end) / 2.0
return loss
def compute_metrics(p):
metric = SpanEvaluator()
start_prob, end_prob = p.predictions
start_ids, end_ids = p.label_ids
metric.reset()
num_correct, num_infer, num_label = metric.compute(start_prob, end_prob, start_ids, end_ids)
metric.update(num_correct, num_infer, num_label)
precision, recall, f1 = metric.accumulate()
metric.reset()
return {"precision": precision, "recall": recall, "f1": f1}