flask中文文档_中文wiki开放式问答系统部署

维基百科预料下载和处理

我们使用一下项目下载并处理中文维基百科语料得到csv

https://github.com/mattzheng/ChineseWiki​github.com

得到的txt我们再用DrQA的document retriever的流程进行下去:

参见:

facebookresearch/DrQA​github.com
3e5593f1b5c5f9fcb8855b84965ea1fa.png

186dc18ecbe9c5211af0c1051a17ea26.png

用下面的代码转换一下,注意到包含】的就是我们的词条,由于bert的文档长度限制以及让模型跟准确,我这里判断了一个条件只要文档长度大于450我们就算一个文档了,特别是我们不希望我们的回答会从百科后面的段落去选择,前面的段落才是百科的重点部分。

import pandas as pd
df = pd.read_csv(r"wiki.csv")
df.columns = ['context','level']
df = df.drop(df[df['context']=='== 参考文献 ==n'].index)
df = df.drop(df[df['context']=='n'].index)
words = df[df['level']==1]['context']

import json
from tqdm import tqdm
import re

sec = []
# total_sec = []
num_count = filename = 0
for num,data in enumerate(tqdm(zip(df['level'],df['context']))):

    level,context = data[0],data[1]
    if len(sec) == 0:
        if level == 1:
            sec = [context]
    elif len(sec)!=0:
        sec.append(context)
    if len(sec)>=4:
        # print('yes')
        sec_dict = {'id':re.sub('n|】|【|=','',''.join(sec[0]))+'|||'+str(num_count),'text':re.sub('n|】|【|=','',''.join(sec[1:]))}
        if len(sec_dict['text'])>450 or level==1:
            if level==1:
                sec = sec[:-1]
            sec_dict = {'id': re.sub('n|】|【|=', '', ''.join(sec[0])) + '|||' + str(num_count),
                        'text': re.sub('n|】|【|=', '', ''.join(sec[1:]))}

            num_count += 1
#             total_sec.append(sec_dict)
#             if filename>20:
            with open(f'data//{filename}.txt','a', encoding='utf-8') as f:
                f.write(json.dumps(sec_dict, ensure_ascii=False) + 'n')
    #                 if len(total_sec)==10:
    #                     break
            sec = []
            if num_count in range(0,1000000000,20000):
                filename +=1
        else:
            pass

然后我们再用DrQA的document retriever的流程先制作一个sqlite数据库,字段就是id和text

python build_db.py /mnt/c/users/nocoo/desktop/chinesewiki-master/data /mnt/c/users/nocoo/desktop/chinesewiki-master/output/output.db

ES引擎搭建

因为drqa用的是英文分词方法,我们需要追踪到分词方法的位置,通过修改源码实现中文分词,这里我使用了结巴,并且把词条名作为我们的词汇表,结巴将不会对这些词分词。

我们通过代码定位drqa的路径

import drqa
print(drqa.__path__)

修改drqa/tokenizers/simple_tokenizer.py,这个是drqa默认的分词方法,添加代码

import jieba
jieba.load_userdict(r'/mnt/c/Users/nocoo/Desktop/ChineseWiki-master/entity.txt')
with open(r'/mnt/d/work/conda-jupyter/stop.txt',encoding = 'utf-8') as f:
    stop = f.read().split()
#对每个text
text = list(set([i for i in jieba.cut(text)])-set(stop))
text = ' '.join(text)
matches = [m for m in self._regexp.finditer(text)]

这样我们就不用大改源码,只要增加一个空格假装自己是英文。

然后再构造向量:

python build_tfidf.py /mnt/c/users/nocoo/desktop/chinesewiki-master/output/output.db /mnt/c/users/nocoo/desktop/chinesewiki-master/output

引擎启动测试

python interactive.py --model /mnt/c/users/nocoo/desktop/chinesewiki-master/output/output-tfidf-ngram=2-hash=16777216-tokenizer=simple.npz

引擎测试

process('question answering', k=5)

8ab6e9de5f29a01285b78c2ff349201e.png

如果搜索专业名词效果还可以。但是搜索人名往往出现问题不能对应到人名的词条,因为人对应的事件会更频繁出现人名。

18dd8674ecbd78459035e475783a1a08.png

下面这个代码让我们可以通过drqa得到应该查询的文档id

from drqa import retriever
ranker = retriever.get_class('tfidf')(tfidf_path=r'/mnt/c/users/nocoo/desktop/chinesewiki-master/output/output-tfidf-ngram=2-hash=16777216-tokenizer=simple.npz')
doc_name= ranker.closest_docs('蜘蛛侠', 1)[0][0]

drqa只需要2G内存,BM25需要4G内存,我们还是用drqa用ES做的搜索吧

这里我增加了一个功能,如果问题中出现了实体,则优先查询实体,如果没有出现实体则使用es文档搜索。方法是使用我们的实体表(每个维基百科的百科词条名),看问题的每个分词是否在实体表中,其中分词我们已经使用了我们的实体表作为分词表了。

系统肯定是慢慢优化的,我们先上线系统吧。

我们需要把代码对接上torchserve的handler

cp -r /mnt/d/work/conda-jupyter/torchserve_package/cmrc2018 /home/nocoolsandwich/work/cmrc2018torchserve/cmrc2018
cd cmrc2018
torch-model-archiver --model-name CMRC2018 --version 1.0 --serialized-file ./checkpoint_score_f1-86.233_em-66.853.pth --handler ./Transformer_handler_generalized.py --extra-files "./setup_config.json,./output-tfidf-ngram=2-hash=16777216-tokenizer=simple.npz,./inference.py,./output.db,./official_tokenization.py,./entity.txt"
mkdir model_store
mv CMRC2018.mar model_store/
torchserve --start --model-store model_store --models my_tc=CMRC2018.mar --no-config-snapshots

模型过大我们要限制一下woker

curl -v -X PUT "http://localhost:8081/models/my_tc?min_worker=1"

测试一下

fe22ef72533378366c8e5af03e8a0fc0.png

586842be86108e88e347b68aa93448c7.png

785bcc8d19ad2b0713e7b7924d43c2b8.png

效果还行吧,接下来我们对接上这个为DrQA前端设计的项目,用的是flask。

cp -r /mnt/c/users/nocoo/desktop/drqa-webui-master  /home/nocoolsandwich/work/cmrc2018torchserve/drqa-webui-master

遇到gunicorn 再次无法再次重启的解决方案

gunicorn --timeout 300 index:app
gunicorn index:app --preload

023f3df4fc6bc13ec635aba1e4b13f0d.png

d629cbedbaef80f08d251f756eca805b.png

9363d2ff0ef70a78f76109c6f0a9f12c.png

c81e55338f991985b4276db245dd0a72.png

当当~,那么我们的中文DrQA就打造成功。

等周末我再整理整理,先发布文章啦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值