【NLP】bert4vec:一個基于預(yù)訓(xùn)練的句向量生成工具
環(huán)境
transformers>=4.6.0,<5.0.0 torch>=1.6.0 numpy huggingface-hub faiss (optional)
安裝
方式一
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ bert4vec方式二
git?clone?https://github.com/zejunwang1/bert4vec
cd?bert4vec/
python?setup.py?sdist
pip?install?dist/bert4vec-1.0.0.tar.gz功能介紹
目前支持加載的句向量預(yù)訓(xùn)練模型包括 SimBERT、RoFormer-Sim 和 paraphrase-multilingual-MiniLM-L12-v2,其中 SimBERT 與 RoFormer-Sim 為蘇劍林老師開源的中文句向量表示模型,paraphrase-multilingual-MiniLM-L12-v2 為 sentence-transformers 開放的多語言預(yù)訓(xùn)練模型,支持中文句向量生成。
句向量生成
from?bert4vec?import?Bert4Vec
#?支持四種模式:simbert-base/roformer-sim-base/roformer-sim-small/paraphrase-multilingual-minilm
model?=?Bert4Vec(mode='simbert-base')?
sentences?=?['喜歡打籃球的男生喜歡什么樣的女生',?'西安下雪了?是不是很冷啊?',?'第一次去見女朋友父母該如何表現(xiàn)?',?'小蝌蚪找媽媽怎么樣',?
?????????????'給我推薦一款紅色的車',?'我喜歡北京']
vecs?=?model.encode(sentences,?convert_to_numpy=True,?normalize_to_unit=False)
# encode函數(shù)支持的默認輸入?yún)?shù)有:batch_size=64, convert_to_numpy=False, normalize_to_unit=False
print(vecs.shape)
print(vecs)
結(jié)果如下:

當(dāng)需要計算英文句子的稠密向量時,需要設(shè)置 mode='paraphrase-multilingual-minilm'。
相似度計算
from?bert4vec?import?Bert4Vec
model?=?Bert4Vec(mode='paraphrase-multilingual-minilm')?
sent1?=?['喜歡打籃球的男生喜歡什么樣的女生',?'西安下雪了?是不是很冷啊?',?'第一次去見女朋友父母該如何表現(xiàn)?',?'小蝌蚪找媽媽怎么樣',?
?????????'給我推薦一款紅色的車',?'我喜歡北京',?'That?is?a?happy?person']
sent2?=?['愛打籃球的男生喜歡什么樣的女生',?'西安的天氣怎么樣???還在下雪嗎?',?'第一次去見家長該怎么做',?'小蝌蚪找媽媽是誰畫的',?
?????????'給我推薦一款黑色的車',?'我不喜歡北京',?'That?is?a?happy?dog']
similarity?=?model.similarity(sent1,?sent2,?return_matrix=False)
# similarity函數(shù)支持的默認輸入?yún)?shù)有:batch_size=64, return_matrix=False
print(similarity)
結(jié)果如下:

假設(shè) sent1 包含 M 個句子,sent2 包含 N 個句子,當(dāng) similarity 函數(shù)的 return_matrix 參數(shù)設(shè)置為 False 時,函數(shù)返回 sent1 和 sent2 中同一行兩個句子之間的余弦相似度,此時要求 M=N,否則會報錯。
當(dāng) similarity 函數(shù)的 return_matrix 參數(shù)設(shè)置為 True 時,函數(shù)返回一個 M*N 相似度矩陣,矩陣的第 i 行第 j 列元素表示 sent1 的第 i 個句子和 sent2 的第 j 個句子之間的余弦相似度。
similarity?=?model.similarity(sent1,?sent2,?return_matrix=True)
print(similarity)
結(jié)果如下:

語義檢索
bert4vec 支持使用 faiss 構(gòu)建 cpu/gpu 句向量索引,Bert4Vec 類的 build_index 函數(shù)參數(shù)列表如下:
def?build_index(
????self,
????sentences_or_file_path:?Union[str,?List[str]],
????ann_search:?bool?=?False,
????gpu_index:?bool?=?False,
????n_search:?int?=?64,
????batch_size:?int?=?64
)
sentences_or_file_path:要進行索引構(gòu)建的句子文件路徑或句子列表。 ann_search:是否進行近似最近鄰查找。若為 False,則查找時進行暴力搜索計算,返回精確結(jié)果。 gpu_index:是否構(gòu)建 gpu 索引。 n_search:近似最近鄰查找時的搜索類別數(shù)量,該參數(shù)越大,查找結(jié)果越準確。 batch_size:句向量計算時的批量大小。
使用 Chinese-STS-B 驗證集 (https://github.com/zejunwang1/CSTS) 中去重后的所有句子構(gòu)建索引,進行近似最近鄰查找的示例代碼如下:
from?bert4vec?import?Bert4Vec
model?=?Bert4Vec(mode='roformer-sim-small')
sentences_path?=?"./sentences.txt"??#?examples文件夾下
model.build_index(sentences_path,?ann_search=True,?gpu_index=False,?n_search=32)
results?=?model.search(queries=['一個男人在彈吉他。',?'一個女人在做飯'],?threshold=0.6,?top_k=5)
#?threshold為最低相似度閾值,top_k為查找的近鄰個數(shù)
print(results)
結(jié)果如下:

Bert4Vec 類支持使用如下函數(shù)保存和加載句向量索引文件:
def?write_index(self,?index_path:?str)
def?read_index(self,?sentences_path:?str,?index_path:?str,?is_faiss_index:?bool?=?True)
sentences_path 為構(gòu)建句向量索引的句子文件路徑,index_path 為句向量索引存儲路徑。
模型下載
筆者將原始的 SimBERT 和 RoFormer-Sim 模型權(quán)重轉(zhuǎn)換為支持使用 Huggingface Transformers 進行加載的模型格式:https://huggingface.co/WangZeJun
from?bert4vec?import?Bert4Vec
model?=?Bert4Vec(mode='simbert-base',?model_name_or_path='WangZeJun/simbert-base-chinese')
model?=?Bert4Vec(mode='roformer-sim-base',?model_name_or_path='WangZeJun/roformer-sim-base-chinese')
model?=?Bert4Vec(mode='roformer-sim-small',?model_name_or_path='WangZeJun/roformer-sim-small-chinese')
model?=?Bert4Vec(mode='paraphrase-multilingual-minilm',?model_name_or_path='sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
mode 與 model_name_or_path 的對應(yīng)關(guān)系如下:
| mode | model_name_or_path |
|---|---|
| simbert-base | WangZeJun/simbert-base-chinese |
| roformer-sim-base | WangZeJun/roformer-sim-base-chinese |
| roformer-sim-small | WangZeJun/roformer-sim-small-chinese |
| paraphrase-multilingual-minilm | sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 |
當(dāng) mode 設(shè)置完成后,無需設(shè)置 model_name_or_path,代碼會從 https://huggingface.co/ 上自動下載相應(yīng)的預(yù)訓(xùn)練模型權(quán)重并加載。
鏈接
https://github.com/ZhuiyiTechnology/simbert https://github.com/ZhuiyiTechnology/roformer-sim https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
往期精彩回顧
