溫州專(zhuān)業(yè)網(wǎng)站建設(shè)西安seo排名
作者:來(lái)自 Elastic?Valentin Crettaz
了解如何在 Elasticsearch 中設(shè)置向量搜索并執(zhí)行 k-NN 搜索。
本文是三篇系列文章中的第二篇,深入探討了向量搜索(也稱(chēng)為語(yǔ)義搜索)的復(fù)雜性以及它在 Elasticsearch 中的實(shí)現(xiàn)方式。
第一部分重點(diǎn)介紹了嵌入(又稱(chēng)向量)的基礎(chǔ)知識(shí)以及向量搜索的底層工作原理。
憑借第一篇文章中學(xué)到的所有向量搜索知識(shí),第二部分將指導(dǎo)你了解如何在 Elasticsearch 中設(shè)置向量搜索和執(zhí)行 k-NN 搜索。
在第三部分中,我們將利用前兩部分中學(xué)到的知識(shí),并在此基礎(chǔ)上深入研究如何在 Elasticsearch 中制作強(qiáng)大的混合搜索查詢(xún)。
首先介紹一些背景
盡管 Elasticsearch 直到 8.0 版(帶有 _knn_search API 端點(diǎn)的技術(shù)預(yù)覽)才支持向量搜索,但自 7.0 版發(fā)布以來(lái),已經(jīng)可以使用 dense_vector 字段類(lèi)型存儲(chǔ)向量。那時(shí),向量只是作為二進(jìn)制文檔值存儲(chǔ),但沒(méi)有使用我們?cè)诘谝黄恼轮薪榻B的任何算法進(jìn)行索引。這些密集向量構(gòu)成了 Elasticsearch 中即將推出的向量搜索功能的前提。
如果你有興趣深入了解導(dǎo)致 Elasticsearch 中當(dāng)前實(shí)現(xiàn)向量搜索的討論,你可以參考此問(wèn)題,其中詳細(xì)介紹了 Elastic 為將此功能推向市場(chǎng)而必須克服的所有障礙。簡(jiǎn)而言之,由于 Elasticsearch 已經(jīng)大量使用 Lucene 作為其底層搜索引擎,我們還決定使用與我們的向量引擎相同的技術(shù),并以非常透明的方式解釋了該決定背后的理由。
歷史問(wèn)題已經(jīng)解決,現(xiàn)在讓我們開(kāi)始工作。
如何設(shè)置 k-NN
Elasticsearch 本身就提供向量搜索,無(wú)需安裝任何特定程序。我們只需要?jiǎng)?chuàng)建一個(gè)索引,該索引定義至少一個(gè)類(lèi)型為 density_vector 的字段,向量數(shù)據(jù)將存儲(chǔ)在該字段中并/或被索引。
下面的映射顯示了一個(gè)名為 title_vector 的 3 維 dense_vector 字段。在此字段中存儲(chǔ)和索引的密集向量將使用我們?cè)诒鞠盗械谝黄恼轮薪榻B的 dot_product 相似度函數(shù)。值得注意的是,在 8.11 之前,hnsw(即 Hierarchical Navigable Small Worlds)是 Apache Lucene 支持的唯一用于索引密集向量的算法。從那時(shí)起,其他算法被添加,未來(lái),Elasticsearch 可能會(huì)提供用于索引和搜索密集向量的其他方法,但由于它完全依賴(lài)于 Apache Lucene,因此這將取決于這方面的進(jìn)展。
"title_vector": {"type": "dense_vector","dims": 3,"index": true,"similarity": "dot_product","index_options": {"type": "hnsw","ef_construction": 128,"m": 24 }
}
下表總結(jié)了 Elasticsearch 提供的 dense_vector 字段類(lèi)型的所有可用配置參數(shù):
參數(shù) | 必需 | 描述 |
---|---|---|
dims | Yes (<8.11) No (8.11+) | 向量維數(shù),在 8.9.2 之前不能超過(guò) 1024,在 8.10.0 之后不能超過(guò) 2048,在 8.11.0 之后不能超過(guò) 4096。此外,從 8.11 開(kāi)始,此參數(shù)不再需要,將默認(rèn)為第一個(gè)索引向量的維數(shù)。 |
element_type | No | 向量元素值的數(shù)據(jù)類(lèi)型,若不指定,則默認(rèn)為 `float`(4 個(gè)字節(jié)),也可以使用 `byte`(1 個(gè)字節(jié))和 `bit`。 |
index | No | 指示是否在專(zhuān)用且優(yōu)化的數(shù)據(jù)結(jié)構(gòu)中索引向量(如果為 “true”)或僅將其存儲(chǔ)為二進(jìn)制文檔值(如果為“false”)。在 8.10 之前,如果未指定,則默認(rèn)值為“false”。從 8.11 開(kāi)始,如果未指定,則默認(rèn)值為 “true”。 |
similarity | Yes (<8.11) No (8.11+) | 直到 8.10 版本,如果 `index` 為 `true`,則此參數(shù)是必需的,并定義用于 k-NN 搜索的向量相似度度量。可用的度量包括:a) `l2_norm`:L2 距離 b) `dot_product`:點(diǎn)積相似度 c) `cosine`:余弦相似度 d) `max_inner_product`:最大內(nèi)積相似度。還請(qǐng)注意,只有當(dāng)你的向量已經(jīng)歸一化(即,它們是幅度為 1 的單位向量)時(shí),才應(yīng)使用 `dot_product`,否則使用 `cosine` 或 `max_inner_product`。從 8.11 版本開(kāi)始,如果未指定,則如果 element_type 為 `bit`,則此參數(shù)默認(rèn)為 `l2_norm`,否則為 `cosine`。 |
index_options | No | 以下是 `type` 參數(shù)可能的值(具體取決于版本):a) 直到 8.11,僅支持 `hnsw`。b) 在 8.12 中,標(biāo)量量化啟用了 `int8_hnsw` c) 在 8.13 中,添加了 `flat` 及其標(biāo)量量化的 `int8_flat` 兄弟 d) 在 8.15 中,添加了 `int4_hnsw` 和 `int4_flat` e) 在 8.18 中,二進(jìn)制量化啟用了 `bbq_hnsw` 和 `bbq_flat`。你可以查看官方文檔以了解它們的詳細(xì)描述(https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html#dense-vector-params)以及如何配置每個(gè)算法。 |
從上表可以看出,自 8.11 版本以來(lái),想量場(chǎng)的定義已大大簡(jiǎn)化:
關(guān)于 8.12 中添加的標(biāo)量量化支持,請(qǐng)記住,我們?cè)诒鞠盗械牡谝徊糠种杏懻撨^(guò)這種壓縮技術(shù)。我們不會(huì)在本文中深入探討,但你可以在另一篇 Elastic Search Labs 文章中了解有關(guān)如何在 Lucene 中實(shí)現(xiàn)這一點(diǎn)的更多信息。同樣,我們不會(huì)深入研究 8.18 中添加的更好的二進(jìn)制量化 (BBQ),我們邀請(qǐng)你在本文中了解有關(guān)該新突破性算法的更多信息。
就這些了!只需定義和配置一個(gè) dense_vector 字段,我們現(xiàn)在就可以索引向量數(shù)據(jù),以便使用 knn 搜索選項(xiàng)或 knn DSL 查詢(xún)(在 8.12 中引入)在 Elasticsearch 中運(yùn)行向量搜索查詢(xún)。Elasticsearch 支持兩種不同的向量搜索模式:1) 使用 script_score 查詢(xún)進(jìn)行精確搜索和 2) 使用 knn 搜索選項(xiàng)或 knn 查詢(xún)(8.12+)進(jìn)行近似最近鄰搜索。接下來(lái)我們將描述這兩種模式。
精確搜索
如果你回想一下本系列的第一篇文章,我們回顧了向量搜索概況,那么精確向量搜索可以歸結(jié)為在整個(gè)向量空間中執(zhí)行線性搜索或強(qiáng)力搜索(brute-force search)?;旧?#xff0c;查詢(xún)向量將根據(jù)每個(gè)存儲(chǔ)的向量進(jìn)行測(cè)量,以找到最近的鄰居。在此模式下,向量不需要在 HNSW 圖中編入索引,而只需存儲(chǔ)為二進(jìn)制文檔值,相似度計(jì)算由自定義 Painless 腳本運(yùn)行。
首先,我們需要以不對(duì)向量進(jìn)行索引的方式定義向量場(chǎng)映射,這可以通過(guò)在映射中指定 index: false 和 no 相似度度量來(lái)實(shí)現(xiàn):
# 1. Create a simple index with a dense_vector field of dimension 3
PUT /my-index
{"mappings": {"properties": {"price": {"type": "integer"},"title_vector": {"type": "dense_vector","dims": 3,"index": false}}}
}# 2. Load that index with some data
POST my-index/_bulk
{ "index": { "_id": "1" } }
{ "title_vector": [2.2, 4.3, 1.8], "price": 23}
{ "index": { "_id": "2" } }
{ "title_vector": [3.1, 0.7, 8.2], "price": 9}
{ "index": { "_id": "3" } }
{ "title_vector": [1.4, 5.6, 3.9], "price": 124}
{ "index": { "_id": "4" } }
{ "title_vector": [1.1, 4.4, 2.9], "price": 1457}
這種方法的優(yōu)點(diǎn)是向量不需要索引,這大大降低了提取時(shí)間,因?yàn)椴恍枰獦?gòu)建底層 HNSW 圖。但是,根據(jù)數(shù)據(jù)集的大小和硬件,隨著數(shù)據(jù)量的增加,搜索查詢(xún)可能會(huì)很快變慢,因?yàn)樘砑拥南蛄吭蕉?#xff0c;訪問(wèn)每個(gè)向量所需的時(shí)間就越長(zhǎng)(即線性搜索的復(fù)雜度為 O(n))。
創(chuàng)建索引并加載數(shù)據(jù)后,我們現(xiàn)在可以使用以下 script_score 查詢(xún)運(yùn)行精確搜索:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"query": {"script_score": {"query" : {"bool" : {"filter" : {"range" : {"price" : {"gte": 100}}}}},"script": {"source": "cosineSimilarity(params.queryVector, 'title_vector') + 1.0","params": {"queryVector": [0.1, 3.2, 2.1]}}}}
}
如你所見(jiàn),script_score 查詢(xún)由兩個(gè)主要元素組成,即查詢(xún)和腳本。在上面的示例中,查詢(xún)部分指定了一個(gè)過(guò)濾器(即 price >= 100),該過(guò)濾器限制了將針對(duì)其執(zhí)行腳本的文檔集。如果未指定查詢(xún),則相當(dāng)于使用 match_all 查詢(xún),在這種情況下,腳本將針對(duì)索引中存儲(chǔ)的所有向量執(zhí)行。根據(jù)向量的數(shù)量,搜索延遲可能會(huì)大幅增加。
由于向量未編入索引,因此沒(méi)有內(nèi)置算法可以測(cè)量查詢(xún)向量與存儲(chǔ)向量的相似性,這必須通過(guò)腳本來(lái)完成,幸運(yùn)的是,Painless 提供了我們迄今為止學(xué)到的大多數(shù)相似性函數(shù),例如:
l1norm(vector, field)
: L1 distance (Manhattan distance)l2norm(vector, field)
: L2 distance (Euclidean distance)hamming(vector, field)
: Hamming distancecosineSimilarity(vector, field)
: Cosine similaritydotProduct(vector, field):
?Dot product similarity
由于我們正在編寫(xiě)腳本,因此也可以構(gòu)建我們自己的相似性算法。 Painless 通過(guò)提供對(duì) doc[<field>].vectorValue(允許迭代向量數(shù)組)和 doc[<field>].magnitude(返回向量的長(zhǎng)度)的訪問(wèn)來(lái)實(shí)現(xiàn)這一點(diǎn)。
總而言之,盡管精確搜索的擴(kuò)展性不佳,但它可能仍然適用于某些非常小的用例,但如果你知道數(shù)據(jù)量會(huì)隨著時(shí)間的推移而增長(zhǎng),則需要考慮改用 k-NN 搜索。 這就是我們接下來(lái)要介紹的內(nèi)容。
近似 k-NN 搜索
大多數(shù)情況下,如果你有大量數(shù)據(jù)并且需要使用 Elasticsearch 實(shí)現(xiàn)向量搜索,則你將選擇此模式。索引延遲稍高一些,因?yàn)?Lucene 需要構(gòu)建底層 HNSW 圖來(lái)存儲(chǔ)和索引所有向量。它在搜索時(shí)的內(nèi)存要求方面也要求更高一些,之所以稱(chēng)為 “近似”,是因?yàn)槠錅?zhǔn)確度永遠(yuǎn)不可能像精確搜索那樣達(dá)到 100%。盡管如此,近似 k-NN 的搜索延遲要低得多,并且允許我們擴(kuò)展到數(shù)百萬(wàn)甚至數(shù)十億個(gè)向量,前提是你的集群大小合適。
讓我們看看它是如何工作的。首先,讓我們創(chuàng)建一個(gè)具有足夠向量場(chǎng)映射的示例索引來(lái)索引向量數(shù)據(jù)(即 index: true + 特定 similarity 定義)并用一些數(shù)據(jù)加載它:
# 1. Create a simple index with a dense_vector field of dimension 3
PUT /my-index
{"mappings": {"properties": {"price": {"type": "integer"},"title_vector": {"type": "dense_vector","dims": 3,"index": true, # default since 8.11"similarity": "cosine", # default since 8.11"index_options": {"type": "int8_hnsw", # default value since 8.12"ef_construction": 128,"m": 24 }}}}
}# 2. Load that index with some data
POST my-index/_bulk
{ "index": { "_id": "1" } }
{ "title_vector": [2.2, 4.3, 1.8], "price": 23}
{ "index": { "_id": "2" } }
{ "title_vector": [3.1, 0.7, 8.2], "price": 9}
{ "index": { "_id": "3" } }
{ "title_vector": [1.4, 5.6, 3.9], "price": 124}
{ "index": { "_id": "4" } }
{ "title_vector": [1.1, 4.4, 2.9], "price": 1457}
簡(jiǎn)單的 k-NN 搜索
運(yùn)行這兩個(gè)命令后,我們的想量數(shù)據(jù)現(xiàn)在已在標(biāo)量量化的 HNSW 圖中正確索引,可供搜索。直到 8.11 版,運(yùn)行簡(jiǎn)單 k-NN 搜索的唯一方法是使用 knn 搜索選項(xiàng),該選項(xiàng)與你習(xí)慣的 query 部分位于同一級(jí)別,如以下查詢(xún)所示:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100}
}
在上面的搜索負(fù)載中,我們可以看到?jīng)]有像詞匯搜索那樣的 query 部分,而是 knn 部分。我們正在搜索與指定查詢(xún)向量最接近的兩個(gè)(k:2)相鄰向量。
從 8.12 開(kāi)始,引入了新的 knn 搜索查詢(xún)(knn?search query),以允許更高級(jí)的混合搜索用例,這是我們將在下一篇文章中討論的主題。除非你具備將 k-NN 查詢(xún)與其他查詢(xún)相結(jié)合所需的專(zhuān)業(yè)知識(shí),否則 Elastic 建議堅(jiān)持使用更易于使用的 knn 搜索選項(xiàng)。首先要注意的是,新的 knn 搜索查詢(xún)沒(méi)有 k 參數(shù),而是像任何其他查詢(xún)一樣使用 size 參數(shù)。第二件值得注意的是,新的 knn 查詢(xún)通過(guò)利用將一個(gè)或多個(gè)過(guò)濾器與 knn 搜索查詢(xún)相結(jié)合的 bool 查詢(xún)來(lái)實(shí)現(xiàn)對(duì) k-NN 搜索結(jié)果的后過(guò)濾,如下面的代碼所示:
POST my-index/_search
{"size": 3,"_source": false,"fields": [ "price" ],"query" : {"bool" : {"must" : {"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"num_candidates": 100}},"filter" : {"range" : {"price" : {"gte": 100}}}}}
}
上述查詢(xún)首先檢索具有最近鄰向量的前 3 個(gè)文檔,然后過(guò)濾掉 price 小于 100 的文檔。值得注意的是,使用這種后過(guò)濾,如果過(guò)濾器過(guò)于激進(jìn),你可能最終得不到任何結(jié)果。還請(qǐng)注意,此行為不同于通常的布爾全文查詢(xún),其中首先執(zhí)行過(guò)濾部分以減少需要評(píng)分的文檔集。如果你有興趣了解有關(guān) knn 頂級(jí)搜索選項(xiàng)和新 knn 搜索查詢(xún)之間的差異的更多信息,你可以前往另一篇很棒的搜索實(shí)驗(yàn)室文章了解更多詳細(xì)信息。
現(xiàn)在讓我們繼續(xù)了解有關(guān) num_candidates 參數(shù)的更多信息。num_candidates 的作用是增加或減少找到真正最近鄰候選的可能性。該數(shù)字越高,搜索速度越慢,但找到真正最近鄰的可能性也越大。每個(gè)分片上將考慮 num_candidates 個(gè)向量,并將前 k 個(gè)向量返回到協(xié)調(diào)器節(jié)點(diǎn),協(xié)調(diào)器節(jié)點(diǎn)將合并所有分片本地結(jié)果并返回全局結(jié)果中的前 k 個(gè)向量,如下圖 1 所示:

向量 id4 和 id2 分別是第一個(gè)分片上的 k 個(gè)局部最近鄰,id5 和 id7 分別是第二個(gè)分片上的 k 個(gè)局部最近鄰。在對(duì)它們進(jìn)行合并和重新排序后,協(xié)調(diào)器節(jié)點(diǎn)將返回 id4 和 id5 作為搜索查詢(xún)的兩個(gè)全局最近鄰。
多個(gè) k-NN 搜索
如果你的索引中有多個(gè)向量字段,則可以發(fā)送多個(gè) k-NN 搜索,因?yàn)?knn 部分還接受查詢(xún)數(shù)組,如下所示:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": [{"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100,"boost": 0.4},{"field": "content_vector","query_vector": [0.1, 3.2, 2.1],"k": 5,"num_candidates": 100,"boost": 0.6}]
}
我們可以看到,每個(gè)查詢(xún)可以采用不同的 k 值以及不同的提升因子。提升因子相當(dāng)于權(quán)重,總得分將是兩個(gè)得分的加權(quán)平均值。
過(guò)濾的 k-NN 搜索
與我們之前在 script_score 查詢(xún)中看到的類(lèi)似,knn 部分也接受過(guò)濾器的規(guī)范,以減少近似搜索應(yīng)運(yùn)行的向量空間。例如,在下面的 k-NN 搜索中,我們將搜索限制為僅搜索價(jià)格大于或等于 100 的文檔。
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100,"filter" : {"range" : {"price" : {"gte": 100}}}}
}
現(xiàn)在,你可能想知道數(shù)據(jù)集是否先按 price 過(guò)濾,然后對(duì)過(guò)濾后的數(shù)據(jù)集運(yùn)行 k-NN 搜索(預(yù)過(guò)濾),還是反過(guò)來(lái),即先檢索最近鄰居,然后按 price 過(guò)濾(后過(guò)濾)。實(shí)際上,兩者都有一點(diǎn)。如果過(guò)濾器過(guò)于激進(jìn),預(yù)過(guò)濾的問(wèn)題在于 k-NN 搜索必須在非常小且可能稀疏的向量空間上運(yùn)行,并且不會(huì)返回非常準(zhǔn)確的結(jié)果。而后過(guò)濾可能會(huì)剔除大量高質(zhì)量的最近鄰居。
因此,即使 knn 部分 filter 被視為預(yù)過(guò)濾器,它也會(huì)在 k-NN 搜索期間工作,以確保至少可以返回 k 個(gè)鄰居。如果你對(duì)其工作原理感興趣,可以查看以下處理此事的 Lucene 問(wèn)題。
具有預(yù)期相似度的過(guò)濾 k-NN 搜索
在上一節(jié)中,我們了解到,在指定過(guò)濾器時(shí),我們可以減少搜索延遲,但我們也冒著將向量空間大幅減少為與查詢(xún)向量部分或大部分不相似的向量的風(fēng)險(xiǎn)。為了緩解這個(gè)問(wèn)題,k-NN 搜索還可以指定所有返回向量預(yù)計(jì)具有的最小相似度值(minimum?similarity)。重用上一個(gè)查詢(xún),它看起來(lái)會(huì)像這樣:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100,"similarity": 0.975,"filter" : {"range" : {"price" : {"gte": 100}}}}
}
基本上,它的工作方式是,通過(guò)跳過(guò)任何與提供的過(guò)濾器不匹配或相似度低于指定過(guò)濾器的向量來(lái)探索向量空間,直到找到 k 個(gè)最近鄰居。如果算法不能接受至少 k 個(gè)結(jié)果(由于過(guò)濾器過(guò)于嚴(yán)格或預(yù)期相似度太低),則將嘗試進(jìn)行強(qiáng)力搜索(brute-force),以便至少返回 k 個(gè)最近鄰居。
關(guān)于如何確定最小預(yù)期相似度的簡(jiǎn)短說(shuō)明。這取決于你在向量場(chǎng)映射中選擇了哪種相似度度量。如果你選擇了 l2_norm,它是一個(gè)距離函數(shù)(即相似度隨著距離的增加而減小),你將需要在 k-NN 查詢(xún)中設(shè)置最大預(yù)期距離,即你認(rèn)為可接受的最大距離。換句話說(shuō),與查詢(xún)向量的距離介于 0 和最大預(yù)期距離之間的向量將被視為足夠 “接近” 以相似。
如果你選擇了 dot_product 或 cosine,它們是相似度函數(shù)(即,相似度隨著向量角度變寬而降低),你將需要設(shè)置最小預(yù)期相似度。與查詢(xún)向量具有最小預(yù)期相似度和 1 之間的相似度的向量將被視為足夠 “接近” 以致相似。
應(yīng)用于上面的示例過(guò)濾查詢(xún)和我們之前已索引的示例數(shù)據(jù)集,下面的表 1 總結(jié)了查詢(xún)向量和每個(gè)索引向量之間的余弦相似度。我們可以看到,向量 3 和 4 被過(guò)濾器選中(price?>= 100),但只有向量 3 具有最小預(yù)期相似度(即 0.975)才能被選中。
Vector | Cosine similarity | Price |
---|---|---|
1 | 0.8473 | 23 |
2 | 0.5193 | 9 |
3 | 0.9844 | 124 |
4 | 0.9683 | 1457 |
k-NN 的局限性
現(xiàn)在我們已經(jīng)回顧了 Elasticsearch 中 k-NN 搜索的所有功能,讓我們看看你需要注意的幾個(gè)限制:
- 直到 8.11,k-NN 搜索都無(wú)法在嵌套文檔內(nèi)的向量字段上運(yùn)行。從 8.12 開(kāi)始,此限制已被取消。但是,這種嵌套的 knn 查詢(xún)不支持指定過(guò)濾器。
- search_type 始終設(shè)置為 dfs_query_then_fetch,并且無(wú)法動(dòng)態(tài)更改它。
- 在使用跨集群搜索跨不同集群進(jìn)行搜索時(shí),不支持 ccs_minimize_roundtrips 選項(xiàng)。
- 這已經(jīng)提到過(guò)幾次了,但由于 Lucene 使用的 HNSW 算法的性質(zhì)(以及任何其他近似最近鄰搜索算法),“近似??” 實(shí)際上意味著返回的 k 個(gè)最近鄰并不總是真實(shí)的。
調(diào)整 k-NN
你可以想象,你可以使用很多選項(xiàng)來(lái)優(yōu)化 k-NN 搜索的索引和搜索性能。我們不會(huì)在本文中介紹它們,但如果你真的想在 Elasticsearch 集群中實(shí)施 k-NN 搜索,我們強(qiáng)烈建議你在官方文檔中查看它們。
超越 k-NN
到目前為止,我們看到的一切都利用了密集(dense)向量模型(因此是致密向量字段類(lèi)型),其中向量通常包含非零值。Elasticsearch 還提供了使用稀疏(sparse)向量模型執(zhí)行語(yǔ)義搜索的另一種方法。
Elastic 創(chuàng)建了一個(gè)稀疏 NLP 向量模型,稱(chēng)為 Elastic Learned Sparse EncodeR,簡(jiǎn)稱(chēng) ELSER,這是一個(gè)域外(即未在特定域上訓(xùn)練)稀疏向量模型,不需要任何微調(diào)。它是在約 30000 個(gè)術(shù)語(yǔ)的詞匯表上進(jìn)行預(yù)訓(xùn)練的,并且作為一個(gè)稀疏模型,這意味著向量具有相同數(shù)量的值,其中大多數(shù)為零。
它的工作方式非常簡(jiǎn)單。在索引時(shí),使用推理攝取處理器生成稀疏向量(術(shù)語(yǔ)/權(quán)重對(duì)),并將其存儲(chǔ)在 sparse_vector 類(lèi)型的字段中,這是 dense_vector 向量字段類(lèi)型的稀疏對(duì)應(yīng)項(xiàng)。在查詢(xún)時(shí),特定的 DSL 查詢(xún)(也稱(chēng)為 sparse_vector)將用 ELSER 模型詞匯表中的可用術(shù)語(yǔ)替換原始查詢(xún)術(shù)語(yǔ),這些術(shù)語(yǔ)已知與它們的權(quán)重最相似。
我們不會(huì)在本文中深入探討 ELSER,但如果你渴望了解它的工作原理,你可以查看這篇開(kāi)創(chuàng)性的文章以及官方文檔,其中詳細(xì)解釋了該主題。
快速瀏覽一些即將推出的相關(guān)主題
Elasticsearch 還支持結(jié)合詞匯搜索和向量搜索,這將是本系列下一篇也是最后一篇文章的主題。
到目前為止,我們必須在 Elasticsearch 之外生成嵌入向量,并將它們明確傳遞到我們所有的查詢(xún)中。是否可以只提供查詢(xún)文本,然后模型就會(huì)動(dòng)態(tài)生成嵌入?好消息是,這可以通過(guò) Elasticsearch 來(lái)實(shí)現(xiàn),方法是利用名為 query_vector_builder 的構(gòu)造(用于密集向量)或使用新的 semantic_text 字段類(lèi)型和 semantic DSL 查詢(xún)(用于稀疏向量),你可以在這篇文章中了解有關(guān)這些技術(shù)的更多信息。
讓我們總結(jié)一下
在本文中,我們深入研究了 Elasticsearch 向量搜索支持。我們首先分享了 Elastic 尋求提供準(zhǔn)確向量搜索的一些背景,以及我們決定使用 Apache Lucene 作為向量索引和搜索引擎的原因。
然后,我們介紹了在 Elasticsearch 中執(zhí)行向量搜索的兩種主要方法,即利用 script_score 查詢(xún)來(lái)運(yùn)行精確的強(qiáng)力搜索,或者通過(guò) knn 搜索選項(xiàng)或 8.12 中引入的 knn 搜索查詢(xún)使用近似最近鄰搜索。
我們展示了如何運(yùn)行簡(jiǎn)單的 k-NN 搜索,然后,我們回顧了使用過(guò)濾器和預(yù)期相似性配置 knn 搜索選項(xiàng)和查詢(xún)的所有可能方法,以及如何同時(shí)運(yùn)行多個(gè) k-NN 搜索。
總結(jié)一下,我們列出了 k-NN 搜索的一些當(dāng)前限制以及需要注意的事項(xiàng)。我們還邀請(qǐng)你查看可用于優(yōu)化 k-NN 搜索的所有可能選項(xiàng)。
如果你喜歡你正在閱讀的內(nèi)容,請(qǐng)務(wù)必查看本系列的其他部分:
- 第 1 部分:向量搜索快速入門(mén)
- 第 3 部分:使用 Elasticsearch 進(jìn)行混合搜索(敬請(qǐng)期待!)
想要獲得 Elastic 認(rèn)證?了解下一次 Elasticsearch 工程師培訓(xùn)何時(shí)開(kāi)始!
Elasticsearch 包含許多新功能,可幫助你為你的用例構(gòu)建最佳搜索解決方案。深入了解我們的示例筆記本以了解更多信息,開(kāi)始免費(fèi)云試用,或立即在你的本地機(jī)器上試用 Elastic。
原文:How to set up vector search in Elasticsearch - Elasticsearch Labs