利用Docling增強多模態RAG功能

Docling

多模態檢索增強生成(RAG)是人工智慧領域的一項變革性創新,它使系統能夠處理和整合文字、影像、音訊和影片等多種資料型別。這種能力對於應對主要由多模態格式組成的非結構化企業資料的挑戰至關重要。透過利用多模態輸入,RAG 增強了對上下文的理解,提高了準確性,並擴大了人工智慧在醫療保健、客戶支援和教育等行業的適用性。

Docling 是 IBM 開發的開源工具包,用於簡化生成式人工智慧應用的文件處理。我們將利用 Docling 構建多模態 RAG 能力。它能將 PDF、DOCX 和圖片等多種格式轉換為 JSON 和 Markdown 等結構化輸出,從而實現與 LangChain 和 LlamaIndex 等人工智慧框架的無縫整合。透過促進非結構化資料的提取和支援高階佈局分析,Docling 可使複雜的企業資料具有機器可讀性並可用於人工智慧驅動的洞察力,從而增強多模態檢索增強生成(RAG)的能力。

學習目標

  • 探索 Docling– 瞭解它如何從非結構化檔案中提取多模態資訊。
  • Docling 管道和人工智慧模型– 研究其架構和關鍵人工智慧元件。
  • 獨特功能– 突出 Docling 的與眾不同之處。
  • 構建多模態 RAG 系統– 使用 Docling 實現資料提取和檢索系統。
  • 端到端流程– 從 PDF 中提取資料、生成影像描述,以及使用向量資料庫和 Phi 4 進行查詢。

用於非結構化資料的Docling

Docling 是由IBM 開發的開源文件處理工具包,旨在將 PDF、DOCX 和影像等非結構化檔案轉換為 JSON 和 Markdown 等結構化格式。它由先進的人工智慧模型(如用於佈局分析的 DocLayNet 和用於表格識別的 TableFormer)提供支援,能夠在保留文件結構的同時準確提取文字、表格和影像。透過與 LangChain 和 LlamaIndex 等生成式人工智慧框架的無縫整合,Docling 支援檢索增強生成(RAG)和問題解答系統等應用。其輕量級架構可在標準硬體上實現高效效能,使其成為尋求資料隱私控制的企業在基於 SaaS 的解決方案之外的另一種經濟高效的選擇。

Docling管道

Docling 的預設處理管道

Docling 的預設處理管道。模型管道的內部部分可輕鬆定製和擴充套件。圖片來源

Docling 實現了對每個給定文件按順序執行的線性操作流水線(如上圖所示)。每個文件首先由 PDF 後端進行解析,檢索由字串內容及其在頁面上的座標組成的程式設計文字標記,同時渲染每個頁面的點陣圖影像,以支援下游操作。然後,標準模型流水線在文件的每一頁上獨立應用一系列人工智慧模型,以提取特徵和內容,如佈局和表格結構。最後,所有頁面的結果都會彙總並透過後處理階段,後處理階段會增強後設資料、檢測文件語言、推斷閱讀順序,並最終生成一個型別化的文件物件,該物件可序列化為 JSON 或 Markdown。

Docling背後的關鍵人工智慧模型

傳統上,開發人員依賴光學字元識別(OCR)將文件轉換為數字格式。然而,由於需要大量的計算能力,這種技術可能會很慢,而且容易出錯。Docling 儘可能避免使用 OCR,而是使用經過專門訓練的計算機視覺模型來識別和分類頁面的視覺元件。

Docling 基於 IBM 研究人員開發的兩個模型。

版面分析模型

佈局分析模型具有物件檢測器的功能,可預測給定頁面影像中各種元素的邊界框和類別。該模型的設計基於 RT-DETR,並使用 DocLayNet(我們著名的用於文件佈局分析的人類註釋資料集)和其他專有資料集進行了重新訓練。DocLayNet 是一個由人工標註的文件佈局分割資料集,包含來自各種文件來源的 80863 個頁面。

該模型利用物件檢測技術來檢查從機器手冊到年度報告等各種文件的佈局。然後對文字塊、影像、表格、標題等元素進行識別和分類。Docling 管道以 72 dpi 的解析度處理頁面影像,使其能夠由單個 CPU 處理。

表格格式模型

TableFormer 模型最初於 2022 年推出,隨後使用自定義標記結構語言進行了增強,它是一種視覺轉換器模型,設計用於恢復表格結構。它可以根據輸入影像預測表格中行和列的邏輯組織,識別哪些單元格屬於列頭、行頭或表格主體。與以往的方法不同,TableFormer 能有效處理各種複雜的表格,包括部分或沒有邊框、空單元格、缺行或缺列、單元格跨度、列標題和行標題中的層次結構,以及縮排或對齊方式的不一致。

Docling的一些主要功能

以下是其特點:

  • 支援多種格式:Docling 可以解析多種文件格式,包括 PDF、DOCX、PPTX、HTML、圖片等。它可將內容匯出為 JSON 和 Markdown 等結構化格式,以便無縫整合到人工智慧工作流中。
  • 高階 PDF 處理:它包含複雜的功能,如佈局分析、閱讀順序檢測、表格結構識別和掃描文件的 OCR。這可確保準確提取表格和數字等複雜的文件元素。Docling 使用先進的人工智慧驅動方法提取表格,主要是利用其定製的 TableFormer 模型。
  • 統一文件表示法:Docling 使用統一且富有表現力的格式來表示解析後的文件,使其更易於在下游應用程式中進行處理和分析。
  • 人工智慧就緒整合:該工具包與 LangChain 和 LlamaIndex 等流行的人工智慧框架無縫整合,使其成為檢索增強生成(RAG)和問題解答系統等應用的理想選擇。
  • 本地執行:它支援本地執行,可在空中封閉環境中安全處理敏感資料
  • 高效效能:Docling 設計用於在對資源要求最低的商品硬體上執行,在可能的情況下避免使用傳統的 OCR,將處理速度提高 30 倍,同時減少錯誤。
  • 模組化架構:其模組化設計允許輕鬆定製和擴充套件新功能或模型,以滿足不同用例的需求
  • 開源可訪問性:與 Watson Document Understanding 等專有工具不同,Docling 在 MIT 許可下開源,允許開發人員自由使用、定製並將其整合到工作流程中,而無需鎖定供應商或支付額外費用。

Docling 提供可選的 OCR 支援,例如,覆蓋掃描的 PDF 或嵌入頁面的 bitmap 影像內容。Docling 依賴於 EasyOCR,這是一個流行的第三方 OCR 庫,支援多種語言。這些功能使 Docling 成為生成式人工智慧工作流程中文件解析和準備的全面解決方案。

使用Docling構建多模態RAG系統

在本文中,我們將首先使用 Docling 從 PDF 中提取各種資料–文字、影像和表格。對於提取的影像,我們將使用視覺語言模型生成影像描述,並將這些影像文字描述與 PDF 中原始文字內容的文字資料和提取的表格文字一起儲存在我們的 VectorDB 中。之後,我們將建立一個 RAG 系統,使用向量資料庫進行檢索,並透過 Ollama 使用 LLM(Phi 4)從 PDF 文件中進行查詢。

透過Google Colab使用T4 GPU實現Python上機操作

您可以在此處找到包含所有步驟的 Colab Notebook。

步驟 1. 安裝庫

我們首先安裝必要的庫

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
!pip install docling
#Following code added to avoid an error in installation - can be removed if not needed
import locale
def getpreferredencoding(do_setlocale = True):
return "UTF-8"
locale.getpreferredencoding = getpreferredencoding
!pip install langchain-huggingfaceCopy Code
!pip install docling #Following code added to avoid an error in installation - can be removed if not needed import locale def getpreferredencoding(do_setlocale = True): return "UTF-8" locale.getpreferredencoding = getpreferredencoding !pip install langchain-huggingfaceCopy Code
!pip install docling
#Following code added to avoid an error in installation - can be removed if not needed
import locale
def getpreferredencoding(do_setlocale = True):
return "UTF-8"
locale.getpreferredencoding = getpreferredencoding
!pip install langchain-huggingfaceCopy Code

步驟 2. 載入轉換器物件

這段程式碼準備了一個文件轉換器,用於處理不帶 OCR 但能生成影像的 PDF 檔案。然後,它將這種轉換應用於指定的 PDF 檔案,並將結果儲存在字典中。

我們使用這個有大量圖表的 PDF 檔案(我們將其儲存在當前工作目錄中,名為“accenture.pdf”)來測試使用 Docling 進行的多模態檢索。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
pdf_pipeline_options = PdfPipelineOptions(do_ocr=False,generate_picture_images=True,)
format_options = {InputFormat.PDF: PdfFormatOption(pipeline_options=pdf_pipeline_options)}
converter = DocumentConverter(format_options=format_options)
sources = [ "/content/accenture.pdf",]
conversions = {source: converter.convert(source=source).document for source in sources}Copy Code
from docling.document_converter import DocumentConverter, PdfFormatOption from docling.datamodel.base_models import InputFormat from docling.datamodel.pipeline_options import PdfPipelineOptions pdf_pipeline_options = PdfPipelineOptions(do_ocr=False,generate_picture_images=True,) format_options = {InputFormat.PDF: PdfFormatOption(pipeline_options=pdf_pipeline_options)} converter = DocumentConverter(format_options=format_options) sources = [ "/content/accenture.pdf",] conversions = {source: converter.convert(source=source).document for source in sources}Copy Code
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
pdf_pipeline_options = PdfPipelineOptions(do_ocr=False,generate_picture_images=True,)
format_options = {InputFormat.PDF: PdfFormatOption(pipeline_options=pdf_pipeline_options)}
converter = DocumentConverter(format_options=format_options)
sources = [ "/content/accenture.pdf",]
conversions = {source: converter.convert(source=source).document for source in sources}Copy Code

步驟 3. 載入嵌入文字的模型

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
from transformers import *
embeddings_model_path = "ibm-granite/granite-embedding-30m-english"
embeddings_model = HuggingFaceEmbeddings(model_name=embeddings_model_path,)
embeddings_tokenizer = AutoTokenizer.from_pretrained(embeddings_model_path)Copy Code
from langchain_huggingface.embeddings import HuggingFaceEmbeddings from transformers import * embeddings_model_path = "ibm-granite/granite-embedding-30m-english" embeddings_model = HuggingFaceEmbeddings(model_name=embeddings_model_path,) embeddings_tokenizer = AutoTokenizer.from_pretrained(embeddings_model_path)Copy Code
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
from transformers import *
embeddings_model_path = "ibm-granite/granite-embedding-30m-english"
embeddings_model = HuggingFaceEmbeddings(model_name=embeddings_model_path,)
embeddings_tokenizer = AutoTokenizer.from_pretrained(embeddings_model_path)Copy Code

步驟 4. 對文件中的文字進行分塊

下面的程式碼用於文件處理管道。它將上一步轉換後的文件分解成更小的塊,表格除外(稍後單獨處理)。然後將每個小塊封裝成一個帶有特定後設資料的文件物件。程式碼處理轉換後的文件時,會將文件分割成若干小塊,跳過表格,併為每個小塊建立帶有後設資料的新文件物件。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker
from docling_core.types.doc.document import TableItem
from langchain_core.documents import Document
doc_id = 0
texts: list[Document] = []
for source, docling_document in conversions.items():
for chunk in HybridChunker(tokenizer=embeddings_tokenizer).chunk(docling_document):
items = chunk.meta.doc_items
if len(items) == 1 and isinstance(items[0], TableItem):
continue # we will process tables later
refs = " ".join(map(lambda item: item.get_ref().cref, items))
text = chunk.text
document = Document(page_content=text,metadata={"doc_id": (doc_id:=doc_id+1),"source": source,"ref": refs,},)
texts.append(document)
print(f"{len(texts)} text document chunks created")Copy Code
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker from docling_core.types.doc.document import TableItem from langchain_core.documents import Document doc_id = 0 texts: list[Document] = [] for source, docling_document in conversions.items(): for chunk in HybridChunker(tokenizer=embeddings_tokenizer).chunk(docling_document): items = chunk.meta.doc_items if len(items) == 1 and isinstance(items[0], TableItem): continue # we will process tables later refs = " ".join(map(lambda item: item.get_ref().cref, items)) text = chunk.text document = Document(page_content=text,metadata={"doc_id": (doc_id:=doc_id+1),"source": source,"ref": refs,},) texts.append(document) print(f"{len(texts)} text document chunks created")Copy Code
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker
from docling_core.types.doc.document import TableItem
from langchain_core.documents import Document
doc_id = 0
texts: list[Document] = []
for source, docling_document in conversions.items():
for chunk in HybridChunker(tokenizer=embeddings_tokenizer).chunk(docling_document):
items = chunk.meta.doc_items
if len(items) == 1 and isinstance(items[0], TableItem):
continue # we will process tables later
refs = " ".join(map(lambda item: item.get_ref().cref, items))
text = chunk.text
document = Document(page_content=text,metadata={"doc_id": (doc_id:=doc_id+1),"source": source,"ref": refs,},)
texts.append(document)
print(f"{len(texts)} text document chunks created")Copy Code

步驟 5. 處理文件中的表格

下面的程式碼旨在處理轉換後文件中的表格。它提取表格,將其轉換為 Markdown 格式,並將每個表格封裝為一個帶有特定後設資料的文件物件。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from docling_core.types.doc.labels import DocItemLabel
doc_id = len(texts)
tables: list[Document] = []
for source, docling_document in conversions.items():
for table in docling_document.tables:
if table.label in [DocItemLabel.TABLE]:
ref = table.get_ref().cref
text = table.export_to_markdown()
document = Document(
page_content=text,
metadata={
"doc_id": (doc_id:=doc_id+1),
"source": source,
"ref": ref
},
)
tables.append(document)
print(f"{len(tables)} table documents created")Copy Code
from docling_core.types.doc.labels import DocItemLabel doc_id = len(texts) tables: list[Document] = [] for source, docling_document in conversions.items(): for table in docling_document.tables: if table.label in [DocItemLabel.TABLE]: ref = table.get_ref().cref text = table.export_to_markdown() document = Document( page_content=text, metadata={ "doc_id": (doc_id:=doc_id+1), "source": source, "ref": ref }, ) tables.append(document) print(f"{len(tables)} table documents created")Copy Code
from docling_core.types.doc.labels import DocItemLabel
doc_id = len(texts)
tables: list[Document] = []
for source, docling_document in conversions.items():
for table in docling_document.tables:
if table.label in [DocItemLabel.TABLE]:
ref = table.get_ref().cref
text = table.export_to_markdown()
document = Document(
page_content=text,
metadata={
"doc_id": (doc_id:=doc_id+1),
"source": source,
"ref": ref
},
)
tables.append(document)
print(f"{len(tables)} table documents created")Copy Code

步驟 6. 定義將PDF影像轉換為base64格式的函式

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import base64
import io
import PIL.Image
import PIL.ImageOps
from IPython.display import display
def encode_image(image: PIL.Image.Image, format: str = "png") -> str:
image = PIL.ImageOps.exif_transpose(image) or image
image = image.convert("RGB")
buffer = io.BytesIO()
image.save(buffer, format)
encoding = base64.b64encode(buffer.getvalue()).decode("utf-8")
return encodingCopy Code
import base64 import io import PIL.Image import PIL.ImageOps from IPython.display import display def encode_image(image: PIL.Image.Image, format: str = "png") -> str: image = PIL.ImageOps.exif_transpose(image) or image image = image.convert("RGB") buffer = io.BytesIO() image.save(buffer, format) encoding = base64.b64encode(buffer.getvalue()).decode("utf-8") return encodingCopy Code
import base64
import io
import PIL.Image
import PIL.ImageOps
from IPython.display import display
def encode_image(image: PIL.Image.Image, format: str = "png") -> str:
image = PIL.ImageOps.exif_transpose(image) or image
image = image.convert("RGB")
buffer = io.BytesIO()
image.save(buffer, format)
encoding = base64.b64encode(buffer.getvalue()).decode("utf-8")
return encodingCopy Code

步驟 7. 從Ollama提取模型用於分析PDF中的影像

我們將使用 Ollama 的視覺語言模型來分析從 PDF 中提取的影像,併為每張影像生成描述。為方便使用 Ollama 模型,我們將安裝以下庫,並在提取模型前啟動 Ollama 伺服器,具體程式碼如下。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
!sudo apt update
!sudo apt install -y pciutils
!pip install langchain-ollama
!curl -fsSL https://ollama.com/install.sh | sh
!pip install ollama==0.4.2
!pip install langchain-community
#Enabling threading to start ollama server in a non blocking manner
import threading
import subprocess
import time
def run_ollama_serve():
subprocess.Popen(["ollama", "serve"])
thread = threading.Thread(target=run_ollama_serve)
thread.start()
time.sleep(5)Copy Code
!sudo apt update !sudo apt install -y pciutils !pip install langchain-ollama !curl -fsSL https://ollama.com/install.sh | sh !pip install ollama==0.4.2 !pip install langchain-community #Enabling threading to start ollama server in a non blocking manner import threading import subprocess import time def run_ollama_serve(): subprocess.Popen(["ollama", "serve"]) thread = threading.Thread(target=run_ollama_serve) thread.start() time.sleep(5)Copy Code
!sudo apt update
!sudo apt install -y pciutils
!pip install langchain-ollama
!curl -fsSL https://ollama.com/install.sh | sh
!pip install ollama==0.4.2
!pip install langchain-community
#Enabling threading to start ollama server in a non blocking manner
import threading
import subprocess
import time
def run_ollama_serve():
subprocess.Popen(["ollama", "serve"])
thread = threading.Thread(target=run_ollama_serve)
thread.start()
time.sleep(5)Copy Code

步驟 8. 為從PDF中提取的每張影像生成說明

下面的程式碼旨在處理轉換文件中的影像。它提取影像,使用視覺模型(透過 Ollama 生成 llama3.2-vision)為每張影像生成描述性文字,並將這些文字封裝到帶有特定後設資料的文件物件中。下面是詳細說明:

從 Ollama 提取“llama3.2-vision”模型。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
!ollama pull llama3.2-visionCopy Code
!ollama pull llama3.2-visionCopy Code
!ollama pull llama3.2-visionCopy Code
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def encode_image(image: PIL.Image.Image, format: str = "png") -> str:
image = PIL.ImageOps.exif_transpose(image) or image
image = image.convert("RGB")
buffer = io.BytesIO()
image.save(buffer, format)
encoding = base64.b64encode(buffer.getvalue()).decode("utf-8")
return encodingCopy Code
def encode_image(image: PIL.Image.Image, format: str = "png") -> str: image = PIL.ImageOps.exif_transpose(image) or image image = image.convert("RGB") buffer = io.BytesIO() image.save(buffer, format) encoding = base64.b64encode(buffer.getvalue()).decode("utf-8") return encodingCopy Code
def encode_image(image: PIL.Image.Image, format: str = "png") -> str:
image = PIL.ImageOps.exif_transpose(image) or image
image = image.convert("RGB")
buffer = io.BytesIO()
image.save(buffer, format)
encoding = base64.b64encode(buffer.getvalue()).decode("utf-8")
return encodingCopy Code
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import ollama
pictures: list[Document] = []
doc_id = len(texts) + len(tables)
for source, docling_document in conversions.items():
for picture in docling_document.pictures:
ref = picture.get_ref().cref
image = picture.get_image(docling_document)
if image:
print(image)
response = ollama.chat(
model="llama3.2-vision",
messages=[{
"role": "user",
"content": "Describe this image?",
"images": [encode_image(image)]
}],
)
text = response['message']['content'].strip()
document = Document(
page_content=text,
metadata={
"doc_id": (doc_id:=doc_id+1),
"source": source,
"ref": ref,
},
)
pictures.append(document)
print(f"{len(pictures)} image descriptions created")Copy Code
import ollama pictures: list[Document] = [] doc_id = len(texts) + len(tables) for source, docling_document in conversions.items(): for picture in docling_document.pictures: ref = picture.get_ref().cref image = picture.get_image(docling_document) if image: print(image) response = ollama.chat( model="llama3.2-vision", messages=[{ "role": "user", "content": "Describe this image?", "images": [encode_image(image)] }], ) text = response['message']['content'].strip() document = Document( page_content=text, metadata={ "doc_id": (doc_id:=doc_id+1), "source": source, "ref": ref, }, ) pictures.append(document) print(f"{len(pictures)} image descriptions created")Copy Code
import ollama
pictures: list[Document] = []
doc_id = len(texts) + len(tables)
for source, docling_document in conversions.items():
for picture in docling_document.pictures:
ref = picture.get_ref().cref
image = picture.get_image(docling_document)
if image:
print(image)
response = ollama.chat(
model="llama3.2-vision",
messages=[{
"role": "user",
"content": "Describe this image?",
"images": [encode_image(image)]
}],
)
text = response['message']['content'].strip()
document = Document(
page_content=text,
metadata={
"doc_id": (doc_id:=doc_id+1),
"source": source,
"ref": ref,
},
)
pictures.append(document)
print(f"{len(pictures)} image descriptions created")Copy Code

從PDF中提取的每張影像生成說明

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import itertools
from docling_core.types.doc.document import RefItem
# Print all created documents
for document in itertools.chain(texts, tables):
print(f"Document ID: {document.metadata['doc_id']}")
print(f"Source: {document.metadata['source']}")
print(f"Content:\n{document.page_content}")
print("=" * 80) # Separator for clarity
for document in pictures:
print(f"Document ID: {document.metadata['doc_id']}")
source = document.metadata['source']
print(f"Source: {source}")
print(f"Content:\n{document.page_content}")
docling_document = conversions[source]
ref = document.metadata['ref']
picture = RefItem(cref=ref).resolve(docling_document)
image = picture.get_image(docling_document)
print("Image:")
display(image)
print("=" * 80) # Separator for clarityCopy Code
import itertools from docling_core.types.doc.document import RefItem # Print all created documents for document in itertools.chain(texts, tables): print(f"Document ID: {document.metadata['doc_id']}") print(f"Source: {document.metadata['source']}") print(f"Content:\n{document.page_content}") print("=" * 80) # Separator for clarity for document in pictures: print(f"Document ID: {document.metadata['doc_id']}") source = document.metadata['source'] print(f"Source: {source}") print(f"Content:\n{document.page_content}") docling_document = conversions[source] ref = document.metadata['ref'] picture = RefItem(cref=ref).resolve(docling_document) image = picture.get_image(docling_document) print("Image:") display(image) print("=" * 80) # Separator for clarityCopy Code
import itertools
from docling_core.types.doc.document import RefItem
# Print all created documents
for document in itertools.chain(texts, tables):
print(f"Document ID: {document.metadata['doc_id']}")
print(f"Source: {document.metadata['source']}")
print(f"Content:\n{document.page_content}")
print("=" * 80) # Separator for clarity
for document in pictures:
print(f"Document ID: {document.metadata['doc_id']}")
source = document.metadata['source']
print(f"Source: {source}")
print(f"Content:\n{document.page_content}")
docling_document = conversions[source]
ref = document.metadata['ref']
picture = RefItem(cref=ref).resolve(docling_document)
image = picture.get_image(docling_document)
print("Image:")
display(image)
print("=" * 80) # Separator for clarityCopy Code

從PDF中提取的每張影像生成說明

步驟 9. 儲存在Milvus向量資料庫中

Milvus 是一個高效能向量資料庫,專為擴大規模而設計。它透過有效組織和搜尋大量非結構化資料(如文字、影像和多模態資訊),為人工智慧應用提供動力。我們首先安裝 langchain-milvus 庫,然後在向量資料庫中儲存文字、表格和圖片。在定義向量資料庫的同時,我們還傳遞了嵌入模型,以便向量資料庫在儲存之前將提取的所有文字(包括表格和圖片說明中的資料)轉換為嵌入。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
!pip install langchain_milvus
import tempfile
from langchain_core.vectorstores import VectorStore
from langchain_milvus import Milvus
db_file = tempfile.NamedTemporaryFile(prefix="vectorstore_", suffix=".db", delete=False).name
vector_db: VectorStore = Milvus(embedding_function=embeddings_model,connection_args={"uri": db_file},auto_id=True,enable_dynamic_field=True,index_params={"index_type": "AUTOINDEX"},)
#add all the LangChain documents for the text, tables and image descriptions to the vector database
import itertools
documents = list(itertools.chain(texts, tables, pictures))
ids = vector_db.add_documents(documents)
print(f"{len(ids)} documents added to the vector database")Copy Code
!pip install langchain_milvus import tempfile from langchain_core.vectorstores import VectorStore from langchain_milvus import Milvus db_file = tempfile.NamedTemporaryFile(prefix="vectorstore_", suffix=".db", delete=False).name vector_db: VectorStore = Milvus(embedding_function=embeddings_model,connection_args={"uri": db_file},auto_id=True,enable_dynamic_field=True,index_params={"index_type": "AUTOINDEX"},) #add all the LangChain documents for the text, tables and image descriptions to the vector database import itertools documents = list(itertools.chain(texts, tables, pictures)) ids = vector_db.add_documents(documents) print(f"{len(ids)} documents added to the vector database")Copy Code
!pip install langchain_milvus
import tempfile
from langchain_core.vectorstores import VectorStore
from langchain_milvus import Milvus
db_file = tempfile.NamedTemporaryFile(prefix="vectorstore_", suffix=".db", delete=False).name
vector_db: VectorStore = Milvus(embedding_function=embeddings_model,connection_args={"uri": db_file},auto_id=True,enable_dynamic_field=True,index_params={"index_type": "AUTOINDEX"},)
#add all the LangChain documents for the text, tables and image descriptions to the vector database
import itertools
documents = list(itertools.chain(texts, tables, pictures))
ids = vector_db.add_documents(documents)
print(f"{len(ids)} documents added to the vector database")Copy Code

步驟 10. 使用Phi 4模型的檢索增強生成功能查詢模型

在下面的程式碼中,我們首先從 Ollama 中提取“Phi 4”模型,然後將其作為 RAG 系統中的 LLM,用於根據查詢從向量資料庫中檢索相關上下文後生成響應。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#Pulling the Ollama model for querying
!ollama pull phi4
#Querying
from langchain_core.output_parsers import StrOutputParser
from langchain.prompts import ChatPromptTemplate
from langchain_community.chat_models import ChatOllama
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
retriever = vector_db.as_retriever()
# Prompt
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# Local LLM
ollama_llm = "phi4"
model_local = ChatOllama(model=ollama_llm)
# Chain
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model_local
| StrOutputParser()
)
chain.invoke("How much worth in dollars is Strategy & Conslution in Services?")
Copy Code
#Pulling the Ollama model for querying !ollama pull phi4 #Querying from langchain_core.output_parsers import StrOutputParser from langchain.prompts import ChatPromptTemplate from langchain_community.chat_models import ChatOllama from langchain_core.runnables import RunnableLambda, RunnablePassthrough retriever = vector_db.as_retriever() # Prompt template = """Answer the question based only on the following context: {context} Question: {question} """ prompt = ChatPromptTemplate.from_template(template) # Local LLM ollama_llm = "phi4" model_local = ChatOllama(model=ollama_llm) # Chain chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | model_local | StrOutputParser() ) chain.invoke("How much worth in dollars is Strategy & Conslution in Services?") Copy Code
#Pulling the Ollama model for querying
!ollama pull phi4
#Querying
from langchain_core.output_parsers import StrOutputParser
from langchain.prompts import ChatPromptTemplate
from langchain_community.chat_models import ChatOllama
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
retriever = vector_db.as_retriever()
# Prompt
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# Local LLM
ollama_llm = "phi4"
model_local = ChatOllama(model=ollama_llm)
# Chain
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model_local
| StrOutputParser()
)
chain.invoke("How much worth in dollars is Strategy & Conslution in Services?")
Copy Code

輸出

According to the context provided, the 'Technology & Strategy/Consulting' section of the company's operations generated a value of $15 billion.

從文件中的下圖可以看出,我們的多模態 RAG 系統的響應是正確的。透過 Docling,我們從圖表中正確提取了資訊,因此檢索系統能夠為我們提供準確的回覆。

服務收入情況資料圖表

原始 PDF 檔案中的圖表

透過更多查詢分析我們的RAG系統

德國的收入是多少?

The revenue in Germany, according to the provided context, is $3 billion. This information is listed under the 'Country-Wise Revenue' section of the document: \n\n. **Germany**: $3 billion\n\nIf you need any further details or have additional questions, feel free to ask!

從文件中的下圖可以看出,我們的多模態 RAG 系統的響應是正確的。透過 Docling,我們從圖表中正確提取了資訊,因此檢索系統能夠為我們提供準確的回覆。

FY22收入全球分佈情況

原始 PDF 格式的圖表

Cloud FY19的收入是多少?

The Cloud FY19 revenue, as provided in the document context, was $11 billion. This information is found in the first table under the section titled 'Cloud' where it states:\n\nFY19: $11B\n\nThis indicates that the revenue from cloud services for fiscal year 2019 was $11 billion.

從文件中的下表可以看出,我們的多模態 RAG 系統的響應是正確的。透過 Docling,我們從圖表中正確提取了資訊,因此檢索系統能夠為我們提供準確的回覆。

各項服務三年複合增長率圖表

原始 PDF 中的圖表

行業 X 3 年複合年增長率是多少?

Based on the provided context from the documents in Accenture’s PDF:\n\n-In Document with doc_id 15 and Document with doc_id 3, both mention IndustryX.\n-The relevant information is found under a section about revenue growthfor Industry X:\n\n**Document 15** indicates: "FY19 $10B Industry X FY19 $3BFY22 $6.5B 3 Yr. CAGR 2 30%"\n\n**Document 3** reiterates this with similarwording: "Cloud = FY19 $10B Industry X FY19. , Illustrative = . , Cloud =$3B. , Illustrative = FY22 $6.5B. , Illustrative = 3 Yr. CAGR 2 30%"\n\nFromthese excerpts, the 3-year compound annual growth rate (CAGR) for Industry Xis **30%."**.\n\n

從文件中的上表可以看出,我們的多模態 RAG 系統的響應是正確的。透過 Docling,資訊被正確地從圖表中提取出來,因此檢索系統能夠為我們提供準確的回應

小結

總之,Docling 是將非結構化資料轉化為機器可讀格式的強大工具,使其成為多模態檢索-增強生成(RAG)等應用的重要資源。透過利用先進的人工智慧模型並與流行的人工智慧框架無縫整合,Docling 增強了高效處理和查詢複雜文件的能力。Docling 的開源特性,加上通用格式支援和模組化架構,使其成為企業在實際應用案例中尋求利用人工智慧生成技術的理想解決方案。

  • Docling 工具包:IBM 的開源工具,用於從 PDF、DOCX 和影像中提取結構化資料(JSON、Markdown),實現無縫人工智慧整合。
  • 高階人工智慧模型:使用 Layout Analysis 和 TableFormer 進行準確的文件處理,減少對傳統 OCR 的依賴。
  • 人工智慧框架整合:可與 LangChain 和 LlamaIndex 協同工作,是 RAG 系統的理想選擇,可提供經濟高效的人工智慧驅動型洞察力。
  • 開源和可定製:獲得麻省理工學院許可,模組化,可適應各種用例,不受供應商鎖定。

評論留言