Views
No views yet
完整代码(训练脚本、数据构建、约束解码推理管线、评测)见 GitHub 仓库: https://github.com/wchyin/exam2json
输入(原始试卷文本) 输出
───────────────────────── ─────────────────────────
二、判断题 → {"question": "路由器通常工作在网络层。",
难度:易 "answer": "对"}
3. 路由器通常工作在网络层。( )
正确答案:对1// 选择题
2{"question": "题干", "options": {"A": "...", "B": "...", "C": "...", "D": "..."}, "answer": "B"}
3// 判断题
4{"question": "题干", "answer": "对"} // answer ∈ {"对", "错"}3./三十九、/第5题)、题型前缀(判断:)、句尾空括号占位(( ))、
小节标题及答案/解析行;句中有内容的括号保留。1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3from peft import PeftModel
4
5ADAPTER = "wchyin/qwen3-0.6b-exam2json-lora"
6
7tok = AutoTokenizer.from_pretrained(ADAPTER)
8model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", torch_dtype=torch.bfloat16, device_map="auto")
9model = PeftModel.from_pretrained(model, ADAPTER).merge_and_unload().eval()
10
11# system prompt 随适配器分发(system_prompt.txt),必须与训练一致
12from huggingface_hub import hf_hub_download
13SYSTEM_PROMPT = open(hf_hub_download(ADAPTER, "system_prompt.txt"), encoding="utf-8").read().strip()
14
15text = "二、判断题\n3. 路由器通常工作在网络层。( )\n正确答案:对"
16messages = [{"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": text}]
17inputs = tok.apply_chat_template(
18 messages, add_generation_prompt=True, enable_thinking=False, # enable_thinking=False 必须!
19 return_tensors="pt", return_dict=True,
20).to(model.device)
21
22out = model.generate(**inputs, max_new_tokens=320, do_sample=False)
23print(tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
24# {"question": "路由器通常工作在网络层。", "answer": "对"}enable_thinking=False 必须传——适配器按无思考块的格式训练,不传会导致模型先输出
<think> 段落再给 JSON。system_prompt.txt——LoRA 是在该前缀下训练的条件分布,
换写法会造成输出偏移。| 项目 | 说明 |
|---|---|
| 基座 | Qwen/Qwen3-0.6B(冻结) |
| 方法 | LoRA(r=16, α=32, dropout=0.05,注入 q/k/v/o/gate/up/down),trl SFTTrainer |
| 可训练参数 | ~10M(约 1.7%) |
| 数据 | 2,108 条模板合成中文试题(选择 930 / 判断 1,178),含噪声增强 |
| 超参 | lr 2e-4 cosine + warmup 100 步,有效 batch 16,3 epoch / 357 步,bf16,梯度检查点 |
| 硬件 | 单卡 RTX 4060 Laptop 8GB |
| 训练曲线 | train loss 3.41→0.12;eval loss 0.589→0.150(单调下降) |
| 指标 | 数值 |
|---|---|
| JSON 可解析 / 结构正确 / answer 正确 | 100% |
| question 完全一致 | 98.8% |
| 选项完全一致 | 95.0% |
| 整条完全一致 | 96.2%(选择 95.0% / 判断 97.5%) |
answer 照抄原文标注的参考答案,模型不做答题。