Muhammad Rafi Arsya
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 actually reads your PDF first — splitting it into overlapping chunks, converting each chunk to a vector embedding using nomic-embed-text, and storing them in ChromaDB. When you ask a question, it finds the most semantically relevant chunks and sends them as grounded context to phi3:mini running locally via Ollama. The LLM answers strictly from the paper — no hallucination, no guessing.

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 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}"]
   )
scroll for full derivation

Chunking with overlap prevents important context from being split across boundaries — without the 50-token overlap, a sentence describing a key result could get cut exactly between two chunks and become unretrievable as a coherent thought. The embedding model maps each chunk to a dense vector in 768-dimensional semantic space, where chunks about similar ideas end up geometrically close together regardless of their exact 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
scroll to see full computation
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
scroll for full derivation

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
scroll to see full computation
03 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
04 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.
05 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
06 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.
By the Numbers
768
Embedding Dims
Top-5
Chunks Retrieved
500
Tokens/Chunk
0
Cloud API Cost
Build Progress
PDF Ingestion Pipeline100%
RAG Q&A100%
Auto-Summary100%
Multi-Paper Library80%
Citation Extraction20%
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