FAISS + SBERT實現的十億級語義相似性搜索

2020-12-14 雷鋒網

譯者:AI研習社(FIONAbiubiu)

雙語原文連結:Billion-scale semantic similarity search with FAISS+SBERT


介紹

語義搜索是一種關注句子意義而不是傳統的關鍵詞匹配的信息檢索系統。儘管有許多文本嵌入可用於此目的,但將其擴展到構建低延遲api以從大量數據集合中獲取數據是很少討論的。在本文中,我將討論如何使用SOTA語句嵌入(語句轉換器)和FAISS來實現最小語義搜尋引擎。

句子Transformers

它是一個框架或一組模型,給出句子或段落的密集向量表示。這些模型是transformer網絡(BERT、RoBERTa等),它們專門針對語義文本相似性的任務進行了微調,因為BERT在這些任務中執行得不是很好。下面給出了不同模型在STS基準測試中的性能。


我們可以看到句子transformer模型比其他模型有很大的優勢。

但是如果你用代碼和GLUE來看看排行榜,你會看到很多的模型超過90。為什麼我們需要句子transformers?

在這些模型中,語義文本相似度被視為一個回歸任務。這意味著,每當我們需要計算兩個句子之間的相似度得分時,我們需要將它們一起傳遞到模型中,然後模型輸出它們之間的數值分數。雖然這對於基準測試很有效,但是對於實際的用例來說,它的伸縮性很差,原因如下。

1.當你需要搜索大約10k個文檔時,你需要進行10k個獨立的推理計算,不可能單獨計算嵌入量而只計算餘弦相似度。見作者的解釋。
2.最大序列長度(模型一次可以接受的單詞/標記的總數)在兩個文檔之間共享,這會導致的表示的含義由於分塊而被稀釋

FAISS

Faiss是一個基於C++的庫,由FacebookAI構建,在Python中有完整的包裝器,用於索引矢量化數據並對其進行有效的搜索。Faiss基於以下因素提供了不同的索引。

  • 搜索時間

  • 搜索質量

  • 每個索引向量使用的內存

  • 訓練時間

  • 無監訓練需要外部數據

因此,選擇合適的指數將是這些因素之間的權衡。

加載模型並對數據集執行推理

首先,讓我們安裝並加載所需的庫

!pip install faiss-cpu
!pip install -U sentence-transformersimport numpy as np
import torch
import os
import pandas as pd
import faiss
import time
from sentence_transformers import SentenceTransformer

加載一個包含一百萬個數據點的數據集

我使用了一個來自Kaggle的數據集,其中包含了17年來出版的新聞標題。

df=pd.read_csv("abcnews-date-text.csv")
data=df.headline_text.to_list()

加載預訓練模型並且進行推斷

model = SentenceTransformer('distilbert-base-nli-mean-tokens')encoded_data = model.encode(data)

為數據集編制索引

我們可以根據我們的用例通過參考指南來選擇不同的索引選項。

讓我們定義索引並向其添加數據

index = faiss.IndexIDMap(faiss.IndexFlatIP(768))index.add_with_ids(encoded_data, np.array(range(0, len(data))))

序列化索引

faiss.write_index(index, 'abc_news')

將序列化的索引導出到託管搜尋引擎的任何計算機中

反序列化索引

index = faiss.read_index('abc_news')

執行語義相似性搜索

讓我們首先為搜索構建一個包裝函數

def search(query):
  t=time.time()
  query_vector = model.encode([query])
  k = 5
  top_k = index.search(query_vector, k)
  print('totaltime: {}'.format(time.time()-t))
  return [data[_id] for _id in top_k[1].tolist()[0]]

執行搜索

query=str(input())
results=search(query)
print('results :')
for result in results:
  print('\t'

CPU中的結果

現在讓我們看看搜索結果和響應時間

只需1.5秒,就可以在僅使用CPU後端的百萬文本文檔的數據集上執行基於意義的智能搜索。

GPU中的結果

首先讓我們關閉CPU版本的Faiss並重啟GPU版本

!pip uninstall faiss-cpu
!pip install faiss-gpu

之後執行相同步驟,但是最後將索引移到GPU上。

res = faiss.StandardGpuResources()
gpu_index = faiss.index_cpu_to_gpu(res, 0, index)

現在讓我們轉移這個搜索方法並用GPU執行這個搜索

很好,你可以在0.02秒內得到結果,使用GPU(在這個實驗中使用了Tesla T4),它比CPU後端快75倍

但是為什麼我不能僅僅序列化編碼數據的NumPy數組而不是索引它們呢?如果我能等幾秒鐘的話,使用餘弦相似性呢?

因為NumPy沒有序列化函數,因此唯一的方法是將其轉換為JSON,然後保存JSON對象,但是大小將增加五倍。例如,在768維向量空間中編碼的一百萬個數據點具有正常的索引,大約為3GB,將其轉換為JSON將使其成為15GB,而普通機器無法保存它的RAM。因此,每次執行搜索時,我們都要運行一百萬次計算推理,這是不實際的。

最後的想法

這是一個基本的實現,在語言模型部分和索引部分仍然需要做很多工作。有不同的索引選項,應該根據用例、數據大小和可用的計算能力選擇正確的索引選項。另外,這裡使用的句子嵌入只是對一些公共數據集進行了微調,在特定領域的數據集上對它們進行微調可以改進,從而提高搜索結果。

參考文獻

[1] Nils Reimers and Iryna Gurevych. 「Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation.」 arXiv (2020): 2004.09813.

[2]Johnson, Jeff and Douze, Matthijs and J{\』e}gou, Herv{\』e}. 「Billion-scale similarity search with GPUs」 arXiv preprint arXiv:1702.08734.



AI研習社是AI學術青年和AI開發者技術交流的在線社區。我們與高校、學術機構和產業界合作,通過提供學習、實戰和求職服務,為AI學術青年和開發者的交流互助和職業發展打造一站式平臺,致力成為中國最大的科技創新人才聚集地。

如果,你也是位熱愛分享的AI愛好者。歡迎與譯站一起,學習新知,分享成長。


雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知。

相關焦點

  • 學界| Facebook新論文介紹相似性搜索新突破:在GPU上實現十億規模
    選自arXiv.org機器之心編譯作者:吳攀相似性搜索的規模和速度一直是研究者努力想要克服的難題。近日,Facebook 人工智慧研究團隊在 arXiv 發布的新論文《Billion-scale similarity search with GPUs》宣稱在這一問題上取得了重大進展,在 GPU 上實現了十億規模級的相似性搜索。
  • NLP: 基於文本語義的智能問答系統
    因此,在傳統關鍵詞匹配的基礎上,進一步引入語義搜索技術,將精華問答庫的問題映射為多維向量,進行語義匹配,提升問題匹配準確性。TF-IDF 方式也在用在關鍵詞提取)方案可以擴展到的業務需求(本文介紹的是一種文本語義匹配通用解決方案)(對話系統檢索式智能問答系統,答案在知識庫中且返回唯一的數據記錄)以圖搜索(resnet 圖片向量化表示)新聞領域文本相似推薦(相似新聞推薦等)基於文本語義匹配檢索系統(文本相似性rank )針對這類問題,重點文本等通過某種方式進行向量化表示
  • 前沿|通用句子語義編碼器,谷歌在語義文本相似性上的探索
    論文地址:https://arxiv.org/abs/1804.07754如果句子可以通過相同的答案來回答,那麼句子在語義上是相似的。否則,它們在語義上是不同的。這項工作中,我們希望通過給回答分類的方式學習語義相似性:給定一個對話輸入,我們希望從一批隨機選擇的回覆中分類得到正確的答案。但是,任務的最終目標是學習一個可以返回表示各種自然語言關係(包括相似性和相關性)的編碼模型。我們提出了另一預測任務(此處是指 SNLI 蘊含數據集),並通過共享的編碼層同時推進兩項任務。
  • 語義分割領域開山之作:Google提出用神經網絡搜索實現語義分割
    基於 NAS 的圖像分類遷移到高解析度的圖像處理(語義分割、目標識別、實例分割)有很大的挑戰:(1)神經網絡的搜索空間和基本運算單元有本質不同。(2)架構搜索必須固有地在高解析度圖像上運行,因此不能實現從低解析度圖像訓練模型遷移到高解析度圖像。論文首次嘗試將元學習應用於密集圖像預測(本人理解就是像素級圖像分割)。
  • 最先進的語義搜索句子相似度計算
    還有眾所周知的Google-fu,在21世紀的職場中,有效使用Google搜索信息的是一項寶貴的技能。人類的所有知識對我們來說都是可用的,問題在於提出正確的問題,以及知道如何瀏覽結果找到相關的答案。我們的大腦會執行語義搜索,我們會查看結果並找到與我們的搜索查詢相似的句子。
  • 李偉:輿情事件等級評估及基於語義理解實現文本精細化分類
    雖然搜索的熱度值或報導的數量能反映一個事件社會關注度,但卻存在著指標單一、數據不全、無法針對用戶特點提供個性化服務等問題。因此評估輿情事件嚴重程度需要有能容納原有方法,但更全面、多維、面向用戶個性化需求的模型來實現。二是輿情事件等級綜合評估模型設計的原則,這涉及到兩個方面。一是要考慮到模型裡面有哪些變量,二是建立模型應該遵循的原則。
  • KDD2020 | 揭秘Facebook搜索中的語義檢索技術
    雖然語義檢索技術(Embedding-based Retrieval,EBR)在傳統的搜尋引擎中得到了廣泛應用,但是 Facebook 搜索之前主要還是使用布爾匹配模型,本文就來談談如何將 Embedding 檢索技術應用在 Facebook 搜索場景中。
  • 漫談語義相似度
    轉載自 | 李rumor語義相似度是自然語言理解(NLU)裡面一大核心拼圖,無論是機器翻譯、搜索、對話等,都有很大的應用空間。向量化表徵語義相似度能讓我們衡量兩個句子的語義相似度,但是實際上我們的應用場景更多是「在句子庫裡面找到最接近給定句子的句子」,例如一個句子「明天天氣」,我要找到整個庫裡面最接近的那個句子,例如「明天的天氣」、「明天下雨嗎」、「天氣之子」等,如果簡單的一個一個匹配去找,複雜度就是O(N),這個數字無疑非常可怕,當庫是千萬級別大小的時候,這個搜索就變得非常低效
  • 人人都可參與的AI技術體驗:谷歌發布全新搜尋引擎Talk to Books
    作為搜尋引擎起家的科技巨頭,谷歌曾推出過很多有意思的搜索工具。昨天,這家公司的研究機構發布了一款基於人工智慧的搜尋引擎,該實驗項目可以讓普通人也能感受最新語義理解和自然語言處理技術的強大能力:它們是目前人工智慧技術發展的重要方向。
  • 語義搜索及框計算:從百度查生僻字談起
    首頁 > 動態 > 關鍵詞 > 百度最新資訊 > 正文 語義搜索及框計算:從百度查生僻字談起
  • 搜尋引擎無需戰爭 語義搜索改變不了格局
    最近,有關搜尋引擎的新聞很多,谷歌為了其搜尋引擎添加了新的搜索功能,雅虎這周二推出了可以直接展示搜索信息的新搜索方式,微軟則把運氣賭在了新搜尋引擎Kumo上。儘管這三家公司的舉動各有不同,但他們都在追求語義搜索方式,也就是說,他們希望計算機能理解用戶的查詢,而不僅僅是返回一串基於關鍵詞的搜索結果。現在還沒有一個搜尋引擎可以達到這樣的水平,但搜尋引擎公司都在朝著這個方向努力。
  • 語義分析的一些方法(上篇)
    工作這幾年,陸陸續續實踐過一些項目,有搜索廣告,社交廣告,微博廣告,品牌廣告,內容廣告等。要使我們廣告平臺效益最大化,首先需要理解用戶,Context(將展示廣告的上下文)和廣告,才能將最合適的廣告展示給用戶。而這其中,就離不開對用戶,對上下文,對廣告的語義分析,由此催生了一些子項目,例如文本語義分析,圖片語義理解,語義索引,短串語義關聯,用戶廣告語義匹配等。
  • 手把手教你從零起步構建自己的圖像搜索模型
    根據我們為許多語義理解項目提供技術指導的經驗,我們編寫了一個教程,讓讀者了解如何構建自己的表徵模型,包括圖像和文本數據,以及如何有效地進行基於相似性的搜索。到本文結束時,讀者自己應該能夠從零起步構建自己的快速語義搜索模型,無論數據集的大小如何。本文配有一個帶有代碼注釋的 notebook,使用了 streamlit 和一個獨立的代碼庫來演示和使用所有相關技術。
  • 語義搜索、圖像搜索、法律搜索……智慧芽全球專利資料庫你體驗過...
    簡單搜索:輸入關鍵詞、公司名、人名、專利號即可檢索專利在簡單搜索時,系統自動推薦關鍵詞/近義詞/上下位詞/用戶歷史搜索等,並對不完整的檢索式進行糾錯,幫助用戶快速獲得有效檢索結果。150多種搜索欄位1.搜索欄位種類全面,通過任何一條線索都能找到相應的專利文獻2.包含搜索命令模式,支持專業用戶自己撰寫和組合搜索命令
  • 2020年文檔相似性算法:初學者教程
    數據科學家主張絕對最好你可能會搜索術語「最佳文檔相似性算法」(best document similarity algorithms)。然後你將從學術論文,博客,問答中得到搜索結果。一些側重於特定算法的教程,而另一些則側重於理論概述。
  • 語義分割-多層特徵融合
    ,也稱為像素級分類問題,其輸出和輸入解析度相同(如題圖中,左邊為2048x1024解析度的Cityscapes街景圖像,輸入模型,得到右邊同樣解析度的語義圖)。由此,語義分割具有兩大需求,即高解析度和高層語義,而這兩個需求和卷積網絡設計是矛盾的。卷積網絡從輸入到輸出,會經過多個下採樣層(一般為5個,輸出原圖1/32的特徵圖),從而逐步擴大視野獲取高層語義特徵,高層語義特徵靠近輸出端但解析度低,高分率特徵靠近輸入端但語義層次低。
  • 利用Word Embedding自動生成語義相近句子
    如果用Word2Vec跑一遍訓練數據,每個中文單詞就可以得到對應的Word Embedding,這是一種低維度向量形式的單詞表示,能夠表徵單詞的部分語義及語法含義。 對於任意兩個已經用WordEmbedding形式表示的單詞,我們可以簡單通過計算兩個向量之間的Cosine相似性,就得出兩個單詞語義接近程度了。
  • 圖像相似性的5種度量方法
    和粒子濾波等都需要圖像相似性度量做理論支撐。市場應用是Google的以圖搜圖,就是根據已有圖像搜索更多類似的圖像。谷歌已經開發出圖像搜索,但是性能很不好,遠遠低於文字檢索質量。國內百度也做了圖像搜索,她的方法更像是擦邊球,通過搜索圖像的標籤給出類似或者完全不同的圖像。下面是兩個搜索網站對同一幅圖像的搜索,結果如下。
  • 百度發布語義理解框架ERNIE 2.0 中英文任務超BERT和XLNet
    今年3月份時,百度曾對外提出了NLP預訓練語言模型 ERNIE,ERNIE通過建模海量數據中的詞、實體及實體關係,學習真實世界的語義知識。較之BERT學習原始語言信號,ERNIE直接對先驗語義知識單元進行建模,增強了模型語義表示能力。
  • Kaggle文本語義相似度計算Top5解決方案分享
    id=8問題相似度計算,即給定客服裡用戶描述的兩句話,用算法來判斷是否表示了相同的語義。文本相似性/相關性度量是NLP和信息檢索中非常基礎的任務,在搜尋引擎,QA系統中有舉足輕重的地位,一般的文本相似性匹配,從大的方法來講,傳統方法和深度學習方法。