天天看點

Chroma 初探:面向 LLM 的開源向量資料庫

作者:岱軍

Chroma 是一個開源的嵌入式資料庫,通過使知識、事實和技能可以插入到 LLM 中,進而輕松建構 LLM 應用程式。這裡可以了解它的工作原理。

翻譯自 Exploring Chroma: The Open Source Vector Database for LLMs 。

Chroma 初探:面向 LLM 的開源向量資料庫

大型語言模型的崛起加速了存儲詞嵌入的向量資料庫的采用。

向量資料庫以向量形式存儲資料,充分利用了先進的機器學習算法的潛力。它實作了高度高效的相似性搜尋,這對于包括推薦系統、圖像識别和自然語言處理在内的人工智能應用至關重要。

在向量資料庫中,每個存儲的資料點都被表示為多元向量,捕捉了複雜資料的本質。進階索引方法,如 k-d 樹或哈希,有助于快速檢索相似的向量。這種架構為資料密集型行業創造了高度可擴充且高效的解決方案,改變了我們處理大資料分析的方式。

在本文中,我們将更詳細地介紹 Chroma ,一個輕量級的開源向量資料庫。

Chroma 概述

Chroma 可用于 Python 或 JavaScript 代碼以生成詞嵌入。它具有一個簡單的 API ,可用于針對在記憶體中或用戶端/伺服器模式下運作的資料庫後端。開發人員可以安裝 Chroma ,使用 Jupyter Notebook 中的 API 進行原型設計,然後在生産環境中使用相同的代碼,該環境可以在用戶端/伺服器模式下運作資料庫。

在記憶體中運作時,Chroma 資料庫集合可以儲存為 Apache Parquet 格式的磁盤檔案。由于生成詞嵌入是一項昂貴的任務,将它們儲存以便稍後檢索可以降低成本和性能開銷。

現在,讓我們來看看 Chroma 向量資料庫的運作方式。

通過 Python 使用 Chroma

使用 Chroma 的第一步是通過 pip 安裝。

一旦安裝完成,您可以将該子產品導入到您的代碼中。

現在,讓我們建立一個字元串清單,我們将對其進行編碼以生成嵌入。

phrases = [
    "Amanda baked cookies and will bring Jerry some tomorrow.",
    "Olivia and Olivier are voting for liberals in this election.",
    "Sam is confused, because he overheard Rick complaining about him as a roommate. Naomi thinks Sam should talk to Rick. Sam is not sure what to do.",
    "John's cookies were only half-baked but he still carries them for Mary."


]           

我們還需要一個唯一辨別上述字元串的字元串清單。

ids = ["001", "002", "003", "004"]           

還可以為每個帶有對原始來源的引用或指針的字元串關聯附加的中繼資料。這是完全可選的。對于我們的教程,我們将添加一些虛拟中繼資料。這被構造為字典對象的清單。

metadatas = [{"source": "pdf-1"}, {"source": "doc-1"}, {"source": "pdf-2"}, {"source": "txt-1"}]           
現在,我們擁有了可以存儲在 Chroma 中的所有實體。讓我們初始化用戶端。           
chroma_client = chromadb.Client()           

如果您想将資料持久化到磁盤,可以将儲存資料庫的目錄位置傳遞給它。

chroma_client = chromadb.PersistentClient(path="/path/to/save/to")           

Chroma 将一組相關内容稱為一個集合(collection)。每個集合都有文檔,這隻是一系列字元串,充當文檔的唯一辨別符的 ids ,以及可選的中繼資料。

嵌入是集合的重要組成部分。它們可以根據 Chroma 内部包含的詞嵌入模型隐式生成,或者您可以基于 OpenA I、 PaLM 或 Cohere 的外部詞嵌入模型生成它們。Chroma 使內建外部 API 以自動化生成嵌入并将其存儲變得容易。我們将在本教程的下一部分更詳細地探讨這個概念。

Chroma 預設使用 Sentence Transformers 的 all-MiniLM-L6-v2 模型建立嵌入。這個嵌入模型可以為各種任務生成句子和文檔嵌入。這個嵌入函數在您的本地機器上運作,并可能需要下載下傳模型檔案,這将自動發生。

由于我們依賴于 Chroma 提供的内置詞嵌入模型,是以我們隻會攝取資料,并讓 Chroma 自動為集合中的每個文檔生成嵌入。

我們可以繼續建立一個集合。

collection = chroma_client.create_collection(name="tns_tutorial")           

現在,我們準備将文檔插入集合。

collection.add(
    documents=phrases,
    metadatas=metadatas,
    ids=ids
)           

我們可以快速檢查插入的文檔是否生成了嵌入。

您應該會看到自動生成的嵌入已添加到集合的嵌入清單中。

現在,我們可以在集合上執行相似性搜尋。讓我們搜尋與短語 “Mary got half-baked from John” 比對的短語。請注意,它隻與一個文檔有相似的含義,但不是完全比對。

results = collection.query(
    query_texts=["Mary got half-baked cake from John"],
    n_results=2
)           

當通路結果變量時,它的内容如下:

{'ids': [['004', '001']],
 'distances': [[0.4699302613735199, 1.333911657333374]],
 'metadatas': [[{'source': 'txt-1'}, {'source': 'pdf-1'}]],
 'embeddings': None,
 'documents': [["John's cookies were only half-baked but he still carries them for Mary.",
   'Amanda baked cookies and will bring Jerry some tomorrow.']]}           

基于距離,清單中的第一個文檔是一個完美比對。我們現在可以直接通路元素以擷取實際短語。嵌入元素為空,因為擷取每個查詢的嵌入是昂貴的。但在幕後,Chroma 正在執行餘弦相似性搜尋,該搜尋基于存儲為向量的嵌入。

print(results['documents'][0][0])           

Chroma 資料庫還支援基于中繼資料或 ids 進行查詢。這使得根據文檔的來源進行搜尋非常友善。

results = collection.query(
    query_texts=["cookies"],
    where={"source": "pdf-1"},
    n_results=1
)
print(results)           

上述查詢首先執行相似性搜尋,然後根據 where 條件過濾查詢,該條件指定了中繼資料。

最後,讓我們删除集合。

在本教程的下一部分中,預計将于下周釋出,我們将擴充學院獎聊天機器人以使用 Chroma 向量資料庫。敬請關注。

以下是您可以在自己的計算機上嘗試的完整代碼。

import chromadb


phrases = [
    "Amanda baked cookies and will bring Jerry some tomorrow.",
    "Olivia and Olivier are voting for liberals in this election.",
    "Sam is confused, because he overheard Rick complaining about him as a roommate. Naomi thinks Sam should talk to Rick. Sam is not sure what to do.",
    "John's cookies were only half-baked but he still carries them for Mary.",
]


ids = ["001", "002", "003", "004"]


metadatas = [{"source": "pdf-1"}, {"source": "doc-1"}, {"source": "pdf-2"}, {"source": "txt-1"}]


chroma_client = chromadb.Client()


collection = chroma_client.get_or_create_collection(name="tns_tutorial")


collection.add(
    documents=phrases,
    metadatas=metadatas,
    ids=ids
)


collection.peek()


results = collection.query(
    query_texts=["Mary got half-baked cake from John"],
    n_results=2
)


print(results['documents'][0][0])


results = collection.query(
    query_texts=["cookies"],
    where={"source": "pdf-1"},
    n_results=1
)
print(results)


collection.delete()           

繼續閱讀