5 2 weeks ago

Specialized Qur'an, Hadith & Fatwa Knowledge System with Multi-Vector RAG & Dual LLM Support

ollama run arelgendy/qmodel:8.5

Details

2 weeks ago

b5eb7d03a18e · 16GB

qwen2
·
14.8B
·
Q8_0
{{- if .System }}<|im_start|>system {{ .System }}<|im_end|> {{ end }}{{- if .Prompt }}<|im_start|>us
You are Sheikh QModel, a distinguished Islamic scholar specialized in the Holy Quran, Sunnah, Tafsir
{ "repeat_penalty": 1.1, "stop": [ "<|im_start|>", "<|im_end|>" ], "

Readme

QModel v8.5 — Islamic RAG System

Specialized Qur’an, Hadith & Fatwa Knowledge System with Multi-Vector RAG & Dual LLM Support

A production-ready Retrieval-Augmented Generation system specialized exclusively in authenticated Islamic knowledge. No hallucinations, no outside knowledge—only content from verified sources.

Version Backend Status


Features

📖 Qur’an Capabilities

  • Verse Lookup: Find verses by topic or keyword
  • Word Frequency: Count occurrences with Surah breakdown
  • Root Analysis: Explore verses sharing the same 3-letter Arabic root with curated root dictionaries
  • Parent-Document Windowing: Automatic \(\pm 1\) verse context expansion for complete theological context
  • Bilingual: Full Arabic + English translation support
  • Tafsir Integration: Expanded contextual interpretation (up to 1,200 characters)

📚 Hadith Capabilities

  • Isnad Highlighting: Chain of narrators emphasized in responses
  • Authenticity Verification: Check if Hadith is in authenticated collections
  • Grade Display: Show Sahih/Hasan/Da’if authenticity levels
  • Matn Deduplication: Redundant narrations consolidated with Muttafaq ‘Alayh detection
  • Cross-Collection References: Displays alternative canonical collections (e.g. Bukhari, Muslim, Abu Dawood)
  • Topic Search: Find relevant Hadiths across 9 major collections
  • Collection Navigation: Filter by Bukhari, Muslim, Abu Dawud, etc.

⚖️ Fatwa & Fiqh Capabilities

  • Verified Scholarly Rulings: 3,598 fatwas from Islamweb’s Fatwa Center (مركز الفتوى) and Imam Ibn Baz
  • Semantic & Source Filtering: Filter fatwas by scholar, council, or source
  • Integrated RAG Context: Rulings retrieved alongside Quran and Hadith evidence
  • Direct Lookup: Fast endpoint access via /fatwa/{id}, /fatwa/search, and /fatwa/sources

🛡️ Safety Features

  • Relevance Gating: The LLM is only called when retrieval found something genuinely relevant (exact reference/text match, else the cross-encoder’s relevance score); out-of-scope requests get a fixed “not found” answer
  • Reasoning Support: Capture and stream model thinking/Chain-of-Thought
  • Source Attribution: Every answer cites exact verse, Hadith, or Fatwa reference — hadith by collection and number, fatwas by source link (added automatically when the model omits it)
  • Verbatim Scripture: Quoted verses and hadith (﴿...﴾, ❝...❞, «...») are checked against the retrieved passages; near-copies are restored to the canonical text, ungrounded quotes are removed
  • Language Guard: Answers that drift into Chinese are regenerated (or cut off when streaming)

🚀 Integration

  • OpenAI-Compatible API: Use with Open-WebUI, Langchain, or any OpenAI client
  • OpenAI Schema: Full support for /v1/chat/completions and /v1/models
  • Streaming Responses: SSE streaming for long-form answers
  • Conversational Multi-Turn Memory: Coreference resolution for continuous contextual dialogues

⚙️ Technical & RAG Architecture

  • Asymmetric E5 Embedding: Proper passage: and query: prefixes for optimal vector similarity
  • Multi-Vector Dense Retrieval: Independent Arabic and English query vectors fused adaptively
  • Inverted BM25 Sparse Index: Bilingual tokenization with stopword filtering and morphological root indexing
  • Adaptive RRF Fusion: Language-weighted Reciprocal Rank Fusion balancing dense & sparse signals
  • Cross-Encoder Reranker: BAAI/bge-reranker-v2-m3 rescoring and confidence gating (on by default)
  • Triple LLM Backend: Local GGUF, Ollama (dev), or HuggingFace (prod)
  • Async API & Caching: FastAPI with TTL-based LRU response cache

Quick Start

Prerequisites

  • Python 3.10+
  • 16 GB RAM minimum (for embeddings + LLM)
  • GPU recommended for HuggingFace backend
  • Ollama installed (for local development) OR internet access (for HuggingFace)

Installation

# Download code + search index from Hugging Face (skips the 15 GB GGUF)
huggingface-cli download aelgendy/QModel --exclude "models/*" --local-dir QModel && cd QModel
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# Configure (choose one backend)
# Option A — GGUF (self-contained, default):
export LLM_BACKEND=gguf
export GGUF_MODEL_PATH=./models/Qwen2.5-14B-Instruct-Q8_0.gguf
huggingface-cli download bartowski/Qwen2.5-14B-Instruct-GGUF Qwen2.5-14B-Instruct-Q8_0.gguf --local-dir ./models

# Option B — Ollama:
ollama pull arelgendy/qmodel:8.5          # or: ollama pull hf.co/aelgendy/QModel
export LLM_BACKEND=ollama
export OLLAMA_MODEL=arelgendy/qmodel:8.5
# Make sure Ollama is running: ollama serve

# Option C — HuggingFace (production):
export LLM_BACKEND=hf
export HF_MODEL_NAME=Qwen/Qwen2.5-14B-Instruct

# Run
python main.py

# Query
curl "http://localhost:8000/ask?q=What%20does%20Islam%20say%20about%20mercy?"

API docs: http://localhost:8000/docs

Data & Index

Pre-built data files are included: - metadata.json — 56,250 documents (6,236 Quran verses + 46,416 hadiths from 15 collections + 3,598 fatwas) - QModel.index — FAISS search index (~220 MB, 56,250 vectors, 1024-d)

To rebuild after dataset changes:

python build_index.py

Fatwas are read from data/fatwas/ (hand-collected) and data/fatwas_scraped/ (scraper output), de-duplicated by id and content; files listed in FATWA_EXCLUDE in build_index.py are skipped. To add fatwas without re-embedding the Qur’an and hadith:

python data_pipeline/scrape_fatwas.py --source islamweb --start 8001 --end 12000 --delay 1.0
python scripts/update_fatwa_index.py              # writes QModel.fatwa-update.index / metadata.fatwa-update.json
python scripts/update_fatwa_index.py --in-place   # or replace the live files (previous pair saved as .bak, overwriting older .bak)

Records without answer text, and scraped listing pages (e.g. audio-lecture indexes), are skipped.


Example Queries

# Basic question
curl "http://localhost:8000/ask?q=What%20does%20Islam%20say%20about%20mercy?"

# Word frequency
curl "http://localhost:8000/ask?q=How%20many%20times%20is%20mercy%20mentioned?"

# Authentic Hadiths only
curl "http://localhost:8000/ask?q=prayer&source_type=hadith&grade_filter=sahih"

# Quran text search
curl "http://localhost:8000/quran/search?q=bismillah"

# Quran topic search
curl "http://localhost:8000/quran/topic?topic=patience&top_k=5"

# Quran word frequency
curl "http://localhost:8000/quran/word-frequency?word=mercy"

# Single chapter
curl "http://localhost:8000/quran/chapter/2"

# Exact verse
curl "http://localhost:8000/quran/verse/2:255"

# Root-word analysis
curl "http://localhost:8000/quran/root/رحم"

# Hadith text search
curl "http://localhost:8000/hadith/search?q=actions+are+judged+by+intentions"

# Hadith topic search (Sahih only)
curl "http://localhost:8000/hadith/topic?topic=fasting&grade_filter=sahih"

# Verify Hadith authenticity
curl "http://localhost:8000/hadith/verify?q=Actions%20are%20judged%20by%20intentions"

# Browse a collection
curl "http://localhost:8000/hadith/collection/bukhari?limit=5"

# Fatwa topic search (with scholar filter)
curl "http://localhost:8000/fatwa/search?q=الوصية&source=BinBaz&top_k=3"

# Fatwa direct ID lookup
curl "http://localhost:8000/fatwa/fatwa_binbaz_4210"

# List loaded Fatwa collections
curl "http://localhost:8000/fatwa/sources"

# Streaming (OpenAI-compatible)
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"QModel","messages":[{"role":"user","content":"What does Islam say about charity?"}],"stream":true}'

Configuration

All configuration via environment variables (.env file or exported directly):

Backend Selection

Backend Pros Cons When to Use
GGUF Self-contained, no external daemon, bundles with the repo/Space Larger image/repo size HF Spaces, offline/portable deployment
Ollama Fast setup, no GPU, free Smaller models, requires separate daemon Development, testing
HuggingFace Larger models, better quality Requires GPU or significant RAM Production

GGUF Backend (Self-contained)

LLM_BACKEND=gguf
GGUF_MODEL_PATH=./models/Qwen2.5-14B-Instruct-Q8_0.gguf
GGUF_N_CTX=8192
GGUF_N_GPU_LAYERS=-1             # -1 = offload all layers to GPU, 0 = CPU-only

Requires the .gguf file to be present at GGUF_MODEL_PATH — download with:

huggingface-cli download bartowski/Qwen2.5-14B-Instruct-GGUF Qwen2.5-14B-Instruct-Q8_0.gguf --local-dir ./models

Model Profile

Model Size (Q8_0) RAM / VRAM Generation Speed Best Use Case
Qwen2.5-14B-Instruct (Default) ~15 GB ~16 GB Blazing (~55 tok/s) Production, Hugging Face Hub, and local GPU deployment

Ollama Backend (Development)

ollama pull arelgendy/qmodel:8.5

LLM_BACKEND=ollama
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=arelgendy/qmodel:8.5

Requires ollama serve running. The model is published in two places, both built from Modelfile (chat template, system prompt and sampling settings):

Source Pull Tags
ollama.com ollama pull arelgendy/qmodel:8.5 release versions (8.5, latest)
Hugging Face ollama pull hf.co/aelgendy/QModel quantization only (Q8_0); reads the repo’s template, system and params files

ollama run arelgendy/qmodel on its own gives the bare language model, without retrieval, citation checks or verse links. For grounded answers, run the QModel API with LLM_BACKEND=ollama and send questions to it (or to Open-WebUI connected to it).

HuggingFace Backend (Production)

LLM_BACKEND=hf
HF_MODEL_NAME=Qwen/Qwen2.5-14B-Instruct
HF_DEVICE=auto                   # auto | cuda | cpu
HF_MAX_NEW_TOKENS=2048

All Environment Variables

Variable Default Description
Backend
LLM_BACKEND gguf gguf, ollama, or hf
GGUF_MODEL_PATH ./models/Qwen2.5-14B-Instruct-Q8_0.gguf Path to local .gguf file
GGUF_N_CTX 8192 Context window size
GGUF_N_GPU_LAYERS -1 Layers to offload to GPU (-1 = all, 0 = CPU-only)
OLLAMA_HOST http://localhost:11434 Ollama server URL
OLLAMA_MODEL qwen2.5:14b Ollama model name
HF_MODEL_NAME Qwen/Qwen2.5-14B-Instruct HuggingFace model ID
HF_DEVICE auto auto, cuda, or cpu
HF_MAX_NEW_TOKENS 2048 Max output length
Embedding & Data
EMBED_MODEL intfloat/multilingual-e5-large Embedding model
FAISS_INDEX QModel.index Index file path
METADATA_FILE metadata.json Dataset file
Retrieval
TOP_K_SEARCH 20 Candidate pool (5–100)
TOP_K_RETURN 5 Results shown to user (1–20)
RERANK_ALPHA 0.6 Dense vs Sparse weight (0.0–1.0)
FAST_QUERY_REWRITE true Rewrite queries without the LLM (regex intent + thesaurus terms), saving ~2 s per question. The LLM rewrite still runs for follow-up questions with chat history
USE_RERANKER true Cross-encoder reranker (true/false). Also drives the confidence gate: off-topic questions refused 92% with it vs 36% without
RERANK_MODEL BAAI/bge-reranker-v2-m3 Cross-encoder model ID
AYAH_WINDOW_SIZE 1 Number of neighboring verses for context expansion
ENABLE_HADITH_DEDUPLICATION true Cluster near-identical Hadith narrations
TAFSIR_MAX_CHARS 1200 Max Tafsir characters provided in LLM context
Generation
TEMPERATURE 0.2 Creativity (0.0–1.0, use 0.1–0.2 for religious)
MAX_TOKENS 2048 Max response length
SHOW_THINKING false Include chain-of-thought/reasoning output (true/false)
Safety
RERANK_MIN_SCORE 0.05 Confidence gate with reranker on: min cross-encoder relevance (0–1) of the best retrieved passage to call the LLM
DENSE_MIN_SCORE 0.80 Confidence gate with reranker off: min dense cosine similarity (multilingual-e5-large scale)
HADITH_BOOST 0.08 Score boost for hadith on hadith queries
QURAN_BOOST 0.12 Score boost for Quran verses on tafsir/quran queries
Other
CACHE_SIZE 512 Query response cache entries
CACHE_TTL 3600 Cache expiry in seconds
ALLOWED_ORIGINS * CORS origins
MAX_EXAMPLES 3 Few-shot examples in system prompt

Configuration Examples

Self-contained (GGUF, e.g. HF Spaces)

LLM_BACKEND=gguf
GGUF_MODEL_PATH=./models/Qwen2.5-14B-Instruct-Q8_0.gguf
GGUF_N_CTX=8192
GGUF_N_GPU_LAYERS=-1
TEMPERATURE=0.2

Development (Ollama)

LLM_BACKEND=ollama
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=arelgendy/qmodel:8.5
TEMPERATURE=0.2
ALLOWED_ORIGINS=*

Production (HuggingFace + GPU)

LLM_BACKEND=hf
HF_MODEL_NAME=Qwen/Qwen2.5-14B-Instruct
HF_DEVICE=cuda
TOP_K_SEARCH=30
TEMPERATURE=0.1
USE_RERANKER=true
ALLOWED_ORIGINS=yourdomain.com,api.yourdomain.com

Tuning Tips

  • Better results: keep USE_RERANKER=true (the default: better ranking and a far more reliable confidence gate, ~1 s per answer), increase TOP_K_SEARCH, use TEMPERATURE=0.1
  • Faster performance: Lower TOP_K_SEARCH and TOP_K_RETURN, reduce MAX_TOKENS, use Ollama
  • More conservative: Increase RERANK_MIN_SCORE / DENSE_MIN_SCORE, lower TEMPERATURE — check the trade-off with python -m eval.run_eval --show-failures

Measuring Retrieval Accuracy

eval/golden.jsonl holds 147 labelled queries (Qur’an topic/text/reference, Hadith topic/text/authenticity, Fatwa, and out-of-scope negatives). Each case lists the dataset ids that count as a correct hit; where one source is decisive (5:90 for “is alcohol forbidden?”, while 2:219 alone would mislead), it is also listed under required and scored as complete@k. eval/run_eval.py runs them through retrieval (no LLM generation) using the local index:

python -m eval.run_eval --out eval/results/baseline.json        # full pipeline, k = TOP_K_RETURN
python -m eval.run_eval --mode hybrid --k 20                     # hybrid_search() alone
python -m eval.run_eval --only fatwa,negative --show-failures    # subset + list misses
python -m eval.run_eval --compare eval/results/baseline.json     # diff against a previous run

It reports Hit@1/3/k, MRR and Recall@k overall, by category and by language, plus the confidence gate’s false-reject rate (answer found but refused) and false-accept rate (out-of-scope queries let through). Run it before and after any retrieval or config change; env vars such as USE_RERANKER=false or TOP_K_SEARCH=100 apply as usual.

Measuring Answer Quality

eval/run_answers.py runs the same golden set through the full pipeline with the LLM and checks what users read:

python -m eval.run_answers --limit 5                           # smoke test
python -m eval.run_answers --only hadith_text,fatwa            # subset
python -m eval.run_answers --out eval/results/answers.json     # full run (~1 h at ~25 s/answer)
  • Refusals: out-of-scope questions get the “not found” answer; real ones don’t
  • Citations: every cited verse / hadith / fatwa was retrieved, at least one is a golden-relevant source, and all required sources are cited
  • Quotes: scripture quoted by the model, before verification — verbatim, altered copy of a real verse, or fabricated — and how many the verifier restored or removed
  • Language: answer matches the question’s language, no CJK leakage

Every answer is saved in the report for manual review.

The labels themselves need expert review: eval/label_review.csv lists every golden label (question, labelled source and its text) with columns for a reviewer’s verdict. Categories with 5–11 cases move 10–20 points on a single case, so read per-category numbers with that in mind.


Docker Deployment

Docker Compose (Recommended)

docker-compose.yml is production-safe by default: it does not bind-mount the repo, and it mounts QModel.index/metadata.json read-only so a dataset update doesn’t require an image rebuild. docker-compose.override.yml is picked up automatically for local dev and layers a full repo bind-mount on top for live code reload.

cp .env.example .env   # Configure backend (see Configuration section)

# Development (live code reload via docker-compose.override.yml)
docker-compose up

# Production (base file only, no bind-mount — runs the image's own code)
docker-compose -f docker-compose.yml up -d

Docker CLI

docker build -t qmodel .

# With Ollama backend
docker run -p 8000:8000 \
  --env-file .env \
  --add-host host.docker.internal:host-gateway \
  qmodel

# With HuggingFace backend
docker run -p 8000:8000 \
  --env-file .env \
  --env HF_TOKEN=your_token_here \
  qmodel

Docker with GGUF

# .env
LLM_BACKEND=gguf
GGUF_MODEL_PATH=./models/Qwen2.5-14B-Instruct-Q8_0.gguf
GGUF_N_CTX=8192
GGUF_N_GPU_LAYERS=-1

The .gguf file must be present under ./models/ before building/running the image (see download command in GGUF Backend) — no external daemon or network access needed at runtime, which is what makes this backend suitable for bundling directly into an HF Space.

Docker with Ollama

# .env
LLM_BACKEND=ollama
OLLAMA_HOST=http://host.docker.internal:11434
OLLAMA_MODEL=arelgendy/qmodel:8.5

Requires Ollama running on the host (ollama serve).

Docker with HuggingFace

# .env
LLM_BACKEND=hf
HF_MODEL_NAME=Qwen/Qwen2.5-14B-Instruct
HF_DEVICE=auto

# Pass HF token
export HF_TOKEN=hf_xxxxxxxxxxxxx
docker-compose up

Docker Compose with GPU (Linux)

The shipped Dockerfile installs the CPU-only torch wheel (paired with faiss-cpu) to keep the image small. That build cannot use a GPU even if one is passed through. For real GPU acceleration, build a variant that installs the CUDA-enabled torch wheel instead (drop the --extra-index-url https://download.pytorch.org/whl/cpu line in the builder stage), then add:

services:
  qmodel:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Production Tips

  • Deploy with docker-compose -f docker-compose.yml up -d so the dev-only docker-compose.override.yml (full repo bind-mount) isn’t applied — the base file already omits it, restarts with on-failure:5, and mounts the data files read-only.
  • Use specific ALLOWED_ORIGINS instead of *

Open-WebUI Integration

QModel is fully OpenAI-compatible and works out of the box with Open-WebUI.

Setup

# Start QModel
python main.py

# Start Open-WebUI
docker run -d -p 3000:8080 --name open-webui ghcr.io/open-webui/open-webui:latest

Connect

  1. Settings → Models → Manage Models
  2. Click “Connect to OpenAI-compatible API”
  3. API Base URL: http://localhost:8000/v1
  4. Model Name: QModel
  5. API Key: Leave blank
  6. Save & Test → ✅ Connected

Docker Compose (QModel + Ollama + Open-WebUI)

version: '3.8'
services:
  qmodel:
    build: .
    ports:
      - "8000:8000"
    environment:
      - LLM_BACKEND=ollama
      - OLLAMA_HOST=http://ollama:11434

  ollama:
    image: ollama/ollama:latest
    ports:
      - "11434:11434"

  web-ui:
    image: ghcr.io/open-webui/open-webui:latest
    ports:
      - "3000:8080"
    depends_on:
      - qmodel

Supported Features

Feature Status
Chat ✅ Full support
Streaming ✅ stream: true
Multi-turn context ✅ Handled by Open-WebUI
Temperature ✅ Configurable
Token limits ✅ max_tokens
Model listing ✅ /v1/models
Source attribution ✅ x_metadata.sources

Architecture

Module Structure

main.py                    ← FastAPI app + router registration
build_index.py             ← Dataset compilation, E5 asymmetric embedding & FAISS indexing
app/
  config.py               ← Config class (env vars)
  llm.py                  ← LLM providers (GGUF, Ollama, HuggingFace)
  cache.py                ← TTL-LRU async cache
  arabic_nlp.py           ← Arabic normalization, stopwords, Quranic root index
  search.py               ← Multi-vector FAISS + BM25, RRF, clustering, windowing, reranker
  analysis.py             ← Intent detection, analytics, counting
  prompts.py              ← Prompt engineering (persona, anti-hallucination)
  models.py               ← Pydantic schemas (Quran, Hadith, Fatwa, Chat)
  state.py                ← AppState, lifespan, multi-turn RAG pipeline
  routers/
    quran.py              ← 6 Quran endpoints
    hadith.py             ← 5 Hadith endpoints
    fatwa.py              ← 3 Fatwa endpoints
    chat.py               ← /ask + OpenAI-compatible chat
    ops.py                ← health, models, debug scores
tests/
  test_enhancements.py    ← Unit tests for multi-vector, windowing, clustering, roots
  test_fatwa.py           ← Unit tests for fatwa endpoints & RAG integration

Data Pipeline

  1. Ingest: Multi-source Islamic knowledge base:
    • Quran: 6,236 verses across 114 Surahs
    • Hadith: 40,943 hadiths across 9 canonical collections
    • Fatwa: Verified rulings from recognized scholars and fiqh councils
  2. Embed: Asymmetric encoding with intfloat/multilingual-e5-large (passage: prefix for indexing, query: prefix for inference)
  3. Index: FAISS IndexFlatIP for inner-product dense vector retrieval + inverted index for BM25

Retrieval & Ranking Pipeline

  1. Conversational Coreference Rewriting: Query rewriter accepts dialogue history to resolve ambiguous pronouns and anaphoric references into standalone topical queries.
  2. Dual-Vector Query Embedding: Encodes both Arabic (query_ar) and English (query_en) query vectors using multilingual-e5-large with the mandatory query: prefix.
  3. Multi-Vector Dense Retrieval: Independent FAISS searches against Arabic and English dense vectors.
  4. Inverted BM25 Sparse Retrieval: BM25 scoring with bilingual stopword removal and Quranic morphological root expansion. The light stemmer only strips an affix when at least 3 letters remain, so short words keep their root letters (فضل, الربا).
  5. Adaptive Reciprocal Rank Fusion (RRF): Merges Arabic dense, English dense, and BM25 sparse hits with dynamic language-weighted multipliers.
  6. Hadith Deduplication & Ayah Windowing:
    • Clusters duplicate Hadith narrations (\(\ge 0.85\) text similarity), tags Muttafaq ‘Alayh (Bukhari + Muslim), and aggregates alternative collection references.
    • Expands top Quran verses with \(\pm N\) adjacent verses (AYAH_WINDOW_SIZE) for complete theological context.
  7. Cross-Encoder Reranking: Rescores the top 25 candidates using BAAI/bge-reranker-v2-m3 (USE_RERANKER, on by default). Five of those slots are reserved for the best BM25-only hits, which RRF would otherwise rank below anything both dense searches found. Each passage is scored with its text in the query’s language first, since the reranker truncates at 512 tokens and a long diacritized verse fills that on its own.
  8. Confidence Gating & Context Assembly: Direct references and verbatim text matches pass; otherwise the best reranker relevance must reach RERANK_MIN_SCORE (or dense similarity DENSE_MIN_SCORE without the reranker). Context carries copyable citation lines: [REF] (verse + URLs), [HADITH_REF] (collection and number in English and Arabic, grade), [FATWA_REF] (source, scholar, URL).

Anti-Hallucination Measures

  • Relevance gate before generation (see step 8 above)
  • Citation format rules and copyable [REF] / [HADITH_REF] / [FATWA_REF] lines in the context
  • Scope rule: non-Islamic requests (poems, sports, trivia) get the fixed “not found” answer; the model must either answer from the context or refuse, never both
  • Quote verification: a quote must appear in a retrieved passage; a near-copy of a retrieved verse or hadith (≥80% of its consonant skeleton) is replaced by the canonical text, anything else by a warning marker. LLMs corrupt scripture while copying it (foreign letters, changed word forms, truncation), so this runs on every answer, streamed or not
  • Fatwa links: when the answer uses a retrieved fatwa (by title or by naming its source) without linking it, the link is appended
  • CJK guard: an answer containing Chinese/Japanese/Korean text is regenerated once at temperature 0, then replaced by a list of the retrieved sources; when streaming, CJK is stripped and generation stops after sustained drift
  • Grade inference from collection name

Performance

Operation Time Backend
Query (cached) ~50ms Both
Query (Ollama) 400–800ms Ollama
Query (HF GPU) 500–1500ms CUDA
Query (HF CPU) 2–5s CPU

Troubleshooting

“Cannot connect to Ollama”

ollama serve                      # Ensure Ollama is running on host
# In Docker, use OLLAMA_HOST=http://host.docker.internal:11434

“HuggingFace model not found”

export HF_TOKEN=hf_xxxxxxxxxxxxx  # Set token for gated models

“Out of memory”

  • Use smaller model: HF_MODEL_NAME=mistralai/Mistral-7B-Instruct-v0.2
  • Use Ollama with neural-chat
  • Reduce MAX_TOKENS to 1024
  • Increase Docker memory limit in docker-compose.yml

“Assistant returns ‘Not found’”

This is expected — QModel rejects low-confidence queries. Try: - More specific queries - Lower RERANK_MIN_SCORE (reranker on) or DENSE_MIN_SCORE (reranker off) in .env - Check raw scores: GET /debug/scores?q=your+query

“Port already in use”

docker-compose down && docker system prune
# Or change port: ports: ["8001:8000"]

Roadmap

  • [ ] Batch processing (multiple questions per request)
  • [ ] Islamic calendar integration (Hijri dates)

Data Sources

  • Qur’an: risan/quran-json & semarketir/quranjson — 114 Surahs, 6,236 verses with Arabic text, transliteration, and English translation.
  • Tafsir: Tafseer Dataset & Quran.com — 5,430 verses enriched with classical Arabic commentaries (Tafsir al-Sa’di, Tafsir al-Mukhtasar, Tafsir al-Jalalayn) + English Tafsir Ibn Kathir.
  • Hadith: AhmedBaset/hadith-json & fawazahmed0/hadith-api — 15 authoritative collections (9 canonical + Riyad al-Salihin, Bulugh al-Maram, Al-Adab al-Mufrad, Ash-Shama’il al-Muhammadiyyah, An-Nawawi’s 40 Hadith, Hadith Qudsi), 46,416 hadiths with 21,264 scholar authenticity grades.
  • Fatwa: 3,598 rulings — Islamweb Fatwa Center (3,534) and Imam Ibn Baz (64).

License

This project uses open-source data from: - Qur’an JSON — Open source - Hadith API — Open source

See individual repositories for license details.


Made with ❤️ for Islamic scholarship.

Version 8.5.0 | October 2026 | Production-Ready