精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器! 原創(chuàng)

發(fā)布于 2025-8-14 07:58
瀏覽
0收藏

本文介紹ColPali與DocLayNet結(jié)合的多模態(tài)RAG系統(tǒng),通過視覺語言建模理解文檔中的表格、圖表等布局信息,顯著提升復(fù)雜文檔問答的準(zhǔn)確性和上下文感知能力。

簡介

檢索增強生成(RAG)已成為構(gòu)建開放領(lǐng)域和特定領(lǐng)域問答系統(tǒng)的標(biāo)準(zhǔn)范例。傳統(tǒng)意義上,RAG流程嚴(yán)重依賴于基于文本的檢索器,這些檢索器使用密集或稀疏嵌入來索引和檢索段落。雖然這些方法對于純文本內(nèi)容有效,但在處理視覺復(fù)雜的文檔(例如科學(xué)論文、財務(wù)報告或掃描的PDF)時,往往會遇到困難,因為這些文檔中的關(guān)鍵信息嵌入在表格、圖形或結(jié)構(gòu)化布局中,而這些布局無法很好地轉(zhuǎn)換為純文本。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

論文插圖:與傳統(tǒng)方法相比,ColPali簡化了文檔檢索流程,同時提供了更高的性能和更低的延遲(來源:??arxiv??)?

為了突破這些限制,Manuel Faysse等人近期的研究成果提出了ColPALI(ICLR 2025),這是一個視覺語言檢索框架,它使用類似ColBERT的視覺嵌入后期交互,基于圖像理解來檢索文檔內(nèi)容。與此同時,Pfitzmann等人提出了Yolo DocLayNet(CVPR 2025),這是一個快速且布局感知的對象檢測模型,專門用于以高精度和高效率提取文檔組件,例如表格、圖表和章節(jié)標(biāo)題。

在本文中,我將指導(dǎo)你完成混合RAG管道的實際實現(xiàn),該管道結(jié)合了ColPALI和DocLayout-YOLO,以實現(xiàn)對閱讀和查看的文檔的問答。

RAG系統(tǒng)中的視覺盲點

盡管在處理文本查詢方面取得了成功,但大多數(shù)RAG系統(tǒng)都忽略了一個關(guān)鍵問題。它們幾乎忽略了表格、圖表和圖形等視覺元素,而這些元素在許多實際文檔中都承載著至關(guān)重要的意義。讓我們來看看下圖。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

圖片來自:SLB 2023年年度報告的摘錄(資料來源:??報告??)?

通過應(yīng)用常見的OCR工具從表格中提取文本,我們可以得到以下結(jié)果。

Option Awards Stock Awards
 Name
 Option/ 
PSU/RSU 
...
...
... (truncated)
Shares, Units, or 
Other Rights That 
Have Not Vested 
($)(1)
 D. Ralston 1/20/2021 67,220(2) 3,498,129
 1/20/2021 33,610(3) 1,749,064
 2/3/2021 29,390(4) 1,529,456
 1/19/2022 64,587(5) 3,361,107
 1/19/2022 22,321(6) 1,161,585
 1/18/2023 41,668(7) 2,168,403
 1/18/2023 14,427(8) 750,781

顯然,OCR結(jié)果無法捕捉多層級標(biāo)題結(jié)構(gòu)和列分組,導(dǎo)致文本呈現(xiàn)扁平的線性,數(shù)值與其對應(yīng)指標(biāo)之間的關(guān)聯(lián)性缺失。這使得數(shù)據(jù)所屬類別(例如授予日期與股票獎勵)難以識別,從而降低了提取數(shù)據(jù)對下游分析的實用性。

用戶查詢:What is the market value of unearned shares, units, or other rights that have not vested for the 1/20/2021 grant date?(2021年1月20日授予日尚未歸屬的未賺取股份、單位或其他權(quán)利的市場價值是多少?)

RAG回應(yīng):The market value of unearned shares, units, or other rights that have not vested for the 1/20/2021 grant date is $1,749,064.(2021年1月20日授予日尚未歸屬的未賺取股份、單位或其他權(quán)利的市場價值為1,749,064美元。)

由于提取的信息缺乏結(jié)構(gòu)和上下文,因此產(chǎn)生的RAG響應(yīng)不準(zhǔn)確,因為它無法可靠地將值與原始表中的預(yù)期含義關(guān)聯(lián)起來。

讓我們探討另一個例子來進(jìn)一步說明傳統(tǒng)RAG系統(tǒng)的局限性。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

圖片來源:SLB 2023年年度報告中的數(shù)據(jù)圖表片段(來源:??報告??)?

這是從上圖中提取的OCR結(jié)果。

Total Shareholder Return
 Indexed ($100)
 $50.0 \n$40.0 \n$30.0 \n$20.0 \n$10.0 \n$0.0-$10.0-$20.0
 2020 2021 2023 2022
 CEO CAP Avg. NEO CAP SLB TSR-$10.6
 $2.2 \n$32.4 \n$13.1 \n$39.4 \n$26.2 \n$17.3 \n$9.3 
 ...
 ...
 ... (truncated)
 $40.00 \n$20.00 \n$0.00
 OSX TSR
 CAP vs. Total Shareholder Return
 (SLB and OSX)
 (in millions of US dollars)
 Compensation Actually Paid

易知,該圖表的OCR輸出也缺乏結(jié)構(gòu)一致性,未能捕捉數(shù)據(jù)點之間的關(guān)系,例如哪些條形或標(biāo)簽對應(yīng)特定年份或股東回報率線。此外,它還未能將數(shù)值與其視覺元素進(jìn)行對齊,導(dǎo)致難以區(qū)分每年的CEO CAP、NEO CAP和TSR值。

問題:What was the SLB Total Shareholder Return (TSR) in 2022?(2022年SLB總股東回報率(TSR)是多少?)

RAG回應(yīng):The SLB Total Shareholder Return (TSR) in 2022 was $134.09.(SLB2022年的總股東回報(TSR)為134.09美元。)

與前面的示例一樣,由于OCR提取的數(shù)據(jù)中結(jié)構(gòu)和上下文的丟失,此處的RAG響應(yīng)也不準(zhǔn)確。

多模態(tài)RAG架構(gòu)

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

作者插圖:我們實驗中的多模態(tài)RAG架構(gòu)

該架構(gòu)由兩個主要組件組成:索引管道和聊天推理管道。在索引階段,文檔語料庫通過兩條并行路徑進(jìn)行處理。第一條路徑使用YOLO-DocLayNet檢測器識別表格和圖形等視覺元素,然后使用ColPALI圖像編碼器將其嵌入并存儲在圖像向量集合中。第二條路徑使用PyTesseractOCR從文檔中提取原始文本,然后使用Mxbai-Embed模型對其進(jìn)行編碼,并保存在同一向量數(shù)據(jù)庫中的文本向量集合中。

在聊天推理過程中,用戶查詢會同時由用于Mxbai-Embed文本檢索的編碼器和用于視覺語言檢索的ColPALI編碼器進(jìn)行編碼。然后,系統(tǒng)會針對各自的向量集合執(zhí)行雙重檢索(文本到文本和文本到圖像)。檢索到的文本和圖像區(qū)域會被轉(zhuǎn)發(fā)到多模態(tài)LLM(LLaMA-4),該模型會綜合兩種模態(tài),生成上下文感知且準(zhǔn)確的響應(yīng)。這種設(shè)計將文本理解與細(xì)粒度的視覺推理相結(jié)合,從而實現(xiàn)強大的文檔質(zhì)量保證(QA)。

我的測試設(shè)置

A. 環(huán)境設(shè)置

為了高效運行完整的多模式RAG管道,我使用單個NVIDIA RTX A6000 GPU和48GB的VRAM,這為運行ColPALI、YOLO模型和句子嵌入模型提供了足夠的內(nèi)存。

對于軟件環(huán)境,我建議使用Miniconda來隔離你的依賴關(guān)系并確保可重復(fù)性。

1.創(chuàng)建Conda環(huán)境

conda create -n multimodal_rag pythnotallow=3.11 
conda activate multimodal_rag

2. 準(zhǔn)備requirements.txt

ultralytics 
git+https://github.com/illuin-tech/colpali 
groq 
pill 
pymilvus 
sentence-transformers 
uvicorn 
fastapi 
opencv-python 
pytesseract 
PyMuPDF 
pydantic 
chainlit 
pybase64 
huggingface_hub[hf_transfer]

3.安裝Python依賴項

pip install -r requirements.txt

B.預(yù)訓(xùn)練模型設(shè)置

要復(fù)現(xiàn)此實驗,你需要下載檢索和布局提取流程中使用的三個預(yù)訓(xùn)練模型。所有模型都將存儲在該pretrained_models/目錄下,以保持一致性并更易于加載。

下面是使用Hugging Face CLI下載它們的命令hf transfer,該命令針對更快的下載速度進(jìn)行了優(yōu)化:

# 下載YOLO DocLayNet用于布局檢測
HF_HUB_ENABLE_HF_TRANSFER=1 hf download hantian/yolo-doclaynet --local-dir pretrained_models/yolo-doclaynet

# 下載 ColQwen 2.5(用于 ColPALI)用于基于圖像的檢索
HF_HUB_ENABLE_HF_TRANSFER=1 hf download vidore/colqwen2.5-v0.2 --local-dir pretrained_models/colqwen2.5-v0.2

# 下載 Mixedbread Embed Large 模型用于基于文本的檢索
HF_HUB_ENABLE_HF_TRANSFER=1 hf download mixedbread-ai/mxbai-embed-large-v1 --local-dir pretrained_models/mxbai-embed-large-v1

C. 代碼設(shè)置和初始化

import torch 
from Typing import Cast 
from Ultralytics import YOLO 
from transforms.utils.import_utils import is_flash_attn_2_available 
from colpali_engine.models.paligemma.colpali.processing_colpali import ColPaliProcessor 
from colpali_engine.models import ColQwen2_5, ColQwen2_5_Processor 
from sentence_transformers import SentenceTransformer 

# 定義設(shè)備
device = "cuda" if torch.cuda.is_available() else "cpu" 

# 定義知識庫源和目標(biāo)圖像目錄
document_source_dir = "document_sources"
 img_dir = "image_database"
 os.makedirs(img_dir, exist_ok= True ) # 確保目錄存在

# YOLO-12L-Doclaynet
 yolo_model = YOLO( "pretrained_models/yolo-doclaynet/yolov12l-doclaynet.pt" ) 
yolo_model = yolo_model.to(device) 

# ColQwen2.5-Colpali
 colpali_model = ColQwen2_5.from_pretrained( 
 "pretrained_models/colqwen2.5-v0.2" , 
 torch_dtype=torch.bfloat16, 
 device_map=device, # 或 "mps" 如果在 Apple Silicon 上
 attn_implementatinotallow= "flash_attention_2" 如果is_flash_attn_2_available() else None , 
 )。eval () 
colpali_processor = ColQwen2_5_Processor.from_pretrained( "pretrained_models/colqwen2.5-v0.2" ) 
processor = cast( 
 ColPaliProcessor, 
 colpali_processor) 

# Mxbai-embed-large-v1
 embed_model = SentenceTransformer( "pretrained_models/mxbai-embed-large-v1" ,device=device) 

# 定義實體顏色
ENTITIES_COLORS = { 
 "Picture" : ( 255 , 72 , 88 ), 
 "Table" : ( 128 , 0 , 128 ) 
} 

print ( "FINISH SETUP..." )

上述代碼初始化了多模態(tài)檢索系統(tǒng)的核心組件。它設(shè)置了設(shè)備(GPU或CPU),確保圖像輸出目錄存在,并加載了三個預(yù)訓(xùn)練模型:YOLOv12L-DocLayNet模型(用于檢測表格和圖形等布局元素)、ColQwen2.5模型(其ColPALI處理器用于對裁剪圖像區(qū)域進(jìn)行視覺語言嵌入)以及mxbai-embed-large-v1模型(使用SentenceTransformers嵌入文本)。此外,它還定義了檢測到的實體類型的顏色映射,以支持預(yù)處理過程中的可視化。

索引管道

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

作者插圖:索引管道

索引管道負(fù)責(zé)將原始文檔轉(zhuǎn)換為結(jié)構(gòu)化的、可搜索的文本和視覺表示形式。在本節(jié)中,我們將逐步講解實際實現(xiàn)過程,展示如何使用代碼處理、編碼和存儲文檔內(nèi)容。

A. 準(zhǔn)備

在繼續(xù)開發(fā)之前,讓我們準(zhǔn)備一些對分析有用的處理函數(shù)。

import matplotlib.pyplot as plt 
import cv2 

def display_img_array ( img_arr ): 
 image_rgb = cv2.cvtColor(img_arr, cv2.COLOR_BGR2RGB) 
 plt.figure(figsize=( 30 , 30 )) 
 plt.imshow(image_rgb) 
 plt.axis( 'off' ) 
 plt.show() 

def show_layout_detection ( detection_results, img_arr ): 
 for result indetection_results : 
 boxes = result.boxes # 獲取檢測框
 for box in boxes: 
 x, y, w, h = box.xywh[ 0 ] # 框坐標(biāo)(中心 x, y, 寬度, 高度)
 x, y, w, h = int (x), int (y), int (w), int (h) # 轉(zhuǎn)換為整數(shù)
 conf = box.conf.item() # 置信度得分
 cls = int (box.cls.item()) # 類 ID
 label = f" {yolo_model.model.names[cls]} {conf: .2 f} "
 color = ENTITIES_COLORS[yolo_model.model.names[cls]] # 獲取此類的顏色
 top_left = (x - w // 2 , y - h // 2 ) 
 bottom_right = (x + w // 2 , y + h // 2 ) # 特定類的彩色框
 cv2.rectangle(img_arr, top_left, bottom_right, color, 2 ) 
 cv2.putText(img_arr, label, (top_left[ 0 ], top_left[ 1 ] - 10 ), cv2.FONT_HERSHEY_SIMPLEX, 0.9 , color, 2 ) # 匹配文本顏色
 display_img_array(img_arr)

上面的兩個輔助函數(shù)將用于可視化布局檢測。其中,display_img_array將BGR圖像轉(zhuǎn)換為RGB并使用matplotlib顯示它;同時,show_layout_detection使用YOLO檢測結(jié)果和特定于類的顏色在檢測到的布局元素(例如表格、圖形)上疊加邊界框和標(biāo)簽。

接下來,讓我們準(zhǔn)備要加載的PDF中的特定頁面,如下所示。

import fitz # PyMuPDF
import numpy as np
import cv2
import os

# 定義文件名和頁面
page_id = 38
 filename = "SLB-2023-Annual-Report.pdf" 

# 閱讀文檔
doc = fitz. open (os.path.join(document_source_dir,filename)) 
page = doc.load_page(page_id) 
pix = page.get_pixmap(dpi= 300 ) 
img_rgb = np.frombuffer(pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, pix.n)) 
img_page = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)

此代碼使用PyMuPDF從PDF文件加載特定頁面,以高分辨率呈現(xiàn),并將其轉(zhuǎn)換為適合OpenCV處理的BGR圖像數(shù)組。

B.布局檢測

現(xiàn)在,讓我們編寫如下布局檢測代碼。

def layout_detection(img_doc):
 return yolo_model.predict(
 source=img_doc, 
 classes=[6,8],
 cnotallow=0.25, 
 iou=0.45)

layout_results = layout_detection(img_page)
show_layout_detection(layout_results, img_page)

在此步驟中,我們專門過濾檢測到的布局元素,使其僅包含與嵌入的相關(guān)視覺區(qū)域相對應(yīng)的類標(biāo)簽6(表格)和8(圖形)。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

圖片來源:SLB 2023年年度報告第37頁(來源:??報告??)?

在這里,我們成功定位了相關(guān)的視覺對象,例如圓形圖和表格,這些將用于下游的視覺嵌入。

C. 提取并保存

接下來,讓我們從圖像中檢索本地化的表格和圖片區(qū)域,并用白色遮罩它們以將它們從原始頁面視圖中刪除。

def extract_and_masking_images(img_doc, layout_results):
 height, width, _ = img_doc.shape
 extracted_imgs = []
 for box in layout_results[0].boxes:
 x, y, w, h = map(int,box.xywh[0]) #矩形坐標(biāo)(中心x、y、寬度、高度)
 # 計算左上角(x_min, y_min)
 x_min = x - w // 2
 y_min = y - h // 2
 x_max = x_min + w
 y_max = y_min + h
 # 將坐標(biāo)夾緊到圖像邊界
 x_start = max(0, x_min)
 y_start = max(0, y_min)
 x_end = min(width, x_max)
 y_end = min(height, y_max)
 # 如果區(qū)域無效,則跳過
 if x_start >= x_end or y_start >= y_end:
 continue
 # 將圖像提取到extracted_imgs數(shù)組中
 extracted_imgs.append(img_doc[y_start:y_end, x_start:x_end].copy())
 #將區(qū)域設(shè)置為白色
 img_doc[y_start:y_end, x_start:x_end] = [255, 255, 255]
 return extracted_imgs, img_doc

extracted_imgs, img_page = extract_and_masking_images(img_page, layout_results)
display_img_array(img_page)

此函數(shù)從文檔圖像中提取檢測到的表格和圖片區(qū)域,并用白色遮罩這些區(qū)域,返回裁剪后的視覺效果和更新后的圖像。更新后的頁面圖像如下所示。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

圖片來源:SLB 2023年年度報告第37頁(來源:??報告??)?

接下來,讓我們使用如下代碼保存提取的圖形。

import os
import cv2

def save_img_files(extracted_imgs, filename, page_id):
 #目標(biāo)路徑
 save_path = os.path.join(img_dir, filename, f"page_{page_id}/")
 # 確保目錄存在
 os.makedirs(os.path.dirname(save_path), exist_ok=True)
 # 保存圖像
 for i in range(len(extracted_imgs)):
 cv2.imwrite(save_path+f"fig_{i}.jpg", extracted_imgs[i])

save_img_files(extracted_imgs, filename, page_id)

此代碼將提取的圖形和表格圖像保存到指定的本地目標(biāo)目錄中img_dir。

D.文本OCR

在此步驟中,讓我們使用帶有pytesseract的普通OCR從屏蔽文檔圖像中提取剩余的文本信息。

import pytesseract

text = pytesseract.image_to_string(img_page)
print(text)

結(jié)果如下:

Short-Term Cash Incentive Awards

We pay performance-based short-term (annual) cash incentives to
our executives to foster a results-driven, pay-for-performance culture,
and to align executives’ interests with those of our shareholders. STI
awards are earned according to the achievement of quantitative
Company financial and non-financial objectives, as well as strategic
objectives. Our Compensation Committee selects performance
measures that it believes support our strategy and strike a balance
between motivating our executives to increase near-term financial and
operating results and driving profitable long-term Company growth
and value for shareholders.

2022 STI Opportunity Mix

Compensation Discussion and Analysis

For 2023, 70% of our NEOs’ target STI opportunity was based on
achieving quantitative Company financial objectives, 10% was based
on achieving quantitative Company non-financial objectives, and 20%
was based on strategic personal objectives. The financial portion of
the target plan was evenly split between adjusted EBITDA and free
cash flow performance goals. The total maximum STI payout for 2023
was 200% of target—consistent with 2022—and the weighted payout
range for each metric as a percentage of target is reflected by the outer
bars in the 2023 STI Opportunity Mix chart below.

2023 STI Opportunity Mix

?>

?>

In January 2023, our Compensation Committee determined to leave the target STI opportunity for all NEOs unchanged from 2022, following
a review of market data indicating that our NEOs’ target STI opportunity (as a percentage of base salary) was competitively positioned. As a
result, the 2023 target STI opportunity for our CEO was 150% of his base salary and for our other NEOs it was 100% of base salary.

The following table reflects our NEOs’ full-year 2023 STI results, together with relevant weightings of the different components and payouts

under each component.

(1) Equals the sum of the financial, non-financial, and personal portions of the STI achieved, shown as a percentage of base salary.
(2) In January 2024, due to factors not contemplated in the 2023 forecast, our Compensation Committee applied a discretionary downward
adjustment to reduce all executive payouts by 5% under our 2023 STI plan.

2024 Proxy Statement

E. 使用Milvus DB Client建立索引

在此步驟中,我們將使用Milvus數(shù)據(jù)庫進(jìn)行向量存儲和檢索;我們選擇使用文件milvus_file.db的簡單本地實例來進(jìn)行此實驗,而不是使用可擴展的生產(chǎn)級設(shè)置。

1.Retriever類

讓我們定義兩個檢索器:用于細(xì)粒度基于圖像的檢索的ColBERT樣式檢索器和用于基于文本的檢索的基本密集檢索器。

from pymilvus import MilvusClient, DataType
import numpy as np
import concurrent.futures
import os
import base64

class MilvusColbertRetriever:
 def __init__(self, milvus_client, collection_name, img_dir, dim=128):
 #使用Milvus客戶端、集合名稱和向量嵌入的維度初始化檢索器。
 # If the collection exists, load it.
 self.collection_name = collection_name
 self.client = milvus_client
 if self.client.has_collection(collection_name=self.collection_name):
 self.client.load_collection(collection_name)
 self.dim = dim
 self.img_dir = img_dir

 def create_collection(self):
 # 在Milvus中創(chuàng)建一個新的集合來存儲嵌入。
 #如果現(xiàn)有集合已存在,請刪除該集合,并為該集合定義架構(gòu)。
 if self.client.has_collection(collection_name=self.collection_name):
 self.client.drop_collection(collection_name=self.collection_name)
 schema = self.client.create_schema(auto_id=True, enable_dynamic_field=True)
 schema.add_field(field_name="pk", datatype=DataType.INT64, is_primary=True)
 schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=self.dim)
 schema.add_field(field_name="seq_id", datatype=DataType.INT16)
 schema.add_field(field_name="doc_id", datatype=DataType.INT64)
 schema.add_field(field_name="doc", datatype=DataType.VARCHAR, max_length=65535)
 self.client.create_collection(collection_name=self.collection_name, schema=schema)

 def create_index(self):
 # 在向量字段上創(chuàng)建索引,以實現(xiàn)快速相似性搜索。
 # 在使用指定參數(shù)創(chuàng)建新索引之前,釋放并刪除任何現(xiàn)有索引。
 self.client.release_collection(collection_name=self.collection_name)
 self.client.drop_index(collection_name=self.collection_name, index_name="vector")
 index_params = self.client.prepare_index_params()
 index_params.add_index(
 field_name="vector",
 index_name="vector_index",
 index_type="IVF_FLAT", 
 metric_type="IP", 
 )
 self.client.create_index(collection_name=self.collection_name, index_params=index_params, sync=True)

 def search(self, data, topk):
 # 對集合執(zhí)行向量搜索,以找到前k個最相似的文檔。
 search_params = {"metric_type": "IP", "params": {}}
 results = self.client.search(
 self.collection_name,
 data,
 limit=int(50),
 output_fields=["vector", "seq_id", "doc_id","$meta"],
 search_params=search_params,
 )
 doc_meta = {}
 for r_id in range(len(results)):
 for r in range(len(results[r_id])):
 entity = results[r_id][r]["entity"]
 doc_id = entity["doc_id"]
 if doc_id not in doc_meta:
 doc_meta[doc_id] = {
 "page_id": entity["page_id"],
 "fig_id": entity["fig_id"],
 "filename": entity["filename"],
 }
 scores = []

 def rerank_single_doc(doc_id, data, client, collection_name):
 #通過檢索單個文檔的嵌入并計算其與查詢的相似度來對其重新排序。
 doc_colbert_vecs = client.query(
 collection_name=collection_name,
 filter=f"doc_id in [{doc_id}]",
 output_fields=["seq_id", "vector", "doc"],
 limit=1000,
 )
 doc_vecs = np.vstack(
 [doc_colbert_vecs[i]["vector"] for i in range(len(doc_colbert_vecs))]
 )
 score = np.dot(data, doc_vecs.T).max(1).sum()
 return (score, doc_id)

 with concurrent.futures.ThreadPoolExecutor(max_workers=300) as executor:
 futures = {
 executor.submit(
 rerank_single_doc, doc_id, data, self.client, self.collection_name
 ): doc_id
 for doc_id in doc_meta.keys()
 }
 for future in concurrent.futures.as_completed(futures):
 score, doc_id = future.result()
 meta = doc_meta[doc_id]
 img_path = os.path.join(self.img_dir, meta["filename"], f"page_{meta['page_id']}", f"fig_{meta['fig_id']}.jpg")
 with open(img_path, "rb") as f:
 img_base64 = base64.b64encode(f.read()).decode('utf-8')
 scores.append({
 "score":float(score), 
 "page_id": meta["page_id"],
 "fig_id": meta["fig_id"],
 "filename": meta["filename"],
 "content": img_base64})

 scores.sort(key=lambda x: x["score"], reverse=True)
 if len(scores) >= topk:
 return scores[:topk]
 else:
 return scores

 def insert(self, data):
 # 將文檔的ColBERT嵌入和元數(shù)據(jù)插入集合中。
 #將數(shù)據(jù)作為多個向量(每個序列一個)與相應(yīng)的元數(shù)據(jù)一起插入。
 colbert_vecs = [vec for vec in data["colbert_vecs"]]
 seq_length = len(colbert_vecs)
 self.client.insert(
 self.collection_name,
 [
 {
 "vector": colbert_vecs[i],
 "seq_id": i,
 "doc_id": data["doc_id"] ,
 "doc": "",
 "page_id": data["page_id"],
 "fig_id": data["fig_id"],
 "filename": data["filename"],
 }
 for i in range(seq_length)
 ],
 )

class MilvusBasicRetriever:
 def __init__(self, milvus_client, collection_name, dim=1024):
 # 使用Milvus客戶端、集合名稱和向量嵌入的維度初始化檢索器。
 #如果集合存在,則加載之。
 self.collection_name = collection_name
 self.client = milvus_client
 if self.client.has_collection(collection_name=self.collection_name):
 self.client.load_collection(collection_name)
 self.dim = dim

 def normalize(self, vec):
 #把向量規(guī)范化
 norm = np.linalg.norm(vec)
 if norm == 0:
 return vec
 return vec / norm

 def create_collection(self):
 # 在Milvus中創(chuàng)建一個新的集合來存儲嵌入。
 #如果現(xiàn)有集合已存在,請刪除該集合,并為該集合定義架構(gòu)。
 if self.client.has_collection(collection_name=self.collection_name):
 self.client.drop_collection(collection_name=self.collection_name)
 schema = self.client.create_schema(auto_id=True, enable_dynamic_field=True)
 schema.add_field(field_name="pk", datatype=DataType.INT64, is_primary=True)
 schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=self.dim)
 schema.add_field(field_name="content", datatype=DataType.VARCHAR, max_length=65535)
 self.client.create_collection(collection_name=self.collection_name, schema=schema)

 def create_index(self):
 #在向量字段上創(chuàng)建索引,以實現(xiàn)快速相似性搜索。
 # 在使用指定參數(shù)創(chuàng)建新索引之前,釋放并刪除任何現(xiàn)有索引。
 self.client.release_collection(collection_name=self.collection_name)
 self.client.drop_index(collection_name=self.collection_name, index_name="vector")
 index_params = self.client.prepare_index_params()
 index_params.add_index(
 field_name="vector",
 index_name="vector_index",
 index_type="IVF_FLAT", # or any other index type you want
 metric_type="IP", # or the appropriate metric type
 )
 self.client.create_index(collection_name=self.collection_name, index_params=index_params, sync=True)

 def search(self, data, topk):
 #對集合執(zhí)行向量搜索,以找到前k個最相似的文檔。
 normalized_data = self.normalize(data)
 search_params = {"metric_type": "IP", "params": {}}
 results = self.client.search(
 self.collection_name,
 [normalized_data],
 limit=topk,
 output_fields=["vector", "content","$meta"],
 search_params=search_params,
 )
 return_arr = []
 for hit in results[0]:
 return_arr.append({
 "score":hit.distance,
 "page_id":hit["entity"]["page_id"],
 "filename":hit["entity"]["filename"],
 "content":hit["entity"]["content"]
 })
 return return_arr

 def insert(self, data):
 data["vector"] = self.normalize(np.array(data["vector"])).tolist()
 self.client.insert(
 self.collection_name,
 [data]
 )

這段代碼定義了兩個與Milvus交互的檢索器類,以支持混合檢索:

  • MilvusColbertRetriever專為使用ColBERT樣式的多向量嵌入進(jìn)行基于圖像的檢索而設(shè)計。它支持插入來自ColPALI的塊級視覺嵌入,使用后期交互(MaxSim)對結(jié)果進(jìn)行重新排序,并返回最匹配的圖像區(qū)域及其元數(shù)據(jù)和base64編碼的內(nèi)容。?
  • MilvusBasicRetriever用于基于文本的檢索。它存儲并搜索來自句子嵌入的單個密集向量,對余弦相似度進(jìn)行歸一化(通過內(nèi)積),并檢索最相關(guān)的文本塊及其源元數(shù)據(jù)。?

兩種檢索器均可處理集合創(chuàng)建、索引和插入,從而實現(xiàn)對視覺和文本文檔內(nèi)容的靈活的多模式檢索。

2. Retriever設(shè)置

使用上面定義的檢索器類,讓我們初始化ColBERT風(fēng)格的圖像檢索器和基本文本檢索器,并將它們安裝在由milvus_file.db支持的本地Milvus實例上,以進(jìn)行存儲和檢索。

client = MilvusClient("milvus_file.db")
colbert_retriever = MilvusColbertRetriever(collection_name="colbert", milvus_client=client,img_dir=img_dir)
basic_retriever = MilvusBasicRetriever(collection_name="basic", milvus_client=client)

對于初始化步驟,我們必須為兩個檢索器創(chuàng)建集合和索引,如下所示。

colbert_retriever.create_collection() 
colbert_retriever.create_index() 
basic_retriever.create_collection() 
basic_retriever.create_index()

3.圖像數(shù)據(jù)加載器

讓我們將使用ColPALI模型的圖像嵌入過程包裝到數(shù)據(jù)加載函數(shù)中。

from colpali_engine.utils.torch_utils import ListDataset
from torch.utils.data import DataLoader
from typing import List
from tqdm import tqdm
from PIL import Image

def create_image_embedding_loader(extracted_imgs):
 images = [Image.fromarray(img_arr) for img_arr in extracted_imgs]
 dataloader_images = DataLoader(
 dataset=ListDataset[str](images),
 batch_size=1,
 shuffle=False,
 collate_fn=lambda x: processor.process_images(x),
 )
 ds: List[torch.Tensor] = []
 for batch_doc in tqdm(dataloader_images):
 with torch.no_grad():
 batch_doc = {k: v.to(colpali_model.device) for k, v in batch_doc.items()}
 embeddings_doc = colpali_model(**batch_doc)
 ds.extend(list(torch.unbind(embeddings_doc.to("cpu"))))
 return ds

embedding_loader = create_image_embedding_loader(extracted_imgs)
embedding_loader

此函數(shù)將提取的圖像區(qū)域列表包裝到DataLoader中,并使用ColPALI模型對其進(jìn)行處理,并返回每個圖像的多向量嵌入列表。返回列表的結(jié)果如下。

[tensor([[-0.0055, 0.0991, -0.0903, ..., -0.0474, -0.0042, -0.1138],
 [-0.0067, 0.1064, -0.0488, ..., -0.0723, 0.0535, -0.0986],
 [-0.0200, 0.1113, -0.1084, ..., -0.0747, 0.0447, -0.0786],
 ...,
 [-0.0027, 0.0811, -0.1602, ..., 0.0354, -0.0112, -0.1670],
 [-0.0557, -0.1099, 0.0128, ..., 0.0203, -0.0728, -0.0688],
 [ 0.1025, 0.0145, -0.0420, ..., 0.0894, -0.0413, 0.1650]], dtype=torch.bfloat16),
 tensor([[-0.0055, 0.0991, -0.0903, ..., -0.0474, -0.0042, -0.1138],
 [-0.0067, 0.1064, -0.0488, ..., -0.0723, 0.0535, -0.0986],
 [-0.0200, 0.1113, -0.1084, ..., -0.0747, 0.0447, -0.0786],
 ...,
 [-0.0141, 0.0645, -0.1377, ..., 0.0430, -0.0061, -0.1338],
 [-0.0835, -0.1094, 0.0049, ..., 0.0211, -0.0608, -0.0645],
 [ 0.1396, 0.0549, -0.0669, ..., 0.0942, 0.0038, 0.1514]], dtype=torch.bfloat16),
 tensor([[-0.0053, 0.0996, -0.0894, ..., -0.0471, -0.0042, -0.1128],
 [-0.0068, 0.1060, -0.0491, ..., -0.0713, 0.0532, -0.0986],
 [-0.0204, 0.1118, -0.1089, ..., -0.0752, 0.0444, -0.0791],
 ...,
 [ 0.0330, 0.0398, -0.0505, ..., 0.0586, 0.0250, -0.1099],
 [-0.0508, -0.0981, -0.0126, ..., 0.0183, -0.0791, -0.0713],
 [ 0.1387, 0.0698, -0.0330, ..., 0.0238, 0.0923, 0.0337]], dtype=torch.bfloat16)]

4. 圖像和文本索引

在此步驟中,讓我們將頁面圖像中提取的數(shù)據(jù)組件(包括圖像和文本)索引到數(shù)據(jù)庫集合中。

import random

for i in range(len(extracted_imgs)):
 data = {
 "colbert_vecs": embedding_loader[i].float().numpy(),
 "doc_id": random.getrandbits(63),
 "page_id": page_id,
 "fig_id": i,
 "filename": filename,
 }
 colbert_retriever.insert(data)

此代碼將每個圖像嵌入到ColBERT樣式檢索器中,并附帶相關(guān)元數(shù)據(jù),分配唯一的doc_id并存儲頁面和圖形索引引用。

data = {
 "vector": embed_model.encode(text),
 "content": text,
 "page_id": page_id,
 "filename": filename
}
basic_retriever.insert(data)

此代碼將文本嵌入及其元數(shù)據(jù)(包括內(nèi)容、頁面ID和文件名)插入到基本文本檢索器中進(jìn)行索引。

5. Retriever測試

最后,讓我們測試一下上面設(shè)置的檢索器。

query = "O.Le Peuch Payout Results in percentage according to SLB Financial Objectives"
batch_query = colpali_processor.process_queries([query]).to(device)
embeddings_query = torch.unbind(colpali_model(**batch_query).to("cpu"))[0].float().numpy()
colbert_retriever_result = colbert_retriever.search(embeddings_query, topk=3)
colbert_retriever_result

此代碼使用ColPALI模型嵌入用戶查詢,并從ColBERT風(fēng)格的檢索器中檢索出最相關(guān)的前3個圖像區(qū)域。結(jié)果如下。

[{ 'score' : 20.13466208751197, 
 'page_id' : 38, 
 'fig_id' : 1, 
 'filename' : 'SLB-2023-Annual-Report.pdf' , 
 'content' : '/9j/4AAQSkZJRgABAQAAAQABAAD/...' }, 
{ 'score' : 20.13466208751197, 
 'page_id' : 38, 
 'fig_id' : 1, 
 'filename' : 'SLB-2023-Annual-Report.pdf' , 
 'content' : '/9j/4AAQSkZJRgABAQAAAQABAAD/...' }, 
{ 'score' : 15.088707166083623,
 'page_id':41,
 'fig_id':1,
 'filename':'SLB-2023-Annual-Report.pdf',
 'content':'/9j/4AAQSkZJRgABAQAAAQABAAD/...' }]

接下來,讓我們測試一下基本的檢索器。

query = "Potential Payout as a % of Target Opportunity"
basic_retriever_result = basic_retriever.search(embed_model.encode(query), topk=3)
basic_retriever_result

此代碼使用文本嵌入模型對查詢進(jìn)行編碼,并從基本檢索器中檢索出最相關(guān)的前3個文本條目。結(jié)果如下。

[{'score': 0.6565427184104919,
 'page_id': 38,
 'filename': 'SLB-2023-Annual-Report.pdf',
 'content': 'Short-Term Cash Incentive Awards\n\nWe pay performance-based short-term (annual) cash incentives to\nour ... (truncated)'},
 {'score': 0.6533020734786987,
 'page_id': 40,
 'filename': 'SLB-2023-Annual-Report.pdf',
 'content': "Free Cash Flow Targets and Results\n\nIn January 2023, our Compensation Committee considered SLB's\n2022 ... (truncated)"},
 {'score': 0.6505128145217896,
 'page_id': 59,
 'filename': 'SLB-2023-Annual-Report.pdf',
 'content': "Executive Compensation Tables\n\nChange in Control\n\nUnder our omnibus incentive plans, in the event of ... (truncated)"}]

在這里,得分的差異是由于檢索方法造成的:ColBERT風(fēng)格的檢索器使用內(nèi)積(IP),從而產(chǎn)生更大的分?jǐn)?shù)值,而基本檢索器反映余弦相似度,通常會產(chǎn)生在-1和之間較小范圍內(nèi)的分?jǐn)?shù)+1。

聊天推理管道

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

作者插圖:聊天推理管道

聊天推理管道通過從文本和圖像嵌入中檢索相關(guān)內(nèi)容來處理用戶查詢,從而生成準(zhǔn)確且情境感知的響應(yīng)。在本節(jié)中,我們將實現(xiàn)查詢編碼、檢索和多模態(tài)步驟,以完成端到端問答工作流程。

A. 準(zhǔn)備

對于聊天補全模型,我們使用Meta開發(fā)的一款功能強大的多模態(tài)LLM Llama-4。我們將使用GROQ API Key來使用此Llama模型。代碼如下。

import os
from groq import Groq

# Groq API-Llama4
os.environ["GROQ_API_KEY"] = "<your-api-key>"
client_groq = Groq()

接下來,讓我們準(zhǔn)備一些處理函數(shù),如下所示。

def url_conversion(img_base64):
 return f"data:image/jpeg;base64,{img_base64}"

def llama4_inference(messages, token=1024):
 completion = client_groq.chat.completions.create(
 model="meta-llama/llama-4-maverick-17b-128e-instruct",
 messages=messages,
 temperature=0.1,
 max_completion_tokens=token,
 top_p=1,
 stream=True,
 stop=None,
 )
 inference_result = ""
 for chunk in completion:
 chunk_inference = chunk.choices[0].delta.content or ""
 inference_result += chunk_inference
 text = inference_result
 return text

此代碼定義了一個函數(shù),用于將base64編碼的圖像轉(zhuǎn)換為可顯示的URL,以及一個llama推理函數(shù),用于通過Groq的API使用LLaMA 4 Maverick模型執(zhí)行流推理。

B. 用戶查詢和相關(guān)上下文

現(xiàn)在,讓我們定義用戶查詢并檢索相關(guān)上下文,如下所示。

user_query = "I want to know the payout"
batch_query = colpali_processor.process_queries([user_query]).to(device)
embeddings_query = torch.unbind(colpali_model(**batch_query).to("cpu"))[0].float().numpy()
colbert_retriever_result = colbert_retriever.search(embeddings_query, topk=3)
basic_retriever_result = basic_retriever.search(embed_model.encode(user_query), topk=3)

此代碼使用ColPALI模型執(zhí)行文本到圖像檢索的查詢嵌入,并使用句子嵌入模型執(zhí)行文本到文本檢索,遵循與上一個檢索步驟相同的方法。

C.系統(tǒng)指令

接下來,讓我們?yōu)槲覀兊膌lama模型定義系統(tǒng)指令提示,如下所示。

system_instruction = """
You are a helpful assistant designed to answer user queries based on document-related content.

You will be provided with two types of context:
1. Text-based context — extracted textual content from documents.
2. Image-based context — visual content (e.g., figures, tables, or screenshots) extracted from documents.

Your tasks are:
- Analyze the user query and determine the appropriate response using the available context.
- Decide whether the answer requires information from the image-based context.

If the image context is necessary to answer the query:
- Set "need_image" to True.
- Set "image_index" to the appropriate index of the image used (e.g., 0 for the first image, 1 for the second, and so on).
- Include a clear explanation or reasoning in the response.

If the image context is **not** needed:
- Set "need_image" to False.
- Set "image_index" to -1.

All responses **must be returned in strict JSON format**:
{"response": <string>, "need_image": <true|false>, "image_index": <int>}

If you are unsure or cannot answer based on the given context, clearly state that you do not know.

Examples:
{"response": "The chart in image 1 shows the revenue trend.", "need_image": true, "image_index": 1}
{"response": "The policy details are outlined in the text section.", "need_image": false, "image_index": -1}
"""

該系統(tǒng)指令定義了助手應(yīng)如何基于兩種類型的文檔上下文(基于文本和基于圖像)回答用戶查詢。它指導(dǎo)模型判斷是否需要圖像來回答查詢,并以嚴(yán)格的JSON格式構(gòu)建響應(yīng),并包含一個標(biāo)志(need_image)和一個image_indexif applicable標(biāo)記。該指令確保文檔理解任務(wù)的響應(yīng)一致、可解釋且支持多模式感知。

D. 消息有效載荷

接下來,讓我們創(chuàng)建將傳遞給Llama模型API的消息有效負(fù)載,如下所示。

#定義有效載荷內(nèi)容
payload_content = [{
 "type": "text",
 "text": f"User Query: {user_query}"
 }]

# 構(gòu)造正在檢索的圖像URL
for i in range(len(colbert_retriever_result)):
 img_payload = {
 "type": "image_url",
 "image_url": {"url":url_conversion(colbert_retriever_result[i]["content"])}
 }
 payload_content.append(img_payload)

# 構(gòu)建基于文本的上下文
for i in range(len(basic_retriever_result)):
 txt_payload = {
 "type": "text",
 "text": f"Text-based Context #{i+1}:\n{basic_retriever_result[i]['content']}"
 }
 payload_content.append(txt_payload)

#創(chuàng)建最終消息形式
messages = [
 {
 "role": "system",
 "content": system_instruction
 },
 {
 "role": "user",
 "content": payload_content
 }
]

此代碼通過將用戶查詢、檢索到的圖像(以base64 URL的形式)和基于文本的上下文組合成結(jié)構(gòu)化消息格式,構(gòu)建LLM的輸入負(fù)載。然后,它將這些內(nèi)容與系統(tǒng)指令一起包裝,形成最終的messages推理輸入。

構(gòu)造messages如下。

[{'role': 'system',
 'content': '\nYou are a helpful assistant designed to answer user queries based on document-related content.\n\nYou will be provided with two types of context:\n1. Text-based ... (truncated)'},
 {'role': 'user',
 'content': [{'type': 'text',
 'text': 'User Query: I want to know the payout'},
 {'type': 'image_url',
 'image_url': {'url': 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...'}},
 {'type': 'image_url',
 'image_url': {'url': 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...'}},
 {'type': 'image_url',
 'image_url': {'url': 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...'}},
 {'type': 'text',
 'text': 'Text-based Context #1:\nExecutive Compensation Tables\n\nSummary Compensation Table\n\nThe following table sets forth information regarding the total compensation ... (truncated)'},
 {'type': 'text',
 'text': 'Text-based Context #2:\nExecutive Compensation Tables\n\nGrants of Plan-Based Awards in 2023\n\nThe following table provides additional information regarding cash ... (truncated)'},
 {'type': 'text',
 'text': 'Text-based Context #3:\nPay vs. Performance Comparison\n\nPay vs. Performance Comparison\n\nAs discussed in the CD&A above, our Compensation Committee has implemented ... (truncated)'}]}

E.模型推理

現(xiàn)在,讓我們使用Llama模型來預(yù)測響應(yīng),如下所示。

import json
import re 

chat_result = llama4_inference(messages) 
chat_result = re.findall( r'\{[^{}]+\}' , chat_result) 
chat_result = json.loads(chat_result[- 1 ]) 
chat_result

此代碼運行LLM推理,使用正則表達(dá)式從輸出中提取最后的JSON格式的響應(yīng),并將其解析為Python字典以供進(jìn)一步使用。

由此推論可得出如下結(jié)果。

{'response': 'The payout varies based on the performance metric. For Relative TSR Percentile Rank, Delta ROCE, and FCF Margin, the payouts are illustrated in the provided graphs. For example, at a Relative TSR Percentile Rank of 60%, the payout is 60%; at a Delta ROCE of 0 bps, the payout is 100%; and at an FCF Margin of 10%, the payout is 100%.',
 'need_image': True,
 'image_index': 0}

F. 輸出響應(yīng)

下一步是按如下方式構(gòu)建輸出響應(yīng)。

if chat_result[ "need_image" ]: 
 img_content = colbert_retriever_result[chat_result[ 'image_index' ]][ 'content' ] 
else : 
 img_content = ""

 output_response = { 
 "response" :chat_result[ "response" ], 
 "need_image" :chat_result[ "need_image" ], 
 "img_base64" :img_content 
 } 
output_response

此代碼檢查LLM響應(yīng)是否需要圖像;如果需要,則從ColBERT檢索器結(jié)果中檢索相應(yīng)的base64圖像內(nèi)容。然后,它會構(gòu)建一個最終響應(yīng)字典,其中包含答案文本、圖像標(biāo)志以及圖像內(nèi)容(如果適用)。

最終構(gòu)建的響應(yīng)如下。

{'response': 'The payout varies based on the performance metric. For Relative TSR Percentile Rank, Delta ROCE, and FCF Margin, the payouts are illustrated in the provided graphs. For example, at a Relative TSR Percentile Rank of 60%, the payout is 60%; at a Delta ROCE of 0 bps, the payout is 100%; and at an FCF Margin of 10%, the payout is 100%.',
 'need_image': True,
 'img_base64': '/9j/4AAQSkZJRgABAQAAAQABAAD/...'}

評估

在本節(jié)中,我們將討論我們提出的多模態(tài)RAG管道和標(biāo)準(zhǔn)純文本RAG管道之間的定性比較,重點介紹檢索相關(guān)性和答案質(zhì)量方面的關(guān)鍵差異,特別是對于基于視覺的查詢。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

作者插圖:我們的管道與常見的RAG管道的比較

我們的定性比較表明,多模態(tài)RAG流程比標(biāo)準(zhǔn)的純文本RAG系統(tǒng)能夠提供更準(zhǔn)確的答案,尤其是在涉及表格、圖形和圖表等結(jié)構(gòu)化視覺內(nèi)容的查詢時。標(biāo)準(zhǔn)RAG流程依賴OCR將文檔視覺內(nèi)容轉(zhuǎn)換為純文本,這通常會導(dǎo)致空間結(jié)構(gòu)的丟失和關(guān)鍵信息的誤解。

相比之下,我們的系統(tǒng)結(jié)合了基于ColPALI的圖像檢索、用于布局檢測的YOLO DocLayNet以及標(biāo)準(zhǔn)文本嵌入,從而同時保留視覺和語義上下文。這使得它能夠準(zhǔn)確地檢索和推理基于OCR的流程通常會遺漏的內(nèi)容,凸顯了真正多模態(tài)方法的有效性。

進(jìn)一步的演示

我開發(fā)了一個簡單的基于Chainlit的應(yīng)用程序來總結(jié)我們的實驗。以下是該Web應(yīng)用程序的前端概覽。

ColPali聯(lián)手DocLayNet:打造能“看懂”文檔布局的視覺問答神器!-AI.x社區(qū)

作者插圖:多模式RAG應(yīng)用程序的前端

通過此應(yīng)用程序,聊天機器人能夠檢索文本和圖像信息來回答用戶查詢。當(dāng)用戶查詢相關(guān)時,它還可以顯示相關(guān)圖像,以增強理解并提供更清晰的背景信息。

為了復(fù)制此Web應(yīng)用程序及其對應(yīng)的后端服務(wù)器,我創(chuàng)建了一個GitHub存儲庫,你可以在??此處??訪問。此存儲庫完全復(fù)制了我們的實驗,包括完整的知識庫索引管道以及端到端部署所需的所有組件。?

結(jié)論

在本文中,我們構(gòu)建了一個多模態(tài)RAG系統(tǒng),該系統(tǒng)結(jié)合了用于基于圖像的檢索的ColPALI和用于視覺區(qū)域檢測的YOLO-DocLayNet,從而突破了傳統(tǒng)純文本檢索的局限性。通過實際結(jié)果演示,我們展示了如何將文本和視覺上下文相結(jié)合,在文檔問答任務(wù)中提供更準(zhǔn)確、更具有上下文感知的答案。

參考文獻(xiàn)

  1. Faysse, M.,Sibille, H.,Wu, T.,Omrani, B.,Viaud, G.,Hudelot, C.和Colombo, P.(2024)。ColPali:基于視覺語言模型的高效文檔檢索。arXiv預(yù)印本arXiv:2407.01449。地址:??https ://arxiv.org/abs/2407.01449??。?
  2. Pfitzmann, B.,Auer, C.,Dolfi, M.,Nassar, AS和Staar, P.(2022)。DocLayNet:用于文檔布局分割的大型人工注釋數(shù)據(jù)集。載于第28屆ACM SIGKDD知識發(fā)現(xiàn)與數(shù)據(jù)挖掘會議論文集(第3743-3751頁)。?
  3. Reimers, N.和Gurevych, I.(2020)。利用知識蒸餾將單語句子嵌入多語言化。載于2020年自然語言處理實證方法會議(EMNLP)論文集。計算語言學(xué)協(xié)會。地址:??https ://arxiv.org/abs/2004.09813??。?

譯者介紹

朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。

原文標(biāo)題:??ColPALI Meets DocLayNet: A Vision-Aware Multimodal RAG for Document-QA??,作者:Abu Hanif Muhammad Syarubany

?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請注明出處,否則將追究法律責(zé)任
已于2025-8-14 09:41:34修改
收藏
回復(fù)
舉報
回復(fù)
相關(guān)推薦
免费毛片在线不卡| 高h视频在线观看| 久久三级视频| 日韩在线视频免费观看| 女人高潮一级片| 欧美人与性动交α欧美精品图片| 成人av在线一区二区| 欧洲美女免费图片一区| 少妇视频一区二区| 国产一区二区三区国产精品| 亚洲福利国产精品| 日韩欧美亚洲日产国| 99国产精品欲| 国产一区二区三区久久久久久久久 | 台湾成人av| www.com欧美| 香蕉国产精品偷在线观看不卡| 日韩中文字幕在线视频| av黄色一级片| 国产精久久久| 91豆麻精品91久久久久久| 激情六月天婷婷| 天堂av在线资源| 国产一区91精品张津瑜| 国产91在线视频| 伊人国产在线观看| 99精品电影| 亚洲视频日韩精品| 成年人的黄色片| 蜜桃在线一区| 欧美日韩在线三区| 日日碰狠狠躁久久躁婷婷| 青草视频在线免费直播 | sese综合| 亚洲国产wwwccc36天堂| 在线国产精品网| 麻豆影视在线| 91亚洲资源网| 国产伦精品一区二区三区视频孕妇 | 亚洲一区中文| 欧美激情一区二区三区成人 | 国产乱国产乱老熟300部视频| 巨胸喷奶水www久久久免费动漫| 午夜一区二区三区视频| 国产欧美精品aaaaaa片| 国产盗摄在线观看| 国产精品灌醉下药二区| 香蕉久久夜色| 亚洲欧洲精品视频| www.好吊色| 狠狠色狠狠色综合人人| 日本道精品一区二区三区| 欧美在线亚洲综合一区| 国产日本在线视频| 性感美女一区二区三区| 亚洲国产精品久久久久久女王| 欧美一区二区三区免费大片| 国产精品成人观看视频免费| 国产精品久久久久久久免费| 日韩激情在线观看| 日韩免费不卡av| 无码人妻aⅴ一区二区三区有奶水| av成人黄色| 欧美性做爰毛片| 久久国产黄色片| 欧美综合二区| 国产精品9999| 一本久道久久综合无码中文| 久久国产成人午夜av影院| 国产在线播放不卡| 国产精品久久免费| 国产激情一区二区三区| 成人国产一区二区| 亚洲 欧美 精品| 久久久国产一区二区三区四区小说| 欧美一区二区视频在线| av小片在线| 中文字幕一区二区三区不卡在线 | 不卡av一区二区| 国产一区二区三区直播精品电影| 色噜噜噜噜噜噜| 亚洲国产精品日韩专区av有中文| 久久99热精品| 精品人妻一区二区三区免费看 | 国产成人精品网站| 亚洲视频在线免费播放| 国产精品996| 久久国产精品99久久久久久丝袜| 国产精品影院在线| 亚洲乱码国产乱码精品精98午夜 | 国产网站欧美日韩免费精品在线观看 | 亚洲a成人v| 欧美v国产在线一区二区三区| 国产精品一级黄片| 999久久久免费精品国产| 亚洲国产一区二区精品专区| 精品999视频| 国产精品久免费的黄网站| 伊人网视频在线| 亚洲精品成人| 欧美亚洲日本网站| 中文字幕一区二区三区免费看| 国产一区二区三区蝌蚪| 久久99精品久久久久久久青青日本| 国产资源在线播放| 亚洲一区二区三区视频在线播放| 亚洲成人自拍网| 久久国产精品久久精品国产| 国产高清视频在线| 亚洲综合区在线| wwwwxxxx日韩| 99亚洲乱人伦aⅴ精品| 国产亚洲精品美女久久久久| 久久这里只有精品国产| 欧美aⅴ一区二区三区视频| 国产精品一区二区不卡视频| 午夜小视频在线| 欧美性极品xxxx做受| 操人视频免费看| 国精一区二区| 欧美亚洲视频在线观看| av免费观看在线| 国产精品视频观看| 爱福利视频一区二区| 国产精品亚洲一区二区在线观看| 亚洲人永久免费| 国产精品不卡av| 国产一区二区三区不卡在线观看| 欧美连裤袜在线视频| 成人在线免费观看黄色| 欧美一卡二卡三卡| 成年人网站在线观看视频| 免费国产自线拍一欧美视频| 翡翠波斯猫1977年美国| 国产鲁鲁视频在线观看特色| 欧美在线播放高清精品| 91精品视频观看| 久久国产视频精品| 成人久久18免费网站麻豆| 精品国产三级a∨在线| a∨色狠狠一区二区三区| 亚洲人成伊人成综合网久久久| 国产精品成人网站| 国产成人综合在线观看| 欧美性受黑人性爽| 懂色av色香蕉一区二区蜜桃| 日韩最新中文字幕电影免费看| 中文字幕免费视频观看| 久久久亚洲精品石原莉奈| 91猫先生在线| 亚洲区小说区| 日本精品视频在线播放| 免费一级毛片在线观看| 日韩欧美999| 丰满少妇一区二区| 日韩av一二三| 亚洲色图自拍| 国产精品日本一区二区不卡视频| 日韩三级成人av网| av中文字幕观看| 亚洲一区成人在线| 在线视频 日韩| 久久aⅴ国产紧身牛仔裤| 欧美日韩综合久久| 久久精品97| 欧美日韩国产成人在线观看| 性一交一乱一乱一视频| 天天操天天综合网| 亚洲精品一区二区三区影院忠贞| 日韩精品91亚洲二区在线观看| 亚洲精品一区国产精品| aa亚洲一区一区三区| 欧美高清电影在线看| 五月天激情婷婷| 色噜噜狠狠色综合中国| 51妺嘿嘿午夜福利| 国产米奇在线777精品观看| 国产91在线亚洲| 午夜精品福利影院| 国产免费一区二区三区在线能观看| 国产天堂在线| 欧美一区二区视频观看视频| 美女的奶胸大爽爽大片| 99精品国产99久久久久久白柏| 国产成人无码一二三区视频| 日韩欧美午夜| 国产伦理一区二区三区| 不卡一二三区| 久久综合国产精品台湾中文娱乐网| 性一交一乱一伧老太| 色老头久久综合| 欧美卡一卡二卡三| 久久蜜桃av一区二区天堂| www.色欧美| 日韩视频精品在线观看| 亚洲春色综合另类校园电影| 综合久久成人| 国产精品日韩专区| 成人女同在线观看| 综合久久五月天| 日本高清视频免费看| 欧美日韩精品免费观看视频| 日本a在线观看| 国产精品毛片久久久久久| 91精品又粗又猛又爽| 麻豆精品视频在线观看免费| 六月婷婷在线视频| 91tv官网精品成人亚洲| 欧美高清一区二区| 高清日韩中文字幕| 成人福利网站在线观看| 人狥杂交一区欧美二区| 欧美黄色三级网站| 日本在线免费中文字幕| 成人高清视频在线观看| 国产偷国产偷精品高清尤物| 亚洲最大的免费| 日本不卡一二三| 久久久亚洲国产| 国产成人高清精品| 国产一区二区三区精品久久久| 丰满少妇高潮在线观看| 欧美在线免费观看亚洲| 日韩视频免费观看高清| 亚洲男人的天堂一区二区| 一级黄色片网址| 久久婷婷综合激情| www.88av| 成人精品国产免费网站| 91视频免费入口| 国产一区二区三区免费播放| 97超碰人人爽| 蜜桃传媒麻豆第一区在线观看| av免费播放网址| 国产一区导航| 2022亚洲天堂| 在线视频精品| 久久亚洲中文字幕无码| 国产在线不卡| 日本a在线天堂| 午夜国产一区二区| 夜夜爽www精品| 999国产精品永久免费视频app| 日本视频一区二区不卡| 妖精一区二区三区精品视频| 乱一区二区三区在线播放| 女仆av观看一区| 免费看污久久久| 精品一区免费| 日韩精品一线二线三线| 精品理论电影在线| 亚洲v国产v在线观看| 色琪琪久久se色| 丰满女人性猛交| 自拍偷拍欧美专区| 日本天堂免费a| 亚洲无毛电影| 欧美爱爱视频免费看| 亚洲视频1区| 国产精品乱码久久久久| 青青草伊人久久| 午夜视频在线网站| 国产成人免费xxxxxxxx| 手机免费看av片| 久久综合国产精品| 免费看一级黄色| 玉足女爽爽91| 久久国产视频一区| 欧美性受xxxx黑人xyx| 麻豆天美蜜桃91| 免费在线看黄| 亚洲xxx拳头交| 色94色欧美sute亚洲线路二| 91九色单男在线观看| 国产在线网站| 主播福利视频一区| 深夜国产在线播放| 97欧美精品一区二区三区| 欧美特大特白屁股xxxx| 国产日韩欧美在线播放| 视频在线一区| 欧美性xxxx69| 久久久久久久久久久久久久久久久久 | 久久综合久久综合久久| 日本一卡二卡在线播放| 亚洲精品久久嫩草网站秘色| 日韩av无码中文字幕| 欧美丝袜丝交足nylons| 亚洲h视频在线观看| 亚洲欧美日韩中文视频| free性欧美hd另类精品| 欧美在线xxx| 久久爱www.| 青青草原亚洲| 韩国在线一区| 久久久精品麻豆| 成人a免费在线看| 91大神福利视频| 欧美性xxxxx极品| 精品人妻一区二区三区三区四区| 亚洲男人天堂古典| av激情在线| 国产精品久久一区| 国产91精品入| 好色先生视频污| 奇米在线7777在线精品| 波多野结衣一二三区| 专区另类欧美日韩| 无码一区二区三区| 亚洲国产另类 国产精品国产免费| 在线视频1区2区| 日韩免费观看高清| 老司机在线精品视频| 日本xxx免费| 美女网站色91| 亚洲天堂久久新| 午夜a成v人精品| www夜片内射视频日韩精品成人| 中文字幕一区日韩电影| 亚洲wwww| 久久99国产精品| 亚洲精品美女| 中文字幕乱妇无码av在线| 国产精品三级久久久久三级| 亚洲影院在线播放| 日韩精品视频中文在线观看| 亚洲精品一线| 99精彩视频| 一级欧洲+日本+国产| www.超碰97.com| 国产精品高清亚洲| 一区二区三区免费在线| 中文字幕免费精品一区高清| 自拍偷自拍亚洲精品被多人伦好爽| 国产综合欧美在线看| 亚洲福利电影| 亚洲v在线观看| 亚洲影视在线播放| 在线观看日韩精品视频| 一区二区三区成人精品| 国产精品手机在线观看| 亚洲一区二区三区四区在线免费观看| 国产手机av在线| 日韩电影免费一区| www久久99| 99久久这里只有精品| xxx国产在线观看| 国产精品入口麻豆原神| 艳妇乳肉豪妇荡乳av| 日韩网站免费观看| 亚洲色图图片| 9色视频在线观看| 岛国一区二区三区| 久草精品视频在线观看| 日韩电影视频免费| 亚洲人体视频| 亚洲第一导航| 韩国毛片一区二区三区| 后入内射无码人妻一区| 欧美剧情电影在线观看完整版免费励志电影| 色欧美激情视频在线| 国产一区红桃视频| 亚洲无中文字幕| 一边摸一边做爽的视频17国产 | 中文字幕 国产| 日韩天堂在线视频| a看欧美黄色女同性恋| 97国产精东麻豆人妻电影| 国产拍欧美日韩视频二区| 亚洲午夜激情视频| 欧美激情成人在线视频| 窝窝社区一区二区| 国产精品v日韩精品v在线观看| 亚洲女与黑人做爰| 懂色av成人一区二区三区| 2021国产精品视频| 凹凸成人精品亚洲精品密奴| 一级做a爱视频| 黑人巨大精品欧美一区免费视频 | 欧美三级不卡| 特级西西人体wwwww| 欧美性三三影院| 美女航空一级毛片在线播放| 免费日韩av电影| 狠狠色综合播放一区二区| 免费毛片一区二区三区| 在线播放日韩专区| 超碰在线亚洲| 另类小说第一页| 亚洲午夜视频在线| 99精品老司机免费视频| 国产一区免费视频| 精品影视av免费| 久久久精品免费看| 久久电影一区二区| 中文字幕精品影院| 俄罗斯女人裸体性做爰| 欧洲色大大久久| 岛国片av在线| 公共露出暴露狂另类av|