在動態RAG架構中,Chroma向量資料函式庫扮演著關鍵角色,有效管理大量的文字資料並進行快速的語義搜尋。透過Python和相關函式庫,我們可以有效地將檔案嵌入Chroma,並利用其提供的API進行查詢和相似度計算。文章首先介紹瞭如何初始化Chroma和嵌入資料,接著示範瞭如何測量回應時間和顯示嵌入結果。此外,文章也詳細說明瞭如何使用Chroma進行語義搜尋,並利用spaCy函式庫計算文字相似度以評估查詢結果的準確性。除了Chroma的應用,文章也探討了Llama模型的組態和最佳化,包含如何調整temperaturerepetition_penalty等引數以控制輸出的多樣性和準確性。最後,文章還提供了一些常見問題的解答,例如如何確保API令牌的安全性、是否使用GPU加速查詢等,並列出了一些參考資料和進一步閱讀的連結。

動態RAG的Chroma向量儲存應用實務

Chroma向量儲存的初始化與資料嵌入

在動態RAG(Retrieval-Augmented Generation)的應用場景中,Chroma向量儲存扮演著至關重要的角色。本文將探討如何初始化Chroma向量儲存並嵌入資料。首先,我們需要檢查集合(collection)是否存在。如果不存在,我們將建立一個新的集合並將檔案(documents)嵌入其中。

資料嵌入流程

  1. 檢查集合是否存在:使用collection_exists變數檢查集合是否已經存在。
  2. 嵌入並儲存資料:如果集合不存在,使用collection.add()方法將檔案ID、檔案內容和元資料(metadatas)加入集合中。
if collection_exists != True:
    collection.add(
        ids=[str(i) for i in range(0, nb)],
        documents=completion_list,
        metadatas=[{"type": "completion"} for _ in range(0, nb)],
    )

內容解密:

  • collection.add()方法用於將資料新增到Chroma向量儲存中。
  • ids引數指定了檔案的唯一識別碼。
  • documents引數包含了要嵌入的檔案內容。
  • metadatas引數提供了額外的元資料資訊,例如資料型別。

測量回應時間

在完成資料嵌入後,我們測量了整個過程的回應時間。

response_time = time.time() - start_time
print(f"Response Time: {response_time:.2f} seconds")

內容解密:

  • 使用time.time()函式記錄開始和結束時間,從而計算出整個過程的耗時。
  • 列印出回應時間,以便評估效能。

顯示嵌入結果

接下來,我們擷取並顯示了嵌入結果中的第一個向量。

result = collection.get(include=['embeddings'])
first_embedding = result['embeddings'][0]
print("First embedding:", first_embedding)
print("Embedding length:", len(first_embedding))

內容解密:

  • collection.get()方法用於擷取集合中的資料,包括嵌入向量。
  • first_embedding變數儲存了第一個嵌入向量的值。
  • 列印出第一個嵌入向量及其長度,以驗證嵌入結果。

查詢集合

本文展示瞭如何使用Chroma向量儲存的語義搜尋功能來查詢相關檔案。

results = collection.query(
    query_texts=df["question"][:nb],
    n_results=1
)

內容解密:

  • collection.query()方法執行查詢操作,根據輸入的問題文字找出最相關的檔案。
  • query_texts引數指定了查詢文字。
  • n_results引數控制傳回的結果數量。

評估查詢結果

為了評估查詢結果的品質,我們使用了spaCy函式庫來計算原始答案和檢索到的檔案之間的相似度。

def simple_text_similarity(text1, text2):
    doc1 = nlp(text1)
    doc2 = nlp(text2)
    vector1 = doc1.vector
    vector2 = doc2.vector
    if np.linalg.norm(vector1) == 0 or np.linalg.norm(vector2) == 0:
        return 0.0
    else:
        similarity = np.dot(vector1, vector2) / (np.linalg.norm(vector1) * np.linalg.norm(vector2))
        return similarity

內容解密:

  • simple_text_similarity函式計算兩個文字之間的餘弦相似度。
  • 使用spaCy的nlp模型將文字轉換為向量表示。
  • 計算餘弦相似度以評估文字之間的語義相似程度。

動態RAG系統的評估與即時查詢功能實作

評估系統效能

在動態RAG系統的開發過程中,評估系統的效能是至關重要的一步。評估方法通常包括計算檢索檔案的準確性以及系統的回應時間。

相似度計算與準確性評估

系統透過比較原始完成文字(original_completion)與檢索到的檔案(retrieved_document)之間的相似度來評估其效能。相似度的計算是使用simple_text_similarity函式,該函式根據spaCy的文字相似度計算方法。

similarity_score = simple_text_similarity(original_completion, retrieved_document)
if similarity_score > 0.7:
    acc_counter += 1

內容解密:

  • similarity_score代表原始完成文字與檢索到的檔案之間的相似度得分。
  • similarity_score大於0.7時,表示檢索到的檔案與原始完成文字高度相關,因此將準確性計數器acc_counter加1。

結果輸出與分析

系統會輸出每個查詢的相關資訊,包括問題、檢索到的檔案、原始完成文字以及相似度得分,以便進行人工觀察和結果追溯。

print(i, " ", f"Question: {q}")
print(f"Retrieved document: {retrieved_document}")
print(f"Original completion: {original_completion}")
print(f"Similarity Score: {similarity_score:.2f}")
print()  # 空行以提高可讀性

內容解密:

  • 輸出資訊包括查詢問題q、檢索到的檔案retrieved_document、原始完成文字original_completion以及相似度得分similarity_score
  • 相似度得分保留兩位小數,以提供更精確的評估結果。

整體準確性計算

在分析所有查詢結果後,系統會計算整體準確性。

if nb > 0:
    acc = acc_counter / nb
    print(f"Number of documents: {nb:.2f}")
    print(f"Overall similarity score: {acc:.2f}")

內容解密:

  • acc代表整體準確性,透過將準確性計數器acc_counter除以查詢總數nb計算得出。
  • 輸出查詢總數和整體相似度得分,以評估系統的整體效能。

即時查詢功能

在會議等實時環境中,系統能夠根據輸入的問題快速檢索相關檔案。

查詢範例

prompt = "Millions of years ago, plants used energy from the sun"
results = collection.query(
    query_texts=[prompt],
    n_results=1
)

內容解密:

  • prompt代表輸入的查詢問題。
  • collection.query方法用於檢索與查詢問題最相關的檔案。

結果輸出

wrapped_question = textwrap.fill(prompt, width=70)
wrapped_document = textwrap.fill(results['documents'][0][0], width=70)
print(f"Question: {wrapped_question}")
print("\n")
print(f"Retrieved document: {wrapped_document}")
print()

內容解密:

  • 使用textwrap.fill方法對查詢問題和檢索到的檔案進行格式化,以提高輸出結果的可讀性。
  • 輸出查詢問題和檢索到的檔案內容。

回應時間測量

系統還會測量查詢的回應時間,以評估其效能。

start_time = time.time()
results = collection.query(
    query_texts=[prompt],
    n_results=1
)
response_time = time.time() - start_time
print(f"Response Time: {response_time:.2f} seconds\n")

內容解密:

  • response_time代表查詢的回應時間,透過記錄查詢前後的時間差計算得出。
  • 輸出回應時間,以評估系統的實時效能。

動態RAG系統的實作與Llama模型組態最佳化

動態RAG(Retrieval-Augmented Generation)系統是一種結合檢索與生成技術的先進AI架構,能夠根據特定查詢需求動態調整檢索策略與生成模型引數,以提升輸出品質。本章節將探討如何實作動態RAG系統,並著重於Llama模型的組態與最佳化。

Llama模型的基本組態

在實作動態RAG系統時,Llama模型的組態至關重要。以下是一個基本的Llama模型組態函式:

def LLaMA2(prompt):
    sequences = pipeline(
        prompt,
        do_sample=True,
        top_k=10,
        num_return_sequences=1,
        eos_token_id=tokenizer.eos_token_id,
        max_new_tokens=100, 
        temperature=0.5, 
        repetition_penalty=2.0, 
        truncation=True
    )
    return sequences

內容解密:

  1. do_sample=True:啟用隨機抽樣,使模型根據詞彙的機率分佈隨機選擇詞彙,增加了輸出的多樣性。
  2. top_k=10:限制模型在抽樣過程中只考慮前10個機率最高的詞彙,平衡了創意與準確性。
  3. num_return_sequences=1:設定模型對每個輸入提示只生成一個輸出序列。
  4. max_new_tokens=100:限制模型最多生成100個新的詞彙,防止輸出過長。
  5. temperature=0.5:控制輸出的隨機性,數值越低輸出越集中,數值越高輸出越多元。
  6. repetition_penalty=2.0:對重複使用的詞彙施加懲罰,降低生成重複內容的可能性。
  7. truncation=True:確保輸出不會超過設定的最大長度,超出的部分會被截斷。

動態調整Llama引數以最佳化輸出

動態RAG系統的一大優勢是能夠根據不同的查詢需求和上下文動態調整Llama模型的引數。例如,可以透過調整temperaturerepetition_penalty來控制輸出的創意性和多樣性。

實務應用與效能評估

在實際應用中,可以透過多次執行查詢和生成任務來評估不同Llama引陣列態下的輸出品質。例如,使用不同的top_k值來觀察對輸出結果的影響。

與其他LLM模型的比較

除了Llama模型外,還可以將動態RAG系統與其他大語言模型(如GPT-4o)進行比較,以評估不同模型的表現。實驗結果表明,GPT-4o在某些場景下能夠提供更優質的輸出。

刪除臨時集合

完成任務後,應刪除臨時建立的集合以釋放資源。可以使用以下程式碼檢查和刪除集合:

# List all collections
collections = client.list_collections()
# Check if the specific collection exists
collection_exists = any(collection.name == collection_name for collection in collections)
print("Collection exists:", collection_exists)
#client.delete_collection(collection_name)

內容解密:

  1. client.list_collections():列出所有現有的集合,用於檢查特定集合是否存在。
  2. any(collection.name == collection_name for collection in collections):檢查指定名稱的集合是否存在。
  3. client.delete_collection(collection_name):刪除指定的集合,釋放資源。
程式碼範例:測量會話時間
end_time = time.time() - session_start_time  # 測量回應時間
print(f"會話準備時間:{end_time:.2f}秒")

內容解密:

這段程式碼用於測量從會話開始到目前為止所花費的時間。其中,time.time()函式傳回當前時間,而session_start_time記錄了會話開始的時間。兩者相減得到會話準備時間,並以秒為單位輸出,保留兩位小數。

動態RAG的優點與挑戰

動態RAG提供了一種開源、輕量級、由RAG驅動的生成式AI,用於快速資料收集、嵌入和查詢。然而,在將其投入生產環境之前,還需要進行更多的工作。此外,當RAG資料量不斷增加時,如何管理這些資料、降低儲存成本和檢索資源將成為一個挑戰。

為了應對這些挑戰,我們可以透過微調(fine-tuning)來整合資料集,例如使用OpenAI GPT-4o-mini模型。此外,對於某些領域,如硬科學,靜態資料可以保持穩定一段較長時間,因此可以透過微調來減少所需的RAG資料量。

常見問題

  1. 為了安全原因,該指令碼是否確保Hugging Face API令牌永遠不會被硬編碼到筆記本中? 答案:是/否(根據實際情況)
  2. 本章的程式中,是否使用了accelerate函式庫來促進ML模型在雲端平台上的佈署? 答案:是/否(根據實際情況)
  3. 在此指令碼中,是否需要與API令牌分開的使用者驗證來存取Chroma資料函式庫? 答案:是/否(根據實際情況)
  4. 筆記本是否使用Chroma進行動態檢索過程中的向量臨時儲存? 答案:是/否(根據實際情況)
  5. 筆記本是否組態為透過GPU最佳化來加速查詢? 答案:是/否(根據實際情況)
  6. 筆記本的會話時間測量是否有助於最佳化動態RAG流程? 答案:是/否(根據實際情況)
  7. 該指令碼是否展示了Chroma與ML模型整合的能力,以提高檢索效能? 答案:是/否(根據實際情況)
  8. 該指令碼是否包含根據會話效能指標調整Chroma資料函式庫引數的功能? 答案:是/否(根據實際情況)