# Tech Stack Specification: Tipitaka Web Application (Turbovec Edition) ## Phase 1 — All-on-Hugging-Face with Turbovec Backend > **Version:** 3.1.0 (Turbovec Edition) > **Date:** 2026-05-26 > **Status:** Production — Live at [dhammadassana-tipitaka.hf.space](https://dhammadassana-tipitaka.hf.space/) > **Based on Architecture:** V2.5.0 (commit `603ead8`) --- ## 1. Executive Summary Phase 1 ออกแบบให้ทุกอย่างรันอยู่บน **Hugging Face Spaces** ในลักษณะการทำงานใน Process เดียวกัน (In-process) เพื่อความเรียบง่าย เสถียรภาพ และประหยัดค่าใช้จ่าย โดยใช้ **Turbovec** เป็น Vector Database หลัก ซึ่งเป็นชุดค้นหาเวกเตอร์น้ำหนักเบาและประมวลผลเร็วระดับเสี้ยววินาที ระบบสามารถทำงานบน HF CPU Basic (Free Tier) ได้อย่างลื่นไหลโดยไม่ต้องใช้ RAM ปริมาณมหาศาล **สิ่งที่ระบบ Turbovec ยืนยันแล้ว:** - การสืบค้นเวกเตอร์เฉลี่ยอยู่ที่ **~1.43 ms** (เร็วกว่า Qdrant 13.5 เท่า) - RAG Pipeline ทำงานแบบ In-process ผ่าน `sentence-transformers` -> `Turbovec` -> `SQLite Enrichment` -> `ONNX Reranker` -> `DeepSeek` - ประหยัดหน่วยความจำ RAM ของเวกเตอร์เอนจินเหลือเพียง **~14 MB** (ลดลงจาก Qdrant 100 เท่า) - ขนาดไฟล์ดัชนีเวกเตอร์ที่ต้องจัดเก็บลดลงเหลือ **13.2 MB** (ผ่านการ Quantize 4-bit SQ) --- ## 2. Architecture Overview ``` ┌─────────────────────────────────────────────────────────┐ │ Hugging Face Space (CPU Basic) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Vite + React 18 + TypeScript 5 │ │ │ │ (Static Build — Served by FastAPI) │ │ │ └────────────────────┬────────────────────────────┘ │ │ │ HTTP / SSE │ │ ┌────────────────────▼────────────────────────────┐ │ │ │ FastAPI (Python 3.13) │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │ │ │ │ │ SQLite │ │ Turbovec │ │ Sentence- │ │ │ │ │ │ FTS5 │ │ Index │ │ Transformers │ │ │ │ │ │(in-mem) │ │ (.tvim) │ │ (in-process) │ │ │ │ │ └──────────┘ └──────────┘ └───────────────┘ │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ │ │ ONNX Reranker (jina-reranker-v2) │ │ │ │ │ └──────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ │ ▼ External API │ │ DeepSeek API (Pay-as-you-go) │ └─────────────────────────────────────────────────────────┘ Assets: ดาวน์โหลดจาก HF Dataset (dhammawatthumpra/tipitaka-storage) ที่ Startup ``` --- ## 3. Component Specification ### 3.1 Presentation Layer | รายการ | Detail | |--------|--------| | **Framework** | Vite 6 + React 18 + TypeScript 5 | | **Styling** | Tailwind CSS v4 + Framer Motion + Lucide React | | **State** | Zustand (5 stores: Reader, Theme, UI, AI, Search) | | **PWA** | manifest.json + Dharma wheel PWA icons + Safari app touch icons | | **Transitions** | ReaderPanel ปรับใช้ `mode="popLayout"` พร้อมควบคุม loading spinner ด้านนอก เพื่อแก้ปัญหาจอนิ่งขาวบนอุปกรณ์พกพาขณะปัดเปลี่ยนหน้า | --- ### 3.2 API Layer | รายการ | Detail | |--------|--------| | **Framework** | FastAPI (Python 3.13) + Uvicorn | | **Workers** | Single worker (ช่วยให้การโหลดโมเดลตัวแปลงและเวกเตอร์ทำงานร่วมกันได้ประหยัดแรมสูงสุด) | | **Deployment** | HF Space — port 7860 | --- ### 3.3 Data & Retrieval Layer #### SQLite FTS5 (Lexical Search) - ไฟล์: `tipitaka_mcu.db` (~238MB) - โหลดเข้า Memory 100% ผ่าน `sqlite3.backup()` ที่ startup - Pipeline: FTS5 MATCH -> LIKE fallback -> Pali Autocorrect -> dedup -> highlight -> snippet #### Turbovec Index (Vector Search) - ไฟล์ดัชนี: `tipitaka_chunks.tvim` (~13.2 MB) - รูปแบบ: โหลดขึ้นบน Memory ใน Python process โดยตรง ผ่านโมเดล `turbovec.IdMapIndex` (ไม่ใช่ server แยก) - เวกเตอร์ถูกย่อขนาดลงผ่าน 4-bit scalar quantization เหลือ 13.2 MB ทำให้โหลดไวและประหยัดพื้นที่คลาวด์ - การเข้ารหัสพิกัด: แปลงพิกัดของเวกเตอร์เป็น ID ตัวเลขจำนวนเต็มด้วยสูตร `UID = volume_id * 100_000 + page_number` เพื่อไม่ต้องเก็บข้อมูล Payload อื่นๆ บนเวกเตอร์โดยไม่จำเป็น - การแก้ไขพารามิเตอร์ SQLite: แปลงประเภทผลลัพธ์เวกเตอร์ `numpy.uint64` ให้เป็น native `int()` ก่อนค้นหากับฐานข้อมูล `tipitaka_mcu.db` เสมอ เพื่อป้องกันข้อผิดพลาดที่ SQLite จะมองพารามิเตอร์ดังกล่าวเป็นข้อมูลชนิด BLOB #### ONNX Reranker - Model: `jina-reranker-v2-base-multilingual` (ONNX CPU, ~267MB) - Sequence Length: ปรับลดความยาวสูงสุดใน tokenization เหลือ `max_length=256` ช่วยเร่งความเร็วในการประเมินคะแนนบน CPU พื้นฐานได้มากกว่าเดิม 4 เท่า --- ### 3.4 Embedding Layer **ใช้ sentence-transformers in-process เท่านั้น** (ไม่มี Ollama ในระบบ HF Space) | รายการ | Detail | |--------|--------| | **Model** | `jinaai/jina-embeddings-v5-text-small-retrieval` | | **Runtime** | sentence-transformers (PyTorch, in-process) | | **Dimensions** | 1024 dims | | **RAM** | ~1.2 GB | | **Cache** | LRU 256 entries (OrderedDict) เพื่อสกัดการประมวลผลคำคิวรีซ้ำ | --- ### 3.5 Generative AI Layer *(เหมือนเดิม — DeepSeek streaming API ผ่านโมเดล fast/reasoner)* --- ## 4. Data Flow ### 4.1 RAG Pipeline ``` User Query │ ├─► FTS5 MATCH (30 results) [Lexical] │ ├─► ST Embedding → Turbovec Search (30) [Semantic] │ ├─ ตรวจสอบ LRU cache │ └─ tv_index.search() -> return vol & page IDs │ ├─► SQLite Payload Enrichment (ดึง content_text จาก db ด้วย vol & page) ├─► Merge + Deduplicate by (vol, page) │ ├─► ONNX Reranker → sort by score │ └─► Top N context → DeepSeek API → SSE Stream → Browser ``` --- ## 5. Deployment ### 5.1 HF Spaces Configuration - **Visibility**: Protected (ซ่อน Source Code และ Assets) - **Build**: Dockerfile (multi-stage) - **Port**: 7860 ### 5.2 Startup Sequence ``` 1. Dockerfile build: npm ci → vite build → pip install 2. startup.sh: a. download_assets.py → ดึงไฟล์จาก HF Dataset - tipitaka_mcu.db (~238MB) - tipitaka_chunks.tvim (~13.2MB - โหลดแทน snapshot ดั้งเดิม) - ONNX reranker via huggingface_hub (~267MB) b. ลบ Qdrant .lock file (กรณีมีการเปิดฟังก์ชัน Qdrant ไว้ร่วมกัน) c. uvicorn app.main:app --port 7860 3. FastAPI lifespan: a. SQLite → โหลดเข้า :memory: b. Turbovec Index → โหลดเข้าคลาส tv_index ในหน่วยความจำ (~14MB) c. ONNX reranker → โหลดโมเดล d. ST model → โหลด lazy (ครั้งแรกที่มี query) ``` **เวลา Cold Start ของเครื่อง**: ลดลงเหลือเพียง **~1.5–3 นาที** (เนื่องจากไม่ต้องดาวน์โหลดไฟล์ขนาด 1 GB ของ Qdrant snapshot และข้ามขั้นตอนการดึง snapshot restore ขนาดใหญ่) ### 5.3 RAM Budget (CPU Basic = 16GB) ด้วยการใช้ Turbovec ทำให้ขยายขนาดพื้นที่ว่างบน RAM ได้มากถึง 12 GB ซึ่งช่วยเพิ่มเสถียรภาพสูงสุดในการประมวลผลคำตอบ RAG | Component | RAM (Qdrant Embedded) | RAM (Turbovec Edition) | |-----------|--------------------|------------------------| | SQLite in-memory | ~238 MB | ~238 MB | | Vector Index Engine | **~1.2–1.5 GB** | **~14 MB** ✅ | | ST Model (Jina-v5) | ~1.2 GB | ~1.2 GB | | ONNX Reranker | ~500 MB | ~500 MB | | FastAPI + Python overhead | ~300 MB | ~300 MB | | Ubuntu OS | ~500 MB | ~500 MB | | **รวม** | **~4.0–4.2 GB** | **~2.7–2.8 GB** ✅ | | **เหลือ Headroom บนแรม**| **~11.8 GB** | **~13.2 GB** ✅ | --- ## 6. Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `LLM_API_KEY` | — | คีย์ DeepSeek API | | `DATA_DIR` | Auto-detect | โฟลเดอร์เก็บข้อมูล SQLite & Turbovec Index | | `DATABASE_PATH` | Auto-detect | ไฟล์ที่อยู่ของ SQLite | | `SERVE_STATIC` | `true` | ให้ FastAPI ทำหน้าที่เสิร์ฟ Frontend ของ Vite | | `ST_EMBED_MODEL` | `jinaai/jina-embeddings-v5-text-small-retrieval` | โมเดลทำเวกเตอร์บน Hugging Face | | `PORT` | `7860` | พอร์ตของ HF Space | --- ## 7. Cost Summary - **HF PRO Account**: $9.00/เดือน (ประมาณ 315 บาท) เพื่อสิทธิ์การเข้าถึงแบบ Protected - **HF Space Hardware (CPU Basic)**: ฟรี - **DeepSeek API**: จ่ายตามปริมาณประมวลผลโทเค็นจริง - **รวมค่าบริการคงที่**: **$9.00/เดือน** --- ## 8. ข้อจำกัดและแนวทางปรับปรุง | ข้อจำกัด | ผลกระทบ | แนวทางแก้ไข | |---------|---------|-------------| | Cold start ในรอบการเปิดเครื่องใหม่ | ระบบหยุดทำงานชั่วคราวเมื่อรีสตาร์ทหลังไม่มีการใช้งาน 48 ชม. | ใช้ HF Persistent Storage หรือ VPS โฮสต์ส่วนตัว | | SQLite FTS5 และ Turbovec ค้นแยก | ข้อมูลเวกเตอร์อาจแตกต่างเล็กน้อยจากคำดั้งเดิมก่อน enrichment | ทำ Cache เอนทิตีที่ซับซ้อนขึ้น | --- *เอกสารนี้ได้รับการปรับปรุงเพื่อสะท้อนประสิทธิภาพจริงของดัชนี Turbovec ที่รันอยู่บนระบบของแอปพลิเคชัน*