Spaces:
Running
Running
| # 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 ที่รันอยู่บนระบบของแอปพลิเคชัน* | |