這個專案整理我在研究所機器學習課程中,針對「固定領域文件問答」所做的實驗。核心問題是:當模型需要回答特定文件內容時,應該使用檢索增強生成(Retrieval-Augmented Generation, RAG),還是透過 LoRA 進行監督式微調(Supervised Fine-Tuning, SFT)?
專案保留了從文字資料、PDF 解析、文件切分、向量檢索,到小型語言模型微調的實作過程。公開版著重於方法、程式結構與可重現流程,不公開模型權重、私人資料或受限制的原始文件。
固定領域問答常遇到三個問題:
- 文件內容很多,模型不一定記得或知道最新資訊。
- 只調整提示詞,仍可能產生沒有依據的回答。
- 微調可以改變回答方式,但需要資料、訓練資源與版本管理。
因此我分別實作兩條路線:
| 方法 | 做法 | 適合情境 |
|---|---|---|
| RAG | 先從文件找出相關段落,再交給模型回答 | 文件經常更新、回答需要追溯來源 |
| LoRA / SFT | 使用問答資料微調模型的部分參數 | 回答格式固定、任務範圍明確 |
目前公開內容呈現兩種方法的實作與評估設計。因部分早期實驗使用的資料版本不同,本專案不宣稱已得到正式的優劣結論。
flowchart LR
A[PDF 或文字文件] --> B[清理與文件切分]
B --> C[向量化與 ChromaDB]
C --> D[問題檢索]
D --> E[RAG 回答]
F[領域問答資料] --> G[Gemma 3 270M]
G --> H[LoRA 監督式微調]
E --> I[正確性、穩定性與時間評估]
H --> I
| 順序 | 檔案 | 內容 |
|---|---|---|
| 01 | 01_text_rag_baseline.ipynb |
從純文字開始建立最基本的 RAG 流程 |
| 02 | 02_web_data_vector_store.ipynb |
測試外部資料取得、向量化與 ChromaDB 儲存 |
| 03 | 03_pdf_ingestion_and_chunking.ipynb |
PDF 文字抽取、清理與文件切分 |
| 04 | 04_rag_pipeline_walkthrough.ipynb |
將 RAG 步驟整理成較完整的示範流程 |
| 05 | 05_pdf_rag_pipeline.ipynb |
使用 PDF、Embedding、ChromaDB 與 Qwen 建立問答管線 |
| 06 | 06_pdf_extraction_smoke_test.ipynb |
用小型測試快速確認 PDF 解析流程 |
| 07 | 07_gemma3_lora_sft.ipynb |
使用 Gemma 3 270M 與 LoRA 微調領域問答模型 |
這些 Notebook 是實驗演進紀錄,不代表每一份都必須依序執行。若要先理解完整流程,建議先看 04、05,再看 07。
- 使用 Python 處理文字與 PDF 資料。
- 設計文件切分方式,建立向量資料庫與檢索流程。
- 串接 Qwen 指令模型完成文件問答。
- 使用 Gemma 3 270M、Unsloth 與 LoRA 進行小資料集微調。
- 調整 LoRA rank、alpha、dropout、學習率與訓練步數。
- 規劃回答正確性、檢索命中率、穩定性與執行時間的評估方式。
Python · Jupyter / Colab · Sentence Transformers · ChromaDB · Qwen · Gemma 3 · LoRA · Unsloth · PyTorch
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txtpython -m pytest tests -qRAG Notebook 可在本機 Jupyter 或 Google Colab 執行;LoRA 微調建議使用具備 GPU 的 Colab 環境。請將自己的公開 PDF 或問答資料放入執行環境,不要把敏感文件提交到 GitHub。
- 原始 Notebook 是不同階段的學習紀錄,部分套件版本與路徑仍以 Colab 為主。
- 公開版不包含原始課程資料、訓練資料、模型權重與執行輸出。
- RAG 與 LoRA 的正式比較仍需要使用同一份測試集與一致的評分方式。
- 建立一致的問答測試集,公平比較 RAG 與 LoRA。
- 加入來源引用與「文件中找不到答案」的拒答機制。
- 記錄檢索命中率、回答正確性、延遲與資源消耗。
- 將實驗流程整理成可重複執行的命令列工具或簡易網頁。