多模態查詢引擎的開發已成為資訊檢索領域的重要趨勢,它能有效整合不同資料型別,提供更精確的搜尋結果。本文將深入探討如何運用 Python 和 LlamaIndex 構築一個多模態向量索引,並以 VisDrone 資料集為例,示範如何實作一個兼具文字和影像查詢功能的引擎。我們將逐步講解索引的建立、查詢的執行、結果的顯示與儲存,以及效能評估的方法,並提供程式碼範例和流程圖,幫助讀者理解整個開發流程。透過 LlamaIndex,我們能有效地管理和查詢多模態資料,提升資訊檢索的效率和準確性,為開發者提供更強大的工具。
建立向量索引和查詢引擎
首先,我們需要建立一個檔案,該檔案將被處理以建立 VisDrone 多模態資料集的向量儲存索引。之前在 GitHub 上建立的 DataFrame df
沒有唯一索引或嵌入。我們將使用 LlamaIndex 在記憶體中建立它們。
import pandas as pd
from PIL import Image, ImageDraw
# 載入 VisDrone 資料集
ds =... # 載入資料集的程式碼
# 建立一個唯一 ID 的 DataFrame
df = pd.DataFrame({
'id': range(len(ds)),
'image': ds.images,
'boxes': ds.boxes,
'labels': ds.labels
})
# 建立 LlamaIndex
from llm import LlamaIndex
index = LlamaIndex(df)
# 查詢引擎
query_engine =... # 查詢引擎的程式碼
查詢和顯示結果
現在,我們可以使用查詢引擎查詢資料集,並顯示結果。
# 使用者輸入
user_input = "truck"
# 查詢資料集
results = query_engine.query(user_input)
# 顯示結果
for result in results:
image_data = result['image']
bboxes = result['boxes']
labels = result['labels']
# 顯示影像
img = Image.frombytes('RGB', (512, 512), image_data)
display(img)
# 新增邊界框
draw = ImageDraw.Draw(img)
for bbox in bboxes:
draw.rectangle(bbox, outline='red')
# 顯示影像
display(img)
儲存影像
最後,我們可以儲存影像。
# 儲存影像
img.save('result.png')
這樣就完成了建立多模態查詢引擎和查詢 VisDrone 資料集的過程。
建立檔案索引
為了建立檔案索引,我們首先需要為每個檔案建立一個唯一的ID。這可以透過將DataFrame的索引轉換為字串來實作。
df['doc_id'] = df.index.astype(str)
接下來,我們建立一個空列表documents
,用於儲存檔案物件。
documents = []
然後,我們遍歷DataFrame的每一行,提取相關的文字標籤,並將其合併成一個字串。
for _, row in df.iterrows():
text_labels = row['labels']
text = " ".join(text_labels)
document = Document(text=text, doc_id=row['doc_id'])
documents.append(document)
建立向量儲存索引
現在,檔案已經準備好,可以使用GPTVectorStoreIndex進行索引了。
vector_store_index = GPTVectorStoreIndex.from_documents(documents)
查詢多模態資料集
設定向量儲存索引作為查詢引擎,我們可以執行查詢來搜尋多模態資料集。
vector_query_engine = vector_store_index.as_query_engine(similarity="cosine")
這樣,我們就可以對多模態資料集執行查詢,例如對VisDrone資料集進行查詢。
內容解密:
在上述程式碼中,我們首先建立了一個唯一的ID列doc_id
,然後建立了一個空列表documents
來儲存檔案物件。接下來,我們遍歷DataFrame的每一行,提取相關的文字標籤,並將其合併成一個字串。然後,我們建立了一個GPTVectorStoreIndex物件,並使用它來索引檔案。最後,我們設定向量儲存索引作為查詢引擎,並執行查詢來搜尋多模態資料集。
圖表翻譯:
flowchart TD A[建立檔案索引] --> B[遍歷DataFrame] B --> C[提取文字標籤] C --> D[合併文字標籤] D --> E[建立檔案物件] E --> F[新增到documents列表] F --> G[建立向量儲存索引] G --> H[設定查詢引擎] H --> I[執行查詢]
此圖表展示了建立檔案索引、遍歷DataFrame、提取文字標籤、合併文字標籤、建立檔案物件、新增到documents列表、建立向量儲存索引、設定查詢引擎和執行查詢的過程。
執行時間分析與文書處理
在進行查詢後,我們首先計算了查詢的執行時間,以確保系統的反應速度是否符合預期。以下是計算執行時間的步驟:
import time
# 記錄開始時間
start_time = time.time()
# 執行查詢
response = vector_query_engine.query(user_input)
# 記錄結束時間
end_time = time.time()
# 計算執行時間
elapsed_time = end_time - start_time
# 輸出執行時間
print(f"查詢執行時間:{elapsed_time:.4f} 秒")
根據輸出的結果,查詢執行時間為 1.8461 秒,這個結果表明系統的反應速度是令人滿意的。
接下來,我們將對查詢的文字回應進行處理。首先,我們使用 textwrap.fill
函式將長文字切割成多行,以便於閱讀:
import textwrap
# 將文字切割成多行
print(textwrap.fill(str(response), 100))
從輸出的結果中,我們可以看到系統的回應是邏輯正確且合理的。系統提到無人機(Drones)使用各種感測器,如攝影機、LiDAR 和 GPS,來識別和追蹤物體,如卡車。
處理回應內容
為了進一步分析回應內容,我們將對回應中的節點進行解析,以找出回應中唯一的單詞,並從中選擇一個進行展示:
from itertools import groupby
def get_unique_words(text):
# 將文字轉換為小寫並移除前後空白
text = text.lower().strip()
# 將文字分割成單詞
words = text.split()
# 尋找唯一的單詞
unique_words = [word for word, _ in groupby(sorted(words))]
return unique_words
# 對每個節點進行處理
for node in response.source_nodes:
print(node.node_id)
# 從節點文字中取得唯一單詞
unique_words = get_unique_words(node.text)
# 進一步處理或分析唯一單詞
#...
這個過程使我們能夠深入瞭解系統回應的內容結構,並能夠根據需要進行進一步的分析或處理。
影像檢索與顯示
在前面的章節中,我們已經學習瞭如何從大語言模型(LLM)中檢索文字資料。現在,我們將學習如何從多模態資料集中檢索影像資料。
影像檢索流程
影像檢索的流程與文字檢索相似。首先,我們需要定義一個函式,用於處理節點文字資料,提取唯一的單詞,並根據這些單詞進行影像檢索。
def get_unique_words(node_text):
# 對節點文字進行分詞和過濾
words = node_text.split()
unique_words = list(set(words))
return unique_words
node_text = "truck"
unique_words = get_unique_words(node_text)
print("Unique Words in Node Text:", unique_words)
影像顯示和儲存
在檢索到影像後,我們需要將其顯示和儲存。為此,我們可以使用Pillow函式庫來處理影像資料。
from PIL import Image
import io
def display_image_with_bboxes(image_data, bboxes, labels, label_name):
# 載入影像資料
image = Image.open(io.BytesIO(image_data))
# 繪製邊界框
for bbox, label in zip(bboxes, labels):
# 繪製邊界框和標籤
image = draw_bounding_box(image, bbox, label)
# 顯示影像
image.show()
# 儲存影像
image.save("boxed_image.jpg")
# 定義邊界框繪製函式
def draw_bounding_box(image, bbox, label):
# 繪製邊界框
draw = ImageDraw.Draw(image)
draw.rectangle(bbox, outline="red")
draw.text((bbox[0], bbox[1]), label, fill="red")
return image
整合檢索和顯示
現在,我們可以整合影像檢索和顯示的流程。
def process_and_display(response, df, ds, unique_words):
# 處理節點文字資料
for i, row in df.iterrows():
if i == row_index:
# 搜尋影像
image_data = search_image(ds, unique_words)
# 顯示和儲存影像
display_image_with_bboxes(image_data, bboxes, labels, label_name)
執行檢索和顯示
最後,我們可以執行影像檢索和顯示的流程。
# 刪除之前儲存的影像
!rm /content/boxed_image.jpg
# 執行檢索和顯示
process_and_display(response, df, ds, unique_words)
圖表翻譯:
flowchart TD A[開始] --> B[處理節點文字] B --> C[搜尋影像] C --> D[顯示和儲存影像] D --> E[結束]
內容解密:
上述程式碼實作了影像檢索和顯示的流程。首先, мы 處理節點文字資料,提取唯一的單詞。然後,我們根據這些單詞進行影像檢索。最後,我們顯示和儲存檢索到的影像。
多模態模組摘要
我們已經建立了一個多模態模組程式,旨在增強生成式人工智慧(AI)的輸出。這個程式包括顯示使用者輸入的源影像、列印使用者輸入和語言模型(LLM)輸出,並顯示多模態回應。
顯示源影像
首先,我們建立了一個函式來顯示使用者輸入的源影像。這個函式使用 Pillow 函式庫來開啟影像並顯示它。
from PIL import Image
import io
def display_source_image(image_path):
image_bytes = io.BytesIO(image_path)
img = Image.open(image_bytes)
img.show()
顯示使用者輸入和 LLM 輸出
接下來,我們列印使用者輸入和 LLM 輸出。這些輸出將以文字形式顯示。
print(user_input)
print(textwrap.fill(str(llm_response), 100))
顯示多模態回應
最後,我們顯示多模態回應。這個回應包括源影像和 bounding box 的顯示。
image_path = "/content/boxed_image.jpg"
display_source_image(image_path)
輸出結果
輸出結果將先顯示文字回應(使用者輸入和 LLM 輸出),然後顯示影像和 bounding box。
How do drones identify a truck?
Drones can identify a truck using visual detection and tracking methods.
影像將以 bounding box 的形式顯示,標記出影像中 truck 的位置。
多模態 RAG 輸出增強
多模態 RAG 輸出增強可以豐富生成式人工智慧的輸出。然而,和所有 AI 程式一樣,需要注意其潛在的限制和挑戰。
圖表翻譯:
graph LR A[使用者輸入] --> B[LLM 輸出] B --> C[多模態回應] C --> D[顯示源影像] D --> E[顯示 bounding box]
內容解密:
上述程式碼使用 Pillow 函式庫來開啟影像並顯示它。display_source_image
函式使用 io.BytesIO
來讀取影像 bytes,並使用 Image.open
來開啟影像。然後,使用 img.show
來顯示影像。
textwrap.fill
函式用於將 LLM 輸出文字包裹在 100 個字元的寬度內,以便於閱讀。
最終,display_source_image
函式被呼叫來顯示源影像和 bounding box。
設計高效能的影像辨識度量指標
設計一個高效能的影像辨識度量指標需要一個有效的影像辨識功能。評估多模態模組化 RAG 的效能需要兩種型別的測量:文字和影像。測量文字相對直截了當,但是測量影像卻是一個挑戰。分析多模態回應的影像與分析文字有很大不同。從多模態查詢引擎中提取了一個關鍵字,然後解析回應以顯示來源影像。但是,我們需要建立一個創新的方法來評估回應的來源影像。
LLM 效能度量指標
LlamaIndex 透過其查詢引擎無縫地呼叫 OpenAI 模型,例如 GPT-4,並在其回應中提供文字內容。對於文字回應,我們將使用與第 2 章「評估輸出與餘弦相似度」部分和第 3 章「向量儲存索引查詢引擎」部分相同的餘弦相似度度量指標。
評估函式使用 sklearn 和 sentence_transformers 來評估兩個文字之間的相似度,在本例中,即輸入和輸出:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import SentenceTransformer
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]
現在,我們可以計算基線使用者輸入和初始 LLM 回應之間的相似度:
llm_similarity_score = calculate_cosine_similarity_with_embeddings(user_input, llm_response)
print(user_input)
print(llm_response)
print(f"Cosine Similarity Score: {llm_similarity_score:.3f}")
輸出顯示使用者輸入、文字回應和兩個文字之間的餘弦相似度:
How do drones identify a truck?
How do drones identify a truck?
Drones can identify a truck using visual detection and tracking m
Cosine Similarity Score: 0.691
輸出令人滿意。但是,我們現在需要設計一個方法來衡量多模態效能。
多模態效能度量指標
為了評估傳回的影像,我們不能簡單地依靠資料集中的標籤。對於小資料集,我們可以手動檢查影像,但當系統擴充套件時,自動化是必要的。在本文中,我們將使用 GPT-4o 的電腦視覺功能來分析影像,解析它以找到我們要查詢的物體,並提供該影像的描述。然後,我們將對玄貓提供的描述應用餘弦相似度。GPT-4o 是一個多模態生成 AI 模型。
首先,讓我們編碼影像以簡化向 GPT-4o 傳輸資料。Base64 編碼將二進位制資料(如影像)轉換為 ASCII 字元,這些字元是標準文字字元。這種轉換至關重要,因為它確保影像資料可以透過設計用於處理文字資料的協定(如 HTTP)進行傳輸。它還避免了二進位制資料傳輸相關的問題,例如資料損壞或解釋錯誤。
import base64
IMAGE_PATH = "/content/boxed_image.jpg"
# 開啟影像檔案並將其編碼為 base64 字串
def encode_image(image_path):
with open(image_path, "rb") as image_file:
encoded_image = base64.b64encode(image_file.read())
return encoded_image
…(待續)
圖片編碼與 OpenAI 介接
首先,我們需要將圖片轉換為 Base64 編碼,以便能夠在 OpenAI 的 API 中傳遞。這個過程可以使用 Python 的 base64
函式庫來完成。
import base64
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
base64_image = encode_image(IMAGE_PATH)
接下來,我們建立一個 OpenAI 的客戶端,並設定 API 金鑰以及指定要使用的模型(在這裡是 gpt-4o
)。
from openai import OpenAI
client = OpenAI(api_key=openai.api_key)
MODEL = "gpt-4o"
提交圖片分析請求
我們選擇了一個唯一的詞彙 (u_word
) 來作為我們的目標標籤,這裡假設為 "truck"
。然後,我們構建了一個請求,包含系統角色和使用者角色,要求模型分析給定的圖片,並找出與目標標籤相關的內容。
u_word = "truck" # 假設的唯一詞彙
model = MODEL
messages = [
{"role": "system", "content": f"You are a helpful assistant analyzing images for {u_word}"},
{"role": "user", "content": [
{"type": "text", "text": f"Analyze the following image for {u_word}"},
{"type": "image", "image": f"data:image/png;base64,{base64_image}"}
]}
]
temperature = 0.0
response_image = client.chat.create(model=model, messages=messages, temperature=temperature)
print(response_image)
分析結果
模型的輸出描述了圖片中與目標標籤 "truck"
相關的內容,包括兩輛卡車的詳細描述,例如它們的型別、載荷和周圍環境。
第一輛卡車(上方 bounding box):
- 出現為一輛平板電腦卡車。
- 載有各種材料,可能是建築材料。
- 停放在一個有其他建築材料的區域。
第二輛卡車(下方 bounding box):
- 也出現為一輛平板電腦卡車。
- 載有不同型別的材料,類別似於第一輛卡車。
- 位於一個類別似的環境中,周圍有建築材料。
兩輛卡車都位於建築或工業區,可能用於運輸材料。
後續步驟
現在,我們可以將這個分析結果提交給 cosine 相似度函式,以便進一步處理和分析圖片中與目標標籤相關的內容。這個過程可以幫助我們更好地理解圖片中的物體和它們之間的關係。
圖表翻譯:
flowchart TD A[圖片編碼] --> B[OpenAI 介接] B --> C[提交圖片分析請求] C --> D[分析結果] D --> E[後續步驟]
這個流程圖展示了從圖片編碼到提交圖片分析請求,然後到分析結果和後續步驟的整個過程。
多模態模組化 RAG 效能評估
在評估多模態模組化 RAG 的效能時,我們需要考慮多個因素,包括文字相似度和影像相似度。文字相似度可以透過計算兩個文字之間的餘弦相似度來評估,而影像相似度則需要使用更複雜的方法,例如使用 GPT-4 進行影像識別並計算識別結果的餘弦相似度。
文字相似度評估
文字相似度評估是透過計算兩個文字之間的餘弦相似度來實作的。這個過程涉及將文字轉換為向量,並計算這些向量之間的餘弦值。餘弦值越接近 1,表示兩個文字之間的相似度越高。
影像相似度評估
影像相似度評估則需要使用更複雜的方法。首先,我們需要使用 GPT-4 進行影像識別,以獲得影像的文字描述。然後,我們可以計算這個文字描述與原始文字之間的餘弦相似度,以評估影像與文字之間的相似度。
多模態模組化 RAG 效能指標
多模態模組化 RAG 的效能指標可以透過計算文字相似度和影像相似度的平均值來評估。這個指標可以反映出系統對於多模態資料的處理能力,以及其對於不同型別資料之間關係的理解能力。
flowchart TD A[文字輸入] --> B[文字相似度評估] B --> C[影像識別] C --> D[影像相似度評估] D --> E[多模態模組化 RAG 效能指標]
圖表翻譯:
上述流程圖描述了多模態模組化 RAG 效能評估的過程。首先,系統接收到文字輸入,並進行文字相似度評估。然後,系統使用 GPT-4 進行影像識別,以獲得影像的文字描述。接下來,系統計算這個文字描述與原始文字之間的餘弦相似度,以評估影像與文字之間的相似度。最後,系統計算文字相似度和影像相似度的平均值,以獲得多模態模組化 RAG 的效能指標。
4. 可以在無人機影像中新增邊界框來識別物體,例如卡車和行人嗎?
可以在無人機影像中新增邊界框來識別物體,例如卡車和行人。這個過程通常涉及使用物體偵測演算法,例如YOLO(You Only Look Once)或SSD(Single Shot Detector),來識別影像中的物體並新增邊界框。
5. 模組化系統是否可以檢索文字和影像資料以回應查詢?
模組化系統可以設計成同時檢索文字和影像資料,以回應查詢。這個過程通常涉及使用多模態檢索演算法,來結合文字和影像特徵,以提供更全面和準確的查詢結果。
6. 是否需要建立向量索引來查詢多模態VisDrone資料集?
建立向量索引可以是查詢多模態VisDrone資料集的一種有效方法。向量索引可以用來儲存和查詢大型資料集,並提供快速和準確的查詢結果。
7. 是否可以在不新增標籤或邊界框的情況下處理檢索的影像?
可以在不新增標籤或邊界框的情況下處理檢索的影像。這個過程通常涉及使用影像處理演算法,來提取影像特徵並進行查詢。
8. 多模態RAG效能指標是否僅根據文字回應?
多模態RAG效能指標不僅根據文字回應,也可以根據影像回應。這個過程通常涉及使用多模態評估指標,來評估RAG系統在文字和影像上的效能。
結論:建構多模態 RAG 系統的挑戰與展望
從技術架構視角來看,本篇文章深入探討瞭如何建構一個多模態 RAG 系統,並以 VisDrone 資料集為例,示範瞭如何結合文字和影像資訊來回應使用者查詢。我們分析了從建立向量索引、執行查詢、顯示結果到評估系統效能的完整流程。其中,利用 LlamaIndex 建立向量索引,並結合 GPT-4o 的多模態能力進行影像分析,是本方案的核心技術亮點。
然而,建構多模態 RAG 系統並非一帆風順。技術限制深析顯示,影像相似度評估的自動化仍是一大挑戰。雖然我們利用 GPT-4o 的電腦視覺功能和 cosine 相似度計算取得初步成果,但在處理大規模資料集時,效能和準確度仍有待提升。此外,如何有效整合不同模態的資訊,並設計更具代表性的評估指標,也是未來研究的重要方向。
展望未來,隨著多模態 AI 技術的快速發展,預期將出現更精準且高效的影像分析工具,進而提升多模態 RAG 系統的整體效能。同時,跨領域技術融合的趨勢,例如結合知識圖譜和影像識別技術,將為多模態 RAG 系統帶來更多創新應用場景。玄貓認為,多模態 RAG 系統代表了資訊檢索的未來方向,值得持續投入研發資源,並積極探索其在不同領域的應用潛力。