Python教你用Bert搭建问答搜索引擎,3分钟创造多项记录,取得stateoftheart结果。但是很多深度学习新手发现BERT模型搭建起来并不容易,上手难度很大。普通人可能需要几天才能勉强建立一个模型。没关系,我们今天介绍的这个模块,可以让你在3分钟内搭建一个基于BERT算法的问答搜索引擎。它是bert-as-service项目。这个开源项目可以让你快速搭建基于多GPU机器的BERT服务(支持微调模型),并允许多个客户端并发使用。1.在开始之前,您需要确保您的计算机上已经成功安装了Python和pip。(方案一)如果使用Python进行数据分析,可以直接安装Anaconda,Anaconda内置了Python和pip。(方案二)另外,推荐大家使用VSCode编辑器,优点很多。请选择以下方式之一输入命令安装依赖项:Windows环境打开Cmd(开始-运行-CMD)。MacOS环境打开Terminal(command+空格进入Terminal)。如果您使用的是VSCode编辑器或Pycharm,则可以直接使用界面底部的Terminal。pipinstallbert-serving-server#服务器端pipinstallbert-serving-client#客户端请注意服务器版本要求:Python>=3.5,Tensorflow>=1.10。另外,下载预训练好的BERT模型。也可以在Python实战宝典后台回复bert-as-service下载这些预训练好的模型。下载完成后,将zip文件解压到一个文件夹中,如/tmp/english_L-12_H-768_A-12/2.Bert-as-service基本使用安装完成后,输入以下命令启动BERTservice:bert-serving-start-model_dir/tmp/english_L-12_H-768_A-12/-num_worker=4-num_worker=4意味着这将启动一个有四个工人的服务,这意味着它最多可以处理四个并发请求。超过4个其他并发请求将在负载均衡器中排队等待处理。以下是正确启动时服务器的样子:使用客户端获取句子的编码现在您可以像这样简单地对句子进行编码:frombert_serving.clientimportBertClientbc=BertClient()bc.encode(['Firstdoit','然后做对','然后做得更好'])作为BERT的一个特性,你可以通过用|||连接一对句子来得到它们的编码。(前后空格),例如公元前。encode(['Firstdoit|||thendoitright'])要远程使用BERT服务,您还可以在一台(GPU)机器上启动该服务,然后从另一台(CPU)机器上调用它,如下所示示例:#onanotherCPU机器frombert_serving.clientimportBertClientbc=BertClient(ip='xx.xx.xx.xx')#GPU机器的ip地址bc.encode(['先做','然后做对','然后做itbetter'])3.构建问答搜索引擎我们将使用bert-as-service从FAQ列表中找到与用户输入的问题最相似的问题,并返回相应的答案。也可以回复bert-as-service下载Python实战宝典后台FAQ列表。首先,加载所有问题,并显示统计信息:prefix_q='#####**Q:**'withopen('README.md')asfp:questions=[v.replace(prefix_q,'')。strip()forvinfpifv.strip()andv.startswith(prefix_q)]print('%dquestionsloaded,avg.lenof%d'%(len(questions),np.mean([len(d.split())fordinquestions])))#加载了33个问题,平均。lenof9一共加载了33题,平均长度为9。然后使用预训练模型:uncased_L-12_H-768_A-12启动一个Bert服务:bert-serving-start-num_worker=1-model_dir=/data/cips/data/lab/data/model/uncased_L-12_H-768_A-12接下来,将我们的问题编码为向量:bc=BertClient(port=4000,port_out=4001)doc_vecs=bc.encode(questions)最后,我们已准备好接收用户查询并对现有问题执行简单的“模糊”搜索。为此,每次有新查询进入时,我们将其编码为向量并计算其点积doc_vecs,然后按降序对结果进行排序,返回前N个相似问题:whileTrue:query=input('yourquestion:')query_vec=bc.encode([query])[0]#将标准化点积计算为分数score=np.sum(query_vec*doc_vecs,axis=1)/np.linalg.norm(doc_vecs,axis=1)topk_idx=np.argsort(score)[::-1][:topk]foridxintopk_idx:print('>%s\t%s'%(score[idx],questions[idx]))完成!现在运行代码,输入你的query,看看这个搜索引擎是如何处理模糊匹配的:完整代码如下,共23行代码(后台回复关键词也可以下载):importnumpyasnpfrombert_serving.clientimportBertClientfromtermcolorimportcoloredprefix_q='#####**Q:**'topk=5withopen('README.md')asfp:questions=[v.replace(prefix_q,'').strip()forvinfpifv.strip()andv.startswith(prefix_q)]print('%dquestionsloaded,avg.lenof%d'%(len(questions),np.mean([len(d.split())fordinquestions])))withBertClient(port=4000,port_out=4001)asbc:doc_vecs=bc.encode(questions)whileTrue:query=input(colored('yourquestion:','green'))query_vec=bc.encode([query])[0]#将标准化点积计算为分数score=np.sum(query_vec*doc_vecs,axis=1)/np.linalg.norm(doc_vecs,axis=1)topk_idx=np.argsort(score)[::-1][:topk]print('前%d个问题类似于“%s”'%(topk,colored(query,'green')))foridxintopk_idx:print('>%s\t%s'%(colored('%.1f'%score[idx],'cyan'),colored(questions[idx],'yellow')))够简单了吧?当然,这是基于预训练的Bert模型的一个简单的QA搜索模型。您还可以对模型进行微调,使模型的整体性能更加完美。可以把自己的数据放在某个目录下,然后执行run_classifier。py来微调模型。它还有很多其他的用途,这里就不一一介绍了,大家可以去官方文档学习。这是我们文章的结尾。如果喜欢今天的Python实战教程,欢迎关注公众号:Python编程学习圈了解更多编程技术知识,送“J”获取大量Python学习资料!
