AIxiv專欄是機器之心釋出學術、技術內容的欄目。過去數年,機器之心AIxiv專欄接收報導了2000多篇內容,覆蓋全球各大高校與企業的頂級實驗室,有效促進了學術交流與傳播。如果您有優秀的工作想要分享,歡迎投稿或者聯絡報導。投稿郵箱:liyazhou@jiqizhixin.com;zhaoyunfeng@jiqizhixin.com
本文作者是來自 OpenSearch 中國研發團隊的機器學習負責人楊揚博士以及機器學習工程師耿志超和管聰。OpenSearch 是一個由亞馬遜雲科技發起的純開源搜尋和實時分析引擎專案。目前軟體超過 5 億下載量,社群在全球擁有 70 個以上的企業合作伙伴。
相關性表現在不同查詢上的穩定性:zero-shot 語義檢索要求語義編碼模型在不同背景的資料集上都有不錯的相關性表現,即要求語言模型即開即用,無需使用者在自己的資料集上 fine-tune。利用稀疏編碼與詞向量(Term Vector)同源的特性,Neural Sparse 可以在遇到陌生文字表述(行業專有詞、縮寫等等)的時候向文字匹配降級,從而避免離譜的檢索結果。 線上搜尋的時間效率:低時延對於實時檢索應用的意義是顯而易見的。目前流行的語義檢索方法一般都會包含語義編碼以及索引兩個過程,這兩者的速度決定了一個檢索應用端到端的檢索效率。Neural Sparse 獨特的 doc-only 模式,無需線上編碼,即能在與文字匹配相近的時延情況下,達成與一流語言模型相媲美的語義檢索的精度。 索引的儲存資源消耗:商業化的檢索應用對儲存資源的消耗是非常敏感的。在對海量資料進行索引時,搜尋引擎的執行成本與儲存資源的消耗強相關。在相關實驗中,索引相同規模的資料,Neural Sparse 僅需要 k-NN 索引的 1/10。同時記憶體消耗也大大小於 k-NN 索引。
Relevance Demo
文件主頁:https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/ 專案 Github 地址:https://github.com/opensearch-project/neural-search
稀疏編碼與稠密編碼對比
*整個系統在只執行 OpenSearch 時的記憶體,包括 JVM 的堆內和堆外記憶體
部分資料集上幾個方法的相關性表現比較
兩階段式搜尋速度對比
PUT /_cluster/settings
{
"transient" : {
"plugins.ml_commons.allow_registering_model_via_url" : true,
"plugins.ml_commons.only_run_on_ml_node" : false
,
"plugins.ml_commons.native_memory_threshold" : 99
}
}
2. 部署編碼器
Opensearch 目前開源了 3 個模型。相關注冊資訊都可以在官方文件中獲取。我們以 amazon/neural-sparse/opensearch-neural-sparse-encoding-v1 為例,首先使用 register API 來註冊:
POST /_plugins/_ml/models/_register?deploy=true
{
"name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-v1",
"version": "1.0.1",
"model_format": "TORCH_SCRIPT"
}
{
"task_id": "<task_id>",
"status": "CREATED"
}
用 task_id 來得到詳細的註冊資訊:
GET /_plugins/_ml/tasks/
在 API 返回中,我們可以拿到具體的 model_id:
{
"model_id": "<model_id>",
"task_type": "REGISTER_MODEL",
"function_name": "SPARSE_TOKENIZE",
"state": "COMPLETED",
"worker_node": [
"wubXZX7xTIC7RW2z8nzhzw"
],
"create_time":1701390988405,
"last_update_time": 1701390993724,
"is_async": true
}
在索引之前,每個文件需要被編碼的文字欄位需要被轉變成稀疏向量。在 OpenSearch 中,這一過程是透過前處理器來自動實現的。你可以使用以下 API 來建立離線索引時的處理器管線:
PUT /_ingest/pipeline/neural-sparse-pipeline
{
"description": "An example neural sparse encoding pipeline",
"processors" : [
{
"sparse_encoding": {
"model_id": "<model_id>",
"field_map": {
"passage_text": "passage_embedding"
}
}
}
]
}
如果需要開啟兩階段加速功能 (非必需功能),則需要建立一個兩階段搜尋管線,並在索引建立之後設定為預設的搜尋管線。
建立一個預設引數的兩階段加速搜尋管線方式如下,更詳細的引數設定和意義請參考 2.15 及以後版本的 OpenSearch 官方文件。
PUT /_search/pipeline/two_phase_search_pipeline
{
"request_processors": [
{
"neural_sparse_two_phase_processor": {
"tag": "neural-sparse",
"description": "This processor is making two-phase processor."
}
}
]
}
4. 設定索引
神經稀疏搜尋利用 rank_features 欄位型別來儲存編碼得到的詞元和相對應的權重。索引將使用上述前處理器來編碼文字。我們可以按以下方式建立索一個包含兩階段搜尋加速管線的索引(如果不想開啟此功能,可把 `two_phase_search_pipeline` 替換為 `_none` 或刪除 `settings.search` 這一配置單元)。
PUT /my-neural-sparse-index
{
"settings": {
"ingest":{
"default_pipeline":"neural-sparse-pipeline"
},
"search":{
"default_pipeline":"two_phase_search_pipeline"
}
},
"mappings": {
"properties": {
"passage_embedding": {
"type": "rank_features"
},
"passage_text": {
"type": "text"
}
}
}
}
PUT /my-neural-sparse-index/_doc/
{
"passage_text": "Hello world"
}
在索引中進行稀疏語義搜尋的介面如下,將 <model_id> 替換為第二步中註冊的 model_id:
GET my-neural-sparse-index/_search
{
"query":
{
"neural_sparse":
{
"passage_embedding":
{
"query_text": "Hi world",
"model_id": <model_id>
}
}
}
}