Back to All Projects
RAG  ·  Local AI  ·  Self-Hosted  ·  Ongoing 2026

PaperMind

A local RAG-powered academic paper analyzer. Upload any PDF, ask questions, get structured summaries, running 100% privately on self-hosted hardware. Zero cloud, zero cost, zero data leakage.

RAG LLM React + Vite FastAPI ChromaDB Ollama phi3:mini Docker Compose
Self-Hosted · papermind.rafiarsya.com: Linux mini PC · Cloudflare Tunnel · Local LLM running 24/7 · No API cost
Status
In Development
Year
2026
Role
Solo Developer
Approach
RAG · Local LLM
01 Project Overview

PaperMind started as a frustration. I kept feeding papers to ChatGPT and getting confidently wrong answers. So I built something that actually reads the paper first, then answers from it.

PaperMind reads the PDF first: it splits the text into overlapping chunks, embeds each with nomic-embed-text, and stores them in ChromaDB. A question retrieves the most relevant chunks and sends them as grounded context to phi3:mini on local Ollama. The model answers strictly from the paper.

Why not just use ChatGPT? Because your research shouldn't leave your machine. Unpublished papers, draft findings, confidential data, PaperMind processes everything locally. The model runs on the same mini PC as this website.
02 Interface

Both halves of the tool running against a real PDF. Nothing here leaves the machine: the retrieval index and the model both sit locally, so the same screens work with no network at all.

ChatAsking questions against an indexed paper
SummarizeSection-by-section summarization view
OutputA generated summary with its source passages
QuestionHow a question is rendered
AnswerHow a retrieved answer is rendered
Chat demoLoading a PDF and querying it
Summary demoSummarizing a full paper
03 How RAG Works, The Math

RAG has two phases: indexing (done once per PDF) and retrieval + generation (done per query). Here's the actual math:

01Phase 1: PDF Indexing
1. Extract text from PDF (PyPDF2 / pdfplumber)
2. Split into overlapping chunks:
   chunk_size    = 500 tokens
   chunk_overlap = 50 tokens

3. For each chunk c_i:
   embedding_i = nomic-embed-text(c_i)
   -- embedding_i is a 768-dim float vector

4. Store in ChromaDB:
   collection.add(
     documents = [c_i],
     embeddings = [embedding_i],
     ids = [f"doc_{paper_id}_chunk_{i}"]
   )

Overlap stops context being split at a boundary — without the 50-token overlap, a sentence describing a key result could be cut between two chunks and become unretrievable. Each chunk maps to a dense vector in 768-dimensional space, where similar ideas land close together regardless of wording.

# A 12-page paper, ~9,400 tokens of body text

chunks = split(text, size=500, overlap=50)
→ 21 overlapping chunks produced

# Chunk 7 (positions 2850–3350 tokens):
embedding_7 = nomic-embed-text(chunk_7)
→ [0.0123, -0.0871, 0.1442...]  (768 floats)

collection.add(
  documents=[chunk_7],
  embeddings=[embedding_7],
  ids=["doc_42_chunk_7"]
)
→ stored, ready for retrieval
02Phase 2: Query Retrieval (Cosine Similarity)
1. Embed the user's question:
   q_embedding = nomic-embed-text(query)

2. Compute cosine similarity to all chunks:
   similarity(q, c_i) = (q · c_i) / (|q| × |c_i|)

   -- dot product of vectors / product of magnitudes
   -- returns value in [-1, 1], higher = more similar

3. Retrieve top-k chunks by similarity:
   top_chunks = sort(chunks, by=similarity, desc=True)[:5]

4. Build grounded prompt:
   prompt = f"""
   Context from the paper:
   {join(top_chunks)}

   Question: {query}
   Answer strictly based on the context above:
   """

5. Send to phi3:mini via Ollama

ChromaDB uses an approximate nearest-neighbour index (HNSW) so retrieval stays fast even across thousands of chunks. The LLM sees only the retrieved context, it cannot access information outside those 5 chunks, which eliminates hallucination by construction rather than by prompting the model to "please be accurate." If the paper genuinely doesn't contain the answer, the top-5 chunks will simply have low similarity scores and the model says so.

# Query: "What dataset did the paper use for training?"
q_embedding = nomic-embed-text(query)
→ [0.0091, -0.0654, 0.1308...]

similarity(q, chunk_3)  = 0.81  ← discusses dataset, high match
similarity(q, chunk_7)  = 0.74  ← mentions preprocessing steps
similarity(q, chunk_12) = 0.69  ← results table, some overlap
similarity(q, chunk_1)  = 0.22  ← abstract, low match
similarity(q, chunk_19) = 0.11  ← references section, irrelevant

top_5 = [chunk_3, chunk_7, chunk_12, chunk_9, chunk_15]
→ sent to phi3:mini as grounding context
04 System Architecture
React 18 + Vite (Frontend)
Port 5173 → nginx on port 3001
FastAPI (Backend)
PDF ingestion · chunk pipeline · query endpoint · streaming
ChromaDB (Vector Store)
768-dim embeddings · HNSW index · per-paper collections
Ollama (Local LLM Runtime)
phi3:mini model · nomic-embed-text · CPU inference on mini PC
Docker Compose + nginx
3 containers: frontend · backend · nginx
Cloudflare Tunnel
papermind.rafiarsya.com → localhost:3001 · http2 protocol
05 Key Features
Natural Language Q&A
Ask anything about your paper in plain English. Top-5 chunks retrieved by cosine similarity. The LLM answers strictly from the retrieved context, grounded, no hallucination.
Structured Auto-Summary
One-click structured summary: main topic, objectives, methodology, key findings, conclusions, all extracted from the actual paper, not generated from prior knowledge.
100% Local: Zero Cloud Dependency
phi3:mini runs on-device via Ollama. No OpenAI API key. No per-token cost. No data leaves the machine. Everything runs on a Linux mini PC 24/7.
Multi-Paper Library
Upload and manage multiple PDFs simultaneously. Each paper gets its own isolated ChromaDB collection, no cross-paper contamination during retrieval.
06 Processing Pipeline
Upload
PDF File
Any academic PDF
Extract
Text Extraction
PyPDF2
Chunk
500-token Chunks
50-token overlap
Embed
nomic-embed-text
768-dim vectors
Store
ChromaDB
HNSW index
Retrieve
Top-5 by Cosine
Semantic search
Generate
phi3:mini
Grounded answer
swipe to explore the full pipeline
07 Use Cases
Research Students
Upload a 40-page paper and get structured answers in seconds. Perfect for literature reviews and research comprehension.
Private Research
Unpublished papers, confidential datasets, NDA-covered work, everything stays on your machine, never leaves.
Zero-Cost AI
Local inference means unlimited queries, no API bills, no rate limits, no subscription. A one-time hardware investment.
Paper Comparison
Upload multiple related papers, query each independently, and compare methodologies and findings side-by-side.
Tech Stack
React 18 Vite FastAPI ChromaDB Ollama phi3:mini nomic-embed PyPDF2 Docker nginx Cloudflare
Local AI. Zero cost. Zero cloud.
Upload your paper, ask your questions, get grounded answers, all running on a mini PC in my room. No API key, no subscription, no data leaving the device.
Try PaperMind