项目目标与规格
目标:微调 Qwen2.5-7B 为中国劳动法律咨询助手
- 能力:准确引用劳动法条款,解答劳动纠纷问题
- 规模:训练数据 ~3000 条,QLoRA 微调
- 硬件:Google Colab T4 GPU(免费)
- 部署:GGUF + Ollama 本地运行
第一步:数据收集与构建
import anthropic
import json
client = anthropic.Anthropic()
LABOR_LAW_TOPICS = [
"劳动合同签订与解除", "试用期规定", "工资待遇",
"加班费计算", "工伤认定", "社保缴纳",
"竞业限制", "劳动仲裁程序", "女职工保护", "裁员补偿"
]
def generate_qa_pair(topic: str) -> list:
"""为指定主题生成 5 个问答对"""
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=3000,
messages=[{"role": "user", "content": f"""
针对主题"{topic}"生成5个真实劳动者可能问的问题及专业法律回答。
格式:JSON 数组,每条包含 instruction 和 output。
要求:
- 问题要真实具体(有场景细节)
- 回答要准确引用法条,给出实操建议
- 回答不少于 200 字"""}]
)
return json.loads(response.content[0].text)
# 生成训练数据
all_data = []
for topic in LABOR_LAW_TOPICS:
pairs = generate_qa_pair(topic)
all_data.extend(pairs)
print(f"{topic}: {len(pairs)} 条")
# 加入系统提示
SYSTEM = "你是一位专业的中国劳动法律顾问,熟悉《劳动法》《劳动合同法》及相关司法解释。"
formatted = []
for item in all_data:
formatted.append({
"conversations": [
{"from": "system", "value": SYSTEM},
{"from": "human", "value": item["instruction"]},
{"from": "gpt", "value": item["output"]}
]
})
with open("labor_law_train.jsonl", "w") as f:
for item in formatted:
f.write(json.dumps(item, ensure_ascii=False) + "\n")
第二步:QLoRA 训练
from unsloth import FastLanguageModel
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth.chat_templates import get_chat_template
from unsloth import train_on_responses_only
# 加载 Qwen2.5-7B(Unsloth 预量化版)
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Qwen2.5-7B-Instruct-bnb-4bit",
max_seq_length=2048,
load_in_4bit=True
)
tokenizer = get_chat_template(tokenizer, chat_template="qwen-2.5")
model = FastLanguageModel.get_peft_model(
model, r=16, lora_alpha=32,
target_modules=["q_proj","k_proj","v_proj","o_proj",
"gate_proj","up_proj","down_proj"],
use_gradient_checkpointing="unsloth", random_state=42
)
from datasets import load_dataset
dataset = load_dataset("json", data_files="labor_law_train.jsonl", split="train")
def apply_template(examples):
texts = [tokenizer.apply_chat_template(
c, tokenize=False, add_generation_prompt=False
) for c in examples["conversations"]]
return {"text": texts}
dataset = dataset.map(apply_template, batched=True)
trainer = SFTTrainer(
model=model, tokenizer=tokenizer,
train_dataset=dataset, dataset_text_field="text",
max_seq_length=2048,
args=TrainingArguments(
output_dir="./labor-law-model",
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=2e-4,
lr_scheduler_type="cosine",
bf16=True, logging_steps=20,
)
)
trainer = train_on_responses_only(trainer,
instruction_part="<|im_start|>user\n",
response_part="<|im_start|>assistant\n"
)
trainer.train()
第三步:合并并转 GGUF
# 合并 LoRA 并保存
model.save_pretrained_merged("labor-law-merged", tokenizer, save_method="merged_16bit")
# 转换为 GGUF(Unsloth 内置支持)
model.save_pretrained_gguf("labor-law-q4", tokenizer, quantization_method="q4_k_m")
# 输出文件:labor-law-q4.gguf(约 4.5 GB)
第四步:Ollama 部署
# 创建 Modelfile
cat > Modelfile <<'EOF'
FROM ./labor-law-q4.gguf
SYSTEM """你是一位专业的中国劳动法律顾问,熟悉《劳动法》《劳动合同法》
及相关司法解释。回答问题时请准确引用法条,并给出实操建议。"""
PARAMETER temperature 0.3
PARAMETER top_p 0.9
EOF
# 创建 Ollama 模型
ollama create labor-law-expert -f Modelfile
# 测试
ollama run labor-law-expert "公司以试用期不合格为由解雇我,我有什么权利?"
效果验证
import requests
def ask_expert(question: str) -> str:
response = requests.post(
"http://localhost:11434/api/generate",
json={"model": "labor-law-expert", "prompt": question, "stream": False}
)
return response.json()["response"]
# 测试用例
test_cases = [
"被公司强制要求加班不给加班费怎么办?",
"劳动合同到期公司不续签,我能拿到经济补偿金吗?",
"工作满 10 年是否可以要求签无固定期限劳动合同?",
]
for q in test_cases:
print(f"\nQ: {q}")
print(f"A: {ask_expert(q)[:300]}...")
项目总结
完整流程:Claude 生成合成数据(3000条)→ Unsloth QLoRA 训练(Colab T4,约 2 小时)→ 合并 + GGUF 量化 → Ollama 本地部署。整个项目成本约 $5-15(API 调用费),即可获得一个专业领域助手。
课程完结
恭喜完成《LLM 微调实战》全部 10 章!从微调原理到生产部署,你已掌握完整的微调工程体系。下一步:用自己的真实业务数据,构建你的专属 AI 助手。