CoolFace
Apppublic

cooelf/Retro-Reader

sourceHugging Faceapache-2.0updated 3y agoView on Hugging Face
1likes
app.py202 linesDownload Raw Back to root
1import torch2from transformers import AlbertTokenizer, AlbertForSequenceClassification, AlbertForQuestionAnswering3import collections4import math5import gradio as gr6 7cls_modelPath = "./cls_model"8mrc_modelPath = "./model4"9 10tokenizer = AlbertTokenizer.from_pretrained(mrc_modelPath)11cls_model = AlbertForSequenceClassification.from_pretrained(cls_modelPath)12cls_model.eval()13mrc_model = AlbertForQuestionAnswering.from_pretrained(mrc_modelPath)14mrc_model.eval()15 16def _get_best_indexes(logits, n_best_size):17    """Get the n-best logits from a list."""18    index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse=True)19 20    best_indexes = []21    for i in range(len(index_and_score)):22        if i >= n_best_size:23            break24        best_indexes.append(index_and_score[i][0])25    return best_indexes26 27def _compute_softmax(scores):28    """Compute softmax probability over raw logits."""29    if not scores:30        return []31 32    max_score = None33    for score in scores:34        if max_score is None or score > max_score:35            max_score = score36 37    exp_scores = []38    total_sum = 0.039    for score in scores:40        x = math.exp(score - max_score)41        exp_scores.append(x)42        total_sum += x43 44    probs = []45    for score in exp_scores:46        probs.append(score / total_sum)47    return probs48 49def get_qa_nbest(input_ids, start_logits, end_logits, seq_len, n_best_size=20, max_answer_length=30):50    score_null = 1000000  # large and positive51    prelim_predictions = []52    null_start_logit = 0  # the start logit at the slice with min null score53    null_end_logit = 0  # the end logit at the slice with min null score54    _PrelimPrediction = collections.namedtuple(  # pylint: disable=invalid-name55        "PrelimPrediction",56        ["start_index", "end_index", "start_logit", "end_logit"])57    _NbestPrediction = collections.namedtuple(  # pylint: disable=invalid-name58            "NbestPrediction", ["text", "start_logit", "end_logit"])59    60    start_indexes = _get_best_indexes(start_logits, n_best_size)61    end_indexes = _get_best_indexes(end_logits, n_best_size)62 63    feature_null_score = start_logits[0] + end_logits[0]64    if feature_null_score < score_null:65        score_null = feature_null_score66    for start_index in start_indexes:67        for end_index in end_indexes:68            if end_index < start_index:69                continue70            length = end_index - start_index + 171            if length > max_answer_length:72                continue73            if start_index >= seq_len:74                        continue75            if end_index >= seq_len:76                continue77            prelim_predictions.append(78                _PrelimPrediction(79                    start_index=start_index,80                    end_index=end_index,81                    start_logit=start_logits[start_index],82                    end_logit=end_logits[end_index]))83    prelim_predictions = sorted(84            prelim_predictions,85            key=lambda x: (x.start_logit + x.start_logit),86            reverse=True)87    88    seen_predictions = {}89    nbest = []90    for pred in prelim_predictions:91        if len(nbest) >= n_best_size:92            break93        94        if pred.start_index > 0:  # this is a non-null prediction\95            predict_answer_tokens = input_ids[0, pred.start_index: (pred.end_index + 1)]96            final_text = tokenizer.decode(predict_answer_tokens)97            if final_text in seen_predictions:98                continue99            seen_predictions[final_text] = True100        else:101            final_text = ""102            seen_predictions[final_text] = True103        104 105        nbest.append(106                _NbestPrediction(107                    text=final_text,108                    start_logit=pred.start_logit,109                    end_logit=pred.end_logit))110    if "" not in seen_predictions:111        nbest.append(112            _NbestPrediction(113                text="",114                start_logit=null_start_logit,115                end_logit=null_end_logit))116 117            # In very rare edge cases we could only have single null prediction.118            # So we just create a nonce prediction in this case to avoid failure.119    if len(nbest) == 1:120        nbest.insert(0,121            _NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0))122 123    # In very rare edge cases we could have no valid predictions. So we124    # just create a nonce prediction in this case to avoid failure.125    if not nbest:126        nbest.append(127            _NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0))128 129 130    total_scores = []131    best_non_null_entry = None132    for entry in nbest:133        total_scores.append(entry.start_logit + entry.end_logit)134        if not best_non_null_entry:135            if entry.text:136                best_non_null_entry = entry137 138    probs = _compute_softmax(total_scores)139    nbest_json = []140    for (i, entry) in enumerate(nbest):141        output = collections.OrderedDict()142        output["text"] = entry.text143        output["probability"] = probs[i]144        output["start_logit"] = entry.start_logit145        output["end_logit"] = entry.end_logit146        nbest_json.append(output)147 148    score_diff = score_null - best_non_null_entry.start_logit - (149                best_non_null_entry.end_logit)150    151    return nbest_json, score_diff152 153def inference(context, question, reference):154    inputs = tokenizer(155                question,156                context,157                add_special_tokens=True,158                pad_to_max_length=True,159                max_length=512,160                return_tensors="pt"161            )162 163    seq_len = inputs.input_ids[0].tolist().index(0)164 165    with torch.no_grad():166        cls_outputs = cls_model(**inputs)167        qa_outputs = mrc_model(**inputs)168 169    cls_logits = cls_outputs.logits[0]170    cls_divide = cls_logits[1] - cls_logits[0]171 172 173    nbest, score_diff = get_qa_nbest(inputs.input_ids, qa_outputs.start_logits[0], qa_outputs.end_logits[0], seq_len=seq_len)174 175    thresh = -1.246073067188263176 177    print(cls_divide, score_diff)178 179    na_score = (0.5*cls_divide + 0.5*score_diff)*0.5180    if na_score > thresh:181        final_answer = f"<No Answer>. The question is not answerable according to the context."182    else:183        final_answer = nbest[0]["text"]184    return final_answer185 186demo = gr.Interface(187    fn=inference,188    inputs=[gr.inputs.Textbox(label="Context"), 189            gr.inputs.Textbox(label="Question"),190            gr.inputs.Textbox(label="Reference Answer (Optional)")],191    outputs=gr.outputs.Textbox(label="Output Answer"),192    examples = [193    ["The Norman dynasty had a major political, cultural and military impact on medieval Europe and even the Near East. The Normans were famed for their martial spirit and eventually for their Christian piety, becoming exponents of the Catholic orthodoxy into which they assimilated. They adopted the Gallo-Romance language of the Frankish land they settled, their dialect becoming known as Norman, Normaund or Norman French, an important literary language. The Duchy of Normandy, which they formed by treaty with the French crown, was a great fief of medieval France, and under Richard I of Normandy was forged into a cohesive and formidable principality in feudal tenure. The Normans are noted both for their culture, such as their unique Romanesque architecture and musical traditions, and for their significant military accomplishments and innovations. Norman adventurers founded the Kingdom of Sicily under Roger II after conquering southern Italy on the Saracens and Byzantines, and an expedition on behalf of their duke, William the Conqueror, led to the Norman conquest of England at the Battle of Hastings in 1066. Norman cultural and military influence spread from these new European centres to the Crusader states of the Near East, where their prince Bohemond I founded the Principality of Antioch in the Levant, to Scotland and Wales in Great Britain, to Ireland, and to the coasts of north Africa and the Canary Islands.", "Who was the duke in the battle of Hastings?", "William the Conqueror"],194    ["The Norman dynasty had a major political, cultural and military impact on medieval Europe and even the Near East. The Normans were famed for their martial spirit and eventually for their Christian piety, becoming exponents of the Catholic orthodoxy into which they assimilated. They adopted the Gallo-Romance language of the Frankish land they settled, their dialect becoming known as Norman, Normaund or Norman French, an important literary language. The Duchy of Normandy, which they formed by treaty with the French crown, was a great fief of medieval France, and under Richard I of Normandy was forged into a cohesive and formidable principality in feudal tenure. The Normans are noted both for their culture, such as their unique Romanesque architecture and musical traditions, and for their significant military accomplishments and innovations. Norman adventurers founded the Kingdom of Sicily under Roger II after conquering southern Italy on the Saracens and Byzantines, and an expedition on behalf of their duke, William the Conqueror, led to the Norman conquest of England at the Battle of Hastings in 1066. Norman cultural and military influence spread from these new European centres to the Crusader states of the Near East, where their prince Bohemond I founded the Principality of Antioch in the Levant, to Scotland and Wales in Great Britain, to Ireland, and to the coasts of north Africa and the Canary Islands.", "What type of major impact did the Norman dynasty have on modern Europe?", "<No Answer>"],195    ["Steam engines are external combustion engines, where the working fluid is separate from the combustion products. Non-combustion heat sources such as solar power, nuclear power or geothermal energy may be used. The ideal thermodynamic cycle used to analyze this process is called the Rankine cycle. In the cycle, water is heated and transforms into steam within a boiler operating at a high pressure. When expanded through pistons or turbines, mechanical work is done. The reduced-pressure steam is then condensed and pumped back into the boiler.", "What types of engines are steam engines?", "external combustion engines"],196    ["Steam engines are external combustion engines, where the working fluid is separate from the combustion products. Non-combustion heat sources such as solar power, nuclear power or geothermal energy may be used. The ideal thermodynamic cycle used to analyze this process is called the Rankine cycle. In the cycle, water is heated and transforms into steam within a boiler operating at a high pressure. When expanded through pistons or turbines, mechanical work is done. The reduced-pressure steam is then condensed and pumped back into the boiler.", "What ideal thermodynamic cycle analyzes the process by which solar engines work?", "<No Answer>"],197    ],198    title="Retrospective Reader for Machine Reading Comprehension",199    description=("<div style='text-align: center; margin: 0 auto;'>The model achieved the best performance at the SQuAD2.0 leaderboard. See more details at: <a href='https://aaai.org/papers/14506-retrospective-reader-for-machine-reading-comprehension/'>Paper</a> and <a href='https://github.com/cooelf/AwesomeMRC'>GitHub</a></div>"),200    )201 202demo.launch(debug=True)