1. 安装
参考here下载对应语言的模型并安装bert的服务端和客户端包
2. 获取词语向量
首先,启动服务器,需要在启动命令中设置参数pooling_strategy=None,命令如下,
bert-serving-start -pooling_strategy NONE -model_dir /tmp/english_L-12_H-768_A-12/
接着,实现获取词向量的代码:
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!
但是这样对于中文来说可能存在一个问题,当我们的输入是
from bert_serving.client import BertClient bc = BertClient() text = ['我 是中国人', '我是 中国 人'] vec = bc.encode(text)
此时得到的vec中两个句子中的向量是一样的,通过在服务端增加show_tokens_to_clien参数,如下所示:
bert-serving-start -show_tokens_to_clien -max_seq_len 30 -pooling_strategy NONE -model_dir E:\Models\Bert\chinese_L-12_H-768_A-12
然后在客户端使用show_tokens,此时就可以看到服务端对于切词的处理:
from bert_serving.client import BertClient bc = BertClient() text = ['我 是中国人', '我是 中国 人'] texts2 = [s.split() for s in text] vec = bc.encode(text, show_tokens=True)
每个句子的token输出,结果如下:
[['[CLS]', '我', '是', '中', '国', '人', '[SEP]'], ['[CLS]', '我', '是', '中', '国', '人', '[SEP]']]
可以发现,bert对于中文句子的处理是按照单个字进行处理,并且在处理之前忽略了句子中的空格符号
因此,如果要自己进行处理,可以按照下面的思路,使用自己的tokenizer即可。
from bert_serving.client import BertClient bc = BertClient() text = ['我 是中国人', '我是 中国 人'] texts2 = [s.split() for s in text] vec = bc.encode(text, is_tokenized=True)
此时得到的向量才是对应分词的词向量
3. 参数
3.1. 修改序列长度
在服务端命令中增加max_seq_len参数。
bert-serving-start -max_seq_len 30 -pooling_strategy NONE -model_dir E:\Models\Bert\chinese_L-12_H-768_A-12
3.2. 显示tokens
在服务端增加show_tokens_to_clien参数
bert-serving-start -show_tokens_to_clien -model_dir E:\Models\Bert\chinese_L-12_H-768_A-12
在客户端增加show_tokens参数
from bert_serving.client import BertClient bc = BertClient() text = ['我 是中国人', '我是 中国 人'] texts2 = [s.split() for s in text] vec = bc.encode(text, is_tokenized=True)