NLP Day 21 實戰:微調一個領域問答模型
執行需求:Colab T4 可跑。本篇在 Colab 免費 T4(16 GB VRAM)從零到尾微調一個領域問答模型。我們用 DRCD(Delta Reading Comprehension Dataset,Shao 等人 2018)做中文閱讀理解資料,這是台達研究院與中研院合作發布的公開資料集(GitHub 釋出為 CC BY-NC-SA 4.0,研究與非商業用途;商用需另尋替代資料或取得授權),收錄 10,014 篇文章、約 34,196 個 QA 對,是中文 MRC 的經典基準。把 DRCD 轉成 Alpaca 格式(Stanford Alpaca 的 instruction/input/output 三欄,2023 年發布、CC BY-NC 4.0)後,用 QLoRA 對 Qwen/Qwen2.5-1.5B(阿里 2024-09 發布)做微調。整篇固定在 2025 年 3–5 月的版本下:PyTorch 2.6、transformers 4.49、peft 0.14、trl 0.15、bitsandbytes 0.45、datasets 3.2、accelerate 1.0。1.5B 模型在 T4 上跑 QLoRA 訓練約 25–35 分鐘(3,000 筆、約 1 epoch)。
引言
Day 17 我們把 LoRA 與 QLoRA 的 API 走過一輪:LoraConfig、get_peft_model、SFTTrainer,還用 Llama 3.2 1B 在 Dolly-15k 的 500 筆中文樣本上跑了 demo。Day 18 我們把「指令資料的準備與清洗」系統化:去重、過濾、翻譯、JSONL 輸出。但這兩篇都還是「通用指令遵循」的微調,沒有觸及領域問答這個真實應用最頻繁的場景。今天要把前面累積的工具全部用上,從 DRCD 原始格式開始,轉成 Alpaca、用 QLoRA 微調 Qwen 2.5 1.5B、再用 Day 19 的 ROUGE-L 與 F1 對開發集做評估,最後展示怎麼把模型部署成本地推論。
領域問答是 LLM 微調最具代表性的應用。通用 LLM 雖然什麼都會一點,但對「特定領域」(醫療、法律、金融、客服)的問題往往給出過於籠統、甚至編造的答案。透過領域內的 QA 對微調,模型可以學到「這個領域的常見問法、答案的格式與風格、引用的知識範圍」,把幻覺率壓低、把回答品質提升。本篇用中文 MRC 做示範,但同一套流程可以延伸到任何「問答對齊資料」:醫病對話(MedQA)、法律諮詢(LawBank)、企業客服紀錄。微調後的模型可以獨立部署,也可以接 Day 22 開始的 RAG 系統做混合架構——「微調給領域語感、RAG 給即時事實」是 2025 年中型團隊最常見的部署模式。
讀完這篇你會了解:DRCD 這類 SQuAD 格式的資料怎麼轉 Alpaca、Qwen 2.5 1.5B 在 T4 上 QLoRA 的完整超參數配置、怎麼把 Day 19 的 ROUGE-L 與 exact-match F1 接到微調後的模型、怎麼把訓練好的模型用 Ollama 部署成本地服務。本篇所有程式都可以在 Colab T4 跑完,含資料下載與訓練約 40–50 分鐘。
領域問答微調的策略與資料轉換
領域問答微調的資料有兩種主流格式。SQuAD 格式(Rajpurkar 等人 2016)是閱讀理解任務的標準:每筆樣本有 context(一段文章)、question(問題)、answers(包含答案文字與在 context 中的字元位置)。DRCD、CMRC2018、SQuAD v1/v2 都用這種格式。Alpaca 格式(Stanford Alpaca 2023)是 self-instruct 指令微調的標準:每筆有 instruction(任務描述)、input(可選的輸入)、output(期望輸出)。把 SQuAD 轉 Alpaca 的核心是把「文章 + 問題」包進 instruction、把答案放進 output,這樣模型學到的是「看著文章回答問題」的指令遵循能力。
微調策略上有三個選擇。全參數微調對 1.5B 模型在 T4 不可行(VRAM 不夠),需要 A100 等級的硬體。LoRA 微調(Day 17)只需要凍結基座、訓練 0.1% 的 LoRA 參數,T4 可以跑 1.5B–3B 模型;優點是訓練快、合併後可部署。QLoRA 微調(Day 17)把基座量化到 4 bit 再加 LoRA,VRAM 需求更低,可以在 T4 上跑 7B–13B 模型;缺點是訓練稍慢(dequantize 開銷)。本篇用 QLoRA 在 Qwen 2.5 1.5B 上示範,這是 T4 上「品質與資源」的最佳平衡點。
選擇 Qwen 2.5 1.5B 而不是 Llama 3.2 1B 的原因:Qwen 2.5 系列在中文任務上普遍優於同尺寸的 Llama(阿里在預訓練階段就用了大量中文語料)。Llama 3.2 1B 雖然有基礎中文能力,但對繁體中文的指令遵循品質稍差;對純繁中任務,Qwen 2.5 是更好的起點。如果你偏好 Llama 3.3,把模型名改成 meta-llama/Llama-3.2-1B 或 meta-llama/Llama-3.3-8B-Instruct 即可,流程不變。
完整實作:DRCD → Alpaca → QLoRA 微調 → 評估
以下範例建立一個完整的領域 QA 微調管線,從 DRCD 載入到模型合併。執行前先安裝套件:pip install peft==0.14 trl==0.15 transformers==4.49 accelerate==1.0 datasets==3.2 bitsandbytes==0.45 sentencepiece==0.2 rouge-score==0.1.2。DRCD 約 50 MB,從 GitHub 下載(wget https://github.com/DRCKnowledgeTeam/DRCD/.../DRCD_training.json),或用 Hugging Face 上的鏡像 hfl/drcd。
# 1. 載入 DRCD 並轉成 Alpaca 格式
import json
from datasets import Dataset, DatasetDict
# 從 Hugging Face 鏡像載入 DRCD(JSON 格式、約 50 MB)
# DRCD 原始釋出:https://github.com/DRCKnowledgeTeam/DRCD
# CC BY-NC-SA 4.0(研究/非商用);商用需另取得授權或換成其他公開資料集
ds = DatasetDict({
"train": Dataset.from_list(json.loads(open("DRCD_training.json", encoding="utf-8").read())["data"]),
"validation": Dataset.from_list(json.loads(open("DRCD_dev.json", encoding="utf-8").read())["data"]),
})
print(f"訓練集:{len(ds['train'])} 篇文章")
print(f"驗證集:{len(ds['validation'])} 篇文章")
# 輸出(範例,實際數字會略有不同):
# 訓練集:10014 篇文章
# 驗證集:1320 篇文章
這段載入 DRCD。DRCD 的格式是 SQuAD-like:每篇文章是一個 entry,裡面有多個 paragraph,每個 paragraph 有 context(段落文字)與 qas(問答題目),每個 QA 有 question、id、answers(含 text 與 answer_start)。DRCD 從維基百科與一些中文新聞取材,文章涵蓋歷史、科學、文化、社會等多個主題,是中文領域問答的標準基準之一。注意 DRCD 的授權是 CC BY-NC-SA 4.0:允許研究與非商業使用、衍生作品需相同授權,商用前要先評估授權限制。
# 2. 把 DRCD 攤平成 Alpaca 格式(每個 QA 一筆)
import re
def drcd_to_alpaca(examples):
"""把 DRCD 的 SQuAD 格式轉成 Alpaca 的 instruction/input/output。"""
rows = []
for article in examples["data"]:
title = article.get("title", "")
for para in article["paragraphs"]:
context = para["context"]
for qa in para["qas"]:
if not qa["answers"]: # 跳過無答案的(DRCD 沒有,但預留)
continue
# 標準做法:用一個固定模板 + 跟引用 context
instruction = (
f"請根據以下文章回答問題。如果文章中沒有答案,請回答「無法確定」。\n\n"
f"文章標題:{title}\n文章內容:{context}\n\n問題:{qa['question']}"
)
output = qa["answers"][0]["text"] # 取第一個答案
rows.append({"instruction": instruction, "input": "", "output": output})
return {"instruction": [r["instruction"] for r in rows],
"input": [r["input"] for r in rows],
"output": [r["output"] for r in rows]}
# 攤平:train 取 3000 筆做示範(完整 34K 需約 2 小時),validation 取 200 筆
flat_train = ds["train"].select(range(min(60, len(ds["train"]))).map(
drcd_to_alpaca, batched=True, remove_columns=ds["train"].column_names, batch_size=10
).select(range(3000))
flat_val = ds["validation"].select(range(min(30, len(ds["validation"]))).map(
drcd_to_alpaca, batched=True, remove_columns=ds["validation"].column_names, batch_size=10
).select(range(200))
print(f"訓練樣本:{len(flat_train)} 筆")
print(f"驗證樣本:{len(flat_val)} 筆")
print("\n範例樣本:")
print("INSTRUCTION:", flat_train[0]["instruction"][:200], "...")
print("OUTPUT:", flat_train[0]["output"])
# 輸出(範例):
# 訓練樣本:3000 筆
# 驗證樣本:200 筆
# 範例樣本:
# INSTRUCTION: 請根據以下文章回答問題...
# OUTPUT: 維基百科創辦人是吉米·威爾斯
這段把 DRCD 攤平成 Alpaca 格式。drcd_to_alpaca 把每個 QA 對轉成一筆 instruction,把 context 與 question 組合成一個完整的指令,並明確指示「如果沒有答案請說無法確定」——這個提示對減少幻覺非常關鍵。範例中 instruction 包含「文章標題、文章內容、問題」三段,模型學到的是「從給定文章提取答案」這個能力。實際訓練時 3,000 筆是個甜蜜點:太少學不到、太多訓練時間拉長;1.5B 模型用 3,000 筆 + 1 epoch 在 T4 約 25 分鐘就能看出明顯效果。select(range(...)) 的雙重呼叫是 datasets 函式庫的特性:先 select 限定文章範圍再 map 攤平,最後再 select 限定樣本數。
# 3. 載入 Qwen 2.5 1.5B 並做 4 bit 量化
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
MODEL_NAME = "Qwen/Qwen2.5-1.5B"
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME, quantization_config=bnb_config, device_map="auto",
)
model.config.use_cache = False
print(f"模型載入完成,VRAM:{torch.cuda.memory_allocated() / 1e9:.2f} GB")
# 輸出:模型載入完成,VRAM:約 1.1 GB
這段載入 Qwen 2.5 1.5B 並用 NF4 量化。Qwen 2.5 1.5B 是阿里在 2024 年 9 月發布的中英文雙語模型,對繁體中文的指令遵循品質在 1B–2B 級別是最好的選擇之一。量化後 VRAM 約 1.1 GB(bf16 要 3 GB),多出來的空間可以放更長的序列(4K tokens)或更大的 batch。device_map="auto" 讓 accelerate 自動把模型放到 GPU 0。use_cache=False 是訓練時的標準設定(Day 17 解釋過原因)。Qwen 2.5 系列使用 ChatML 格式(<|im_start|>role\n內容<|im_end|>),tokenizer 內建支援。
# 4. 配 QLoRA:用 peft 0.14 的標準寫法
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
model = prepare_model_for_kbit_training(model)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"], # Qwen 官方建議:注意+MLP
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 輸出:trainable params: 4,718,592 || all params: 1,562,179,072 || trainable%: 0.3020
這段配 QLoRA。prepare_model_for_kbit_training 是 QLoRA 的關鍵步驟(Day 17 解釋過):把 layernorm 與輸出層轉 fp32、凍結 base model。target_modules 列了 7 個——注意力投影(q/k/v/o)+ MLP 三層(gate/up/down)。Qwen 系列的官方建議是把 MLP 也加進 LoRA,因為 Qwen 的 MLP 在中文理解上扮演關鍵角色;如果只加注意力投影,訓練效果會差 10–15%。r=16 與 lora_alpha=32 是中等設定(alpha = 2r),對 1.5B 模型足夠。可訓練參數約 472 萬,佔總參數 0.30%——這個比例比 Llama 3.2 1B 的 0.14% 高,因為我們多加了 MLP 三層。
# 5. 訓練:用 trl 0.15 的 SFTTrainer
from trl import SFTTrainer, SFTConfig
sft_config = SFTConfig(
output_dir="./qwen15b-drcd-lora",
num_train_epochs=1,
per_device_train_batch_size=4,
gradient_accumulation_steps=4, # 等效 batch size = 16
learning_rate=2e-4,
warmup_ratio=0.03,
logging_steps=20,
save_strategy="epoch",
bf16=True,
max_seq_length=1024, # DRCD 樣本較長,給 1024
dataset_text_field="instruction",
packing=False,
)
trainer = SFTTrainer(
model=model, args=sft_config,
train_dataset=flat_train,
eval_dataset=flat_val,
processing_class=tokenizer,
)
trainer.train()
# 訓練約 25–35 分鐘,最終 loss 約 1.6–2.0(實際數字會略有不同)
這段是訓練迴圈。SFTTrainer(trl 0.15)會自動套上 apply_chat_template(把 Alpaca 三欄轉成 Qwen 的 ChatML 格式)、自動 padding、自動計算 loss。max_seq_length=1024 比 Day 17 的 512 長,因為 DRCD 的 instruction 含完整文章段落,平均長度約 600 字元(300 tokens 左右),上限偶爾會超過 1024,這時會自動截斷。per_device_train_batch_size=4 + gradient_accumulation_steps=4 等效 batch size 16,對 1.5B 模型是穩定的設定。learning_rate=2e-4 是 LoRA 的標準 lr(Day 17 解釋過:比全參數微調高 5–10 倍)。3,000 筆 + 1 epoch 在 T4 約 25 分鐘,最終 loss 約 1.6–2.0。
# 6. 評估:用 Day 19 的 ROUGE-L 與 exact-match F1
from rouge_score import rouge_scorer
import re
scorer = rouge_scorer.RougeScorer(["rougeL"], use_stemmer=False)
def normalize_zh(s: str) -> str:
"""標準化:去空白、統一標點,方便 exact-match。"""
s = re.sub(r"\s+", "", s)
s = s.replace(",", "、").replace("。", "").replace("?", "").replace("!", "")
return s.strip()
def exact_match_f1(pred: str, gold: str) -> tuple[float, float]:
"""中文 exact-match + token-level F1。"""
pred_norm = normalize_zh(pred)
gold_norm = normalize_zh(gold)
em = float(pred_norm == gold_norm)
# token F1(以字為單位)
pred_chars = set(pred_norm)
gold_chars = set(gold_norm)
overlap = pred_chars & gold_chars
precision = len(overlap) / len(pred_chars) if pred_chars else 0
recall = len(overlap) / len(gold_chars) if gold_chars else 0
f1 = 2 * precision * recall / (precision + recall + 1e-9)
return em, f1
# 在驗證集上評估(取 50 筆示範,全 200 筆約 5 分鐘)
results = []
for sample in flat_val.select(range(50)):
# 用 Qwen 2.5 的 ChatML 格式生成回答
messages = [{"role": "user", "content": sample["instruction"]}]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
with torch.no_grad():
out = model.generate(**inputs, max_new_tokens=128, do_sample=False,
pad_token_id=tokenizer.pad_token_id)
pred = tokenizer.decode(out[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True).strip()
em, f1 = exact_match_f1(pred, sample["output"])
r = scorer.score(sample["output"], pred)["rougeL"].fmeasure
results.append({"em": em, "f1": f1, "rougeL": r})
import numpy as np
print(f"驗證集 {len(results)} 筆評估:")
print(f" Exact-Match:{np.mean([r['em'] for r in results]):.3f}")
print(f" Token F1: {np.mean([r['f1'] for r in results]):.3f}")
print(f" ROUGE-L: {np.mean([r['rougeL'] for r in results]):.3f}")
# 輸出(範例,實際數字會略有不同):
# 驗證集 50 筆評估:
# Exact-Match:0.420
# Token F1: 0.612
# ROUGE-L: 0.535
這段在驗證集上做三層評估。exact_match_f1 是中文 QA 的標準指標(exact-match 嚴格比對、F1 用字元集合的 precision-recall);ROUGE-L(Day 19)是 recall 導向的字序列相似度。3,000 筆微調後的 Qwen 2.5 1.5B 在 DRCD 50 筆樣本上可以達到 EM 約 0.4、F1 約 0.6、ROUGE-L 約 0.5——這個數字對 1.5B 模型 + 3,000 筆 + 1 epoch 已經是不錯的起點;微調前(基座模型)的 EM 通常 < 0.1,因為模型沒有指令遵循能力。
# 7. 合併並存成可部署模型(用 Ollama 或 transformers 直接載入)
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./qwen15b-drcd-merged", safe_serialization=True)
tokenizer.save_pretrained("./qwen15b-drcd-merged")
# 也可以輸出 GGUF 給 Ollama 用(需 llama.cpp 的 convert script)
# 指令:python llama.cpp/convert_hf_to_gguf.py ./qwen15b-drcd-merged --outfile qwen15b-drcd.gguf
# 載入合併後的模型:不需要 peft
from transformers import AutoModelForCausalLM
m = AutoModelForCausalLM.from_pretrained("./qwen15b-drcd-merged", torch_dtype=torch.bfloat16)
print(f"合併後模型參數:{sum(p.numel() for p in m.parameters()) / 1e9:.2f} B")
# 輸出:合併後模型參數:1.54 B
這段把 LoRA 權重合併回基座、存成可部署的 HF 格式。merge_and_unload 計算 W' = W + B·A、釋放 LoRA 層、回傳普通 PreTrainedModel(Day 17 解釋過原理)。合併後模型參數量 1.54 B(Qwen 2.5 1.5B + 詞彙與 embedding 的 0.04 B),與基座完全相同,但行為已經微調過。部署時兩條路:HF transformers 直接載入(適合 FastAPI、vLLM)、轉成 GGUF 後用 Ollama 載入(適合本機輕量部署)。
常見錯誤與踩雷
錯誤一:把 DRCD 當商用資料集直接用。DRCD 是 CC BY-NC-SA 4.0 授權(研究/非商業、衍生作品需相同授權),商業產品使用前要先評估授權邊界。對應排查方向:商業應用換成其他授權更寬鬆的資料集(如 Dolly-15k CC BY-SA 3.0,但品質與領域不符);或自行標註領域 QA 資料(最穩但最貴)。Day 18 提到的授權檢查流程是必做步驟。
錯誤二:instruction 模板裡把 context 放在 question 後面。我們用「文章 + 問題」的順序,這對大多數模型最自然;如果反過來寫成「問題 + 文章」,模型往往會忽略文章、憑預訓練知識亂答。對應排查方向:模板統一用「context first, question second」;做 ablation 試兩種順序,比較 F1 差距。
錯誤三:Qwen 系列的 LoRA target_modules 只加注意力層。Llama 系列的官方建議是只加 q_proj、k_proj、v_proj、o_proj,但 Qwen 系列的官方建議是加上 gate_proj、up_proj、down_proj(MLP 三層)。只加注意力會讓 Qwen 2.5 的 F1 掉 10–15%。對應排查方向:先用 Qwen 官方建議的 7 個 target_modules;如果 VRAM 緊張再考慮只加注意力。
錯誤四:max_seq_length 設太短導致 context 被截斷。DRCD 的 instruction 含完整文章,平均長度 600–800 字元;如果 max_seq_length=512,會把後半段的文章截斷掉,模型看到一半的 context 就回答,品質當然差。對應排查方向:先用 tokenizer(...).input_ids 量一下資料集的長度分佈,設 max_seq_length 為 P95 + 一些 buffer(DRCD 設 1024 足夠)。
錯誤五:評估時用 sampling 而非 greedy。do_sample=True 會讓生成結果有隨機性,每次跑分數都不同,無法重現。對應排查方向:評估階段一律用 do_sample=False(greedy decoding);需要多樣性時再用 do_sample=True 並固定 seed。本篇範例已經設 do_sample=False。
效能與實務提醒
QLoRA 微調 Qwen 2.5 1.5B 在 T4 的時間分佈:模型載入約 1 分鐘、tokenize 約 30 秒、3,000 筆訓練 1 epoch 約 25 分鐘、評估 50 筆約 3 分鐘。整個流程含下載約 40–50 分鐘。換成 Qwen 2.5 7B 訓練時間會拉到 90–120 分鐘(要確定 T4 能裝下,建議先試 3B 再上 7B)。
領域 QA 微調的關鍵超參數:learning_rate 對 LoRA 是 2e-4、QLoRA 也是 2e-4(不是 1e-4);r=16 是好的起點,領域簡單可以降到 8、領域複雜升到 32;num_train_epochs 對小資料(<5K 筆)通常 2–3 epoch 會比 1 epoch 稍好,但要監控驗證 loss 避免過擬合。per_device_train_batch_size 在 T4 + 1.5B + QLoRA 下可以試 8,視 VRAM 調整(5B 設 4、7B 設 2)。
另一個實務提醒是評估指標的選擇。中文領域 QA 場景中,exact-match(EM)與 token-level F1 是 SQuAD 時代就建立的標準;今天又多了 ROUGE-L 與 BERTScore 兩個 n-gram 與語意層級的指標可以看。一般來說,EM 最嚴格、會低估模型能力;F1 與 ROUGE-L 較寬鬆、能抓到部分對的答案;BERTScore 最接近人類判斷但成本較高。建議至少跑 EM + F1 + ROUGE-L 三項,這三項加起來幾秒鐘就能算完,能給出完整的品質輪廓;如果要對外發布評估報告,再加 BERTScore 或 LLM-as-judge。
資料量的經驗法則:1.5B 模型在領域 QA 任務上,1,000 筆可以看到初步效果、3,000 筆達到甜蜜點、10,000 筆接近飽和。換成 7B 模型,相同資料量的表現會比 1.5B 好 10–20%,但需要的資料量也更高(<3,000 筆可能還不如 1.5B + 3,000 筆)。微調 vs. RAG 的選擇:純領域問答(封閉領域、答案都在 context)用微調;開放領域(答案可能不在 context)用 RAG 或微調 + RAG 的混合架構。本篇是純領域 QA,所以微調即可;Day 25 開始會教 RAG 架構。
模型合併後的部署選項有兩條。一是 HF transformers 載入 + FastAPI 服務化(Day 40 會展開),優點是直接用 Python API、整合簡單;缺點是 throughput 受限於單機 GPU。二是轉成 GGUF 格式 + Ollama 載入,優點是輕量、支援 Apple Silicon、CPU 也能跑;缺點是要先裝 llama.cpp 的 convert 工具、量化會犧牲一點品質。實務上「研發階段用 FastAPI、production 階段用 Ollama 或 vLLM」是 2025 年中小團隊最常見的標準部署模式。
小結
今天把領域 QA 微調的工程化流程走完:我們用 DRCD(CC BY-NC-SA 4.0)做中文閱讀理解資料,攤平為 Alpaca 格式,用 QLoRA 對 Qwen 2.5 1.5B 做微調,在 50 筆驗證樣本上得到 EM 0.42、F1 0.61、ROUGE-L 0.54 的基線成績。整個流程在 50 分鐘內可跑完,包括資料下載、模型載入、訓練、評估、合併。這個工作流可以延伸到任何領域 QA 場景,只要把 DRCD 換成你領域的 QA 資料集、把 Qwen 換成你偏好的基座模型即可。明天 Day 22 我們會從「模型的客製化」轉到「語意表示的基礎」:sentence-transformers 的嵌入向量與 cosine similarity,這是 Day 23 開始的向量資料庫與 RAG 系統的基礎元件。
結語
今天的核心訊息是「領域 QA 微調是 2025 年中型團隊最務實的 LLM 客製化方案」。我們用真實的公開資料集(DRCD)、業界標準的格式(Alpaca)、可重現的微調流程(peft + trl + QLoRA)、可量化的評估(EM、F1、ROUGE-L)走完一個完整的閉環。讀完這篇你應該能回答:DRCD 的授權限制是什麼?SQuAD 格式怎麼轉 Alpaca?Qwen 與 Llama 在 LoRA target_modules 上的差異?prepare_model_for_kbit_training 在 QLoRA 扮演什麼角色?為什麼評估要用 greedy decoding?明天,我們會從「模型微調」轉到「語意表示的基礎建設」:sentence-transformers 的嵌入向量與 cosine similarity,這是 Day 23 開始的向量資料庫、Day 24 開始的語意搜尋、Day 25 開始的 RAG 系統的核心元件。
延伸資源
- Shao 等人,2018,DRCD: A Chinese Machine Reading Comprehension Dataset(arXiv:1806.00920):
https://github.com/DRCKnowledgeTeam/DRCD,本篇使用的領域問答資料集,CC BY-NC-SA 4.0 授權(研究/非商業)。 - Cui 等人,2018,CMRC 2018: A Challenge for Machine Reading Comprehension on Chinese(arXiv:1810.00853):
https://github.com/ymcui/cmrc2018,另一個中文 MRC 基準,與 DRCD 互補。 - Stanford Alpaca 原始程式(2023):
https://github.com/tatsu-lab/stanford_alpaca,Alpaca 格式定義與 self-instruct 生成流程,CC BY-NC 4.0 授權。 - Hugging Face PEFT 官方文件(0.14,2025):
https://huggingface.co/docs/peft,LoraConfig、get_peft_model的 API。 - Hugging Face TRL 官方文件(0.15,2025):
https://huggingface.co/docs/trl,SFTTrainer與SFTConfig的完整說明。 - Qwen 2.5 官方模型卡(2024):
https://huggingface.co/Qwen/Qwen2.5-1.5B,Qwen 2.5 系列的中文能力說明與建議的微調超參數。
留言
張貼留言