生成式 AI 模型的評估至關重要,尤其在實際應用場景中,評估指標的選取直接影響模型的最佳化方向。本文除了介紹根據 TF-IDF 和 Sentence Transformers 的餘弦相似度和語義相似性評估方法外,更進一步探討如何利用根據索引的 RAG 技術提升生成式 AI 的效能。這種方法的核心思想是將大量的非結構化資料轉換為結構化的索引,以便快速檢索相關資訊,並結合生成式 AI 模型生成更準確、更具參考價值的結果。尤其在處理大規模資料集時,根據索引的 RAG 方法相較於向量式檢索方法,更能有效提升檢索速度和可擴充套件性。

評估生成式AI輸出品質:餘弦相似度與語義相似性的應用

在開發和最佳化生成式AI模型的過程中,評估輸出品質是一項至關重要的任務。本文將探討如何利用餘弦相似度和語義相似性來衡量生成式AI輸出的品質,並透過具體的程式碼範例來說明這些方法的實作。

為什麼需要評估生成式AI輸出品質?

生成式AI模型(如GPT-4)能夠根據輸入提示生成文字輸出。然而,如何評估這些輸出的品質卻是一個挑戰。傳統的方法包括人工評估,但這種方法耗時耗力,且難以擴充套件。因此,我們需要自動化的評估指標來衡量生成式AI輸出的品質。

使用餘弦相似度評估輸出品質

餘弦相似度是一種常用的文字相似度衡量指標。它透過計算兩個文字向量之間的夾角餘弦值來評估它們的相似程度。在這裡,我們將使用TF-IDF(詞頻-逆檔案頻率)來計算文字向量。

程式碼範例:使用TF-IDF計算餘弦相似度

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

def calculate_cosine_similarity(text1, text2):
    vectorizer = TfidfVectorizer()
    tfidf = vectorizer.fit_transform([text1, text2])
    similarity = cosine_similarity(tfidf[0:1], tfidf[1:2])
    return similarity[0][0]

# 示例用法
user_prompt = "評估生成式AI輸出品質"
gpt4_response = "在開發和最佳化生成式AI模型的過程中,評估輸出品質是一項至關重要的任務。"
similarity_score = calculate_cosine_similarity(user_prompt, gpt4_response)
print(f"餘弦相似度得分:{similarity_score:.3f}")

輸出結果可能顯示一個相對較低的相似度得分,例如0.396。這個結果表明,僅使用TF-IDF計算餘弦相似度可能無法準確捕捉文字之間的語義相似性。

使用增強輸入改善評估結果

為了改善評估結果,我們可以計算增強輸入與GPT-4輸出之間的相似度。

程式碼範例:計算增強輸入與GPT-4輸出的相似度

augmented_input = "評估生成式AI輸出品質的方法包括餘弦相似度和語義相似性。"
similarity_score = calculate_cosine_similarity(augmented_input, gpt4_response)
print(f"餘弦相似度得分:{similarity_score:.3f}")

輸出結果顯示一個較高的相似度得分,例如0.857。這表明增強輸入與GPT-4輸出之間的相似度更高。

使用Sentence Transformers提升語義相似性評估

為了進一步提升語義相似性評估的準確性,我們可以使用Sentence Transformers。Sentence Transformers能夠捕捉文字之間的深層語義關係。

程式碼範例:使用Sentence Transformers計算語義相似性

from sentence_transformers import SentenceTransformer
import torch

# 載入預訓練模型
model = SentenceTransformer('all-MiniLM-L6-v2')

def calculate_cosine_similarity_with_embeddings(text1, text2):
    embeddings1 = model.encode(text1)
    embeddings2 = model.encode(text2)
    similarity = cosine_similarity([embeddings1], [embeddings2])
    return similarity[0][0]

# 示例用法
similarity_score = calculate_cosine_similarity_with_embeddings(augmented_input, gpt4_response)
print(f"語義相似度得分:{similarity_score:.3f}")

輸出結果顯示一個較高的語義相似度得分,例如0.739。這表明Sentence Transformers能夠有效地捕捉文字之間的語義相似性。

程式碼解密:
  1. calculate_cosine_similarity函式:使用TF-IDF計算兩個文字之間的餘弦相似度。

    • 作用:提供一個基本的文字相似度評估方法。
    • 邏輯:透過TF-IDF向量化文字,然後計算向量之間的餘弦相似度。
  2. calculate_cosine_similarity_with_embeddings函式:使用Sentence Transformers計算兩個文字之間的語義相似性。

    • 作用:捕捉文字之間的深層語義關係。
    • 邏輯:透過Sentence Transformers將文字編碼為向量,然後計算向量之間的餘弦相似度。
  3. Sentence Transformers模型選擇:選擇all-MiniLM-L6-v2模型進行語義相似性評估。

    • 作用:提供一個高效且準確的語義相似性評估方法。
    • 邏輯:利用預訓練的Sentence Transformers模型捕捉文字之間的語義關係。

透過結合這些方法和程式碼範例,我們可以更有效地評估和最佳化生成式AI模型的輸出品質。

為什麼使用根據索引的RAG?

根據索引的搜尋將先進的RAG驅動的生成式AI提升到另一個層次。當面對大量資料時,它提高了檢索的速度,從原始的資料區塊轉變為有組織的、已索引的節點,使我們能夠從輸出結果追溯到檔案的來源及其位置。

架構分析

根據索引的搜尋比根據向量的搜尋在RAG中更快,因為它直接透過索引存取相關資料,而根據向量的搜尋則是順序比較所有記錄的嵌入向量。在第2章中,我們實作了一個根據向量的相似性搜尋程式,如圖3.1所示:

  1. 資料收集與準備(Pipeline #1):收集並準備資料。
  2. 嵌入向量與向量儲存(Pipeline #2):將資料進行嵌入處理,並將準備好的資料儲存在向量儲存中。
  3. 檢索查詢與生成式AI(Pipeline #3):執行檢索查詢,並使用生成式AI處理使用者輸入,執行根據向量相似性搜尋的檢索,增強輸入,生成回應,並應用效能指標。

這種方法非常靈活,因為它提供了許多實作每個元件的方法,具體取決於專案的需求。

內容解密:

此架構展示了根據索引的RAG系統的基礎組成部分。透過將資料處理流程劃分為多個獨立的管道,我們能夠更靈活地調整和最佳化每個階段,以滿足特定的應用需求。

根據索引的RAG的優勢

  1. 提高檢索速度:透過使用索引直接存取相關資料,顯著提高了在大規模資料集上的檢索效率。
  2. 增強可追溯性:根據索引的RAG系統能夠提供輸出結果的來源和詳細內容,提高了生成結果的可信度和可靠性。
  3. 最佳化資料管理:透過將資料組織成索引節點,簡化了資料的管理和維護工作。

程式碼範例:

import os
from llama_index import SimpleDirectoryReader, VectorStoreIndex
from llama_index.vector_stores import DeepLakeVectorStore
from llama_index.storage.storage_context import StorageContext

# 設定Deep Lake向量儲存
my_activeloop_org_id = "your_org_id"
my_activeloop_dataset_name = "your_dataset_name"
dataset_path = f"hub://{my_activeloop_org_id}/{my_activeloop_dataset_name}"

# 建立向量儲存索引
vector_store = DeepLakeVectorStore(dataset_path=dataset_path, overwrite=True)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

# 載入檔案並建立索引
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)

# 查詢引擎設定
query_engine = index.as_query_engine()
response = query_engine.query("你的查詢問題")

print(response)

內容解密:

此程式碼範例展示瞭如何使用LlamaIndex和Deep Lake建立根據索引的RAG系統。首先,我們設定了Deep Lake向量儲存的路徑,然後使用SimpleDirectoryReader載入檔案並建立向量儲存索引。最後,我們設定了查詢引擎並執行了一個查詢。

索引型別的介紹

在本章中,我們將介紹多種索引型別,包括:

  1. 向量索引(Vector Index):用於根據向量相似性的搜尋。
  2. 樹索引(Tree Index):透過樹狀結構組織資料,提高查詢效率。
  3. 列表索引(List Index):簡單的列表結構,適用於小型資料集。
  4. 關鍵字索引(Keyword Index):根據關鍵字的搜尋,適用於特定領域的查詢。

這些索引型別將根據不同的應用場景和資料特性進行選擇和最佳化。

無人機技術LLM RAG代理的構建

在本章中,我們將構建一個特定領域的無人機技術LLM RAG代理,使用者可以與其互動。無人機技術正在擴充套件到各個領域,如火災偵測、交通資訊和體育賽事。因此,我們選擇無人機技術作為我們的應用範例。

內容解密:

透過構建無人機技術LLM RAG代理,我們將展示如何使用根據索引的RAG系統來增強特定領域的生成式AI應用。這個代理將具備查詢和生成與無人機技術相關內容的能力。

強化根據索引的檢索與生成式AI技術在無人機領域的應用

隨著人工智慧(AI)技術的快速發展,根據檢索的生成模型(RAG)正逐漸成為解決複雜查詢和生成任務的重要工具。本章將探討如何利用Deep Lake、LlamaIndex和OpenAI等技術構建一個根據索引的RAG系統,並將其應用於無人機技術領域。

系統架構與元件

本系統採用與第二章類別似的三階段管道架構,以確保團隊成員能夠專注於不同的任務並高效協作。系統架構如圖3.1所示,主要包含以下三個主要元件:

  1. 資料收集與預處理(Pipeline Component #1 和 D2-Index)

    • 蒐集無人機技術相關的檔案資料,並進行預處理。
    • 將每個檔案儲存為單獨的檔案,並將其名稱和位置新增到後設資料中,以便於後續的檢索和追蹤。
    • 確保每個回應都能直接連結到原始資料來源。
  2. 向量儲存與索引建立(Pipeline Component #2 和 D3-Index)

    • 利用llama-index-vector-stores-deeplake套件建立Deep Lake向量儲存,將預處理後的資料載入其中。
    • 該套件提供了完整的解決方案,包括分塊、嵌入、儲存和LLM整合,簡化了根據索引的RAG實作。
    • 實作快速且高效的資料檢索。
  3. 根據索引的檢索與生成(Pipeline Component #3 和 D4-Index)

    • 利用Deep Lake和LlamaIndex實作根據索引的檢索和生成。
    • 整合自動化排名和評分機制,確保檢索結果的相關性和準確性。
    • 透過LLM代理對檢索到的資訊進行智慧合成,生成有意義的見解或行動方案。

向量式與根據索引的檢索方法比較

特徵 向量式相似性檢索 根據索引的檢索
彈性 中等(預先計算的結構)
速度 大型資料集較慢 快速且最佳化
可擴充套件性 受限於即時處理 高度可擴充套件
複雜度 設定較簡單 需要索引步驟,較複雜
更新頻率 易於更新 需要重新索引

實作步驟

1. 環境設定

首先,安裝必要的套件:

!pip install llama-index-vector-stores-deeplake==0.1.6
!pip install deeplake==3.9.8
!pip install llama-index==0.10.64

驗證套件是否正確安裝:

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.vector_stores.deeplake import DeepLakeVectorStore

2. 資料收集與預處理

蒐集無人機技術相關的檔案,並進行清理和預處理。將每個檔案儲存為單獨的檔案,以便於後續處理。

3. 建立Deep Lake向量儲存

利用DeepLakeVectorStore將預處理後的資料載入到向量儲存中,實作高效的檢索功能。

4. 根據索引的RAG實作

透過LlamaIndex和Deep Lake實作根據索引的檢索和生成。整合LLM代理,對檢索到的資訊進行智慧合成,生成有意義的見解或行動方案。

程式碼範例與解析

安裝環境

!pip install llama-index-vector-stores-deeplake==0.1.6
!pip install deeplake==3.9.8
!pip install llama-index==0.10.64

內容解密:

上述程式碼用於安裝必要的Python套件,包括llama-index-vector-stores-deeplakedeeplakellama-index。這些套件對於建立根據索引的RAG系統至關重要。

驗證套件安裝

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.vector_stores.deeplake import DeepLakeVectorStore

內容解密:

此段程式碼驗證了必要的套件是否正確安裝,並匯入了VectorStoreIndexSimpleDirectoryReaderDeepLakeVectorStore等關鍵類別,用於後續的資料處理和向量儲存建立。

無人機技術檔案的收集與準備(Pipeline1)

在開發一個涉及無人機(drone)技術的檢索增強生成(RAG)系統時,第一步是收集和準備相關的檔案及其後設資料,以便能夠將系統的輸出結果追溯到原始資料來源。本章節將詳細介紹如何實作這一過程。

建立資料目錄

首先,我們需要建立一個資料目錄來存放我們將要處理的檔案:

!mkdir data

收集無人機相關檔案

接下來,我們將使用一個包含無人機技術相關網站的列表來收集資料。這些網站涵蓋了無人機資料集、目標檢測和電腦視覺等主題。以下是用於收集資料的Python程式碼:

import requests
from bs4 import BeautifulSoup
import re
import os

# 定義要爬取的網址列表
urls = [
    "https://github.com/VisDrone/VisDrone-Dataset",
    "https://paperswithcode.com/dataset/visdrone",
    "https://openaccess.thecvf.com/content_ECCVW_2018/papers/111",
    "https://github.com/VisDrone/VisDrone2018-MOT-toolkit",
    "https://en.wikipedia.org/wiki/Object_detection",
    "https://en.wikipedia.org/wiki/Computer_vision",
    # ... 其他網址
]

# 定義清理文字的函式
def clean_text(content):
    # 移除參考文獻標籤和不想要的字元
    content = re.sub(r'\[\d+\]', '', content)  # 移除參考文獻標籤
    content = re.sub(r'[^\w\s\.]', '', content)  # 移除標點符號
    return content

# 定義抓取和清理網頁內容的函式
def fetch_and_clean(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # 若請求失敗則丟擲異常
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # 優先查詢 "mw-parser-output" 類別的 div,若無則查詢 "content" 類別
        content = soup.find('div', {'class': 'mw-parser-output'})
        if content is None:
            content = soup.find('div', {'class': 'content'})
        
        # 移除特定的區塊,如 "References"、"Bibliography" 等
        for section_title in ['References', 'Bibliography', 'External links']:
            section = content.find('span', id=section_title)
            while section:
                for sib in section.parent.find_next_siblings():
                    sib.decompose()
                section.parent.decompose()
                section = content.find('span', id=section_title)
        
        # 提取並清理文字
        text = content.get_text(separator=' ', strip=True)
        text = clean_text(text)
        return text
    except requests.exceptions.RequestException as e:
        print(f"從 {url} 抓取內容時發生錯誤:{e}")
        return None  # 發生錯誤時傳回 None

# 處理每個網址並將內容寫入單獨的檔案
output_dir = './data/'
os.makedirs(output_dir, exist_ok=True)
for url in urls:
    article_name = url.split('/')[-1].replace('.html', '')  # 處理網址以生成檔名
    filename = os.path.join(output_dir, article_name + '.txt')
    clean_article_text = fetch_and_clean(url)
    if clean_article_text is not None:
        with open(filename, 'w', encoding='utf-8') as file:
            file.write(clean_article_text)
print("已將內容寫入 data 目錄下的檔案。")

內容解密:

此程式碼首先定義了一個網址列表,這些網址指向與無人機技術相關的網頁。然後,它使用 requests 函式庫來抓取這些網頁的內容,並使用 BeautifulSoup 來解析 HTML 並提取相關文字。在提取文字之前,它會移除參考文獻區塊和其他不想要的部分。最後,它將清理後的文字寫入到單獨的檔案中,每個檔案對應一個網址。

載入檔案

完成資料收集後,我們使用 SimpleDirectoryReader 類別從 ./data/ 目錄載入檔案:

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

內容解密:

SimpleDirectoryReader 類別會遞迴掃描指定目錄,識別並載入支援的檔案型別(如 .txt.pdf.docx),然後提取內容並傳回包含文字和後設資料(如檔名和檔案路徑)的檔案物件列表。

檢視檔案內容

檢視第一個檔案的內容和後設資料:

print(documents[0])

內容解密:

輸出顯示了檔案的後設資料,包括檔案路徑和檔名。這有助於追溯資料來源。檔案的內容可能包含一些與無人機技術無直接關係的噪聲資料,這模擬了現實世界中資料收集的挑戰。