A high-performance RAG system for PDFs using multi-vector embeddings (ColPali / ColQwen / ColSmol) with vector search in Qdrant, prefetch optimization, and reranking for improved relevance. Designed for speed, accuracy, and scalability, this system is ideal for building intelligent search, document understanding, and QA applications.
0
stars
8
commits
Python
primary language
Sep 12, 2025
updated
A fully local Retrieval-Augmented Generation (RAG) pipeline for PDF search and question answering.
It uses Late Interaction with ColPali / ColQwen / ColSmol family of models for encoding PDF page images, stores embeddings in Qdrant, and answers queries using a VLM with retrieved context.
This project includes an interactive Streamlit web app to index PDFs and ask questions.
Prefetch (Fast Retrieval) β Query pooled embeddings to quickly fetch top-K candidates from Qdrant.
Rerank (High Accuracy) β Pass candidates to ColPali, ColQwen, or ColSmol models for late-interaction reranking.
sequenceDiagram
%% Define participants in lanes
participant User
participant Indexing as Indexing Pipeline
participant Embedder as Embedder
participant VectorDB as Vector Database
participant Retriever as Retriever
participant Reranker as Reranker
participant LLM as LLM
par Offline Indexing
User->>Indexing: Upload PDF
Indexing->>Indexing: Extract Images
Indexing->>Embedder: Create embeddings
Embedder->>Indexing: Return embeddings
Indexing->>Indexing: Pool embeddings for each image
Indexing->>VectorDB: Store pooled & original embeddings
and Online Retrieval + RAG
User->>Retriever: Submit Query
Retriever->>Embedder: Embed Query (ColPali / ColQwen / ColSmol)
Embedder->>Retriever: Return query embeddings
Retriever->>VectorDB: Prefetch Top-K results
VectorDB->>Retriever: Return candidate results
Retriever->>Reranker: Send candidates for reranking
Reranker->>Retriever: Return ranked results
Retriever->>LLM: Pass reranked context
LLM->>User: Return final answer
end
flowchart TD
%% INDEXING STAGE
subgraph Indexing[π₯ Indexing Pipeline]
direction LR
A[Upload PDF / Images] --> B[Extract images & text]
B --> C[Generate embeddings<br/>ColPali / ColQwen / ColSmol]
C --> D[Mean-pool embeddings per image]
D --> E[Store pooled & original embeddings in Qdrant]
end
%% RETRIEVAL + RAG STAGE
subgraph Retrieval[π Retrieval + RAG]
direction LR
F[User Query] --> G[Embed query]
G --> H[Prefetch Top-K from Qdrant]
H --> I[Rerank results<br/>ColPali / ColQwen / ColSmol]
I --> J[Pass ranked results to LLM]
J --> K[Generate contextual answer]
end
%% FLOW BETWEEN STAGES
E --> H
K --> L[Final Answer to User]
pdf2image)Clone the repository
git clone https://github.com/logxdx/contextualized-late-interation-with-pdfs.git
cd contextualized-late-interation-with-pdfs
Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install dependencies
pip install -r requirements.txt
Install Poppler
Linux (Debian/Ubuntu):
sudo apt-get install poppler-utils
macOS:
brew install poppler
Windows:
bin folder to your PATH.Configure environment variables
Create a .env file in the project root:
# API key & URL for your LLM provider (ollama by default)
API_KEY=your_api_key_here
BASE_URL=http://localhost:11434/v1
# Optional Hugging Face token if model access is gated
HF_TOKEN=your_hf_token_here
contextualized-late-interation-with-pdfs/
β
βββ rag.py # Core RAG backend logic
βββ app.py # Streamlit UI
βββ requirements.txt # Python dependencies
βββ .env.example # Example environment file
βββ README.md # Project documentation
You can use the backend without the UI.
python rag.py
Inside __main__, update:
rag = RAG("vidore/colpali-v1.3")
rag.index_file(pdf_path="attention_is_all_you_need.pdf", batch_size=1)
rag.answer(
query="How does multi-headed attention work?",
top_k=4,
prefetch_limit=10
)
rag.close()
Start the web interface:
streamlit run app.py
Main Tabs:
PDF Processing
pdf2image).Vector Storage
Embeddings are stored in Qdrant with three vector fields:
originalmean_pooling_rowsmean_pooling_columnsRetrieval
Answer Generation
batch_size when indexing for faster throughput.dpi in _pdf_to_image for lower memory use.batch_size or use torch.float16.HF_TOKEN.This project is released under the MIT License.
8 commits
Python
100.0%
A high-performance RAG system for PDFs using multi-vector embeddings (ColPali / ColQwen / ColSmol) with vector search in Qdrant, prefetch optimization, and reranking for improved relevance. Designed for speed, accuracy, and scalability, this system is ideal for building intelligent search, document understanding, and QA applications.
0
stars
8
commits
Python
primary language
Sep 12, 2025
updated
A fully local Retrieval-Augmented Generation (RAG) pipeline for PDF search and question answering.
It uses Late Interaction with ColPali / ColQwen / ColSmol family of models for encoding PDF page images, stores embeddings in Qdrant, and answers queries using a VLM with retrieved context.
This project includes an interactive Streamlit web app to index PDFs and ask questions.
Prefetch (Fast Retrieval) β Query pooled embeddings to quickly fetch top-K candidates from Qdrant.
Rerank (High Accuracy) β Pass candidates to ColPali, ColQwen, or ColSmol models for late-interaction reranking.
sequenceDiagram
%% Define participants in lanes
participant User
participant Indexing as Indexing Pipeline
participant Embedder as Embedder
participant VectorDB as Vector Database
participant Retriever as Retriever
participant Reranker as Reranker
participant LLM as LLM
par Offline Indexing
User->>Indexing: Upload PDF
Indexing->>Indexing: Extract Images
Indexing->>Embedder: Create embeddings
Embedder->>Indexing: Return embeddings
Indexing->>Indexing: Pool embeddings for each image
Indexing->>VectorDB: Store pooled & original embeddings
and Online Retrieval + RAG
User->>Retriever: Submit Query
Retriever->>Embedder: Embed Query (ColPali / ColQwen / ColSmol)
Embedder->>Retriever: Return query embeddings
Retriever->>VectorDB: Prefetch Top-K results
VectorDB->>Retriever: Return candidate results
Retriever->>Reranker: Send candidates for reranking
Reranker->>Retriever: Return ranked results
Retriever->>LLM: Pass reranked context
LLM->>User: Return final answer
end
flowchart TD
%% INDEXING STAGE
subgraph Indexing[π₯ Indexing Pipeline]
direction LR
A[Upload PDF / Images] --> B[Extract images & text]
B --> C[Generate embeddings<br/>ColPali / ColQwen / ColSmol]
C --> D[Mean-pool embeddings per image]
D --> E[Store pooled & original embeddings in Qdrant]
end
%% RETRIEVAL + RAG STAGE
subgraph Retrieval[π Retrieval + RAG]
direction LR
F[User Query] --> G[Embed query]
G --> H[Prefetch Top-K from Qdrant]
H --> I[Rerank results<br/>ColPali / ColQwen / ColSmol]
I --> J[Pass ranked results to LLM]
J --> K[Generate contextual answer]
end
%% FLOW BETWEEN STAGES
E --> H
K --> L[Final Answer to User]
pdf2image)Clone the repository
git clone https://github.com/logxdx/contextualized-late-interation-with-pdfs.git
cd contextualized-late-interation-with-pdfs
Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install dependencies
pip install -r requirements.txt
Install Poppler
Linux (Debian/Ubuntu):
sudo apt-get install poppler-utils
macOS:
brew install poppler
Windows:
bin folder to your PATH.Configure environment variables
Create a .env file in the project root:
# API key & URL for your LLM provider (ollama by default)
API_KEY=your_api_key_here
BASE_URL=http://localhost:11434/v1
# Optional Hugging Face token if model access is gated
HF_TOKEN=your_hf_token_here
contextualized-late-interation-with-pdfs/
β
βββ rag.py # Core RAG backend logic
βββ app.py # Streamlit UI
βββ requirements.txt # Python dependencies
βββ .env.example # Example environment file
βββ README.md # Project documentation
You can use the backend without the UI.
python rag.py
Inside __main__, update:
rag = RAG("vidore/colpali-v1.3")
rag.index_file(pdf_path="attention_is_all_you_need.pdf", batch_size=1)
rag.answer(
query="How does multi-headed attention work?",
top_k=4,
prefetch_limit=10
)
rag.close()
Start the web interface:
streamlit run app.py
Main Tabs:
PDF Processing
pdf2image).Vector Storage
Embeddings are stored in Qdrant with three vector fields:
originalmean_pooling_rowsmean_pooling_columnsRetrieval
Answer Generation
batch_size when indexing for faster throughput.dpi in _pdf_to_image for lower memory use.batch_size or use torch.float16.HF_TOKEN.This project is released under the MIT License.
8 commits
Python
100.0%