diff --git a/MindIE/MindIE-Torch/built-in/nlp/BERT/LICENSE b/MindIE/MindIE-Torch/built-in/nlp/BERT/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..a0e03103591c1158a839681f3c404ee9118b182e --- /dev/null +++ b/MindIE/MindIE-Torch/built-in/nlp/BERT/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/MindIE/MindIE-Torch/built-in/nlp/BERT/aie_compile.py b/MindIE/MindIE-Torch/built-in/nlp/BERT/aie_compile.py new file mode 100644 index 0000000000000000000000000000000000000000..e5de28e9e3337e0af6cea09a9b84e439ec431e37 --- /dev/null +++ b/MindIE/MindIE-Torch/built-in/nlp/BERT/aie_compile.py @@ -0,0 +1,145 @@ +# Copyright(C) 2023. Huawei Technologies Co.,Ltd. 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 +# +# https://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 sys +import os +import argparse +import torch +import mindietorch +from mindietorch import _enums + +sys.path.append("./DeepLearningExamples/PyTorch/LanguageModeling/BERT/") +import modeling + + +COSINE_THRESHOLD = 0.99 + + +def cosine_similarity(gt_tensor, pred_tensor): + gt_tensor = gt_tensor.flatten().to(torch.float32) + pred_tensor = pred_tensor.flatten().to(torch.float32) + if torch.sum(gt_tensor) == 0.0 or torch.sum(pred_tensor) == 0.0: + if torch.allclose(gt_tensor, pred_tensor, atol=1e-4, rtol=1e-4, equal_nan=True): + return 1.0 + res = torch.nn.functional.cosine_similarity(gt_tensor, pred_tensor, dim=0, eps=1e-6) + res = res.cpu().detach().item() + return res + + +def aie_compile(torch_model, args): + input_shape = (args.batch_size, args.max_seq_length) + input_ids = torch.randint(high=1, size=input_shape, dtype=torch.int32) + segment_ids = torch.randint(high=1, size=input_shape, dtype=torch.int32) + input_mask = torch.randint(high=5, size=input_shape, dtype=torch.int32) + input_data = [input_ids, + segment_ids, + input_mask] + + # trace model + print("trace start. ") + traced_model = torch.jit.trace(torch_model, input_data) + print("trace done. ") + # print("traced model is ", traced_model.graph) + + traced_model.eval() + print("mindietorch compile start !") + mindietorch.set_device(0) + compile_inputs = [mindietorch.Input(shape=input_shape, dtype=torch.int32, format=mindietorch.TensorFormat.ND), + mindietorch.Input(shape=input_shape, dtype=torch.int32, format=mindietorch.TensorFormat.ND), + mindietorch.Input(shape=input_shape, dtype=torch.int32, format=mindietorch.TensorFormat.ND)] + compiled_model = mindietorch.compile( + traced_model, + inputs=compile_inputs, + precision_policy=_enums.PrecisionPolicy.FP16, + soc_version="Ascend310P3", + optimization_level=args.op_level + ) + print("mindietorch compile done !") + print("compiled model is ", compiled_model.graph) + compiled_model.save(args.pt_dir) + print("torch aie compiled model saved. ") + + if args.compare_cpu: + print("start to check the percision of npu model.") + com_res = True + compiled_model = torch.jit.load(args.pt_dir) + jit_res = traced_model(input_ids, segment_ids, input_mask) + print("jit infer done !") + input_ids_npu = input_ids.to("npu:0") + segment_ids_npu = segment_ids.to("npu:0") + input_mask_npu = input_mask.to("npu:0") + aie_res = compiled_model(input_ids_npu, segment_ids_npu, input_mask_npu) + aie_res_cpu = tuple(element.to("cpu")for element in aie_res) + print("aie infer done !") + + for j, a in zip(jit_res, aie_res_cpu): + res = cosine_similarity(j, a) + print(res) + if res < COSINE_THRESHOLD: + com_res = False + + if com_res: + print("Compare success ! NPU model have the same output with CPU model !") + else: + print("Compare failed ! Outputs of NPU model are not the same with CPU model !") + return + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + ## Required parameters + parser.add_argument("--torch_pt", + default="./bert_base_qa.pt", + type=str, + help="The original torch pt file from pretraining") + parser.add_argument("--save_dir", + default="./", + type=str, + help="The path of the directory that stores the compiled model") + parser.add_argument("--config_file", + default="./bert_config.json", + type=str, + help="The BERT model config") + parser.add_argument('--batch_size', + default=8, + type=int, + help="batch size") + parser.add_argument('--max_seq_length', + default=512, + type=int, + help="position embedding length") + parser.add_argument('--op_level', + default=0, + type=int, + help="optimization level in the compile spec ") + parser.add_argument("--compare_cpu", action='store_true', + help="Whether to check the percision of npu model.") + args = parser.parse_args() + + output_root = args.save_dir + if not os.path.exists(output_root): + os.makedirs(output_root) + + args.pt_dir = os.path.join(output_root, "bert_base_batch_{}.pt".format(args.batch_size)) + config = modeling.BertConfig.from_json_file(args.config_file) + if config.vocab_size % 8 != 0: + config.vocab_size += 8 - (config.vocab_size % 8) + torch_model = modeling.BertForQuestionAnswering(config) + torch_model.load_state_dict(torch.load(args.torch_pt, map_location='cpu')["model"]) + torch_model.to("cpu").eval() + + aie_compile(torch_model, args) + mindietorch.finalize() + + + diff --git a/MindIE/MindIE-Torch/built-in/nlp/BERT/bert_config.json b/MindIE/MindIE-Torch/built-in/nlp/BERT/bert_config.json new file mode 100644 index 0000000000000000000000000000000000000000..fca794a5f07ff8f963fe8b61e3694b0fb7f955df --- /dev/null +++ b/MindIE/MindIE-Torch/built-in/nlp/BERT/bert_config.json @@ -0,0 +1,13 @@ +{ + "attention_probs_dropout_prob": 0.1, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "hidden_size": 768, + "initializer_range": 0.02, + "intermediate_size": 3072, + "max_position_embeddings": 512, + "num_attention_heads": 12, + "num_hidden_layers": 12, + "type_vocab_size": 2, + "vocab_size": 30522 +} diff --git a/MindIE/MindIE-Torch/built-in/nlp/BERT/evaluate_data.py b/MindIE/MindIE-Torch/built-in/nlp/BERT/evaluate_data.py new file mode 100644 index 0000000000000000000000000000000000000000..32913df5975676dadf0cba4b007a1ef53ef59bf4 --- /dev/null +++ b/MindIE/MindIE-Torch/built-in/nlp/BERT/evaluate_data.py @@ -0,0 +1,108 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# 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 +# +# https://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. +# ============================================================================ +""" Official evaluation script for v1.1 of the SQuAD dataset. """ +from __future__ import print_function +from collections import Counter +import string +import re +import argparse +import json +import sys + + +def normalize_answer(s): + """Lower text and remove punctuation, articles and extra whitespace.""" + def remove_articles(text): + return re.sub(r'\b(a|an|the)\b', ' ', text) + + def white_space_fix(text): + return ' '.join(text.split()) + + def remove_punc(text): + exclude = set(string.punctuation) + return ''.join(ch for ch in text if ch not in exclude) + + def lower(text): + return text.lower() + + return white_space_fix(remove_articles(remove_punc(lower(s)))) + + +def f1_score(prediction, ground_truth): + prediction_tokens = normalize_answer(prediction).split() + ground_truth_tokens = normalize_answer(ground_truth).split() + common = Counter(prediction_tokens) & Counter(ground_truth_tokens) + num_same = sum(common.values()) + if num_same == 0: + return 0 + precision = 1.0 * num_same / len(prediction_tokens) + recall = 1.0 * num_same / len(ground_truth_tokens) + f1 = (2 * precision * recall) / (precision + recall) + return f1 + + +def exact_match_score(prediction, ground_truth): + return (normalize_answer(prediction) == normalize_answer(ground_truth)) + + +def metric_max_over_ground_truths(metric_fn, prediction, ground_truths): + scores_for_ground_truths = [] + for ground_truth in ground_truths: + score = metric_fn(prediction, ground_truth) + scores_for_ground_truths.append(score) + return max(scores_for_ground_truths) + + +def evaluate(dataset, predictions): + f1 = exact_match = total = 0 + for article in dataset: + for paragraph in article['paragraphs']: + for qa in paragraph['qas']: + total += 1 + if qa['id'] not in predictions: + message = 'Unanswered question ' + qa['id'] + \ + ' will receive score 0.' + print(message, file=sys.stderr) + continue + ground_truths = list(map(lambda x: x['text'], qa['answers'])) + prediction = predictions[qa['id']] + exact_match += metric_max_over_ground_truths( + exact_match_score, prediction, ground_truths) + f1 += metric_max_over_ground_truths( + f1_score, prediction, ground_truths) + + exact_match = 100.0 * exact_match / total + f1 = 100.0 * f1 / total + + return {'exact_match': exact_match, 'f1': f1} + + +if __name__ == '__main__': + expected_version = '1.1' + parser = argparse.ArgumentParser( + description='Evaluation for SQuAD ' + expected_version) + parser.add_argument('dataset_file', help='Dataset file') + parser.add_argument('prediction_file', help='Prediction File') + args = parser.parse_args() + with open(args.dataset_file) as dataset_file: + dataset_json = json.load(dataset_file) + if (dataset_json['version'] != expected_version): + print('Evaluation expects v-' + expected_version + + ', but got dataset with v-' + dataset_json['version'], + file=sys.stderr) + dataset = dataset_json['data'] + with open(args.prediction_file) as prediction_file: + predictions = json.load(prediction_file) + print(json.dumps(evaluate(dataset, predictions))) diff --git a/MindIE/MindIE-Torch/built-in/nlp/BERT/requirements.txt b/MindIE/MindIE-Torch/built-in/nlp/BERT/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..a18696488efb37dbffecc82633206cce088481ea --- /dev/null +++ b/MindIE/MindIE-Torch/built-in/nlp/BERT/requirements.txt @@ -0,0 +1,10 @@ +torch==2.1.0 +numpy +boto3 +tqdm +requests +decorator +attrs +psutil +absl-py +tensorflow>=1.10.0 \ No newline at end of file