輕松構建聊天機器人、準確性新SOTA,RAG有了更強大的AI檢索器
黃志恒擁有愛丁堡大學博士和加州大學伯克利博士后研究經歷。志恒曾在微軟、百度、Facebook、騰訊和亞馬遜等 IT 公司工作。志恒在亞馬遜 AWS 擔任首席科學家領導了 Amazon Kendra 和 Amazon Q。志恒現在是 Denser.ai 的創始人。截至 2024 年 5 月,Google Scholar 引用次數超過 13,300 次。
李萬鈞是一位資深全棧工程師,同時具備設計師和運維工程師的專長。他曾在多個大型項目中擔任核心工程師和架構師,擁有豐富的實戰經驗。目前在 denser.ai 擔任全棧工程師,專注于將 AI 技術深度融合到軟件開發的各個階段。
檢索增強生成 (RAG) 是將檢索模型與生成模型結合起來,以提高生成內容的質量和相關性的一種有效的方法。RAG 的核心思想是利用大量文檔或知識庫來獲取相關信息。各種工具支持 RAG,包括 Langchain 和 LlamaIndex。
AI Retriever 是 RAG 框架的基礎,確保 AI 應用中的準確和無縫體驗。Retriever 大致分為兩類:關鍵詞搜索和向量搜索。關鍵詞搜索依賴于關鍵詞匹配,而向量搜索則關注語義相似性。流行的工具包括用于關鍵詞搜索的 Elasticsearch 和用于向量搜索的 Milvus、Chroma 和 Pinecone。
在大語言模型時代,從工程師和科學家到市場營銷等各個領域的專業人士,都熱衷于開發 RAG AI 應用原型。像 Langchain 這樣的工具對此過程至關重要。例如,用戶可以使用 Langhian 和 Chroma 快速構建一個用于法律文檔分析的 RAG 應用。
本文中,DenserAI 團隊推出的 Denser Retriever 在快速原型設計方面表現突出。用戶可以通過一個簡單的 Docker Compose 命令快速安裝 Denser Retriever 及其所需工具。Denser Retriever 不僅僅止步于此,它還提供了自托管解決方案,支持企業級生產環境的部署。
此外,Denser Retriever 在 MTEB 檢索數據集上提供了全面的檢索基準測試,以確保部署中的最高準確性。用戶不僅可以享受 Denser Retriever 的易用性,還可以享受其最先進的準確性。
- GitHub地址:https://github.com/denser-org/denser-retriever/tree/main
- 博客地址:https://denser.ai/blog/denser-retriever/
Denser Retriever 能做什么?
Denser Retriever 的初始版本提供了以下功能:
- 支持異構檢索器,如關鍵詞搜索、向量搜索和機器學習模型重排序。
- 利用 xgboost 機器學習技術有效結合異構檢索器。
- 在 MTEB 檢索基準測試中實現 State of the art accuracy。
- 演示如何使用 Denser Retriever 來驅動端到端應用,如聊天機器人和語義搜索。
為什么選擇 Denser Retriever?
- Open Source Commitment:Denser Retriever 是開源的,提供透明性和持續的社區驅動改進機會。
- Production-Ready:設計用于生產環境的部署,確保在實際應用中的可靠性和穩定性。
- State-of-the-art accuracy:提供最先進的準確性,提高 AI 應用質量。
- 可擴展性:無論是處理不斷增長的數據需求還是擴展用戶需求,Denser Retriever 都能無縫擴展以滿足要求。
- 靈活性:該工具適應廣泛的應用,并可根據具體需求進行定制,是多種行業的多功能選擇。
在這篇博客中,我們將展示如何安裝 Denser Retriever,從文本文件或網頁頁面構建檢索索引,并在此索引上進行查詢。
由于篇幅限制,本文不會涵蓋更多高級主題,如使用自定義數據集訓練 Denser Retriever、在 MTEB 基準數據集上進行評估以及創建端到端 AI 應用(如聊天機器人)。有興趣的用戶可參考以下資源獲取這些高級主題的信息。
設置
安裝 Denser Retriever
我們使用 Poetry 安裝和管理 Denser Retriever 包。在倉庫根目錄下使用以下命令安裝 Denser Retriever。
git clone https://github.com/denser-org/denser-retriever
cd denser-retriever
make install
更多細節可以在 DEVELOPMENT 文檔中找到:https://github.com/denser-org/denser-retriever/blob/main/DEVELOPMENT.md
安裝 Elasticsearch 和 Milvus
運行 Denser Retriever 需要 Elasticsearch 和 Milvus,它們分別支持關鍵詞搜索和向量搜索。我們按照以下指示在本地計算機(例如,您的筆記本電腦)上安裝 Elasticsearch 和 Milvus。
要求:docker 和 docker compose,它們都包含在 Docker Desktop 中,適用于 Mac 或 Windows 用戶。
- 手動下載 docker-compose.dev.yml 并保存為 docker-compose.yml,或者使用以下命令。
wget https://raw.githubusercontent.com/denser-org/denser-retriever/main/docker-compose.dev.yml \
-O docker-compose.yml
- 使用以下命令啟動服務。
docker compose up -d
- Optionally,我們可以運行以下命令驗證 Milvus 是否正確安裝。
poetry run python -m pytest tests/test_retriever_milvus.py
索引和查詢用例
在索引和查詢用例中,用戶提供一組文檔,如文本文件或網頁,以構建檢索器。然后用戶可以查詢該檢索器以從提供的文檔中獲取相關結果。此用例的代碼可在 index_and_query_from_docs.py 中找到。
代碼地址:https://github.com/denser-org/denser-retriever/blob/main/experiments/index_and_query_from_docs.py
要運行此示例,請導航到 denser-retriever 倉庫并執行以下命令:
poetry run python experiments/index_and_query_from_docs.py=
如果運行成功,我們預期會看到類似以下的輸出。
2024-05-27 12:00:55 INFO: ES ingesting passages.jsonl record 96
2024-05-27 12:00:55 INFO: Done building ES index
2024-05-27 12:00:55 INFO: Remove existing Milvus index state_of_the_union
2024-05-27 12:00:59 INFO: Milvus vector DB ingesting passages.jsonl record 96
2024-05-27 12:01:03 INFO: Done building Vector DB index
[{'source': 'tests/test_data/state_of_the_union.txt',
'text': 'One of the most serious constitutional responsibilities...',
'title': '', 'pid': 73,
'score': -1.6985594034194946}]
在接下來的部分中,我們將解釋其中的基礎過程和機制。
概述
下圖說明了 Denser Retriever 的結構,它由三個組件組成:
- 關鍵詞搜索依賴于使用精確關鍵詞匹配的傳統搜索技術。我們在 Denser Retriever 中使用 Elasticsearch。
- 向量搜索使用神經網絡模型將查詢和文檔編碼為高維空間中的密集向量表示。我們使用 Milvus 和 snowflake-arctic-embed-m 模型,該模型在 MTEB/BEIR 排行榜的各個尺寸變體中均實現了最先進的性能。
- ML 交叉編碼器重排序器可用于進一步提升上述兩種檢索方法的準確性。我們使用 cross-encoder/ms-marco-MiniLM-L-6-v2,該模型在準確性和推理延遲之間具有良好的平衡。
配置文件
我們在以下 yam 文件中配置上述三個組件。大多數參數是不言自明的。關鍵字、向量、重排序的部分分別配置 Elasticsearch、Milvus 和重排序器。
我們使用 combine: model 通過一個 xgboost 模型(experiments/models/msmarco_xgb_es+vs+rr_n.json)來結合 Elasticsearch、Milvus 和重排序器,該模型是使用 mteb msmarco 數據集訓練的(參見訓練配方了解如何訓練這樣的模型)。
除了模型組合,我們還可以使用線性或排名來結合 Elasticsearch、Milvus 和重排序器。在 MTEB 數據集上的實驗表明,模型組合可以顯著提高準確性,優于線性或排名方法。
一些參數,例如 es_ingest_passage_bs,僅在訓練 xgboost 模型時使用(即查詢階段不需要)。
version: "0.1"
# linear, rank or model
combine: model
keyword_weight: 0.5
vector_weight: 0.5
rerank_weight: 0.5
model: ./experiments/models/msmarco_xgb_es+vs+rr_n.json
model_features: es+vs+rr_n
keyword:
es_user: elastic
es_passwd: YOUR_ES_PASSWORD
es_host: http://localhost:9200
es_ingest_passage_bs: 5000
topk: 100
vector:
milvus_host: localhost
milvus_port: 19530
milvus_user: root
milvus_passwd: Milvus
emb_model: Snowflake/snowflake-arctic-embed-m
emb_dims: 768
one_model: false
vector_ingest_passage_bs: 2000
topk: 100
rerank:
rerank_model: cross-encoder/ms-marco-MiniLM-L-6-v2
rerank_bs: 100
topk: 100
output_prefix: ./denser_output_retriever/
max_doc_size: 0
max_query_size: 10000
生成 passages (段落)
我們現在描述如何從給定的文本文件(state_of_the_union.txt)構建一個檢索器。以下代碼顯示如何讀取文本文件,將文件分割成文本塊并將其保存為 jsonl 文件(passages.jsonl)。
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from denser_retriever.utils import save_HF_docs_as_denser_passages
from denser_retriever.retriever_general import RetrieverGeneral
# Generate text chunks
documents = TextLoader("tests/test_data/state_of_the_union.txt").load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
texts = text_splitter.split_documents(documents)
passage_file = "passages.jsonl"
save_HF_docs_as_denser_passages(texts, passage_file, 0)
passages.jsonl 中的每一行都是一個段落,包含 source、title、text 和 pid(段落 ID)字段。
{"source": "tests/test_data/state_of_the_union.txt",
"title": "",
"text": "Madam Speaker, Madam Vice President, our First Lady and Second Gentleman...",
"pid": 0}
構建 Denser 檢索器
我們可以使用給定的 passages.jsonl 和 experiments/config_local.yaml 配置文件來構建 Denser 檢索器。
# Build denser index
retriever_denser = RetrieverGeneral("state_of_the_union", "experiments/config_local.yaml")
retriever_denser.ingest(passage_file)
查詢 Denser 檢索器
我們可以簡單地使用以下代碼來查詢檢索器以獲得相關段落。
# Query
query = "What did the president say about Ketanji Brown Jackson"
passages, docs = retriever_denser.retrieve(query, {})
print(passages)
每個返回的段落都會接收一個置信分數,以指示它與給定查詢的相關性。我們得到類似以下的結果。
[{'source': 'tests/test_data/state_of_the_union.txt',
'text': 'One of the most serious constitutional...',
'title': '', 'pid': 73,
'score': -1.6985594034194946}]
將所有內容整合在一起
我們將所有代碼整合如下。代碼也可在 repo 中找到。
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from denser_retriever.utils import save_HF_docs_as_denser_passages
from denser_retriever.retriever_general import RetrieverGeneral
# Generate text chunks
documents = TextLoader("tests/test_data/state_of_the_union.txt").load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
texts = text_splitter.split_documents(documents)
passage_file = "passages.jsonl"
save_HF_docs_as_denser_passages(texts, passage_file, 0)
# Build denser index
retriever_denser = RetrieverGeneral("state_of_the_union", "experiments/config_local.yaml")
retriever_denser.ingest(passage_file)
# Query
query = "What did the president say about Ketanji Brown Jackson"
passages, docs = retriever_denser.retrieve(query, {})
print(passages)
從網頁構建檢索器
與上述方法類似,除了段落語料庫的生成。index_and_query_from_webpage.py 源代碼可以在這里找到。
要運行這個用例,請進入 denser-retriever repo 并運行:
poetry run python experiments/index_and_query_from_webpage.py
poetry run python experiments/index_and_query_from_webpage.py
如果成功,我們預計會看到類似以下的內容。
2024-05-27 12:10:47 INFO: ES ingesting passages.jsonl record 66
2024-05-27 12:10:47 INFO: Done building ES index
2024-05-27 12:10:52 INFO: Milvus vector DB ingesting passages.jsonl record 66
2024-05-27 12:10:56 INFO: Done building Vector DB index
[{'source': 'https://lilianweng.github.io/posts/2023-06-23-agent/',
'text': 'Fig. 1. Overview of a LLM-powered autonomous agent system...',
'title': '',
'pid': 2,
'score': -1.6985594034194946}]
進一步閱讀
由于篇幅限制,我們在這篇博客中未包括以下主題。
- 使用客戶數據集訓練 Denser Retriever。用戶提供一個訓練數據集來訓練一個 xgboost 模型,該模型決定如何結合關鍵字搜索、向量搜索和重排序。訓練和測試的工作流程如下圖所示。
- 在 MTEB 數據集上評估 Denser Retriever。通過 xgboost 模型結合關鍵字搜索、向量搜索和重排序可以進一步提高向量搜索基線。例如,我們最好的 xgboost 模型在所有 MTEB 數據集上的 NDCG@10 得分為 56.47,相比向量搜索基線(NDCG@10 得分 54.24)絕對提高了 2.23,相對提高了 4.11%。
- 端到端搜索和聊天應用。我們可以輕松使用 Denser Retriever 構建端到端的聊天機器人。
- 過濾器 (Filters)。上述索引和查詢用例假設搜索項僅包含非結構化文本。此假設可能不成立,因為數據集可能包含數值、分類和日期屬性。過濾器可用于為這些屬性設置約束。
Denser Retriever文檔:https://retriever.denser.ai/docs