批次處理是提高大量文字資料處理效率的關鍵技術。本文詳細介紹瞭如何使用批次處理方法取得文字嵌入,並將其儲存至 Pinecone 向量資料函式庫,以利後續查詢及分析。每個批次內的文字資料會被轉換成向量表示,並賦予唯一 ID,方便追蹤與管理。過程中,程式碼也納入了錯誤處理機制,以應對網路連線問題或速率限制等突發狀況,確保資料處理的穩定性。此外,文章也說明瞭如何使用 Pinecone 執行向量相似度搜尋,以及如何透過自我查詢機制,讓系統根據使用者查詢自動產生新的查詢,提升檢索效率和準確性。最後,文章還示範瞭如何使用 Langchain 和 Lark 建立一個包含書籍資訊的向量資料函式庫,並利用 AttributeInfo 類別定義 metadata 屬性,方便日後資料的篩選與分析。
執行批次處理以取得文字嵌入
為了高效地處理大量文字資料,批次處理是一種常見的策略。以下是實作批次處理的步驟:
1. 初始化批次大小和文字資料
首先,需要定義批次大小 (batch_size) 和要處理的文字資料 (chunks)。這些引數將決定每個批次中有多少個文字單位需要被處理。
2. 迴圈處理每個批次
使用 tqdm 進行迴圈處理,每次迭代都會處理一個批次的文字資料。這個迴圈會根據批次大小和文字資料的長度進行迭代。
3. 計算批次結束索引
在每個迭代中,計算當前批次的結束索引 (i_end)。這是為了確保不會超出文字資料列表的長度而導致索引錯誤。
4. 提取當前批次的文字資料
根據當前的起始索引 (i) 和結束索引 (i_end),從 chunks 列表中提取出當前批次的文字資料,並儲存在 meta_batch 中。
5. 建立批次中的ID列表
為每個文字單位在批次中建立一個唯一的ID。這些ID將用於識別每個嵌入。
6. 準備文字資料進行嵌入
從 meta_batch 中提取出純文字資料,並儲存在 texts 列表中,以便進行嵌入運算。
7. 嘗試取得嵌入
使用指定的嵌入函式(例如 玄貓())嘗試取得 texts 中的每個文字單位的嵌入。這個過程可能會因為速率限制或其他原因而失敗,因此需要使用 try-except 區塊來捕捉和處理這些異常。
8. 處理取得嵌入失敗的情況
如果取得嵌入失敗,則進入一個迴圈中,每隔幾秒鐘就嘗試一次,直到成功或達到最大重試次數為止。
9. 修改批次資料結構
將 meta_batch 轉換為一個列表,其中每個元素都是包含批次號碼和對應文字的字典。這樣可以方便地新增其他的過濾條件。
10. 建立待插入列表
將ID、嵌入和元資料組合成元組,並轉換為列表,以便於之後的插入操作。
11. 執行插入操作
最後,呼叫 upsert 方法將批次資料插入到索引中(例如 Pinecone 索引),以便於後續的查詢和分析。
import tqdm
# 假設 batch_size 和 chunks 已經定義好了
batch_size = 32
chunks = [...] # 列表中的文字資料
for i in tqdm.tqdm(range(0, len(chunks), batch_size)):
i_end = min(i + batch_size, len(chunks))
meta_batch = chunks[i:i_end]
ids_batch = [str(j) for j in range(i, i_end)]
texts = [item for item in meta_batch]
try:
embeds =玄貓(texts) # 取得嵌入
except Exception as e:
# 處理異常,例如速率限制
while True:
# 等待幾秒鐘後重試
time.sleep(5)
try:
embeds =玄貓(texts)
break
except Exception as e:
# 如果仍然失敗,可能需要增加重試次數或採取其他策略
pass
# 修改批次資料結構
meta_batch = [{"batch": i, "text": text} for text in meta_batch]
# 建立待插入列表
to_upsert = [(id, embed, meta) for id, embed, meta in zip(ids_batch, embeds, meta_batch)]
# 執行插入操作
index.upsert(to_upsert)
這個過程展示瞭如何使用批次處理來高效地取得文字嵌入,並將其插入到索引中,以便於後續的查詢和分析。
Pinecone向量資料函式庫查詢
Pinecone是一個強大的向量資料函式庫,允許您高效地查詢和管理高維度向量。以下是如何使用Pinecone進行向量查詢的範例。
查詢函式
首先,定義一個查詢函式pinecone_vector_search,該函式接受兩個引數:user_query和k。其中,user_query是使用者輸入的查詢文字,而k是要傳回的最接近向量的數量。
def pinecone_vector_search(user_query, k):
# 將使用者查詢轉換為向量表示
xq = get_vector_embeddings(user_query)
# 執行Pinecone查詢
res = index.query(vector=xq, top_k=k, include_metadata=True)
return res
查詢過程
以下是查詢過程的步驟解釋:
- 定義查詢函式:定義
pinecone_vector_search函式,接受user_query和k兩個引數。 - 轉換使用者查詢:使用
get_vector_embeddings函式將使用者查詢轉換為向量表示。 - 執行Pinecone查詢:使用Pinecone的
query方法執行查詢,傳入向量表示、top_k引數和include_metadata=True。 - 傳回結果:傳回查詢結果,包括最接近的向量及其相關的資訊。
範例查詢
以下是範例查詢:
user_query = "do we get free unicorn rides?"
res = pinecone_vector_search(user_query, k=1)
print(res)
結果解釋
查詢結果包含了最接近的向量及其相關的資訊,包括:
id:向量的唯一識別碼metadata:與向量相關的資訊,例如文字描述score:向量與查詢向量之間的相似度分數values:與向量相關的其他值
在這個範例中,查詢結果顯示了最接近的向量,其相似度分數為0.835591,且包含了相關的文字描述。
5.4 自我查詢(Self-Querying)機制
自我查詢是一種高階的檢索方法,允許檢索器根據使用者的查詢自動生成新的查詢,並執行對向量資料函式庫的查詢。這種方法可以用於任何型別的資料函式庫,包括NoSQL、SQL或向量資料函式庫。
5.4.1 自我查詢的優點
自我查詢具有多個優點,包括:
- 結構化理解:可以建立一個結構化的schema,以反映使用者的描述,從而實作對資訊的結構化理解。
- 雙層檢索:檢索器可以執行兩層操作,首先是根據使用者輸入和資料函式庫內容之間的語義相似性進行查詢,同時也會根據儲存檔案或行的中繼資料進行篩選,從而實作更精確和相關的檢索。
5.4.2 實作自我查詢
要實作自我查詢,需要使用一個檢索器架構,如圖5-3所示。
圖表翻譯:
圖5-3展示了一個自我查詢檢索器架構。該架構允許檢索器根據使用者的查詢自動生成新的查詢,並執行對向量資料函式庫的查詢。
graph LR
A[使用者查詢] -->|輸入|> B[檢索器]
B -->|生成新查詢|> C[向量資料函式庫]
C -->|傳回結果|> B
B -->|傳回結果|> A
5.4.3 程式碼實作
以下程式碼展示瞭如何使用langchain和lark實作自我查詢:
from langchain_core.documents import Document
from langchain_community.vectorstores.chroma import Chroma
from langchain_openai import OpenAIEmbeddings
import lark
import getpass
import os
import warnings
# 停用警告
warnings.filterwarnings("ignore")
# 建立檔案列表
docs = [
Document(
page_content="一個關於年輕巫師在魔法學校的旅程的故事。",
metadata={
"title": "哈利波特",
"author": "J.K.羅琳",
"genre": "奇幻",
"ISBN": "978-0-7475-3269-9",
"publisher": "Bloomsbury",
"summary": "哈利波特是一個關於年輕巫師在魔法學校的旅程的故事。",
"rating": 4.5
}
)
]
內容解密:
上述程式碼建立了一個檔案列表,每個檔案包含一個書籍的詳細資訊,包括標題、作者、型別、ISBN、出版社、摘要和評分。這些資訊可以用於自我查詢,根據使用者的查詢自動生成新的查詢,並執行對向量資料函式庫的查詢。
自然語言查詢系統的設計
在設計一個自然語言查詢系統時,需要考慮如何有效地儲存和檢索檔案中的metadata。這裡,我們將使用Chroma從檔案中建立一個向量資料函式庫,並使用AttributeInfo類別來結構化每本文的metadata。
建立向量資料函式庫
首先,我們需要建立一個向量資料函式庫,來儲存檔案中的metadata。這裡,我們使用Chroma.from_documents()方法,傳入檔案列表和嵌入模型OpenAIEmbeddings()。
from langchain.chains.query_constructor.base import AttributeInfo
from langchain_openai.chat_models import ChatOpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 定義檔案列表
docs = [
{
"title": "Harry Potter and the Philosopher's Stone",
"author": "J.K. Rowling",
"year_published": 1997,
"genre": "Fiction",
"isbn": "978-0747532699",
"publisher": "Bloomsbury",
"language": "English",
"page_count": 223,
"summary": "The first book in the Harry Potter series where Harry discovers his magical heritage.",
"rating": 4.8,
},
#... 更多檔案...
]
# 建立嵌入模型
embeddings = OpenAIEmbeddings()
# 建立向量資料函式庫
vectorstore = Chroma.from_documents(docs, embeddings)
定義AttributeInfo
接下來,我們需要定義AttributeInfo類別,來結構化每本文的metadata。這裡,我們定義了兩個列表:basic_info和detailed_info,分別包含基本資訊和詳細資訊的屬性。
# 基本資訊
basic_info = [
AttributeInfo(name="title", description="書籍標題", type="string"),
AttributeInfo(name="author", description="書籍作者", type="string"),
AttributeInfo(name="year_published", description="出版年份", type="integer"),
]
# 詳細資訊
detailed_info = [
AttributeInfo(name="genre", description="書籍型別", type="string or list[string]"),
AttributeInfo(name="isbn", description="國際標準書號", type="string"),
]
自查詢系統
最後,我們可以使用SelfQueryRetriever類別,來建立一個自查詢系統。這個系統可以根據使用者的查詢,自動過濾metadata,並傳回相關的結果。
# 建立自查詢系統
retriever = SelfQueryRetriever(vectorstore, basic_info + detailed_info)
這樣,我們就設計了一個自然語言查詢系統,可以根據使用者的查詢,自動過濾metadata,並傳回相關的結果。
步驟一:匯入必要模組
首先,我們需要匯入必要的模組,包括 ChatOpenAI、SelfQueryRetriever 和 AttributeInfo。這些模組分別負責聊天模型整合、自我查詢和定義後設資料屬性。
from LangChain import ChatOpenAI, SelfQueryRetriever, AttributeInfo
步驟二:定義基本資訊屬性
接下來,我們定義基本資訊屬性,包括書籍的標題、作者、出版商、語言和頁數。
basic_info = [
AttributeInfo(
name="title",
description="The title of the book",
type="string",
),
AttributeInfo(
name="author",
description="The author of the book",
type="string",
),
AttributeInfo(
name="publisher",
description="The publishing house that published the book",
type="string",
),
AttributeInfo(
name="language",
description="The primary language the book is written in",
type="string",
),
AttributeInfo(
name="page_count",
description="Number of pages in the book",
type="integer",
),
]
步驟三:定義詳細資訊屬性
然後,我們定義詳細資訊屬性,包括書籍的摘要和評分。
detailed_info = [
# 在這裡新增詳細資訊屬性
]
analysis = [
AttributeInfo(
name="summary",
description="A brief summary or description of the book",
type="string",
),
AttributeInfo(
name="rating",
description="""An average rating for the book (from reviews), ranging from 1-5""",
type="float",
),
]
步驟四:合併所有屬性列表
最後,我們合併所有屬性列表,包括基本資訊、詳細資訊和分析,形成完整的後設資料屬性資訊。
metadata_field_info = basic_info + detailed_info + analysis
結果
透過以上步驟,我們完成了後設資料屬性資訊的定義和合併,形成了一個完整的後設資料屬性列表,包含書籍的基本資訊、詳細資訊和分析。這個列表可以用於後續的資料處理和分析。
玄貓總結:批次處理文字嵌入、Pinecone向量資料函式庫查詢及自我查詢機制
深入剖析文字嵌入批次處理流程及Pinecone向量資料函式庫的查詢機制後,我們發現高效能的資料處理與精準的語義搜尋已成為當今資訊檢索的核心挑戰。本文提出的批次處理方法有效解決了大量文字資料嵌入的效率瓶頸,同時利用tqdm追蹤進度,並透過try-except機制提升系統穩定性,尤其在面對API速率限制時更顯重要。Pinecone向量資料函式庫的整合,則提供了一個強大的向量搜尋方案,能快速且準確地找出與使用者查詢語義相似的文字。
然而,單純的向量相似度搜尋仍有其侷限性。本文進一步探討的自我查詢機制,透過結合向量搜尋和metadata過濾,更精準地滿足使用者資訊需求。Langchain和Lark的整合應用,更展現了自我查詢機制在建構複雜知識圖譜和實作深度語義理解方面的潛力。技術架構的設計,特別是metadata的結構化儲存和利用AttributeInfo定義屬性資訊,是提升查詢效率和精準度的關鍵。
展望未來,隨著AI技術的持續發展,預期向量資料函式庫的效能將進一步提升,自我查詢機制也將更加成熟。結合更先進的自然語言處理技術,未來的資訊檢索系統將能更精準地理解使用者意圖,並提供更個人化、更具洞察力的搜尋結果。玄貓認為,掌握這些關鍵技術,將是構建下一代智慧搜尋引擎的根本,對於提升資訊取得效率和知識探索能力至關重要。對於重視資料價值的企業,建議及早投入研發,並探索這些技術在特定領域的應用,以期在未來的資訊競爭中取得領先地位。