環境:
python 3.5 tensorflow 1.12.1 bert-serving-server 1.9.1 bert-serving-cline 1.9.1
官網上說要保證Python >= 3.5 with Tensorflow >= 1.10
1.安裝BERT服務端和客戶端
pip install bert-serving-server # server pip install bert-serving-client # client, independent of `bert-serving-server`
2.下載預訓練的中文BERT模型
根據 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
下載成功后,解壓
3.啟動BERT服務端
bert-serving-start -model_dir chinese_L-12_H-768_A-12 -num_worker=1
-model_dir
是預訓練模型的路徑,-num_worker
是線程數,表示同時可以處理多少個並發請求
BERT 模型對內存有比較大的要求,如果啟動時一直卡在 load graph from model_dir
可以將 num_worker
設置為 1 或者加大機器內存。
4. 在客戶端獲取句向量
from bert_serving.client import BertClient bc = BertClient(ip='localhost',check_version=False, check_length=False) vec = bc.encode(['努力寫大論文中']) print(vec) # 維度(1,768)
vec
是一個 numpy.ndarray ,它的每一行是一個固定長度的句子向量,長度由輸入句子的最大長度決定。如果要指定長度,可以在啟動服務使用 max_seq_len
參數,過長的句子會被從右端截斷。
在計算中文向量時,可以直接輸入整個句子不需要提前分詞。因為 Chinese-BERT 中,語料是以字為單位處理的,因此對於中文語料來說輸出的是字向量。
舉個例子,當用戶輸入:
bc.encode(['你好嗎?'])
實際上,BERT 模型的輸入是:
tokens: [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 0
5.獲取詞向量
啟動服務時將參數 pooling_strategy
設置為 None :
bert-serving-start -pooling_strategy NONE -model_dir /root/zhihu/bert/chinese_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!
參考文獻:
【1】bert-as-service三行代碼使用bert模型 - accumulate_zhang的博客 - CSDN博客