作者:?Andre Luiz
討論如何以及何時使用 semantic_text
、dense_vector
或 sparse_vector
,以及它們與嵌入生成的關系。
通過這個自定進度的 Search AI 實踐學習親自體驗向量搜索。你可以開始免費云試用,或者在本地機器上嘗試 Elastic。
多年來,使用嵌入來提升信息檢索的相關性和準確性已經顯著增長。像 Elasticsearch 這樣的工具已經發展出支持這種類型數據的專用字段類型,比如密集向量、稀疏向量和語義文本。然而,為了獲得良好的效果,關鍵在于理解如何正確地將嵌入映射到 Elasticsearch 可用的字段類型:semantic_text
、dense_vector
和 sparse_vector
。
本文將討論這些字段類型、各自的適用時機,以及它們在索引和查詢過程中與嵌入生成和使用策略之間的關系。
密集向量類型
在 Elasticsearch 中,dense_vector
字段類型用于存儲密集向量,這些向量是文本的數值表示,其中幾乎所有維度都是相關的。這些向量由語言模型生成,如 OpenAI、Cohere 和 Hugging Face,旨在捕捉文本的整體語義含義,即使它與其他文檔沒有共享相同的詞語。
在 Elasticsearch 中,密集向量的維度上限為 4096,具體取決于所使用的模型。例如,all-MiniLM-L6-v2
模型生成 384 維向量,而 OpenAI 的 text-embedding-ada-002
生成 1536 維向量。
當需要更大的控制權時,例如使用預生成的向量、應用自定義相似度函數或與外部模型集成,dense_vector
字段通常被作為存儲這類嵌入的默認類型。
何時以及為何使用 dense_vector
類型?
密集向量非常適合用于捕捉句子、段落或完整文檔之間的語義相似性。當目標是比較文本的整體含義,即使它們不共享相同詞語時,它們也表現得非常好。
當你已經有一個外部嵌入生成流程,使用如 OpenAI、Cohere 或 Hugging Face 等模型,并且只想手動存儲和查詢這些向量時,dense_vector
字段是理想選擇。這種字段類型高度兼容嵌入模型,并在生成和查詢上提供完全的靈活性,讓你可以控制向量的生成、索引以及搜索中的使用方式。
此外,它支持多種語義搜索形式,如 KNN
或 script_score
查詢,適用于需要調整排序邏輯的場景。這些能力使 dense_vector
成為 RAG(檢索增強生成)、推薦系統以及基于相似度的個性化搜索等應用的理想選擇。
最后,該字段允許你自定義相關性邏輯,可使用如 cosineSimilarity
、dotProduct
或 l2norm
等函數,根據你使用場景的需求來調整排序。
對于那些需要靈活性、自定義能力和與高級用例兼容性的用戶來說,密集向量仍然是最佳選擇。
如何對 dense_vector
類型使用查詢?
對定義為 dense_vector
的字段進行搜索時,使用的是 k-nearest neighbor 查詢(KNN 查詢)。該查詢用于查找與查詢向量最接近的文檔。以下是一個將 KNN 查詢應用于 dense_vector
字段的示例:
{"knn": {"field": "my_dense_vector","k": 10,"num_candidates": 50,"query_vector": [/* vector generated by model */]}
}
除了使用 Knn 查詢外,如果需要自定義文檔評分,也可以使用 script_score 查詢,將其與如 cosineSimilarity、dotProduct 或 l2norm 等向量比較函數結合,以更可控的方式計算相關性。請看示例:
{
"script_score": {"query": { "match_all": {} },"script": {"source": "cosineSimilarity(params.query_vector,
'my_dense_vector') + 1.0","params": {"query_vector": [/* vector */]}}}
}
如果你想深入了解,我推薦閱讀文章《How to set up vector search in Elasticsearch》。
稀疏向量類型
sparse_vector
字段類型用于存儲稀疏向量,這種向量的大多數值為零,只有少數詞語具有顯著權重。這種向量常見于基于詞項的模型,如 SPLADE 或 ELSER(Elastic Learned Sparse EncodeR)。
何時以及為何使用稀疏向量類型?
稀疏向量非常適合在需要詞匯層面更精確搜索,同時不犧牲語義智能的情況下使用。它們將文本表示為 token/value 對,僅突出最相關的詞語及其權重,提供了清晰性、控制力和效率。
這種字段類型在基于詞項生成向量時特別有用,比如 ELSER 或 SPLADE 模型,根據詞元在文本中的相對重要性為每個詞元分配不同權重。
當你想控制查詢中特定詞語的影響時,稀疏向量類型允許你手動調整詞語的權重,以優化結果排序。
主要優勢包括搜索的透明性,因為可以清楚理解為什么某個文檔被認為相關;存儲效率,因為只保存非零值的詞元,而密集向量則保存所有維度。
此外,稀疏向量是混合搜索策略的理想補充,甚至可以與密集向量結合,將詞匯精度與語義理解融合。
如何對稀疏向量類型使用查詢?
sparse_vector
查詢允許你基于詞元/值格式的查詢向量搜索文檔。下面是查詢示例:
{"query": {"sparse_vector": {"field": "field_sparse","query_vector": {"token1": 0.5,"token2": 0.3,"token3": 0.2}}}
}
如果你更喜歡使用訓練好的模型,可以使用推理端點,它會自動將查詢文本轉換為稀疏向量:
{"query": {"sparse_vector": {"field": "field_sparse","inference_id": "the inference ID to produce the token/weights","query": "search text"}}
}
要進一步了解這個主題,我建議閱讀《Understanding sparse vector embeddings with trained ML models》。
語義文本類型 - semantic_text
semantic_text
字段類型是 Elasticsearch 中使用語義搜索最簡單、最直接的方式。它通過推理端點自動處理嵌入生成,既在索引時也在查詢時完成。這意味著你不必擔心手動生成或存儲向量。
何時以及為何使用 semantic_text
?
semantic_text
字段是采用 Elasticsearch 語義搜索最簡單直接的方式。它適合那些想以最少技術投入開始,并且不想手動處理向量的用戶。該字段自動化了嵌入生成和向量搜索映射等步驟,使設置更快、更方便。
當你重視簡潔和抽象時,應考慮使用 semantic_text
,它消除了手動配置映射、嵌入生成和數據接收流程的復雜性。只需選擇推理模型,剩下的由 Elasticsearch 處理。
主要優勢包括自動嵌入生成(在索引和查詢時進行),以及預配置支持所選推理模型的現成映射。
此外,該字段原生支持長文本自動拆分(文本分塊),允許將大段文本分成更小的片段,每個片段都有自己的嵌入,提升搜索精度。這極大提高了生產力,特別適合希望快速交付價值且不想處理語義搜索底層工程的團隊。
不過,雖然 semantic_text
提供速度和簡潔,但也有一定限制。它支持市場標準模型,只要它們作為 Elasticsearch 中的推理端點可用。但不支持像 dense_vector
字段那樣使用外部生成的嵌入。
如果你需要更多控制嵌入生成方式、想使用自己的嵌入,或者需要結合多個字段進行高級策略,dense_vector
和 sparse_vector
字段則提供了適合更定制或領域專用場景的靈活性。
如何對 semantic_text
類型使用查詢
在 semantic_text
出現之前,查詢要根據嵌入類型(密集或稀疏)使用不同的查詢。稀疏字段用 sparse_vector
查詢,密集字段用 KNN 查詢。
使用 semantic_text
類型時,搜索通過 semantic 查詢進行,它自動生成查詢向量,并與已索引文檔的嵌入進行比較。semantic_text
類型允許你定義一個推理端點來嵌入查詢,如果沒有指定,則會使用索引時相同的端點來處理查詢。
{"query": {"semantic": {"field": "semantic_text_field","query": "search text"}}
}
要了解更多,我建議閱讀文章《Elasticsearch:使用 semantic_text 簡化語義搜索》。
總結
在選擇如何在 Elasticsearch 中映射嵌入時,理解你想如何生成向量以及需要多少控制權是非常重要的。如果你追求簡單,semantic_text
字段支持自動且可擴展的語義搜索,適合很多初始用例。當需要更多控制、微調性能或與自定義模型集成時,dense_vector
和 sparse_vector
字段提供所需的靈活性。
理想的字段類型取決于你的用例、可用基礎設施以及機器學習堆棧的成熟度。最重要的是,Elastic 提供了構建現代且高度適應性搜索系統的工具。
原文:Elasticsearch new semantic_text mapping: Simplifying semantic search - Elasticsearch Labs