File size: 13,754 Bytes
a43002d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# 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 ที่รันอยู่บนระบบของแอปพลิเคชัน*