模型概述
模型特點
模型能力
使用案例
🚀 多語言文本語義搜索孿生BERT模型
本項目的模型基於 sentence-transformers
構建,能夠將句子和段落映射到384維的密集向量空間,專為語義搜索設計。它在來自不同來源的2.15億個(問題,答案)對上進行了訓練,可有效為給定的段落找到相關文檔。
🚀 快速開始
本模型可用於語義搜索,它能將查詢/問題和文本段落編碼到一個密集向量空間中,為給定的段落找到相關的文檔。
✨ 主要特性
- 多語言支持:能夠處理多種語言的文本,實現跨語言的語義搜索。
- 高效編碼:將句子和段落快速編碼為384維的密集向量。
- 精準匹配:在大規模數據集上訓練,能準確找到相關文檔。
📦 安裝指南
如果你已經安裝了 sentence-transformers
,使用這個模型會很方便:
pip install -U sentence-transformers
💻 使用示例
基礎用法
使用 sentence-transformers
庫調用模型:
from sentence_transformers import SentenceTransformer, util
query = "How many people live in London?"
docs = ["Around 9 Million people live in London", "London is known for its financial district"]
# 加載模型
model = SentenceTransformer('SeyedAli/Multilingual-Text-Semantic-Search-Siamese-BERT-V1')
# 編碼查詢和文檔
query_emb = model.encode(query)
doc_emb = model.encode(docs)
# 計算查詢和所有文檔嵌入之間的點積分數
scores = util.dot_score(query_emb, doc_emb)[0].cpu().tolist()
# 組合文檔和分數
doc_score_pairs = list(zip(docs, scores))
# 按分數降序排序
doc_score_pairs = sorted(doc_score_pairs, key=lambda x: x[1], reverse=True)
# 輸出段落和分數
for doc, score in doc_score_pairs:
print(score, doc)
高級用法
PyTorch用法(HuggingFace Transformers)
不使用 sentence-transformers
時,你可以按以下方式使用模型:首先將輸入傳遞給Transformer模型,然後對上下文詞嵌入應用正確的池化操作。
from transformers import AutoTokenizer, AutoModel
import torch
import torch.nn.functional as F
# 平均池化 - 取所有標記的平均值
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output.last_hidden_state
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
# 編碼文本
def encode(texts):
# 對句子進行分詞
encoded_input = tokenizer(texts, padding=True, truncation=True, return_tensors='pt')
# 計算標記嵌入
with torch.no_grad():
model_output = model(**encoded_input, return_dict=True)
# 執行池化
embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
# 歸一化嵌入
embeddings = F.normalize(embeddings, p=2, dim=1)
return embeddings
# 我們想要獲取句子嵌入的句子
query = "How many people live in London?"
docs = ["Around 9 Million people live in London", "London is known for its financial district"]
# 從HuggingFace Hub加載模型
tokenizer = AutoTokenizer.from_pretrained("SeyedAli/Multilingual-Text-Semantic-Search-Siamese-BERT-V1")
model = AutoModel.from_pretrained("SeyedAli/Multilingual-Text-Semantic-Search-Siamese-BERT-V1")
# 編碼查詢和文檔
query_emb = encode(query)
doc_emb = encode(docs)
# 計算查詢和所有文檔嵌入之間的點積分數
scores = torch.mm(query_emb, doc_emb.transpose(0, 1))[0].cpu().tolist()
# 組合文檔和分數
doc_score_pairs = list(zip(docs, scores))
# 按分數降序排序
doc_score_pairs = sorted(doc_score_pairs, key=lambda x: x[1], reverse=True)
# 輸出段落和分數
for doc, score in doc_score_pairs:
print(score, doc)
TensorFlow用法(HuggingFace Transformers)
與上述PyTorch示例類似,要在TensorFlow中使用該模型,你需要將輸入傳遞給Transformer模型,然後對上下文詞嵌入應用正確的池化操作。
from transformers import AutoTokenizer, TFAutoModel
import tensorflow as tf
# 平均池化 - 考慮注意力掩碼以進行正確的平均
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output.last_hidden_state
input_mask_expanded = tf.cast(tf.tile(tf.expand_dims(attention_mask, -1), [1, 1, token_embeddings.shape[-1]]), tf.float32)
return tf.math.reduce_sum(token_embeddings * input_mask_expanded, 1) / tf.math.maximum(tf.math.reduce_sum(input_mask_expanded, 1), 1e-9)
# 編碼文本
def encode(texts):
# 對句子進行分詞
encoded_input = tokenizer(texts, padding=True, truncation=True, return_tensors='tf')
# 計算標記嵌入
model_output = model(**encoded_input, return_dict=True)
# 執行池化
embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
# 歸一化嵌入
embeddings = tf.math.l2_normalize(embeddings, axis=1)
return embeddings
# 我們想要獲取句子嵌入的句子
query = "How many people live in London?"
docs = ["Around 9 Million people live in London", "London is known for its financial district"]
# 從HuggingFace Hub加載模型
tokenizer = AutoTokenizer.from_pretrained("SeyedAli/Multilingual-Text-Semantic-Search-Siamese-BERT-V1")
model = TFAutoModel.from_pretrained("SeyedAli/Multilingual-Text-Semantic-Search-Siamese-BERT-V1")
# 編碼查詢和文檔
query_emb = encode(query)
doc_emb = encode(docs)
# 計算查詢和所有文檔嵌入之間的點積分數
scores = (query_emb @ tf.transpose(doc_emb))[0].numpy().tolist()
# 組合文檔和分數
doc_score_pairs = list(zip(docs, scores))
# 按分數降序排序
doc_score_pairs = sorted(doc_score_pairs, key=lambda x: x[1], reverse=True)
# 輸出段落和分數
for doc, score in doc_score_pairs:
print(score, doc)
🔧 技術細節
以下是該模型使用的一些技術細節:
屬性 | 詳情 |
---|---|
維度 | 384 |
是否生成歸一化嵌入 | 是 |
池化方法 | 平均池化 |
適用的分數函數 | 點積 (util.dot_score )、餘弦相似度 (util.cos_sim ) 或歐幾里得距離 |
⚠️ 重要提示
使用
sentence-transformers
加載此模型時,會生成長度為1的歸一化嵌入。在這種情況下,點積和餘弦相似度是等價的,優先使用點積,因為它更快。歐幾里得距離與點積成正比,也可以使用。
📚 詳細文檔
背景
本項目旨在使用自監督對比學習目標,在非常大的句子級數據集上訓練句子嵌入模型。我們使用對比學習目標:給定來自一對句子中的一個句子,模型應該從一組隨機採樣的其他句子中預測出在數據集中實際與之配對的句子。
該模型是在Hugging Face組織的 使用JAX/Flax進行NLP和CV的社區周 期間開發的。它是 使用10億個訓練對訓練有史以來最好的句子嵌入模型 項目的一部分。我們藉助高效的硬件基礎設施(7個TPU v3 - 8)以及谷歌Flax、JAX和雲團隊成員在高效深度學習框架方面的指導來運行該項目。
預期用途
本模型旨在用於語義搜索,它可以將查詢/問題和文本段落編碼到一個密集向量空間中,為給定的段落找到相關的文檔。
⚠️ 重要提示
該模型的輸入詞塊限制為512個,超過此長度的文本將被截斷。此外,該模型僅在最多250個詞塊的輸入文本上進行訓練,對於較長的文本可能效果不佳。
訓練過程
完整的訓練腳本可在當前倉庫中找到:train_script.py
。
預訓練
我們使用預訓練的 nreimers/MiniLM-L6-H384-uncased
模型。有關預訓練過程的更多詳細信息,請參考該模型的卡片。
訓練
我們使用多個數據集的組合來微調模型。總共約有2.15億個(問題,答案)對。我們根據加權概率對每個數據集進行採樣,具體配置在 data_config.json
文件中詳細說明。
模型使用 MultipleNegativesRankingLoss 進行訓練,採用平均池化、餘弦相似度作為相似度函數,縮放比例為20。
數據集 | 訓練元組數量 |
---|---|
WikiAnswers WikiAnswers中的重複問題對 | 77,427,422 |
PAQ 維基百科中每個段落的自動生成(問題,段落)對 | 64,371,441 |
Stack Exchange 所有StackExchanges的(標題,正文)對 | 25,316,456 |
Stack Exchange 所有StackExchanges的(標題,答案)對 | 21,396,559 |
MS MARCO 來自Bing搜索引擎的50萬個查詢的三元組(查詢,答案,硬負樣本) | 17,579,773 |
GOOAQ: Open Question Answering with Diverse Answer Types 300萬個谷歌查詢和谷歌特色片段的(查詢,答案)對 | 3,012,496 |
Amazon-QA 亞馬遜產品頁面的(問題,答案)對 | 2,448,839 |
Yahoo Answers Yahoo Answers的(標題,答案)對 | 1,198,260 |
Yahoo Answers Yahoo Answers的(問題,答案)對 | 681,164 |
Yahoo Answers Yahoo Answers的(標題,問題)對 | 659,896 |
SearchQA 14萬個問題的(問題,答案)對,每個問題有前5個谷歌片段 | 582,261 |
ELI5 Reddit ELI5(像解釋給五歲孩子一樣解釋)的(問題,答案)對 | 325,475 |
Stack Exchange 重複問題對(標題) | 304,525 |
Quora Question Triplets Quora問題對數據集的(問題,重複問題,硬負樣本)三元組 | 103,663 |
Natural Questions (NQ) 10萬個真實谷歌查詢與相關維基百科段落的(問題,段落)對 | 100,231 |
SQuAD2.0 SQuAD2.0數據集的(問題,段落)對 | 87,599 |
TriviaQA (問題,證據)對 | 73,346 |
總計 | 214,988,242 |







