bert-as-service使用
BERT 模型是一種 NLP 預訓練技術,本文不介紹 BERT 的原理,主要關注如何快速上手使用 BERT 模型生成詞向量用于下游任務。
Google 已經公開了 TensorFlow 版本的[預訓練模型和代碼]
(https://github.com/google-research/bert),可以用于生成詞向量,但是還有更簡單的方法:直接調用封裝好的庫 bert-as-service 。
使用 bert-as-service 生成詞向量
bert-as-service 是騰訊 AI Lab 開源的一個 BERT 服務,它讓用戶可以以調用服務的方式使用 BERT 模型而不需要關注 BERT 的實現細節。bert-as-service 分為客戶端和服務端,用戶可以從 python 代碼中調用服務,也可以通過 http 的方式訪問。
安裝
使用 pip 命令進行安裝,客戶端與服務端可以安裝在不同的機器上:
pip install bert-serving-server # 服務端
pip install bert-serving-client # 客戶端,與服務端互相獨立
其中,服務端的運行環境為 Python >= 3.5 和 Tensorflow >= 1.10
客戶端可以運行于 Python 2 或 Python 3
下載預訓練模型
根據 NLP 任務的類型和規模不同,Google 提供了多種預訓練模型供選擇:
BERT-Base, Chinese: 簡繁體中文, 12-layer, 768-hidden, 12-heads, 110M parameters
BERT-Base, Multilingual Cased: 多語言(104 種), 12-layer, 768-hidden, 12-heads, 110M parameters
BERT-Base, Uncased: 英文不區分大小寫(全部轉為小寫), 12-layer, 768-hidden, 12-heads, 110M parameters
BERT-Base, Cased: 英文區分大小寫, 12-layer, 768-hidden, 12-heads , 110M parameters
也可以使用中文效果更好的哈工大版 BERT:
Chinese-BERT-wwm
以上列出了幾個常用的預訓練模型,可以到 這里 查看更多。
解壓下載到的 .zip 文件以后,會有 6 個文件:
TensorFlow 模型文件(bert_model.ckpt) 包含預訓練模型的權重,模型文件有三個
字典文件(vocab.txt) 記錄詞條與 id 的映射關系
配置文件(bert_config.json ) 記錄模型的超參數
啟動 BERT 服務
使用 bert-serving-start 命令啟動服務:
bert-serving-start -model_dir /tmp/english_L-12_H-768_A-12/ -num_worker=2
其中,-model_dir 是預訓練模型的路徑,-num_worker 是線程數,表示同時可以處理多少個并發請求
如果啟動成功,服務器端會顯示:
在客戶端獲取句向量
可以簡單的使用以下代碼獲取語料的向量表示:
from bert_serving.client import BertClient
bc = BertClient()
doc_vecs = bc.encode(['First do it', 'then do it right', 'then do it better'])```doc_vecs 是一個 numpy.ndarray ,它的每一行是一個固定長度的句子向量,長度由輸入句子的最大長度決定。如果要指定長度,可以在啟動服務使用 max_seq_len 參數,過長的句子會被從右端截斷。BERT 的另一個特性是可以獲取一對句子的向量,句子之間使用 ||| 作為分隔,例如:```cpp
bc.encode(['First do it ||| then do it right'])
獲取詞向量
啟動服務時將參數 pooling_strategy 設置為 None :
bert-serving-start -pooling_strategy NONE -model_dir /tmp/english_L-12_H-768_A-12/
這時的返回是語料中每個 token 對應 embedding 的矩陣
bc = BertClient()
vec = bc.encode(['hey you', 'whats up?'])vec # [2, 25, 768]
vec[0] # [1, 25, 768], sentence embeddings for `hey you`
vec[0][0] # [1, 1, 768], word embedding for `[CLS]`
vec[0][1] # [1, 1, 768], word embedding for `hey`
vec[0][2] # [1, 1, 768], word embedding for `you`
vec[0][3] # [1, 1, 768], word embedding for `[SEP]`
vec[0][4] # [1, 1, 768], word embedding for padding symbol
vec[0][25] # error, out of index!
遠程調用 BERT 服務
可以從一臺機器上調用另一臺機器的 BERT 服務:
# 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'])
這個例子中,只需要在客戶端 pip install -U bert-serving-client
其他
配置要求
BERT 模型對內存有比較高的要求,如果啟動時一直卡在 load graph from model_dir 可以將 num_worker 設置為 1 或者加大機器內存。
處理中文是否要提前分詞
在計算中文向量時,可以直接輸入整個句子不需要提前分詞。因為 Chinese-BERT 中,語料是以字為單位處理的,因此對于中文語料來說輸出的是字向量。
舉個例子,當用戶輸入:
bc.encode(['hey you', 'whats up?', '你好么?', '我 還 可以'])
實際上,BERT 模型的輸入是:
tokens: [CLS] hey you [SEP]
input_ids: 101 13153 8357 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
input_mask: 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0tokens: [CLS] what ##s up ? [SEP]
input_ids: 101 9100 8118 8644 136 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
input_mask: 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0tokens: [CLS] 你 好 么 ? [SEP]
input_ids: 101 872 1962 720 8043 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
input_mask: 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0tokens: [CLS] 我 還 可 以 [SEP]
input_ids: 101 2769 6820 1377 809 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
input_mask: 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
在英語中詞條化后的 ##something 是什么
當某個詞在不在詞典中時,使用最長子序列的方法進行詞條化,例如:
input = "unaffable"
tokenizer_output = ["un", "##aff", "##able"]
參考資料
https://github.com/google-research/bert
https://github.com/hanxiao/bert-as-service
self.graph_path, self.bert_config = pool.apply(optimize_graph, (self.args,))
TypeError: ‘NoneType’ object is not iterable
from google.protobuf.pyext import _message ImportError: DLL load failed: 找不到指定的程序。
這些錯誤都是因為沒用bert 原生的預訓練模型
總結
以上是生活随笔為你收集整理的bert-as-service使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: batch normalization
- 下一篇: 深度学习网络模型可视化netron