使用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]>>