---
license: apache-2.0
language:
- zh
base_model:
- Qwen/Qwen3-8B
new_version: CongJ-Pan/XiaoHong-v1
pipeline_tag: text-generation
library_name: transformers
tags:
- conversational
- literature
- ancient-chinese
- qwen
---

# XiaoHong-v1 (小紅) - 紅樓夢古漢語知識問答系統

XiaoHong-v1 (小紅) 是基於 **Qwen3-8B** 的大型語言模型，並採用了論文《RA-DIT: Retrieval-Augmented Dual Instruction Tuning (Lin et al., 2023)》中的 LM-FT (Language Model Fine-Tuning) 方法，透過 QLoRA 技術進行領域微調，是一款專為 RAG（檢索增強生成）場景打造的專用語言模型。

該模型專精於《紅樓夢》、中國古典文學、詩詞歌賦、歷史典故及傳統文化等知識領域的問答。同時，模型具備深度推理能力（需要後續透過程式碼方法激活），在給出最終解答前，會先於內在的 `<think>` 標籤中進行邏輯推演與知識梳理，帶來更準確、更有深度的回答。

## 🌟 模型特色

- **專屬人設「小紅」**：具備親切、專業的古典文學助手人格。
- **強制推理思維**：面對複雜問題，我們提供標準的接入方案，會自動於 `<think>` 標籤中進行步驟拆解與深度邏輯推演，再輸出最終精煉的回答。
- **繁體中文語境**：針對繁體中文語境與古典文學語氣進行了深度最佳化。
- **基要事實與深度並重**：面對簡單寒暄（如「你好」）時能直接親切回應；面對學術分析（如《紅樓夢》回目對仗分析）時能展現專業深度。

## 💡 使用方法與 System Prompt

為了讓模型發揮最佳效能，強烈建議在推論時使用與訓練階段**完全一致**的 System Prompt，並採用 `ChatML` 格式。

### 推薦的 System Prompt
```text
你是一位專業的古典文學與知識問答助手。你的名字叫做「小紅」。請始終使用繁體中文回答。遇到需要深度分析與邏輯推演的問題，請先在 <think> 標籤內進行思考；若是簡單的事實擷取或問候，請直接給出答案，不需思考過程。
```

## ⚠️ 進階整合：vLLM 與 HF Endpoints 部署避坑指南 ⚠️

若您打算將模型部署至 [vLLM](https://github.com/vllm-project/vllm) 或是 Hugging Face Inference Endpoints，**請務必閱讀本節**。如果在這些平台上使用標準的 `/v1/chat/completions` API，您將會遇到模型**不思考**或**標籤遺失**的嚴重問題。

### 問題核心
1. vLLM 的 `chat/completions` 在處理 `continue_final_message` 時會吞噬掉 `<think>\n` 的換行符號（`\n`），導致 Qwen3 模型錯亂而放棄思考。
2. vLLM 預設開啟 `skip_special_tokens=True`，會在回傳時將 `</think>` 標籤強制過濾掉，導致前端收到無閉合的輸出，與正式回答混在一起。

### 🚀 經過驗證的正確調用策略（Python - OpenAI SDK 相容格式）

最穩健的做法是**在客戶端使用 Tokenizer 將對話格式化為字串，手動加上 `<think>\n`，並改用底層的 `completions` API**：

```python
from transformers import AutoTokenizer
from openai import OpenAI

# 1. 在本地端載入 Tokenizer 以精確渲染 ChatML
tokenizer = AutoTokenizer.from_pretrained("CongJ-Pan/XiaoHong-v1")
client = OpenAI(base_url="您的vLLM端點網址/v1/", api_key="YOUR_TOKEN")

messages = [
    {"role": "system", "content": "你是一位專業的古典文學與知識問答助手。你的名字叫做「小紅」。請始終使用繁體中文回答。"},
    {"role": "user", "content": "請分析《紅樓夢》中林黛玉葬花的心境與象徵意義。"}
]

# 2. 轉為原始字串
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

# 3. 強制預填思考標籤與關鍵換行（\n 絕不可少）
prompt += "<think>\n"

# 4. 改呼叫 Completions API
response_stream = client.completions.create(
    model="/repository", # 依據您的部署情況設定，例如 HF Endpoints 常掛載在 /repository
    prompt=prompt,
    max_tokens=2048,
    temperature=0.001,
    top_p=0.9,
    stream=True,
    stop=["<|im_end|>", "<|endoftext|>"], # 必須手動賦予防呆終止標記
    extra_body={
        "skip_special_tokens": False # 🚀 救命仙丹：迫使 vLLM 保留 </think> 標籤
    }
)

# 這裡您就會完整接收到從 <think> 直到 </think> 的全部內容了！
```

### 🛡️ 前端顯示：防禦性解析 (Defensive Parsing)

由於 LLM 串流輸出偶爾會發生斷線或由於 stop criteria 導致標籤不完整，強烈建議在前端顯示時，**不要只依賴正則表達式尋找 `</think>`**。觀察模型特徵，思考結束後必定會接連空兩行：

```python
def parse_think_tags(text: str) -> tuple[str, str]:
    if "<think>" in text:
        content = text.split("<think>", 1)[1].strip()
        # 利用連續空行作為思考與正式回答的截斷特徵
        for marker in ["\n\n\n", "\n\n"]:
            if marker in content:
                parts = content.split(marker, 1)
                return parts[0].strip(), parts[1].strip() # 返回 (思考, 回答)
        return content.strip(), "" # 尚在思考中
    return "", text.strip()
```

## 📊 訓練細節 (Training Details)

- **訓練框架**：Unsloth + TRL (SFTTrainer)
- **硬體**：Amazon EC2 g6e.xlarge (1 × NVIDIA A10G 24GB)
- **微調方法**：QLoRA (Rank=64, Alpha=128, Target Modules=All Linear)
- **資料集**：`complete_trainingSet_v4_B.jsonl` (包含高品質 `<think>` 推理路徑的古典文學語料)
- **合併策略**：LoRA 權重已完整合併至 Base Model。

## ⚠️ 限制與免責聲明
- 本模型目前主要支援「繁體中文」回答。若強制要求以外語對答，模型可能偶爾出現語言混用的狀況。
- 本模型針對古典文學進行特化，對於現代科技、醫學或即時新聞等領域可能產生幻覺。