Gemma 4 E2B Dental Triage + K+1 OOS Detection (kplus1-seed-b)

繁體中文牙科分診模型,使用 (K+1)-way training(Zhan et al. 2021, ACL)擴充 Out-of-Scope 拒絕能力。

核心特性

  • 8 個牙科分科:家庭牙科 / 牙周病科 / 牙髓病科 / 口腔顎面外科 / 齒顎矯正科 / 贋復假牙科 / 特殊需求牙科 / 一般行政
  • + 1 個 OTHER 標籤:自動拒絕非牙科分診問題(其他醫療、閒聊、跨領域問題)

Pilot 結果(n=3 seed-paired, 2026-05-14)

跟僅用 prompt 描述 OTHER(無 K+1 訓練資料)的 baseline 比較:

指標 Prompt 控制組 (n=3) (K+1) 訓練組 (n=3) Δ
In-Scope Accuracy 84.04% 83.33% −0.71%(不顯著)
OOS Recall 1.08% 96.33% +95.25%(89× 提升)
OOS Precision 99.9%
False Rejection Rate 0.00% 0.23% +0.23%
Hallucinated outputs 75 / 542 0.7 / 542 幾乎消除

3 對 paired bootstrap(n=10000)顯示 in-scope accuracy 統計上無差異(p > 0.47),證實 K+1 訓練不傷 in-domain 表現。

OOS Recall by subtype(測試集 400 筆,PTT 真實爬取)

Subtype Description OOS Recall
(a) 牙科邊緣(保險、教育、設備) 94%
(b) 其他醫療科(皮膚、骨科、內科) 96%
(c) 一般閒聊 99%
(d) 跨領域(程式、數學、料理) 100%

最困難的 subtype (a)(最接近 in-scope)仍達 94% recall,證實模型不只是學「明顯離題」的 surface features。

使用方法

Unsloth 加速版(4-bit, 6GB GPU 可跑)

from unsloth import FastModel
import torch

MODEL = "howwming/gemma4-e2b-dental-triage-kplus1"

model, tokenizer = FastModel.from_pretrained(
    MODEL,
    load_in_4bit=True,
    max_seq_length=2048,
)

SYSTEM_PROMPT = """你是台灣牙科專業分診助理。請根據病患描述,從以下八個科別中選出最適合的一個:

- 家庭牙科:一般檢查、補牙、洗牙、預防保健、兒童牙科
- 牙周病科:牙齦腫痛/流血、牙周病、植牙評估
- 牙髓病科:牙痛(深層、自發性)、根管治療、牙髓壞死
- 口腔顎面外科:拔牙、智齒、口腔腫瘤、外傷、顎面手術
- 齒顎矯正科:咬合不正、戴牙套、隱適美、暴牙
- 贋復假牙科:假牙、牙橋、全瓷冠、3D 列印牙冠
- 特殊需求牙科:身心障礙、極度恐懼、高齡或慢性病患者牙科
- 一般行政/櫃檯事務:掛號、預約、轉診、保險申請

若問題不屬於上述八個牙科分科的範圍(例如:其他醫療科別、一般閒聊、跨領域問題、或牙科保險費用等非分診需求),請回答 OTHER。

請僅回答「科別:XXX」一行,不要附加說明。"""

REJECT_MSG = "您的問題似乎不在本系統處理的範圍內。本系統專門協助分流以下牙科分科:家庭牙科、牙周病科、牙髓病科、口腔顎面外科、齒顎矯正科、贋復假牙科、特殊需求牙科、一般行政/櫃檯事務。請描述具體的牙齒症狀或問題。"

def predict(user_text: str) -> str:
    messages = [
        {"role": "system", "content": [{"type": "text", "text": SYSTEM_PROMPT}]},
        {"role": "user", "content": [{"type": "text", "text": user_text}]},
    ]
    inputs = tokenizer.apply_chat_template(
        messages, add_generation_prompt=True, tokenize=True,
        return_tensors="pt", return_dict=True
    ).to(model.device)
    out = model.generate(**inputs, max_new_tokens=30, do_sample=False)
    response = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
    label = response.replace("科別:", "").strip()
    if label == "OTHER":
        return REJECT_MSG
    return f"建議掛號:{label}"

print(predict("牙齦最近一直流血,刷牙時更嚴重"))   # 建議掛號:牙周病科
print(predict("想做牙齒矯正,戴牙套要多久?"))      # 建議掛號:齒顎矯正科
print(predict("我背痛了三天,是不是要看骨科?"))    # 拒答訊息
print(predict("今天天氣很好"))                    # 拒答訊息

標準 transformers + PEFT 版

from peft import PeftModel
from transformers import AutoProcessor, AutoModelForCausalLM
import torch

BASE = "google/gemma-4-e2b-it"
ADAPTER = "howwming/gemma4-e2b-dental-triage-kplus1"

processor = AutoProcessor.from_pretrained(BASE)
model = AutoModelForCausalLM.from_pretrained(BASE, torch_dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(model, ADAPTER)
# ...同上 predict()

訓練細節

項目
Base model unsloth/gemma-4-e2b-it(Gemma 4 E2B, 5.2B 參數)
LoRA r / α / dropout 64 / 128 / 0.05
Target modules q/k/v/o_proj + gate/up/down_proj
Trainable params 62M (1.20% of base)
Epochs 5
Batch 1 × grad_accum 16 = effective 16
Optimizer AdamW, lr=2e-4, cosine schedule, warmup_steps=10
Hardware RTX 5080 16GB, bf16
Library Unsloth fast finetune
Seed 202(pilot seed-b)
Selection best-acc checkpoint(val accuracy 87.5% @ epoch 4)

Training data

  • 1,756 in-domain 牙科分診樣本(8 科)+ Augmentation files
  • 236 OTHER 訓練樣本,4 個 subtypes 各 ~60 筆:
    • 牙科邊緣案例(保險、教育、設備)
    • 其他醫療科別
    • 一般閒聊
    • 跨領域問題
  • OTHER training data 全部由 Claude 合成;OOS test 全部來自 PTT 真實貼文 → 強分布隔離

Limitations

  1. Distribution shift artifact risk:訓練 OTHER 為 Claude 合成;雖然測試 PTT 真實 OOS 仍達 96% recall,但對 Claude 不擅長生成的 OOS 風格(typos、code-switching)可能表現較差。
  2. In-scope accuracy ceiling:本 adapter 為 best-acc checkpoint,84% in-scope accuracy;T26 模型(不含 OOS 能力)的 86.62% 仍是 in-domain 上限。
  3. 單一語系/領域:僅在繁體中文牙科分診上驗證。
  4. 單一模型尺寸:僅在 Gemma 4 E2B 5.2B 參數上驗證。
  5. 非診斷性質:本模型僅做掛號分科建議,不取代醫師專業判斷。

引用

@misc{hou2026kplus1dental,
  author = {Hou, HaoMing},
  title = {(K+1)-way OOS Detection for Taiwanese Dental Triage},
  year = {2026},
  publisher = {HuggingFace},
  url = {https://huggingface.co/howwming/gemma4-e2b-dental-triage-kplus1}
}

@inproceedings{zhan2021oos,
  title = {Out-of-Scope Intent Detection with Self-Supervision and Discriminative Training},
  author = {Zhan, Li-Ming and others},
  booktitle = {ACL 2021},
  year = {2021}
}

相關 repo

Framework versions

  • PEFT 0.18.1
  • Unsloth 2026.4.6
  • Transformers 5.5.0
  • Torch 2.10.0+cu128
Downloads last month
48
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Space using howwming/gemma4-e2b-dental-triage-kplus1 1