PaliGemma 2 Mix 是 Google 开发的一款多模态 AI 模型。它是 PaliGemma 视觉语言模型(VLM) 的增强版本,融合了 SigLIP 视觉模型与 Gemma 2 语言模型的先进能力。
在本教程中,我将讲解如何使用 PaliGemma 2 Mix 构建一个由 AI 驱动的账单扫描与支出分析器,它能够:
从收据中提取并归类各项开支。
执行光学字符识别(OCR)以获取关键信息。
基于提供的图像总结支出情况。
虽然我们将专注于构建一个财务洞察工具,但您也可以将本博文中学到的内容用于探索 PaliGemma 2 Mix 的其他用例,例如图像分割、目标检测和问答。
什么是 PaliGemma 2 Mix?
PaliGemma 2 Mix 是一款先进的视觉-语言模型(VLM),可同时处理图像与文本输入,并生成基于文本的输出。它旨在支持多种 多模态 AI 任务,同时支持多种语言。
PaliGemma 2 被设计用于广泛的视觉-语言任务,包括图像与短视频字幕生成、视觉问答、光学字符识别(OCR)、目标检测和分割。
图示所用图片来源: Google
PaliGemma 2 Mix 模型适用于:
图像与短视频字幕生成 :为静态图像与短视频生成准确、具备上下文的字幕。
视觉问答(VQA) :分析图像并根据视觉内容回答文本问题。
光学字符识别(OCR) :从图像中提取并解释文本,适用于文档、收据和扫描材料。
目标检测与分割 :识别、标注并分割图像中的对象,便于结构化分析。
多语言支持 :模型支持多种语言的文本生成与理解,适用于全球化应用。
您可以在 官方发布文章 中了解更多关于 PaliGemma 2 Mix 模型的信息。
项目概览:使用 PaliGemma 2 Mix 的账单扫描与支出分析器
我们将按以下主要步骤进行:
加载并准备数据集 :首先加载并准备收据图像作为输入。
初始化 PaliGemma 2 Mix 模型 :配置并加载模型以处理视觉-语言任务。
处理输入图像 :将图像转换为合适格式(RGB),为分析做准备。
提取关键信息 :执行光学字符识别(OCR)以获取总金额。
归类开支 :将消费按食品杂货、服装、电子产品及其他等类别进行分类。
生成支出洞察 :汇总分类后的开支并生成支出分布图。
构建交互式 Gradio 界面 :最后,创建一个 UI,用户可上传多张账单、提取数据并可视化分析支出。
步骤 1:先决条件
在开始之前,请确保已安装以下工具与库:
Python 3.8+
torch
Transformers
PIL
Matplotlib
Gradio
运行以下命令安装所需依赖:
pip install gradio -U bitsandbytes -U transformers -q 技术支持
安装完成后,运行以下导入命令:
import gradio as gr
import torch
import pandas as pd
import matplotlib. pyplot as plt
from transformers import PaliGemmaForConditionalGeneration, PaliGemmaProcessor, BitsAndBytesConfig
from transformers import BitsAndBytesConfig
from PIL import Image
import re技术支持
步骤 2:模型初始化
我们通过 量化 来优化性能,并加载 PaliGemma 2 Mix 模型。演示中我们将使用 100 亿参数的模型 ,输入图像分辨率为 448 x 448。运行该模型至少需要一块 40GB 显存的 T4 GPU(Colab 配置)。
device = "cuda" if torch. cuda. is_available( ) else "cpu"
model_id = "google/paligemma2-10b-mix-448"
bnb_config = BitsAndBytesConfig(
load_in_8bit= True ,
llm_int8_threshold= 6.0 ,
)
model = PaliGemmaForConditionalGeneration. from_pretrained(
model_id, quantization_config= bnb_config
) . eval ( )
processor = PaliGemmaProcessor. from_pretrained( model_id)
print ( "Model and processor loaded successfully!" ) 技术支持
BitsAndBytes 量化有助于在保持性能的同时降低内存占用,使大型模型能够在有限的 GPU 资源上运行。在本实现中,我们使用 4-bit 量化以进一步优化内存效率。
我们使用 transformers 库中的 PaliGemmaForConditionalGeneration 类加载模型,传入模型 ID 和量化配置。同样,我们加载处理器(processor),用于在将输入传给模型之前将其预处理为张量。
步骤 3:图像处理
在模型分片加载完成后,我们在送入模型前对图像进行处理,以保持格式兼容与一致性。我们将图像转换为 RGB 格式:
def ensure_rgb ( image: Image. Image) - > Image. Image:
if image. mode != "RGB" :
image = image. convert( "RGB" )
return image技术支持
现在,图像已准备好用于推理。
步骤 4:使用 PaliGemma 推理
接下来,我们设置运行模型推理的主函数。该函数接收输入图像与问题,将其整合为提示词,通过处理器传给模型进行推理。
def ask_model ( image: Image. Image, question: str ) - > str :
prompt = f"<image> answer en { question} "
inputs = processor( text= prompt, images= image, return_tensors= "pt" ) . to( device)
with torch. inference_mode( ) :
generated_ids = model. generate(
** inputs,
max_new_tokens= 50 ,
do_sample= False
)
result = processor. batch_decode( generated_ids, skip_special_tokens= True )
return result[ 0 ] . strip( ) 技术支持
步骤 5:提取关键信息
在主函数就绪后,我们开始从图像中提取关键参数——在此场景中,即 总金额 和 商品类别 。
def extract_total_amount ( image: Image. Image) - > float :
question = "ocr\n what is the total amount? in numbers only"
answer = ask_model( image, question)
print ( f"Answer from model: { answer} " )
try :
amounts = re. findall( r'\d+\.\d+|\d+' , answer)
if amounts:
return float ( amounts[ - 1 ] )
except ValueError:
pass
return 0.0 技术支持
extract_total_amount() 函数通过 OCR 从收据图像中提取总金额。它构造一个仅提取数字值的查询(问题),然后调用 ask_model() 生成模型回复。
def categorize_goods ( image: Image. Image) - > str :
question = "what is the category of goods in the image - Grocery/ Clothing/ Electronics/ Other?"
answer = ask_model( image, question)
print ( f"Category from model: { answer} " )
answer = answer. split( "\n" ) [ - 1 ] . strip( ) . capitalize( )
valid_categories = [ "Grocery" , "Clothing" , "Electronics" , "Other" ]
return answer if answer in valid_categories else "Other" 技术支持
categorize_goods() 函数通过向模型提出包含预设类别(食品杂货、服装、电子产品或其他)的提问,对图像中的商品类型进行分类。ask_model() 随后处理图像并返回文本答案。如果处理后的答案与任一预设有效类别匹配,则返回该类别;否则,默认为 "Other"。
步骤 6:信息分析
关键函数已就绪,下面来分析输出结果。
def generate_spending_chart ( categories: dict ) :
filtered_categories = { k: v for k, v in categories. items( ) if v > 0 }
labels = list ( filtered_categories. keys( ) )
values = list ( filtered_categories. values( ) )
if not values or sum ( values) == 0 :
fig, ax = plt. subplots( )
ax. text( 0.5 , 0.5 , "No Spending Data" , ha= "center" , va= "center" , fontsize= 12 )
ax. axis( "off" )
return fig
fig, ax = plt. subplots( )
ax. pie( values, labels= labels, autopct= '%1.1f%%' , startangle= 90 )
ax. axis( 'equal' )
plt. title( "Spending Distribution" )
return fig技术支持
上述函数创建饼图,以可视化不同类别的支出分布。若不存在有效支出数据,则生成一张包含“No Spending Data”提示的空白图;否则,将生成带有类别标签与百分比的饼图,确保比例与对齐合理。
步骤 6:同时分析多张账单
我们通常需要分析多张账单,因此创建一个函数以同时处理所有账单。
def process_multiple_bills ( files: list ) :
results = [ ]
images = [ ]
total_spending = 0
category_totals = { "Grocery" : 0 , "Clothing" : 0 , "Electronics" : 0 , "Other" : 0 }
for file in files:
image = Image. open ( file )
image = ensure_rgb( image)
images. append( image)
total_amount = extract_total_amount( image)
category = categorize_goods( image)
total_spending += total_amount
category_totals[ category] += total_amount
results. append( { "Bill" : len ( results) + 1 , "Category" : category, "Total Amount" : f"₹ { total_amount: .2f } " } )
pie_chart = generate_spending_chart( category_totals)
summary_text = f"**Total Spending Across All Bills:** ₹ { total_spending: .2f } "
return images, pd. DataFrame( results) , summary_text, pie_chart技术支持
要一次性分析多张账单,我们执行以下步骤:
初始化存储 :创建用于存放结果与图像的列表,将 total_spending 设为 0,并定义用于记录各类别合计的字典。
处理每张账单 :
打开并将图像转换为 RGB。
将图像添加到列表。
从收据中提取总金额。
对收据中的商品进行分类。
更新总支出与各类别合计。
将提取的数据存入结果列表。
生成洞察 :创建支出分布饼图,并附上总支出摘要。
返回结果 :最终返回图像列表、账单摘要的 DataFrame、总支出摘要以及支出图表。
步骤 7:构建 Gradio 界面
关键逻辑函数已齐备,接下来使用 Gradio 构建交互式界面。
def gradio_demo ( ) :
with gr. Blocks( ) as demo:
gr. Markdown( "## PaliGemma 2 Mix Powered- Multiple Bill Scanner\nUpload multiple bill images, and this demo will extract text, categorize spending, and generate insights." )
with gr. Row( ) :
with gr. Column( ) :
image_input = gr. File( file_count= "multiple" , file_types= [ "image" ] , label= "Upload Bill Images" )
submit_button = gr. Button( "Process Bills" )
with gr. Column( ) :
image_output = gr. Gallery( label= "Uploaded Bills" )
table_output = gr. Dataframe( label= "Bill Summary" )
summary_output = gr. Text( label= "Total Spending Summary" )
chart_output = gr. Plot( label= "Aggregated Spending Distribution" )
submit_button. click(
fn= process_multiple_bills,
inputs= image_input,
outputs= [ image_output, table_output, summary_output, chart_output]
)
demo. launch( debug= True )
if __name__ == "__main__" :
gradio_demo( ) 技术支持
上述代码创建了结构化的 Gradio 界面,包含多图像文件上传器与提交按钮用于触发处理。提交后,上传的账单图像会显示在图库中,提取的数据以表格展示,总支出以文本总结,并生成支出分布饼图。
该函数将用户输入与 process_multiple_bills() 相连接,确保数据提取与可视化顺畅进行。最后通过 demo.launch() 启动 Gradio 应用,实现实时交互。
我还用两张基于图像的账单(亚马逊购物发票)测试了该演示,得到如下结果。
注意: VLM 在提取数字方面存在困难,偶尔会导致结果不准确。例如,下面第二张账单的总金额就提取错误。可以通过使用更大的模型,或对现有模型进行 微调 来纠正。
结语
在本教程中,我们使用 PaliGemma 2 Mix 构建了一个由 AI 驱动的多账单扫描器,能够从收据中提取并归类支出。我们利用 PaliGemma 2 Mix 的视觉-语言能力来执行 OCR 与分类,从而轻松获取消费洞察。也欢迎您将本教程改造用于自己的场景。
PaliGemma 2 Mix 是 Google 开发的一款多模态 AI 模型。它是 PaliGemma 视觉语言模型(VLM)的增强版本,融合了 SigLIP 视觉模型与 Gemma 2 语言模型的先进能力。
在本教程中,我将讲解如何使用 PaliGemma 2 Mix 构建一个由 AI 驱动的账单扫描与支出分析器,它能够:
虽然我们将专注于构建一个财务洞察工具,但您也可以将本博文中学到的内容用于探索 PaliGemma 2 Mix 的其他用例,例如图像分割、目标检测和问答。
什么是 PaliGemma 2 Mix?
PaliGemma 2 Mix 是一款先进的视觉-语言模型(VLM),可同时处理图像与文本输入,并生成基于文本的输出。它旨在支持多种多模态 AI 任务,同时支持多种语言。
PaliGemma 2 被设计用于广泛的视觉-语言任务,包括图像与短视频字幕生成、视觉问答、光学字符识别(OCR)、目标检测和分割。
图示所用图片来源:Google
PaliGemma 2 Mix 模型适用于:
您可以在官方发布文章中了解更多关于 PaliGemma 2 Mix 模型的信息。
项目概览:使用 PaliGemma 2 Mix 的账单扫描与支出分析器
我们将按以下主要步骤进行:
步骤 1:先决条件
在开始之前,请确保已安装以下工具与库:
运行以下命令安装所需依赖:
安装完成后,运行以下导入命令:
步骤 2:模型初始化
我们通过量化来优化性能,并加载 PaliGemma 2 Mix 模型。演示中我们将使用100 亿参数的模型,输入图像分辨率为 448 x 448。运行该模型至少需要一块 40GB 显存的 T4 GPU(Colab 配置)。
BitsAndBytes 量化有助于在保持性能的同时降低内存占用,使大型模型能够在有限的 GPU 资源上运行。在本实现中,我们使用 4-bit 量化以进一步优化内存效率。
我们使用
transformers库中的PaliGemmaForConditionalGeneration类加载模型,传入模型 ID 和量化配置。同样,我们加载处理器(processor),用于在将输入传给模型之前将其预处理为张量。步骤 3:图像处理
在模型分片加载完成后,我们在送入模型前对图像进行处理,以保持格式兼容与一致性。我们将图像转换为 RGB 格式:
现在,图像已准备好用于推理。
步骤 4:使用 PaliGemma 推理
接下来,我们设置运行模型推理的主函数。该函数接收输入图像与问题,将其整合为提示词,通过处理器传给模型进行推理。
步骤 5:提取关键信息
在主函数就绪后,我们开始从图像中提取关键参数——在此场景中,即总金额和商品类别。
extract_total_amount()函数通过 OCR 从收据图像中提取总金额。它构造一个仅提取数字值的查询(问题),然后调用ask_model()生成模型回复。categorize_goods()函数通过向模型提出包含预设类别(食品杂货、服装、电子产品或其他)的提问,对图像中的商品类型进行分类。ask_model()随后处理图像并返回文本答案。如果处理后的答案与任一预设有效类别匹配,则返回该类别;否则,默认为 "Other"。步骤 6:信息分析
关键函数已就绪,下面来分析输出结果。
上述函数创建饼图,以可视化不同类别的支出分布。若不存在有效支出数据,则生成一张包含“No Spending Data”提示的空白图;否则,将生成带有类别标签与百分比的饼图,确保比例与对齐合理。
步骤 6:同时分析多张账单
我们通常需要分析多张账单,因此创建一个函数以同时处理所有账单。
要一次性分析多张账单,我们执行以下步骤:
DataFrame、总支出摘要以及支出图表。步骤 7:构建 Gradio 界面
关键逻辑函数已齐备,接下来使用 Gradio 构建交互式界面。
上述代码创建了结构化的 Gradio 界面,包含多图像文件上传器与提交按钮用于触发处理。提交后,上传的账单图像会显示在图库中,提取的数据以表格展示,总支出以文本总结,并生成支出分布饼图。
该函数将用户输入与
process_multiple_bills()相连接,确保数据提取与可视化顺畅进行。最后通过demo.launch()启动 Gradio 应用,实现实时交互。我还用两张基于图像的账单(亚马逊购物发票)测试了该演示,得到如下结果。
注意:VLM 在提取数字方面存在困难,偶尔会导致结果不准确。例如,下面第二张账单的总金额就提取错误。可以通过使用更大的模型,或对现有模型进行微调来纠正。
结语
在本教程中,我们使用 PaliGemma 2 Mix 构建了一个由 AI 驱动的多账单扫描器,能够从收据中提取并归类支出。我们利用 PaliGemma 2 Mix 的视觉-语言能力来执行 OCR 与分类,从而轻松获取消费洞察。也欢迎您将本教程改造用于自己的场景。