PaliGemma 2 Mix is a multimodal AI model developed by Google. It is an improved version of the PaliGemma vision language model (VLM), integrating advanced capabilities from the SigLIP vision model and Gemma 2 language models.
In this tutorial, I’ll explain how to use PaliGemma 2 Mix to build an AI-powered bill scanner and spending analyzer capable of:
Extracting and categorizing expenses from bill receipts.
Performing optical character recognition (OCR) to retrieve key information.
Summarizing spending based on provided images.
While our focus will be on building a financial insights tool, you can use what you learn in this blog to explore other use cases of PaliGemma 2 Mix, such as image segmentation, object detection, and question answering.
What Is PaliGemma 2 Mix?
PaliGemma 2 Mix is an advanced vision-language model (VLM) that processes both images and text as input and generates text-based outputs. It is designed to handle a diverse range of multimodal AI tasks while supporting multiple languages.
PaliGemma 2 is designed for a wide array of vision-language tasks, including image and short video captioning, visual question answering, optical character recognition (OCR), object detection, and segmentation.
Once the above dependencies are installed, run the following import commands:
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
We configure and load the PaliGemma 2 Mix model with quantization to optimize performance. For this demo, we’ll be using the 10b parameter model with 448 x 448 input image resolution. You need a minimum of T4 GPU with 40GB memory (Colab configuration) to run this model.
device ="cuda"if torch.cuda.is_available()else"cpu"# Model setup
model_id ="google/paligemma2-10b-mix-448"
bnb_config = BitsAndBytesConfig(
load_in_8bit=True,# Change to load_in_4bit=True for even lower memory usage
llm_int8_threshold=6.0,)# Load model with quantization
model = PaliGemmaForConditionalGeneration.from_pretrained(
model_id, quantization_config=bnb_config
).eval()# Load processor
processor = PaliGemmaProcessor.from_pretrained(model_id)# Print success messageprint("Model and processor loaded successfully!")Funcționează cu
BitsAndBytes quantization helps to reduce memory usage while maintaining performance, making it possible to run large models on limited GPU resources. In this implementation, we use 4-bit quantization to further optimize memory efficiency.
We load the model using the PaliGemmaForConditionalGeneration class from the transformers library by passing in the model ID and quantization configuration. Similarly, we load the processor, which preprocesses the inputs into tensors before passing it to the model.
Step 3: Image Processing
Once the model shards are loaded, we process the images before passing them to the model to maintain image format compatibility and gain uniformity. We convert images to RGB format:
Now, we set up the main function for running inference with the model. This function takes in input images and questions, incorporates them into prompts, and passes them to the model via the processor for inference.
Now that we have the main function ready, we’ll work next on extracting the key parameters from the image—in our case, these are the total amount and goods category.
defextract_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)# Capture both integer and decimal valuesif amounts:returnfloat(amounts[-1])# Get the last valid amount as the totalexcept ValueError:passreturn0.0
The extract_total_amount() function processes an image to extract the total amount from a receipt using OCR. It constructs a query (question) instructing the model to extract only numerical values, and then it calls the ask_model() function to generate a response from the model.
defcategorize_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"
The categorize_goods() function classifies the type of goods in an image by prompting the model with a predefined question listing possible categories: grocery, clothing, electronics, or other. The ask_model() function then processes the image and returns a textual response. If the processed response matches any of the predefined valid categories, it returns that category—otherwise, it defaults to the "Other" category.
Step 6: Analyzing Information
We have all the key functions ready, so let’s analyse the outputs.
defgenerate_spending_chart(categories:dict):
filtered_categories ={k: v for k, v in categories.items()if v >0}# Remove zero-value categories
labels =list(filtered_categories.keys())
values =list(filtered_categories.values())ifnot values orsum(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
The above function creates a pie chart to visualize spending distribution across different categories. If no valid spending data exists, it generates a blank figure with a message indicating "No Spending Data." Otherwise, it creates a pie chart with category labels and percentage values, ensuring a proportional and well-aligned visualization.
Step 6: Analyzing Multiple Bills Simultaneously
We typically have multiple bills to analyze, so let’s create a function to process all our bills simultaneously.
For analyzing multiple bills at once, we perform the following steps:
Initialize storage: We create lists for storing results and images, set total_spending to 0, and define a dictionary for category-wise totals.
Process each bill:
Open and convert the image to RGB.
Append the image to the list.
Extract the total amount from the receipt.
Categorize the goods in the receipt.
Update total spending and category-wise totals.
Store the extracted data in a results list.
Generate insights: We create a spending distribution pie chart along with a summary of total spending.
Return results: Finally, we return the list of images, a DataFrame of bill summaries, the total spending summary, and the spending chart.
Step 7: Build the Gradio Interface
Now, we have all key logic functions in place. Next, we work on building interactive UI with Gradio.
defgradio_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()Funcționează cu
The above code creates a structured Gradio UI with a file uploader for multiple images and a submit button to trigger processing. Upon submission, uploaded bill images are displayed in a gallery, extracted data is shown in a table, total spending is summarized in text, and a spending distribution pie chart is generated.
The function connects user inputs to the process_multiple_bills() function, ensuring seamless data extraction and visualization. Finally, the demo.launch() function starts the Gradio app for real-time interaction.
I also tried this demo with two image-based bills (Amazon shopping invoice) and got the following results.
Note: VLMs find it difficult to extract numbers, which may lead to incorrect results at times. For instance, it extracted the wrong total amount for the second bill below. This is correctable with the use of larger models or simply fine-tuning the existing ones.
Conclusion
In this tutorial, we built an AI-powered multiple bill scanner using PaliGemma 2 Mix, which can help us extract and categorize our expenses from receipts. We used PaliGemma 2 Mix’s vision-language capabilities for OCR and classification to analyze spending insights effortlessly. I encourage you to adapt this tutorial to your own use case.
I am a Google Developers Expert in ML(Gen AI), a Kaggle 3x Expert, and a Women Techmakers Ambassador with 3+ years of experience in tech. I co-founded a health-tech startup in 2020 and am pursuing a master's in computer science at Georgia Tech, specializing in machine learning.
Learn how to set up, integrate, and run the Gemma 3 270M model in an Android application, along with best practices for ensuring its reliability and safety for on-device inference.
Learn how to build an Android app that uses Google's Gemma 3n to answer questions about images directly on your phone, without needing a cloud connection.
Learn how to use Google's Gemini 2.0 Flash model to develop a visual assistant capable of reading on-screen content and answering questions about it using Python.
PaliGemma 2 Mix is a multimodal AI model developed by Google. It is an improved version of the PaliGemma vision language model (VLM), integrating advanced capabilities from the SigLIP vision model and Gemma 2 language models.
In this tutorial, I’ll explain how to use PaliGemma 2 Mix to build an AI-powered bill scanner and spending analyzer capable of:
While our focus will be on building a financial insights tool, you can use what you learn in this blog to explore other use cases of PaliGemma 2 Mix, such as image segmentation, object detection, and question answering.
What Is PaliGemma 2 Mix?
PaliGemma 2 Mix is an advanced vision-language model (VLM) that processes both images and text as input and generates text-based outputs. It is designed to handle a diverse range of multimodal AI tasks while supporting multiple languages.
PaliGemma 2 is designed for a wide array of vision-language tasks, including image and short video captioning, visual question answering, optical character recognition (OCR), object detection, and segmentation.
Source of the images used in the diagram: Google
PaliGemma 2 Mix model is designed for:
You can find more information about the PaliGemma 2 Mix model in the official release article.
Project Overview: Bill Scanner and Spending Analyzer With PaliGemma 2 Mix
Let’s outline the main steps that we’re going to take:
Step 1: Prerequisites
Before we start, let’s ensure that we have the following tools and libraries installed:
Run the following commands to install the necessary dependencies:
Once the above dependencies are installed, run the following import commands:
Step 2: Model Initialization
We configure and load the PaliGemma 2 Mix model with quantization to optimize performance. For this demo, we’ll be using the 10b parameter model with 448 x 448 input image resolution. You need a minimum of T4 GPU with 40GB memory (Colab configuration) to run this model.
BitsAndBytes quantization helps to reduce memory usage while maintaining performance, making it possible to run large models on limited GPU resources. In this implementation, we use 4-bit quantization to further optimize memory efficiency.
We load the model using the
PaliGemmaForConditionalGenerationclass from thetransformerslibrary by passing in the model ID and quantization configuration. Similarly, we load the processor, which preprocesses the inputs into tensors before passing it to the model.Step 3: Image Processing
Once the model shards are loaded, we process the images before passing them to the model to maintain image format compatibility and gain uniformity. We convert images to RGB format:
Now, our images are ready for inference.
Step 4: Inference with PaliGemma
Now, we set up the main function for running inference with the model. This function takes in input images and questions, incorporates them into prompts, and passes them to the model via the processor for inference.
Step 5: Extracting Key Information
Now that we have the main function ready, we’ll work next on extracting the key parameters from the image—in our case, these are the total amount and goods category.
The
extract_total_amount()function processes an image to extract the total amount from a receipt using OCR. It constructs a query (question) instructing the model to extract only numerical values, and then it calls theask_model()function to generate a response from the model.The
categorize_goods()function classifies the type of goods in an image by prompting the model with a predefined question listing possible categories: grocery, clothing, electronics, or other. Theask_model()function then processes the image and returns a textual response. If the processed response matches any of the predefined valid categories, it returns that category—otherwise, it defaults to the "Other" category.Step 6: Analyzing Information
We have all the key functions ready, so let’s analyse the outputs.
The above function creates a pie chart to visualize spending distribution across different categories. If no valid spending data exists, it generates a blank figure with a message indicating "No Spending Data." Otherwise, it creates a pie chart with category labels and percentage values, ensuring a proportional and well-aligned visualization.
Step 6: Analyzing Multiple Bills Simultaneously
We typically have multiple bills to analyze, so let’s create a function to process all our bills simultaneously.
For analyzing multiple bills at once, we perform the following steps:
DataFrameof bill summaries, the total spending summary, and the spending chart.Step 7: Build the Gradio Interface
Now, we have all key logic functions in place. Next, we work on building interactive UI with Gradio.
The above code creates a structured Gradio UI with a file uploader for multiple images and a submit button to trigger processing. Upon submission, uploaded bill images are displayed in a gallery, extracted data is shown in a table, total spending is summarized in text, and a spending distribution pie chart is generated.
The function connects user inputs to the
process_multiple_bills()function, ensuring seamless data extraction and visualization. Finally, thedemo.launch()function starts the Gradio app for real-time interaction.I also tried this demo with two image-based bills (Amazon shopping invoice) and got the following results.
Note: VLMs find it difficult to extract numbers, which may lead to incorrect results at times. For instance, it extracted the wrong total amount for the second bill below. This is correctable with the use of larger models or simply fine-tuning the existing ones.
Conclusion
In this tutorial, we built an AI-powered multiple bill scanner using PaliGemma 2 Mix, which can help us extract and categorize our expenses from receipts. We used PaliGemma 2 Mix’s vision-language capabilities for OCR and classification to analyze spending insights effortlessly. I encourage you to adapt this tutorial to your own use case.