精品欧美一区二区三区在线观看 _久久久久国色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)推薦
国产精品成人一区| 青青青国产在线观看| 久久青草国产手机看片福利盒子 | 91麻豆国产自产在线观看亚洲| 久久久久人妻一区精品色| 精品国产亚洲AV| 欧美激情一二三| 亚洲在线日韩| 性一交一乱一透一a级| 黄色一区三区| 夜夜精品视频一区二区| 国产福利电影在线播放| 911福利视频| 精品亚洲一区二区三区在线播放 | 精品3atv在线视频| av漫画在线观看| 久久男人的天堂| 国产成人亚洲精品狼色在线| 中文av资源在线| 国产乱女淫av麻豆国产| 欧美老女人在线视频| 精品在线播放免费| 91麻豆一二三四在线| 99re6在线观看| 欧美极品少妇xxxxⅹ喷水 | 一区二区欧美在线| 伊人久久亚洲热| 成人激情四射网| 中文字幕精品—区二区日日骚| 色综合久久久久综合体| 粉嫩一区二区三区四区公司1| 超碰手机在线观看| 亚洲一区中文字幕在线观看| 中文字幕永久在线不卡| 国产成人精品一区二区三区免费 | 国产欧美高清在线| 亚洲免费视频网站| 99视频这里有精品| 国产精品6699| 日本一区二区三区高清不卡| 都市激情国产精品| 玖玖爱在线观看| 91精品国产91久久久久久不卡| 99久久777色| 午夜精品成人av| 国精品人伦一区二区三区蜜桃| 国产v综合ⅴ日韩v欧美大片| 欧美激情中文不卡| 在线日韩三级| 欧美三日本三级少妇99| 久久伊人一区| 欧美一区二区黄色| 亚洲精品激情| 黄色在线播放网站| 欧美丰满少妇人妻精品| 国产精品自拍偷拍| 欧美日韩国产中文字幕| 欧美1级日本1级| 在线视频三区| 先锋影音av在线| 日韩精品在在线一区二区中文| 精品国产青草久久久久福利| 国产精品综合在线视频| 欧洲亚洲精品久久久久| 国产精品视频第一页| 91网址在线播放| 国产精品专区一| 日韩欧美在线国产| 日韩高清不卡在线| 韩国成人动漫| 欧美一级黄视频| 日韩欧美国产三级电影视频| 三级影片在线观看欧美日韩一区二区| 在线不卡日本v二区707| 欧美日韩亚洲国产另类| 青少年xxxxx性开放hg| 欧美成人剧情片在线观看| 中文字幕一区二区三区精华液| 欧美日韩国产在线一区| 国产精品蜜臀| 中文字幕在线观看免费| 天堂在线精品视频| 国产综合精品一区二区三区| 亚洲国产一区二区三区四区| 99久久久精品| 久久99视频| 国产视频中文字幕在线观看| 欧美日韩国产一级片| 丝袜美腿亚洲一区二区图片| 欧美美女日韩| 亚洲精品视频专区| 91精品国产自产| 一区二区三区国| 欧美精品xxx| 色综合久久88色综合天天| 加勒比av一区二区| 99ri日韩精品视频| 国产小视频福利在线| 国产黄在线免费观看| 久色视频在线播放| 亚洲a在线播放| 亚洲人成在线观看| 香蕉成人伊视频在线观看| 免费观看30秒视频久久| 欧美日韩激情| 在线免费看h| 视频二区在线| 国产大片中文字幕| 一级少妇精品久久久久久久| 一区二区三区精品国产| 国产精品成人观看视频国产奇米| 日韩一本二本av| 国产精品久久久久天堂| 日韩一级网站| 高清精品视频| 最新国产在线拍揄自揄视频| 中文字幕久久久久| 午夜在线观看一区| caopor在线视频| 日本精品一区二区三区高清 久久 日本精品一区二区三区不卡无字幕 | 中文字幕网址在线| 97在线播放视频| 五月久久久综合一区二区小说| 精品国产无码在线观看| 国产xxxxx在线观看| 精品视频在线观看| 国产aaa精品| 久久久久久一区二区三区四区别墅| 一级爱爱免费视频| 国精产品一区一区| 精品日韩久久久| 亚洲一区二区精品在线| 91亚洲精华国产精华| 91国产在线精品| 亚洲乱码国产乱码精品精天堂| 欧美在线视频全部完| 亚洲人成人一区二区在线观看| 大尺度一区二区| 久久午夜电影| 激情视频一区| 六月丁香久久丫| 天然素人一区二区视频| 国内精品在线视频| 97精品人妻一区二区三区| 免费黄色激情视频| 糖心vlog在线免费观看| 日韩一区二区三区视频在线| 亚洲国产精品一区二区久久恐怖片| 99re亚洲国产精品| 国产在线精品视频| 午夜宅男久久久| 国产精品草草| 日韩国产欧美一区二区| 都市激情久久| 国产成人77亚洲精品www| 动漫一区二区| 四虎久久免费| 日本护士...精品国| 国产欧美久久久| 在线中文字幕网站| 国产免费av一区| 日本三级2019| 制服丨自拍丨欧美丨动漫丨| 风间由美一二三区av片| 丰满少妇一区二区三区专区| 亚洲欧美国产中文| 最新天堂中文在线| 色综合手机在线| 国产原创精品在线| 狠狠操狠狠干视频| 中文在线字幕观看| 欲求不满的岳中文字幕| 成人性生交大免费看| 亚洲女优在线观看| 中文字幕在线观看2018| 欧美亚洲日本在线| 国产在线视频99| 日本三级午夜理伦三级三| 国产性一乱一性一伧一色| 日韩在线视频网址| 国产在线观看免费av| 国产第一页在线播放| 五月婷婷开心网| 亚洲精品无码久久久久| 国产一区二区在线不卡| 亚洲第一成年人网站| 九九九伊在人线综合| 日韩免费影院| 欧美福利在线播放| 国内精品视频| 极品国产人妖chinesets亚洲人妖| 亚洲欧美tv| 欧美肥老太太性生活| 亚洲午夜在线| 国产在线不卡视频| 久久夜色精品国产噜噜av| 亚洲精品你懂的| 午夜不卡在线视频| 3d动漫精品啪啪| 亚洲韩国日本中文字幕| 色偷偷综合社区| 91精品国产高清久久久久久久久| 91精品视频在线免费观看| 欧美精品与人动性物交免费看| 免费的一级黄色片| 日韩欧美色视频| 国产小视频你懂的| 国产精品国产精品国产| 日本精品999| av剧情在线观看| 日韩视频1区| 牛牛国产精品| 久久成人av少妇免费| 欧美经典一区二区| 欧美日韩视频不卡| 日韩有码在线观看| 成人黄色大片在线免费观看| 亚洲午夜精品久久久中文影院av| 红桃av在线播放| 日韩无码精品一区二区| 自拍偷拍欧美亚洲| 六月丁香色婷婷| 中文字幕在线视频久| 97久久夜色精品国产| 国产精品一区在线观看乱码| 亚洲一区二区四区蜜桃| 亚洲成成品网站| 国产va免费精品高清在线| 精品国产一区二区三区四区vr | 97视频在线观看免费| 高清视频在线观看一区| 亚洲成熟丰满熟妇高潮xxxxx| 人妻aⅴ无码一区二区三区| 国产剧情精品在线| 中文字幕乱码中文乱码51精品| 日韩在线理论| 成人av中文字幕| 欧美性一二三区| 久久精品国产久精国产一老狼| 99re在线| 亚洲精品鲁一鲁一区二区三区| www.国产高清| 免费在线你懂的| 少妇高潮一区二区三区| 国产乱一区二区| 欧美三级视频在线观看| 91国内在线视频| 欧美大黑bbbbbbbbb在线| 欧美性大战久久久久xxx| avhd101老司机| 国产成人精品av在线观| 成人日韩av| 在线午夜精品| 精品久久久久久久久久久| 欧美成人中文字幕| 水蜜桃亚洲一二三四在线| 添女人荫蒂视频| 精品人妻一区二区三区浪潮在线| 狠狠久久伊人中文字幕| 麻豆九一精品爱看视频在线观看免费| 婷婷开心久久网| 91国内在线视频| www.国产在线视频| 豆国产97在线 | 亚洲| 2024短剧网剧在线观看| 欧美精品aa| 亚洲成人你懂的| 久久免费视频在线观看| ww国产内射精品后入国产| 久草国产精品视频| 亚洲私拍视频| 精品一区二区在线播放| 91精品国产色综合久久ai换脸| 91福利入口| 国产白袜脚足j棉袜在线观看| 日本啊v在线| 欧美日韩精品免费观看视频完整| 洋洋av久久久久久久一区| 高清欧美性猛交xxxx| 精品欧美一区免费观看α√| 无码人妻精品一区二区| 国产精品国产亚洲精品| av电影在线观看完整版一区二区| 亚洲免费视频网站| 日本一区二区三区四区在线观看| 亚洲天堂一级片| 九九热线视频只有这里最精品| 狠狠色丁香久久婷婷综合丁香| 日韩欧美一级特黄在线播放| 国产主播一区二区三区四区| 小向美奈子av| 亚洲欧洲自拍| 成人午夜看片网址| 久久夜色撩人精品| 少妇高清精品毛片在线视频 | 日本一卡二卡在线| av在线app| 久久国产精品第一页| 日韩国产精品一区| 国产日韩视频在线播放| 久草热在线观看| 国产a久久精品一区二区三区| 一区二区三区不卡在线观看| 成人观看高清在线观看免费| 欧美 日韩 国产 成人 在线观看| 草草在线观看| 成人黄页毛片网站| 久久久av一区| 国产精品久久久久久久99| 国产一二区在线观看| 国产乱码精品一区二区三区五月婷| 深夜福利国产精品| 精品久久久99| av免费在线免费| 丁香五精品蜜臀久久久久99网站 | 成人免费91| 亚洲欧美一区二区三区国产精品 | 国产精品综合不卡av| 九九精品视频免费| 综合中文字幕| 日韩欧美国产激情| 美国av一区二区三区| 成人毛片一区二区三区| 成人精品视频| 欧美色大人视频| www.国产亚洲| 二区在线视频| 国产99久久精品| 欧洲亚洲在线视频| 麻豆天美蜜桃91| 好吊妞国产欧美日韩免费观看网站| 欧美性猛交xxxxx水多| 伊人婷婷久久| 亚洲av电影一区| 国产美女主播视频一区| 性视频1819p久久| 蜜桃av免费观看| 秋霞影院一区二区三区| 欧美日韩国产精选| 国产在线青青草| 19禁羞羞电影院在线观看| 久久综合av免费| 国产精华一区二区三区| 中文字幕在线视频第一页| 国产视频一区欧美| 国产最新精品视频| caoporn91| 中文字幕一区二区av| 日韩视频在线免费观看| 久久久久久久久久久久| 群体交乱之放荡娇妻一区二区| 欧美大片一区二区| 在线观看日本www| 清纯唯美激情亚洲| 91精品国产免费| 久久精品亚洲天堂| 国产精品igao视频网网址不卡日韩| 欧美日韩国产区一| 一区二区三区入口| 开心久久婷婷综合中文字幕| 色综合天天综合网国产成人综合天 | 国产成人97精品免费看片| 欧美日韩一级大片| 亚洲午夜视频| 国产成人精品免费视频| 日韩乱码在线观看| 老司机久久99久久精品播放免费| 国产成人激情视频| 中文字幕免费在线观看视频| 日韩中文字幕av电影| 成人xxxxx| 99热这里只有精品9| 99精品欧美一区二区三区小说 | 国产精品国产三级国产专区53| a级片在线免费看| 91亚洲大成网污www| 污视频在线免费观看一区二区三区| 91美女视频在线| 亚洲第一主播视频| 北条麻妃av高潮尖叫在线观看| 六九午夜精品视频| 精品第一国产综合精品aⅴ| 美女又爽又黄视频毛茸茸| 久久蜜桃av| 国产成人+综合亚洲+天堂| 成人激情四射网| 日本一区二区三级电影在线观看| 9色porny| 国产一区二区三区精品在线观看 | 日韩亚洲欧美视频| 亚洲日本免费电影| 亚洲精品久久久久久久久久久久久 | 很黄的网站在线观看| 91黄色激情网站| 在线观看免费视频国产| 欧美另类亚洲| 91网免费观看| 秋霞午夜在线观看| 91高清在线观看| 91成年人网站|