问答模型(十一) reader部署

使用Flask框架将预训练的PaddleNLP BERT模型部署为API,实现实时问答与答案置信度计算。输入查询和上下文,获取精准答案及其概率评估。

使用flask将最开始训练好的paddle框架的阅读理解部署到本地,向前端同学开放输入query及context后返回answer及答案置信度的api

import hashlib
import os
import random

from paddlenlp.datasets import load_dataset
import paddlenlp as ppnlp
from utils import prepare_train_features, prepare_validation_features
from functools import partial
from paddlenlp.metrics.squad import squad_evaluate, compute_prediction
from paddle.static import InputSpec
import collections
import time
import json
import paddle
from paddlenlp.data import Stack, Dict, Pad
import copy
from flask import Flask, request, Response
import flask
import json


MODEL_NAME = "bert-base-chinese"
model = ppnlp.transformers.BertForQuestionAnswering.from_pretrained(MODEL_NAME)
model_state_dict = paddle.load("checkpoint_raw8_2/model_state.pdparams")
model.set_state_dict(model_state_dict)


max_seq_length = 512
doc_stride = 128
_, dev_ds1 = ppnlp.datasets.load_dataset('dureader_robust', splits=('train', 'dev'))
_ = ""
tokenizer = ppnlp.transformers.BertTokenizer.from_pretrained(MODEL_NAME)
test_batchify_fn = lambda samples, fn=Dict({
    "input_ids": Pad(axis=0, pad_val=tokenizer.pad_token_id),
    "token_type_ids": Pad(axis=0, pad_val=tokenizer.pad_token_type_id)
}): fn(samples)

model.eval()

app = flask.Flask(__name__)
resutn_save = {}
@app.route("/gen", methods=["POST"])
def gen():
    r = request.data
    rjson = json.loads(r)

    test_ds = copy.deepcopy(dev_ds1)
    test_ds.data = [test_ds.data[0]]
    test_ds.new_data = [test_ds.new_data[0]]
    test_ds.data[0][
        "context"] = rjson["contexts"]
    test_ds.data[0]["question"] = rjson["questions"]
    test_ds.data[0]["answer"] = ''
    test_ds.data[0]["answer_starts"] = []
    test_ds.new_data = copy.deepcopy(test_ds.data)

    test_trans_func = partial(prepare_validation_features,
                              max_seq_length=max_seq_length,
                              doc_stride=doc_stride,
                              tokenizer=tokenizer)

    test_ds = test_ds.map(test_trans_func, batched=True)
    test_batch_sampler = paddle.io.BatchSampler(
        test_ds, batch_size=1, shuffle=False)

    test_data_loader = paddle.io.DataLoader(
        dataset=test_ds,
        batch_sampler=test_batch_sampler,
        collate_fn=test_batchify_fn,
        return_list=True)

    data_loader = test_data_loader

    all_start_logits = []
    all_end_logits = []
    tic_eval = time.time()

    for i, batch in enumerate(data_loader):
        input_ids, token_type_ids = batch

        start_logits_tensor, end_logits_tensor = model(input_ids,
                                                       token_type_ids)

        for idx in range(start_logits_tensor.shape[0]):
            if len(all_start_logits) % 1000 == 0 and len(all_start_logits):
                print("Processing example: %d" % len(all_start_logits))
                print('time per 1000:', time.time() - tic_eval)
                tic_eval = time.time()

            all_start_logits.append(start_logits_tensor.numpy()[idx])
            all_end_logits.append(end_logits_tensor.numpy()[idx])
    all_predictions, scores, _ = compute_prediction(
        data_loader.dataset.data, data_loader.dataset.new_data,
        (all_start_logits, all_end_logits), False, 20, 30)

    squad_evaluate(
        examples=data_loader.dataset.data,
        preds=all_predictions,
        is_whitespace_splited=False)
    for example in data_loader.dataset.data:
        # print()
        # print('问题:', example['question'])
        # print('原文:', ''.join(example['context']))
        # print('答案:', all_predictions[example['id']])

        answer =  all_predictions[example['id']]

        break
    score = 0
    for i in scores:
        score = scores[i][0]['probability']

    a = {"result": answer, "proba": score}

    # a = {"result":answer}


    response_pickled = json.dumps(a)



    return  Response(response=response_pickled, status=200, mimetype="application/json")


if __name__ == "__main__":

    app.run(host="xx.xx.xxx.xxx", port=xxxx)

api测试

# coding:utf-8

import requests
import json


def get_ans(question, contexts):
    # data = "{\"question\":" + question + ", \"contexts:\"" + contexts + "}"
    print(question)
    print(contexts)
    data = {"questions": question, "contexts": contexts}
    print(data)
    data = json.dumps(data)
    r = requests.post("http://xx.xx.xxx.xxx:xxxx/gen", data=data)
    print("r:", r.json())
    return r.json


question = "泥鳅怎么做"
context = "从中医的角度讲,泥鳅有很高的药用价值,能补中益气、养肾生精。非常适宜身体虚弱、脾胃虚寒、体虚盗汗的人食用,对某些急性肝炎的治疗也十分有益。而从现代营养学的角度分析,泥鳅是鱼类里的补钙冠军,同等重量下,泥鳅的钙含量是鲤鱼的近6倍,是带鱼的10倍左右。泥鳅同时富含有利于钙吸收的维生素,因此是很好的补钙食物。此外,泥鳅还富含亚精胺和核苷,能增加皮肤弹性和湿润度,并提高身体的抗病毒能力。建议采用清蒸或炖煮的方式烹调泥鳅,这样能够较好地保存其营养价值,如果能搭配豆腐一起吃,补钙效果会更好。"
print(get_ans(question, context))

输出如下

泥鳅怎么做
从中医的角度讲,泥鳅有很高的药用价值,能补中益气、养肾生精。非常适宜身体虚弱、脾胃虚寒、体虚盗汗的人食用,对某些急性肝炎的治疗也十分有益。而从现代营养学的角度分析,泥鳅是鱼类里的补钙冠军,同等重量下,泥鳅的钙含量是鲤鱼的近6倍,是带鱼的10倍左右。泥鳅同时富含有利于钙吸收的维生素,因此是很好的补钙食物。此外,泥鳅还富含亚精胺和核苷,能增加皮肤弹性和湿润度,并提高身体的抗病毒能力。建议采用清蒸或炖煮的方式烹调泥鳅,这样能够较好地保存其营养价值,如果能搭配豆腐一起吃,补钙效果会更好。
{'questions': '泥鳅怎么做', 'contexts': '从中医的角度讲,泥鳅有很高的药用价值,能补中益气、养肾生精。非常适宜身体虚弱、脾胃虚寒、体虚盗汗的人食用,对某些急性肝炎的治疗也十分有益。而从现代营养学的角度分析,泥鳅是鱼类里的补钙冠军,同等重量下,泥鳅的钙含量是鲤鱼的近6倍,是带鱼的10倍左右。泥鳅同时富含有利于钙吸收的维生素,因此是很好的补钙食物。此外,泥鳅还富含亚精胺和核苷,能增加皮肤弹性和湿润度,并提高身体的抗病毒能力。建议采用清蒸或炖煮的方式烹调泥鳅,这样能够较好地保存其营养价值,如果能搭配豆腐一起吃,补钙效果会更好。'}
r: {'result': '清蒸或炖煮', 'proba': 0.470887690782547}
<bound method Response.json of <Response [200]>>
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值