發佈日期:

向量搜尋資料庫的比較

ChromaDB介紹

官方文件: https://docs.trychroma.com/getting-started

GitHub: https://github.com/chroma-core/chroma

Chroma是一個新的AI原生開源嵌入式資料庫,非常輕量且易用。 Chroma是開源嵌入式資料庫,它使知識、事實​​和技能可插入,從而輕鬆建立LLM應用程式。它可以運行在記憶體中(可保存在磁碟中),也可做為資料庫伺服器來使用(這和傳統資料庫類似)。

基本使用範例

import chromadb

# 建立客戶端
# 記憶體模式
# client = chromadb.Client()

# 持久模式,資料保存在磁碟
client = chromadb.PersistentClient(path="./chromac")

# Docker客戶端模式
# chroma_client = chromadb.HttpClient(host="localhost", port=8000)

# 遍歷所有集合
collections = client.list_collections()
print("現有的集合:", collections)

# 建立新集合
collection = client.create_collection("testname")

# 取得集合
collection = client.get_collection("testname")

# 建立或取得集合
collection = client.get_or_create_collection("testname")

# 刪除集合
client.delete_collection("testname")

# 建立或取得集合(帶有嵌入函數)
def embedding_function(doc):
    # 定義你的嵌入函數
    return [0.1, 0.2, 0.3]

collection = client.get_or_create_collection(name="my_collection2", embedding_function=embedding_function)

# 取得集合中最新的5條資料
latest_documents = collection.peek()
print("最新的資料:", latest_documents)

# 新增資料
collection.add(
    documents=[
        "2022年2月2號,美國國防部宣布:將向歐洲增派部隊,應對俄烏邊境地區的緊張局勢。",
        "2月17號,烏克蘭軍方稱:東部民間武裝向政府軍控制區發動砲擊,而東部民間武裝則指責烏政府軍先動用了重型武器發動襲擊,烏東地區緊張局勢持續升級。"
    ],
    metadatas=[
        {"source": "my_source"},
        {"source": "my_source"}
    ],
    ids=["id1", "id2"]
)

# 改變資料(更新或新增)
collection.upsert(
    ids=["id1"],
    documents=["更新後的文檔內容"],
    metadatas=[{"source": "updated_source"}]
)

# 刪除資料
collection.delete(ids=["id1", "id2"])

# 查詢資料
results = collection.query(
    query_texts=["俄烏戰爭發生在哪天?"],
    n_results=2
)
print("查詢結果:", results)

Elasticsearch Vector Store

Elasticsearch 是一個非常強大和靈活的搜索和分析引擎。雖然它的主要用例圍繞全文搜索,但它的用途足夠廣泛,可以用於各種其他功能。其中一個引起許多開發人員和數據科學家注意的功能是使用 Elasticsearch 作為向量資料庫。隨著 dense_vector 數據類型的出現和利用該 script_score 函數的能力,Elasticsearch 的功能已經擴展到促進向量相似性搜索。

Elasticsearch 與專用向量搜索庫相比的優點

使用 Elasticsearch 作為向量資料庫的不可否認的優勢之一是其內置功能,可以過濾對特定數據子集的查詢。當您想要縮小搜索空間範圍或應用程式需要上下文感知向量搜索時,此功能非常有用。相比之下,雖然其他專用的向量搜索庫(如 ChromaDB 和 Faiss)為純向量搜索提供了無可挑剔的速度和效率,但它們缺乏 Elasticsearch 中的全功能查詢功能。例如,ChromaDB 確實允許查詢元數據,但它僅限於字元串的精確匹配。此限制有時會妨礙複雜搜索方案中所需的靈活性和粒度。

將 Elasticsearch 豐富的查詢環境與向量相似度搜索相結合,意味著使用者可以兩全其美:基於向量的精確結果,並通過使用細緻入微的上下文感知篩檢程式對這些搜索進行分層的能力來增強。這種合併使 Elasticsearch 成為需要深度和廣度的開發人員的有力選擇。

Elasticsearch 與專用向量搜索庫的缺點

Elasticsearch 憑藉其廣泛的工具集和適應性,在搜尋引擎領域為自己開闢了一席之地。然而,當與 Faiss 和 ChromaDB 等專門的向量搜索庫相比時,它在某些領域暴露了它的局限性。

近似最近鄰和分層可導航小世界技術

對於Elasticsearch的OpenSearch版本7來說,它缺乏對近似最近鄰(ANN)算法和分層可導航小世界(HNSW)技術的內置支持。這些先進的方法對於提高在廣泛數據集中的搜索速度至關重要。利用它們,搜索速度可以大大加快,而準確性只有很小的權衡。

Faiss 和 ChromaDB

Faiss 和 ChromaDB 將這些策略作為核心技術,展示了快速導航廣闊向量空間的天生能力。他們在該領域的實力使其在圍繞廣泛數據集並需要快速結果的應用中具有優勢。

使用過濾器來緩解

對於Elasticsearch愛好者來說,一切並不黯淡。該系統固有的靈活性提供了一種對策。通過熟練地將過濾器應用於查詢,可以減少Elasticsearch中的搜索空間。這種減少在一定程度上可以平衡因缺乏ANN和HNSW支持而造成的效率差距。此類過濾器使Elasticsearch能夠關注相關數據子集,從而使搜索過程更易於管理和更快速。

Faiss Vector Store

官方網站: https://faiss.ai/index.html

Faiss 是一個用於高效相似性搜索和密集向量聚類的庫。它包含搜索任何大小的向量集的演算法,直到可能不適合 RAM 的向量集。它還包含用於評估和參數調整的支援代碼。Faiss 基於多年的研究,實現了多種先進的技術,使其在大規模向量數據搜索中具有顯著優勢。以下是 Faiss 的主要優點:

Faiss 向量資料庫的優點在於其能夠快速在大量數據中找到匹配項,節省存儲空間,同時保持搜索的準確性。它通過多層次的方法和高效索引技術顯著提高搜索速度,並利用 GPU 進行加速,使得大規模數據的搜索更加高效且穩定。這些特性使得 Faiss 非常適合需要快速檢索大量資料的應用。

  1. 非詳盡搜索:基於 “Video google: A text retrieval approach to object matching in videos.” 的倒排文件技術,使得在大型數據集中進行非詳盡搜索成為可能,避免了全量掃描,提高了搜索效率。
  2. 產品量化 (PQ):來自 “Product quantization for nearest neighbor search” 的產品量化方法,是一種高維向量的有損壓縮技術,能在壓縮域中進行相對準確的重建和距離計算,減少存儲和計算成本。
  3. 三級量化 (IVFADC-R):從 “Searching in one billion vectors: re-rank with source coding” 引入的三級量化方法,進一步提高了搜索效率。
  4. 倒排多重索引:基於 “The inverted multi-index” 的技術,大大提高了倒排索引的速度,適用於快速且精度要求不高的操作。
  5. 優化產品量化 (OPQ):來自 “Optimized product quantization” 的技術,通過向量空間的線性變換,使索引更為高效。
  6. GPU 加速:在 “Billion-scale similarity search with GPUs” 中描述的 GPU 實現和快速 k 選擇,使得在大規模相似性搜索中能充分利用 GPU 的計算能力。
  7. 分層可導航小世界 (HNSW):使用 “Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs” 的 HNSW 索引方法,提供高效而穩健的近似最近鄰搜索。
  8. 二進位多索引哈希:基於 “Fast Search in Hamming Space with Multi-Index Hashing” 的二進位多索引哈希方法,提高了哈希空間中的搜索速度。
  9. 基於圖的索引 (NSG):從 “Fast Approximate Nearest Neighbor Search With The Navigating Spreading-out Graph” 引入的 NSG 方法,進一步提高了近似最近鄰搜索的效率。
  10. 殘差量化器:來自 “Improved Residual Vector Quantization for High-dimensional Approximate Nearest Neighbor Search” 的殘差量化器技術,改進了高維度近似最近鄰搜索的性能。

Redis Vector Store

官方介紹: https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/vectors/

大多數具有 Web 服務背景的開發人員可能都熟悉 Redis。從本質上講,Redis 是一個開源鍵值存儲,可以用作緩存、消息代理和資料庫。開發人員之所以選擇 Redis,是因為它速度快,擁有龐大的用戶端庫生態系統,並且已被各大企業部署多年。

RediSearch 是一個 Redis 模組,為 Redis 提供查詢、二級索引、全文搜索和向量搜索。要使用 RediSearch,首先要在 Redis 數據上聲明索引。然後,可以使用 RediSearch 用戶端查詢該數據。有關 RediSearch 功能集的詳細資訊,請參閱 README 或 RediSearch 文檔。

Redis向量資料庫支援2種向量索引類型,分別是暴力搜尋的FLAT以及近似搜尋HNSW,同時也提供餘弦距離、內積距離和歐幾里德距離3種距離運算,另外還支援範圍搜尋,以及可以添加組合過濾器和語義搜尋的混合搜尋,並提供JSON物件支援。

發佈日期:

雲端現有的相似性搜尋資料庫研究

AWS DocDB

官方網頁: https://aws.amazon.com/tw/documentdb/

Amazon DocumentDB (with MongoDB compatibility) 是一種完全托管的 NoSQL 資料庫服務,可讓開發人員輕鬆地設置、操作和擴展 MongoDB 兼容的資料庫。它提供以下功能:

  • MongoDB 兼容性:Amazon DocumentDB 與 MongoDB 兼容,因此您可以使用相同的工具、驅動程序和應用程序來管理和查詢您的數據。
  • 完全託管:Amazon DocumentDB 是一種完全託管的服務,因此您無需管理基礎架構。
  • 可擴展性:Amazon DocumentDB 可根據需要進行擴展,因此您可以隨著數據增長而擴展資料庫。
  • 高可用性:Amazon DocumentDB 提供高可用性,因此您的數據始終可用。
  • 安全性:Amazon DocumentDB 提供多種安全功能,可幫助保護您的數據。

Amazon DocumentDB 適用於各種應用,包括:

  • 內容管理:Amazon DocumentDB 可用於存儲和管理內容管理系統 (CMS) 的內容。
  • 移動應用:Amazon DocumentDB 可用於存儲和管理移動應用程序的數據。
  • 實時大數據分析:Amazon DocumentDB 可用於實時分析大數據。

Alibaba Cloud OpenSearch Vector Store介紹

官方介紹: https://www.alibabacloud.com/help/en/open-search/vector-search-edition/introduction-to-vector-search-edition

OpenSearch Vector Search Edition是阿裡巴巴集團開發的一款大規模分散式搜尋引擎。OpenSearch Vector Search Edition 為整個阿裡巴巴集團提供搜索服務,包括淘寶、天貓、菜鳥、優酷以及為中國大陸以外地區的客戶提供的其他電子商務平臺。OpenSearch Vector Search Edition 也是阿裡雲 OpenSearch 的基礎引擎。經過多年的發展,OpenSearch Vector Search Edition已經滿足了高可用、高時效、性價比等業務需求。OpenSearch Vector Search Edition 還提供自動化運維系統,您可以根據業務特性構建自定義搜索服務。

OpenSearch Vector Search Edition 的優勢

  • Stability 穩定性
    OpenSearch Vector Search Edition 的底層是使用 C++ 程式設計語言開發的。經過十餘年的發展,OpenSearch Vector Search Edition為各類核心業務系統提供了穩定的搜索服務。OpenSearch 向量搜索版適用於對穩定性要求高的核心搜索場景。
  • Efficiency 效率
    OpenSearch Vector Search Edition 是一個分散式搜尋引擎,允許您檢索大量數據。OpenSearch Vector Search Edition 支援實時數據更新。數據更新秒級即可生效。因此,OpenSearch Vector Search Edition 適用於時間敏感的查詢和搜索場景。
  • Cost-effectiveness 成本效益
    OpenSearch Vector Search Edition 支持多種策略進行索引壓縮和多值索引載入測試,能夠經濟高效地滿足查詢需求。

Amazon Neptune – Neptune Analytics vector store

介紹影片

影片文字節錄

您可以通過將數據形狀轉換為嵌入(即向量)來回答有關數據的複雜問題。使用向量搜索索引可以回答有關數據的上下文及其與其他數據的相似性和連接的問題。

借助 Neptune Analytics 中的向量相似性搜索,您可以輕鬆構建機器學習 (ML) 增強搜尋體驗和生成式人工智慧 (GenAI) 應用程式。它還為您提供了更低的總體擁有成本和更簡單的管理開銷,因為您不再需要管理單獨的數據存儲、構建管道或擔心保持數據存儲同步。您可以在 Neptune Analytics 中使用向量相似性搜索,通過將針對特定域上下文的圖形查詢與從 LLMs Amazon Bedrock 託管、GraphStorm 中的圖形神經網路 (GNN) 或其他來源導入的嵌入的低延遲、最近鄰相似性搜尋結果的結果集成來增強您的LLMs功能。

例如,生物資訊學研究人員對將現有的血壓藥物重新用於其他可治療疾病感興趣,他們希望在內部知識圖譜上使用向量相似性搜索來找到蛋白質相互作用網路中的模式。或者一家大型在線圖書零售商可能需要使用已知的盜版材料來快速識別類似的媒體,並結合知識圖譜來識別欺騙性清單行為的模式並找到惡意賣家。

在這兩種情況下,在構建解決方案時,對知識圖譜進行向量搜索可以提高準確性和速度。它使用當今可用的工具減少了運營開銷和複雜性。

更多API參考: https://docs.aws.amazon.com/neptune-analytics/latest/apiref/Welcome.html

發佈日期:

使用Docker來運行Ollama

為什麼要使用Docker來運行Ollama

使用 Docker 來運行 Ollama 可以提供許多優點,包括簡化設置、可移植性、隔離、資源管理、可擴展性和可重複性。可以把Ollama變成一個API服務,提供其他的應用程式直接使用API的方式來呼叫Ollama,並運行不同的本地端模型。而把Ollama變為一個Docker服務,更可以在多台機器上分發 Ollama 模型。這對於需要在高可用性環境中運行 Ollama 的情況非常有用。

以下為Ollama的API手冊

https://github.com/ollama/ollama/blob/main/docs/api.md

利用Docker來運行服務的狀況

以下是一些使用 Docker 運行 Ollama 的具體示例:

  • 在您的本地機器上開發和測試 Ollama 模型: Docker 允許您在本地機器上設置一個隔離的環境來開發和測試 Ollama 模型。這可以幫助您確保模型在部署到生產環境之前按預期工作。
  • 在生產環境中部署 Ollama 模型: Docker 可用於在生產環境中部署 Ollama 模型。您可以使用 Docker 映像來創建和管理 Ollama 服務器,這些服務器可以提供對模型的 API 訪問。
  • 在多台機器上分發 Ollama 模型: Docker 可用於在多台機器上分發 Ollama 模型。這對於需要在高可用性環境中運行 Ollama 的情況非常有用。

其中最重要好處的會是第三點,當我們把本地端LLM視為一個API服務,便可以對此服務做平衡負載,並根據使用量來增加機器,擴張服務的Scale,讓整體服務具備有良好的擴充性。

安裝Ollama Docker image

官方網站: https://hub.docker.com/r/ollama/ollama

Ollama 使得在本地啟動和運行大型語言模型變得容易。

僅 CPU

docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

Nvidia GPU 

安裝 NVIDIA Container Toolkit⁠.

使用 Apt 安裝

Configure the repository 配置存儲庫

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
    | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
    | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
    | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update

安裝 NVIDIA Container Toolkit 軟體包

sudo apt-get install -y nvidia-container-toolkit

使用 Yum 或 Dnf 安裝

配置存儲庫

curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo \
    | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo

安裝 NVIDIA Container Toolkit 軟體包

sudo yum install -y nvidia-container-toolkit

配置 Docker 以使用 Nvidia 驅動程式

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

啟動容器

docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

AMD GPU

要使用帶有 AMD GPU 的 Docker 執行 Llama,請使用標籤 rocm 和以下命令:

docker run -d --device /dev/kfd --device /dev/dri -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama:rocm

在本地運行模型

docker exec -it ollama ollama run llama3

延伸閱讀

發佈日期:

Ollama – 本地端運行的LLM服務

Ollama 介紹

Ollama 是一個開源軟體,讓使用者可以在自己的硬體上運行、創建和分享大型語言模型 (LLM) 服務。它提供了一個易於使用的平台,讓用戶無需複雜的設定即可利用 LLM 的功能。

Ollama 的主要優點包括:

  • 本地端運行: Ollama 允許用戶在本地端運行 LLM,這可以保護敏感數據隱私,並降低對網路連接的依賴性。
  • 易於使用: Ollama 提供了命令行介面 (CLI) 和 Python SDK,使 Ollama 易於設置、使用和自定義。
  • 彈性: Ollama 支持多種 LLM 模型,包括 Llama 2 和 Mistral。它還允許用戶從其他格式導入模型並設置運行參數。
  • 可擴展: Ollama 是一個開源項目,鼓勵用戶貢獻和擴展其功能。

Ollama 可用於各種任務,包括:

  • 文字生成: Ollama 可以生成文字、翻譯語言、編寫不同類型的創意內容,並以信息豐富的方式回答您的問題。
  • 文字處理: Ollama 可以用於各種文字處理任務,例如摘要、問答和情感分析。
  • 代碼生成: Ollama 可以生成代碼、翻譯程式碼並以信息豐富的方式回答您的編碼問題。

Ollama的優點

Ollama與LM Studio相似,都是可以於本地端運行、比較多個大語言模型的工具,並且也都是開源軟體

功能 Ollama LM Studio
原生功能集基本豐富
用戶界面可使用Command line豐富易操作的視窗介面
開源性
支持的操作系統 Windows、macOS、Linux Windows、macOS
擴展性可使用API的方式呼叫較偏向本地端應用程式面
Ollama與LM Studio的比較

Ollama本身其實是完全可以使用command line去執行的服務,因為這樣的特性,Ollama非常容易可以與其他的服務集成,因為它可以變成一個API的服務,讓其他服務去用API的方式來呼叫這個地端模型,也因此,我們會可以在伺服器上面,利用Ollama,使我們的線上服務串接到多個不同的地端LLM模型

以下為一個使用curl來呼叫地端模型的範例

curl http://localhost:11434/api/chat -d '{
  "model": "llama3",
  "messages": [
    { "role": "user", "content": "why is the sky blue?" }
  ]
}'

安裝Ollama

curl -fsSL https://ollama.com/install.sh | sh

使用Ollama

用下面的指令來使用Llama3模型

ollama run llama3

設定大語言模型的腳色及回覆指導

Ollama 庫中的模型可以通過提示進行自定義。例如,要自定義 llama3 模型:

ollama pull llama3

建立 Modelfile :

FROM llama3

# set the temperature to 1 [higher is more creative, lower is more coherent]
PARAMETER temperature 1

# set the system message
SYSTEM """
You are Mario from Super Mario Bros. Answer as Mario, the assistant, only.
"""

接下來,創建並運行模型:

ollama create mario -f ./Modelfile
ollama run mario
>>> hi
Hello! It's your friend Mario.

ollama create 用於從 Modelfile 建立模型。

ollama create mymodel -f ./Modelfile

刪除模型

ollama rm llama3

複製模型

ollama cp llama3 my-model

啟動 Ollama

ollama serve 當您想要在不運行桌面應用程式的情況下啟動 Ollama 時使用。

關閉Ollama

systemctl stop ollama

重新啟動Ollama

sudo systemctl restart ollama

API 應用程式介面

生成完成: 使用提供的模型為給定提示生成回應。這是一個流式處理終結點,因此將有一系列回應。最終回應物件將包括來自請求的統計資訊和其他數據。

產生要求(流式處理)

POST /api/chat

呼叫範例

curl http://localhost:11434/api/chat -d '{
  "model": "llama3",
  "prompt": "Why is the sky blue?"
}'

回應範例

{
  "model": "llama3",
  "created_at": "2023-08-04T08:52:19.385406455-07:00",
  "response": "The",
  "done": false
}

要求(無流式處理)

Request 請求

curl http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt": "Why is the sky blue?"
}'

Response 回應

返回 JSON 物件流:

{
  "model": "llama3",
  "created_at": "2023-08-04T08:52:19.385406455-07:00",
  "response": "The",
  "done": false
}

可使用的模型列表

ModelParametersSizeDownload
Llama 38B4.7GBollama run llama3
Llama 370B40GBollama run llama3:70b
Phi 3 Mini3.8B2.3GBollama run phi3
Phi 3 Medium14B7.9GBollama run phi3:medium
Gemma 29B5.5GBollama run gemma2
Gemma 227B16GBollama run gemma2:27b
Mistral7B4.1GBollama run mistral
Moondream 21.4B829MBollama run moondream
Neural Chat7B4.1GBollama run neural-chat
Starling7B4.1GBollama run starling-lm
Code Llama7B3.8GBollama run codellama
Llama 2 Uncensored7B3.8GBollama run llama2-uncensored
LLaVA7B4.5GBollama run llava
Solar10.7B6.1GBollama run solar
發佈日期:

Prompt engineering 提示工程

獲得更好結果的六種策略

 寫清楚的說明

  • 在查詢中包含詳細資訊以獲得更相關的答案
  • 要求模型採用角色
  • 使用分隔符清楚地指示輸入的不同部分
  • 指定完成任務所需的步驟
  • 舉例說明
  • 指定所需的輸出長度
  •  提供參考文本

 提供參考文本

  • 指示模型使用參考文本回答問題
  • 指示模型使用參考文本的引用來回答

將複雜的任務拆分為更簡單的子任務

正如軟體工程中的良好做法是將複雜系統分解為一組模組化元件一樣,提交給語言模型的任務也是如此。複雜任務往往比簡單任務具有更高的錯誤率。此外,複雜任務通常可以重新定義為更簡單任務的工作流,其中早期任務的輸出用於構造後續任務的輸入。

  • 使用意圖分類來標識與用戶查詢最相關的指令
  • 對於需要很長對話的對話應用程式,請總結或過濾以前的對話
  • 分段總結長文檔,並以遞歸方式構建完整的摘要

給模型時間“思考”

如果要求將 17 乘以 28,您可能不會立即知道,但仍然可以隨著時間的推移計算出來。同樣,模型在試圖立即回答時會犯更多的推理錯誤,而不是花時間找出答案。在回答之前要求一個「思維鏈」可以説明模型更可靠地推理出正確的答案。

  • 在匆忙得出結論之前,指示模型制定自己的解決方案
  • 使用內心獨白或一系列查詢來隱藏模型的推理過程
  • 詢問模型在之前的刀路中是否遺漏了任何內容

使用外部工具

通過向模型提供其他工具的輸出來補償模型的弱點。例如,文本檢索系統(有時稱為RAG或檢索增強生成)可以告訴模型有關相關文檔的資訊。像 OpenAI 的 Code Interpreter 這樣的代碼執行引擎可以説明模型進行數學運算和運行代碼。如果一項任務可以通過工具而不是語言模型更可靠或更高效地完成,請卸載它以充分利用兩者。

  • 使用基於嵌入的搜索實現高效的知識檢索
  • 使用代碼執行來執行更準確的計算或調用外部 API
  • 授予模型對特定函數的訪問許可權

系統地測試更改

如果可以衡量性能,則更容易提高性能。在某些情況下,對提示的修改將在幾個孤立的示例上獲得更好的性能,但在更具代表性的示例集上會導致整體性能較差。因此,為了確保更改對性能有淨積極影響,可能需要定義一個全面的測試套件(也稱為“eval”)。

  • 參考黃金標準答案評估模型輸出

更多範例請見: https://platform.openai.com/docs/guides/prompt-engineering/strategy-write-clear-instructions

發佈日期:

RAG中準備檢索資料的概念及方向

相關論文: https://arxiv.org/abs/2005.11401

Embedding向量搜尋的概念

在RAG(Retrieval-Augmented Generation)模型中,embedding 向量搜尋是一個關鍵步驟,用於在資料庫中找到與當前查詢相關的資訊。RAG結合了檢索和生成的能力,通過將外部知識融入生成過程中來提高生成內容的質量和相關性。以下是 embedding 向量搜尋的主要步驟:

  1. 查詢嵌入 (Query Embedding)
    將用戶的查詢轉換成嵌入向量。這通常是通過一個預訓練的語言模型(如BERT或RoBERTa)來完成。這些模型能夠將文字表示成固定長度的向量,捕捉文字的語義信息。
  2. 資料庫嵌入 (Database Embedding)
    資料庫中的每個文本片段(如文章、段落、句子)也被轉換成嵌入向量。這些嵌入向量通常預先計算並存儲起來,以便在查詢時能快速檢索。
  3. 相似度計算 (Similarity Calculation)
    使用某種相似度度量(如餘弦相似度)來計算查詢嵌入向量與資料庫中嵌入向量之間的相似度。餘弦相似度測量兩個向量之間的夾角,角度越小,相似度越高。
  4. 檢索相關資料 (Retrieve Relevant Data)
    根據相似度分數,選擇與查詢最相關的前N個資料庫片段。這些片段將作為檢索結果返回。
  5. 融合與生成 (Fusion and Generation)
    RAG模型將檢索到的相關片段與查詢結合起來,通過生成模型(如GPT-3)生成最終的回應。生成模型利用檢索到的資訊,生成更為準確和豐富的回答。

簡單範例

假設我們有一個簡單的資料庫,包含以下句子:

  1. “Python是一種流行的編程語言。”
  2. “GPT-3是OpenAI開發的語言模型。”
  3. “嵌入向量是機器學習中的重要概念。”

用戶查詢:「什麼是GPT-3?」

  1. 查詢嵌入:將「什麼是GPT-3?」轉換成嵌入向量Q。
  2. 資料庫嵌入:將資料庫中的每個句子轉換成嵌入向量D1, D2, D3。
  3. 相似度計算:計算Q與D1, D2, D3的相似度。例如,相似度分數可能是:
    Q與D1: 0.2
    Q與D2: 0.9
    Q與D3: 0.3
  4. 檢索相關資料:根據相似度分數,檢索到最相關的片段是「GPT-3是OpenAI開發的語言模型」。
  5. 融合與生成:RAG模型將檢索到的片段與查詢結合,生成關於GPT-3的詳細說明。

以下為一個用書名做向量檢索的文章,看了此文章會更能理解向量空間的文字意義檢索的概念

https://towardsdatascience.com/building-a-recommendation-system-using-neural-network-embeddings-1ef92e5c80c9

從Fancy AI了解準備資料的幾種方式

網站如下: https://www.fancyai.co/

從上面的圖片我們可看出大概可分為【直接分段】或【以QA方式去呈現】,而QA方式又分成【讓AI自動整理問答對】、【人工整理問答對】。

三種方式的優缺點比較

這三種方法各有其優缺點,適用於不同的應用場景和需求。

1. 手動輸入問答對

優點:

  • 高準確性: 手動輸入的問答對由專家或知識擁有者編寫,確保了答案的準確性和相關性。
  • 高度針對性: 可以針對特定領域或問題編寫,回答更具針對性。
  • 質量控制: 可以進行嚴格的審查和驗證,確保資料的質量。

缺點:

  • 耗時耗力: 手動編寫問答對需要大量人力和時間,尤其是資料量大的情況下。
  • 不易擴展: 隨著知識庫的增長,維護和更新問答對會變得愈發困難。

2. AI自動產生問答對

優點:

  • 自動化程度高: 使用AI技術(如自然語言處理)自動生成問答對,大幅減少人力投入。
  • 快速生成: 可以在短時間內生成大量問答對,適合快速擴展知識庫。
  • 適應性強: 可以根據需要自動更新和擴展問答對。

缺點:

  • 準確性不穩定: AI自動生成的問答對可能存在錯誤或不精確的情況,需要人工審核。
  • 質量參差不齊: 自動生成的答案質量可能不均一,部分回答可能缺乏深度或詳細性。

3. 直接將文件做分段

優點:

  • 節省時間: 直接將長文檔分段,可以快速建立起知識庫,節省了人工編寫問答對的時間。
  • 完整性: 保留了原始文檔的完整信息,便於系統檢索和引用。
  • 多樣性: 文檔中的信息可能涵蓋多個方面,能夠提供更豐富的回答。

缺點:

  • 相關性不一定高: 分段的文檔內容可能不是針對具體問題,回答的針對性和相關性可能不如手動問答對。
  • 需要處理和優化: 分段後的文檔需要進行處理和優化,以確保分段的合理性和檢索的效率。
  • 資料雜亂: 如果文檔內容過於雜亂或不夠結構化,可能會影響檢索結果的質量。

適用的場景

  • 手動輸入問答對 適合需要高度精確和針對性回答的應用場景,如專業領域的技術支持或知識管理。
  • AI自動產生問答對 適合需要快速建立和擴展知識庫的情況,如大型網站的常見問題解答(FAQ)系統。
  • 直接將文件做分段 適合需要處理大量現有文檔資料的應用,如文檔管理系統或數字圖書館。

直接分段的範例

以上面的例子來說,用戶查詢「怎麼串接GPT-3的API?」,

假設我們有以下一段文檔:

Python是一種流行的編程語言。它擁有豐富的庫和框架,適用於各種應用場景。GPT-3是由OpenAI開發的一個強大的語言模型,可以生成高質量的自然語言文本。嵌入向量是機器學習中的重要概念,用於表示文字的語義信息。

我們可以將這段文檔拆分成以下分段:

  1. “Python是一種流行的編程語言。”
  2. “它擁有豐富的庫和框架,適用於各種應用場景。”
  3. “GPT-3是由OpenAI開發的一個強大的語言模型,可以生成高質量的自然語言文本。”
  4. “嵌入向量是機器學習中的重要概念,用於表示文字的語義信息。”

然後對每個分段生成嵌入向量,並在檢索系統中建立索引。當用戶查詢「什麼是GPT-3?」時,系統會找到與該查詢最相關的分段(如第三個分段),並用它來生成回應。

產生問答對的範例

問答對生成

  1. 問題:Python是什麼?
    回答:Python是一種流行的編程語言。
  2. 問題:Python有哪些特點?
    回答:Python擁有豐富的庫和框架,適用於各種應用場景。
  3. 問題:GPT-3是什麼?
    回答:GPT-3是由OpenAI開發的一個強大的語言模型,可以生成高質量的自然語言文本。
  4. 問題:嵌入向量是什麼?
    回答:嵌入向量是機器學習中的重要概念,用於表示文字的語義信息。
  5. 問題:Python的應用場景有哪些?
    回答:Python適用於各種應用場景,因為它擁有豐富的庫和框架。
  6. 問題:GPT-3的開發者是誰?
    回答:GPT-3是由OpenAI開發的。

生成問答對的步驟

  1. 文本分析
    • 對給定的文本進行語義分析,識別出關鍵概念和信息點。
    • 例如,在這段文本中,關鍵概念包括「Python」、「庫和框架」、「GPT-3」、「OpenAI」、「嵌入向量」、「機器學習」等。
  2. 生成問題
    • 根據關鍵概念生成相關的問題。
    • 問題應該簡潔明了,針對文本中的具體信息點。
  3. 生成答案
    • 根據文本中提供的信息生成相應的答案。
    • 答案應該準確反映文本中的內容,並且與問題直接相關。
發佈日期:

使用LlamaIndex載入多種類文件

LlamaIndex的教學資料

這邊有許多的簡單範例:

https://github.com/SamurAIGPT/LlamaIndex-course

這邊則是載入文件的範例:

https://github.com/SamurAIGPT/LlamaIndex-course/blob/main/dataconnectors/Data_Connectors.ipynb

範例程式載入PDF如下

from pathlib import Path
from llama_index.core import download_loader

PDFReader = download_loader("PDFReader")

loader = PDFReader()

pdf_document = loader.load_data(file=Path('./sample.pdf'))

載入YouTube的字幕的範例如下

from llama_index.core import download_loader

YoutubeTranscriptReader = download_loader("YoutubeTranscriptReader")

loader = YoutubeTranscriptReader()
youtube_documents = loader.load_data(ytlinks=['https://www.youtube.com/watch?v=nHcbHdgVUJg&ab_channel=WintWealth'])

使用上面的寫法我們會發現會跳出這樣的警告

DeprecationWarning: Call to deprecated function (or staticmethod) download_loader. (`download_loader()` is deprecated. Please install tool using pip install directly instead.) PDFReader = download_loader(“PDFReader”)

錯誤警告訊息

新的文件讀取方式

現在官方推薦的檔案讀取方式如下

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./files").load_data()

不過,如果我們需要這個Reader使用特別的解析器去解析特別格式的文件的話,則要使用額外相關的函式庫,如下面的介紹

相關的函式庫

接著當我們查詢載入本地端檔案的API時,可以看到這個頁面有許多Reader的介紹

https://docs.llamaindex.ai/en/stable/api_reference/readers/file/

但是如果直接在llamaindex.core會找不到裡面許多的函數,這時候可以在這邊找到

https://llamahub.ai/?tab=readers

這邊可以找到許多其他開發者開發的好用函式庫

讀取各式文件的函式庫

首先先安裝所需的套件

pip install llama-index-readers-file

那Reader頁面中許多各式各樣的Reader則請參考此文件:

https://llamahub.ai/l/readers/llama-index-readers-file?from=readers

使用範例如下,下面這子我們會可以用doc.text去取得這張圖片的一個文字描述

from llama_index.core import SimpleDirectoryReader
from llama_index.readers.file import ImageCaptionReader
# Image Reader example
parser = ImageCaptionReader()
file_extractor = {
    ".jpg": parser,
    ".jpeg": parser,
    ".png": parser,
}  # Add other image formats as needed
documents = SimpleDirectoryReader(
    "./data", file_extractor=file_extractor
).load_data()
for index, doc in enumerate(documents):
    print(doc.text)

要注意的是,當我們這邊使用圖片閱讀器,事實上他會載入Hugging Face的一些transformers模型去做圖片辨識,有一些模型只能使用GPU,所以,我們一定要記得我們的Pytorch要使用GPU版本的

參考此文件: https://pytorch.org/get-started/locally/

如果已經安裝了CPU版本的,記得先把torch反安裝後再重新安裝GPU版本

發佈日期:

在LlamaIndex中的查詢流程

查詢流程解析

檢索器(Retrievers)

檢索器就像是一個數據查找工具,它會根據用戶的查詢從索引中高效地獲取相關的上下文信息。選擇合適的檢索策略至關重要,它會影響檢索到的數據的相關性和效率。

路由器(Routers)

路由器決定了應該使用哪個檢索器從知識庫中獲取相關的上下文信息。更確切地說,RouterRetriever 類負責基於查詢選擇一個或多個候選檢索器來執行查詢。它們會使用選擇器基於每個候選檢索器的元數據和查詢來選擇最佳選項。

節點後處理器(Node Postprocessors)

節點後處理器接收一組檢索到的節點,然後可以對它們進行轉換、過濾或重新排序等操作。

響應合成器(Response Synthesizers)

響應合成器使用大型語言模型 (LLM)、用戶查詢和給定的一組檢索到的文本片段來生成響應。

甚麼是Retriever

檢索器(Retriever)是用來根據給定的查詢從數據源中提取相關的資訊(節點)。這是檢索增強生成(Retrieval-Augmented Generation,RAG)流程中的關鍵步驟,其中檢索器有助於識別可用於生成回應的最相關數據。

以下是檢索器在LlamaIndex中的工作方式概述:

  1. 數據攝取:從各種來源(例如PDF、SQL數據庫)中攝取數據並建立索引。
  2. 檢索:當提出查詢時,檢索器會從已索引的數據中提取相關的節點(數據片段)。
  3. 回應合成:然後使用檢索到的節點來生成回應,通常是將它們與查詢一起輸入語言模型。

檢索器建立在索引之上,指定了如何從索引中檢索節點。

不同的Retriever介紹

https://docs.llamaindex.ai/en/stable/module_guides/querying/retriever/retrievers/

有許多不同種的檢索器,較基本的有下面這些

  • 向量存儲檢索器(Vector index retriever)
    向量存儲檢索器從向量存儲索引中檢索出前 k 個最相似的節點。在這裡,模式不具有顯著意義。
  • 列表檢索器
    您可以使用列表檢索器從列表索引中檢索出所有節點。這個檢索器支持兩種模式:default embeddings。默認模式檢索所有節點,而嵌入模式使用嵌入檢索出使用嵌入檢索出前 k 個節點。
  • 樹形檢索器 (GPT all leaf retriever)
    正如其名,樹形檢索器從節點的分層樹中提取節點。這個檢索器支持許多不同的模式,默認是選擇select_leaf
  • 關鍵字表檢索器 (Base Keyword Table Retriever)
    關鍵字表檢索器從查詢中提取關鍵字,並使用它們來查找具有匹配關鍵字的節點。這個檢索器支持三種不同的模式: defaultsimple、和rake模式。
  • 知識圖檢索器 (KG Table Retriever)
    知識圖檢索器從節點的分層樹中檢索節點。支持 keywordsembeddings、和hybrid模式。
    1. 關鍵字模式(keywords): 使用查詢中提取的關鍵字來尋找相關的節點。
    2. 嵌入模式(embeddings): 使用嵌入向量來尋找相關的節點。
    3. 混合模式(hybrid): 同時使用關鍵字和嵌入向量來尋找相關的三元組。混合模式的思想是將關鍵字和嵌入向量結合起來,以更全面地找到與查詢相關的信息。這樣可以充分利用關鍵字的文本特徵和嵌入向量的語義信息。

簡單的使用範例

以下是使用ListIndex且模式為embedding的使用範例

from llama_index import ListIndex
from llama_index import download_loader

YoutubeTranscriptReader = download_loader("YoutubeTranscriptReader")

loader = YoutubeTranscriptReader()
docs = loader.load_data(ytlinks=['https://www.youtube.com/watch?v=nHcbHdgVUJg&ab_channel=WintWealth'])
list_index = ListIndex(docs)
retriever = list_index.as_retriever(
    retriever_mode='embedding',
)

使用範例

retriever.retrieve('What is the difference between a stock and a bond?')

檢索出的資訊

[NodeWithScore(node=Document(id_='nHcbHdgVUJg', embedding=[0.006401017773896456, -0.02431839518249035, -0.005019601434469223, -0.03640920668840408, -0.021309370175004005, 0.02166498266160488, ......, -0.011140232905745506], metadata={'video_id': 'nHcbHdgVUJg'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text="I'm a Commerce graduate I went to Vijay\nCollege which is like a Government\nCollege type so I'm also not from IIT\nI graduated from MIT Pune Pu......t for it or not and like\nnobody tell you that you're cut out to\nbe a founder or not one thing which\nwhich is common in all the founders who\nsucceed is they don't give up so that's\nwhat that's probably yeah so\nhello", start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n'), score=0.7269996487772504)]
發佈日期:

在LlamaIndex中使用索引(Index)

甚麼是索引(Index)

在 LlamaIndex 中,索引是一種資料結構,用於組織和存儲來自各種數據來源的信息,使搜索變得更加容易。索引是建立在一組節點(Node)之上的。節點(Node)是 LlamaIndex 的基本單位,一種包含一段文本的資料結構。每當提供一個文件時,可以將其分割成多個片段並存儲在節點中。

索引類型

LlamaIndex 提供不同類型的索引,以下是要學習的一些類型:

List Index

將節點存儲為像鏈表結構那樣的順序鏈。默認情況下,它會從所有節點中獲取數據並作為響應的一部分發送。

可以使用基於嵌入的查詢來獲取前 k 個節點,或者添加關鍵字過濾器進行查詢。

Vector Store Index

向量存儲索引將每個節點及其對應的嵌入存儲在一個向量存儲中。在查詢向量索引時,它總是提供與查詢最相關的前 k 個最相似的節點。

Tree Index

樹形索引從一組節點建立一個分層的樹狀結構。

在內部,樹是通過摘要提示形成的。它以一系列文本文件作為輸入,然後以自下而上的方式建立樹形索引,其中每個父節點是其下方節點的摘要。

查詢樹形索引涉及從根節點向下到葉節點的過程。默認情況下(child_branch_factor=1),查詢在給定父節點的情況下選擇一個子節點。如果 child_branch_factor=2,則查詢在每一層選擇兩個子節點。

Keyword Table Index

GPTKeywordTableIndex 實現從索引的節點中提取關鍵字,並使用這些關鍵字來查找相關的文檔。當我們提出問題時,這個實現首先會從問題中生成關鍵字。接著,索引會搜尋相關的文檔並將它們發送給大語言模型(LLM)。

Knowledge Graph Index

官方教學文件: https://docs.llamaindex.ai/en/stable/examples/index_structs/knowledge_graph/KnowledgeGraphDemo/

KnowledgeGraphIndex類別透過自動從文本中提取實體和關係識別來簡化 RAG 知識圖構建,消除複雜的手動解析。它還提供了客製化的靈活性,可讓您根據您的特定需求定製圖形結構和推理規則。知識圖捕捉了實體之間豐富的關係,使得 RAG 中的查詢和推理比向量資料庫更加精確、多樣化和複雜。

從技術上講,KG 提供比 Vector DB 更多的 precise 輸出,KG 還支援比 Vector DB 更多的 diverse 和complex 查詢。此外,KG 比 Vector DB 具有更好的 reasoning 和推理功能……但通常情況下,KGs 與 Vector DBs 的比較是蘋果與柳丁的遊戲。

知識圖譜最適合具有清晰 relationships 的文檔,而向量資料庫則與基於 similarity 的上下文更相關。因此,在 KG 和 Vector DB 之間進行選擇取決於 RAG 專案的具體要求和目標。

何時使用特定的索引

列表索引 當您的文檔數量不多時,ListIndex 是理想的選擇。與其嘗試找到相關數據,索引會將所有片段連接起來並全部發送給大語言模型(LLM)。如果結果文本太長,索引會分割文本並請 LLM 精煉答案。

當使用“embedding”參數時,它與 VectorStoreIndex 非常相似,區別在於列表索引會發送所有匹配的節點而無需任何門檻,而 VectorStoreIndex 只有在節點達到某個匹配分數門檻時才會發送。

向量索引 當我們希望獲取通過一定匹配分數門檻的前 K 個相關文檔時,可以使用 Vector Index。

樹形索引 當處理基於摘要的任務時,樹形索引(Tree Index)非常有用。

關鍵字表索引 在 Keyword Table Index 中,每個節點都會被發送到 LLM 以生成關鍵字。將每個文檔發送給 LLM 會大幅增加索引成本。這比其他索引更慢且更昂貴。因此,除非使用此索引所提供的結果遠好於其他索引,否則不建議使用。

發佈日期:

使用LlamaIndex載入文檔

YouTube 文件載入器

將 YouTube 影片的文字記錄轉換為文件格式

from llama_index.core import download_loader
# 載入環境變數
from dotenv import load_dotenv 
load_dotenv()

YoutubeTranscriptReader = download_loader("YoutubeTranscriptReader")

loader = YoutubeTranscriptReader()
youtube_documents = loader.load_data(ytlinks=['https://www.youtube.com/watch?v=nHcbHdgVUJg&ab_channel=WintWealth'])

會得到如下格式的json資料

[Document(id_='nHcbHdgVUJg', embedding=None, metadata={'video_id': 'nHcbHdgVUJg'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text="I'm a Commerce graduate.......", start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n')]

載入PDF文件

使用下面的程式碼可以讀取本地端的pdf文件,請確保該檔案存在

from pathlib import Path
from llama_index.core import download_loader

PDFReader = download_loader("PDFReader")

loader = PDFReader()

pdf_document = loader.load_data(file=Path('./sample.pdf'))

會產生如下的json檔案

[Document(id_='c63920fc-1f19-4112-ab6a-d18aa193c037', embedding=None, metadata={'page_label': '1', 'file_name': 'sample.pdf'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text=' \n \n \n \n \n \nLangChain 技术解密: \n构建大模型应用的全景指南 \n \n \n王浩帆 编著 \n \n \n \n \n \n \n \n \n \n \n \n \n', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n'), ......]

載入Notion筆記本

from llama_index.core import download_loader
import os

NotionPageReader = download_loader('NotionPageReader')

integration_token = "your-notion-token"
database_id = "your-database-id"
reader = NotionPageReader(integration_token=integration_token)
notion_documents = reader.load_data(database_id=database_id)

建立對話機器人

import os
from llama_index.core import VectorStoreIndex

all_documents = youtube_documents + pdf_document
index = VectorStoreIndex.from_documents(all_documents)

對話測試

query_engine = index.as_query_engine()
response = query_engine.query("介紹LangChain")
print(response)

LangChain是一个基于大语言模型的应用程序开发框架,旨在简化创建大模型应用程序的过程。它提供了一套完整的工具、组件和接口,使开发者能够轻松地利用大语….

可得到以上回應