一日一技:急速搭建問答搜索引擎

鼎鼎大名的 Bert 算法相信大部分同學都聽說過,它是 Google 推出的 NLP 領域 “王炸級” 預訓練模型,其在 NLP 任務中刷新了多項記錄,並取得 state of the art 的成績。

但是有很多深度學習的新手發現 BERT 模型並不好搭建,上手難度很高,普通人可能要研究幾天才能勉強搭建出一個模型。

沒關係,今天我們介紹的這個模塊,能讓你在 3 分鐘內基於 BERT 算法搭建一個問答搜索引擎。它就是 bert-as-service 項目。這個開源項目,能夠讓你基於多 GPU 機器快速搭建 BERT 服務(支持微調模型),並且能夠讓多個客戶端併發使用。

1. 準備

開始之前,你要確保 Python 和 pip 已經成功安裝在電腦上,如果沒有,可以訪問這篇文章:超詳細 Python 安裝指南 進行安裝。

**(可選 1) **如果你用 Python 的目的是數據分析,可以直接安裝 Anaconda:Python 數據分析與挖掘好幫手—Anaconda,它內置了 Python 和 pip.

**(可選 2) **此外,推薦大家用 VSCode 編輯器,它有許多的優點:Python 編程的最好搭檔—VSCode 詳細指南

請選擇以下任一種方式輸入命令安裝依賴

  1. Windows 環境 打開 Cmd (開始 - 運行 - CMD)。
  2. MacOS 環境 打開 Terminal (command + 空格輸入 Terminal)。
  3. 如果你用的是 VSCode 編輯器 或 Pycharm,可以直接使用界面下方的 Terminal.
pip install bert-serving-server # 服務端
pip install bert-serving-client # 客戶端

請注意,服務端的版本要求:Python >= 3.5Tensorflow >= 1.10 。

此外還要下載預訓練好的 BERT 模型,在 https://github.com/hanxiao/bert-as-service#install 上可以下載。

也可在 Python 實用寶典後臺回覆 bert-as-service 下載這些預訓練好的模型。

下載完成後,將 zip 文件解壓到某個文件夾中,例如 /tmp/english_L-12_H-768_A-12/

2.Bert-as-service 基本使用

安裝完成後,輸入以下命令啓動 BERT 服務:

bert-serving-start -model_dir /tmp/english_L-12_H-768_A-12/ -num_worker=4

-num_worker=4 代表這將啓動一個有四個 worker 的服務,意味着它最多可以處理四個併發請求。超過 4 個其他併發請求將在負載均衡器中排隊等待處理。

下面顯示了正確啓動時服務器的樣子:

使用客戶端獲取語句的編碼

現在你可以簡單地對句子進行編碼,如下所示:

from bert_serving.client import BertClient
bc = BertClient()
bc.encode(['First do it', 'then do it right', 'then do it better'])

作爲 BERT 的一個特性,你可以通過將它們與 |||(前後有空格)連接來獲得一對句子的編碼,例如

bc.encode(['First do it ||| then do it right'])

遠程使用 BERT 服務

你還可以在一臺 (GPU) 機器上啓動服務並從另一臺 (CPU) 機器上調用它,如下所示:

# on another CPU machine
from bert_serving.client import BertClient
bc = BertClient(ip='xx.xx.xx.xx') # ip address of the GPU machine
bc.encode(['First do it', 'then do it right', 'then do it better'])

3. 搭建問答搜索引擎

我們將通過 bert-as-service 從 FAQ 列表中找到與用戶輸入的問題最相似的問題,並返回相應的答案。

FAQ 列表你也可以在 Python 實用寶典後臺回覆 bert-as-service 下載。

首先,加載所有問題,並顯示統計數據:

prefix_q = '##### **Q:** '
with open('README.md') as fp:
    questions = [v.replace(prefix_q, '').strip() for v in fp if v.strip() and v.startswith(prefix_q)]
    print('%d questions loaded, avg. len of %d' % (len(questions), np.mean([len(d.split()) for d in questions])))
    # 33 questions loaded, avg. len of 9

一共有 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 個類似的問題:

while True:
    query = input('your question: ')
    query_vec = bc.encode([query])[0]
    # compute normalized dot product as score
    score = np.sum(query_vec * doc_vecs, axis=1) / np.linalg.norm(doc_vecs, axis=1)
    topk_idx = np.argsort(score)[::-1][:topk]
    for idx in topk_idx:
        print('> %s\t%s' % (score[idx], questions[idx]))

**完成!**現在運行代碼並輸入你的查詢,看看這個搜索引擎如何處理模糊匹配:

完整代碼如下,一共 23 行代碼(在後臺回覆關鍵詞也能下載):

上滑查看完整代碼

import numpy as np
from bert_serving.client import BertClient
from termcolor import colored

prefix_q = '##### **Q:** '
topk = 5

with open('README.md') as fp:
    questions = [v.replace(prefix_q, '').strip() for v in fp if v.strip() and v.startswith(prefix_q)]
    print('%d questions loaded, avg. len of %d' % (len(questions), np.mean([len(d.split()) for d in questions])))

with BertClient(port=4000, port_out=4001) as bc:
    doc_vecs = bc.encode(questions)

    while True:
        query = input(colored('your question: ', 'green'))
        query_vec = bc.encode([query])[0]
        # compute normalized dot product as score
        score = np.sum(query_vec * doc_vecs, axis=1) / np.linalg.norm(doc_vecs, axis=1)
        topk_idx = np.argsort(score)[::-1][:topk]
        print('top %d questions similar to "%s"' % (topk, colored(query, 'green')))
        for idx in topk_idx:
            print('> %s\t%s' % (colored('%.1f' % score[idx], 'cyan'), colored(questions[idx], 'yellow')))

夠簡單吧?當然,這是一個基於預訓練的 Bert 模型製造的一個簡單 QA 搜索模型。

你還可以微調模型,讓這個模型整體表現地更完美,你可以將自己的數據放到某個目錄下,然後執行 run_classifier.py 對模型進行微調,比如這個例子:

https://github.com/google-research/bert#sentence-and-sentence-pair-classification-tasks

它還有許多別的用法,我們這裏就不一一介紹了,大家可以前往官方文檔學習:

https://github.com/hanxiao/bert-as-service

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cL3KTH-CoontjNrzGH1_jw