Beyond Text: Unlock OCR-Free RAG in PostgreSQL with Modal & VectorChord
Building effective Retrieval-Augmented Generation (RAG) systems for documents often feels like wrestling with messy, complex pipelines. Especially when dealing with PDFs or scanned images, traditional methods rely heavily on Optical Character Recognition (OCR) and layout analysis. These steps can be slow, error-prone, and often lose crucial visual context like tables, figures, and formatting. But what if you could query documents based on how they look, not just the extracted text?
This post is your guide to building exactly that: an OCR-free RAG system directly within your familiar PostgreSQL database. We’ll leverage the power of the ColQwen2 Vision Language Model, the efficiency of VectorChord for multi-vector search in Postgres, and the scalability of Modal for GPU-powered embedding generation. Get ready to simplify your RAG stack and potentially boost your retrieval accuracy, all without complex pre-processing.
We’ll cover:
-
What ColQwen2 is and why it’s a game-changer.
-
How VectorChord makes advanced vector search possible in Postgres.
-
A step-by-step tutorial to build and evaluate the system.
What is ColQwen2? The Power of Visual Understanding
To grasp ColQwen2, let’s first look at its foundation: ColPali. As introduced in the paper “ColPali: Efficient Document Retrieval with Vision Language Models”, ColPali represents a novel approach using Vision Language Models (VLMs). Instead of relying on imperfect OCR, it directly indexes documents using their rich visual features – text, images, tables, layout, everything the eye can see.
Think about the limitations of traditional OCR: complex layouts get mangled, tables become gibberish, and images are often ignored entirely. It’s like trying to understand a book by only reading a flawed transcript. ColPali avoids this by using a powerful VLM (originally PaliGemma) to create embeddings that capture the document’s holistic visual nature. Two key concepts make it shine:
-
Contextualized Vision Embeddings: Generating rich embeddings directly from the document image using a VLM.
-
Late Interaction: This clever technique allows the query’s textual meaning to directly interact with the document’s detailed visual features at search time. It’s not just matching text summaries; it’s comparing the query concept against the visual evidence within the document page.
The ColPali architecture (Image from the ColPali paper)
ColQwen2 builds upon this powerful ColPali architecture but swaps the underlying VLM for the more recent Qwen2-VL-2B. It generates ColBERT-style multi-vector representations, capturing fine-grained details from both text and images. As seen on the vidore-leaderboard, ColQwen2 delivers impressive performance with practical model size.
How Does VectorChord Enable ColQwen2 in Postgres?
This is where VectorChord becomes the crucial piece of the puzzle, bringing this cutting-edge VLM capability into your PostgreSQL database. ColQwen2 (and ColPali) relies heavily on those multi-vector representations and the Late Interaction mechanism, specifically requiring an efficient MaxSim (Maximum Similarity) operation.
Calculating MaxSim – finding the highest similarity score between any vector in the query set and any vector in the document set – can be computationally brutal, especially across millions of document vectors. VectorChord tackles this head-on:
-
Native Multi-Vector Support: It’s designed from the ground up to handle multi-vector data efficiently within Postgres.
-
Optimized MaxSim: Drawing inspiration from the WARP paper, VectorChord uses techniques like dynamic similarity imputation to dramatically speed up MaxSim calculations, making large-scale visual document retrieval feasible.
-
Hybrid Search Ready: Beyond multi-vector, it also supports dense, sparse, and hybrid search (check out our previous post!).
-
Scalable & Disk-Friendly: Designed for performance without demanding excessive resources.
In short, VectorChord transforms PostgreSQL into a powerhouse capable of handling the advanced vector search techniques required by models like ColQwen2 or ColPali.
Tutorial: Building Your OCR-Free RAG System
Alright, theory’s great, but let’s roll up our sleeves and build this thing! We’ll walk through setting up the environment, processing data using Modal for scalable embedding generation, indexing into VectorChord within Postgres, and finally, evaluating our shiny new OCR-free RAG system.
Prerequisites
Before we start, ensure you have:
-
A PostgreSQL instance (Docker recommended) with the VectorChord extension installed OR a VectorChord Cloud cluster.
-
A Modal account (free tier available). Modal’s fast GPU provisioning and scaling are perfect for the embedding generation step. To efficiently process a large volume of documents using the ColQwen2 model, it’s crucial to leverage Modal’s rapid startup and GPU expansion features. This approach will significantly reduce the time required for local processing.
If you want to reproduce the tutorial quickly, you can use the tensorchord/vchord-suite image to run multiple extensions that TensorChord provides.
You can run the following command to build and start Postgres with VectorChord-BM25 and VectorChord.
Set up Modal:
Step 1: Load the Data (Using Modal Volumes)
We’ll use the ViDoRe Benchmark dataset. To handle this data efficiently across potentially distributed Modal functions, we’ll download it to a Modal Volume. Volumes provide persistent, shared storage ideal for this ‘download once, process many times’ scenario.
Modal offers a straightforward Python API for interacting with its platform. With modal.Image, you can set the base image for the Modal App, and the function decorator helps define the function to be executed within the Modal application. To download the dataset to the Modal Volume, execute the following command. Modal will then automatically build the Docker image and promptly launch the container to run your function.
Run the download function:
Modal handles building the environment and running the script in the cloud.
Step 2: Process Data & Generate Embeddings (With Modal & ColQwen2)
This is the heavy lifting: converting document images into ColQwen2 multi-vector embeddings. Doing this locally for many documents would be slow. Modal shines here:
-
Easy GPU Access & Autoscaling: Launch a ColQwen2 model service on Modal and use it to generate the image embeddings and query embeddings for the dataset. The decision to implement an HTTP service instead of using the SDK directly was made to ensure seamless auto-scaling during large-scale embedding operations. If you want to deploy the embedding service as a persistent web endpoint, you can directly change
modal.clstomodal.web_serverfor ColPaliServer and runningmodal deploy. -
Recovery: We checkpoint progress to a separate Modal Volume, allowing us to resume embedding generation if interrupted.
Generate the embeddings:
Step 3: Create Index in VectorChord (Using Vechord SDK)
With embeddings generated and saved in a Modal Volume, we first need to bring them local.
Now, we’ll use the vechord SDK to load these embeddings into our PostgreSQL database and create the necessary multi-vector index. vechord provides a Pythonic, ORM-like way to interact with VectorChord in Postgres.
%[https://github.com/tensorchord/vechord]
Run the indexer script, vechord handles table creation, index creation, and data insertion.
Step 4: Evaluation - Does it Work?
The final step is crucial: evaluating retrieval performance. Does this OCR-free system deliver accurate results, and can it be fast? We’ll use vechord to run queries against our indexed data and look at NDCG@10 and Recall@10. We’ll also test the impact of VectorChord’s WARP optimization, which accelerates MaxSim calculations. In this tutorial, we will use vidore/arxivqa_test_subsampled dataset for evaluation queries, the data are shown below.
Running the evaluation script yields impressive results:
Analysis:
-
High Baseline Accuracy: First, let’s look at the baseline performance without WARP optimization. The system achieves an excellent NDCG@10 of 0.8615 and Recall@10 of 0.92. This confirms the fundamental effectiveness of ColQwen2 embeddings paired with VectorChord’s precise MaxSim search, delivering state-of-the-art results for visual document retrieval even without speed optimizations.
-
Dramatic WARP Speed Boost: Now, observe the impact of enabling VectorChord’s WARP optimization. The total execution time plummets from a substantial 810 seconds down to just 41 seconds! This represents a massive ~18.7x speedup for the evaluation query set. This clearly demonstrates WARP’s power in dramatically accelerating the computationally intensive MaxSim operations required for late-interaction models like ColQwen2.
-
Minimal Accuracy Trade-off: Impressively, this significant speed gain comes at the cost of only a very minor dip in retrieval accuracy. The NDCG@10 slightly decreases to 0.8353 (a difference of less than 0.3), and Recall@10 reduces minimally to 0.9 (a difference of only 0.02).
Conclusion: Visual RAG Made Simpler in Postgres
In this tutorial, we successfully built a high-performance, OCR-free RAG system by bringing together the visual understanding capabilities of ColQwen2, the scalable multi-vector search of VectorChord within PostgreSQL, and the efficient GPU processing of Modal. We saw how this stack allows us to directly query documents based on their visual content, bypassing the pitfalls of traditional OCR pipelines.
The ability to seamlessly integrate this visual dimension into your RAG system directly within Postgres opens up exciting possibilities for applications dealing with visually rich documents like scientific papers, invoices, product manuals, historical archives, and much more.
Ready to try it yourself?
-
Explore the Code: https://github.com/xieydd/vectorchord-colqwen2
-
Dive Deeper into VectorChord: Check out the VectorChord documentation or try the hassle-free VectorChord Cloud.
-
Experiment: Try different VLMs or datasets.
-
Share Your Thoughts: Let us know your experiences or questions in the comments below!
This approach represents a significant step towards simpler, more robust, and visually-aware document retrieval systems.