AI 学习路线 · 深入
Part 15 · 模型微调 Fine-Tuning
目标:理解"什么时候必须微调、怎么选基座、怎么备数据",并完整跑通一次业务微调。
Section 1 · 微调 vs RAG vs Prompt(边界再理清)
Subsection 1 · 记判断表
需求类型 用啥临时改风格/格式 Prompt要答私有知识/新资料 RAG要固定输出格式/领域术语 微调要模型学会新能力/新知识 微调要低成本快速验证 先 Prompt → 不够再 RAG → 再微调- 顺序永远是:先用最轻的,不够再上重的。
Subsection 2 · 过关自测 判断 4 个场景该用啥(答案:1 客服固定话术→微调 2 公司制度问答→RAG 3 翻译→Prompt 4 让模型识别专业医学术语→微调)。
过关:能对号入座 = Section 1 完成。
Section 2 · 选基座模型
Subsection 1 · 记选型
中文通用/业务 Qwen2.5 系列(首选)中文对话 ChatGLM 系列英文通用 Llama3 系列推理强 DeepSeek 系列(较大,需好显卡)小体量快速试 Qwen2.5-0.5B / 1.5B- 结论:没特殊理由就选 Qwen——教程多、社区大、中文好。
Subsection 2 · 定你的实验模型
写笔记:我接下来微调实验用 Qwen2.5-1.5B-Instruct(显存要求低,适合学习)。
过关:能说出选型理由 = Section 2 完成。
Section 3 · 微调数据格式(JSONL)
Subsection 1 · 记格式 微调数据通常是 JSONL(每行一个 JSON),对话格式叫 ChatML:
{"messages": [{"role": "user", "content": "问题"}, {"role": "assistant", "content": "答案"}]}{"messages": [{"role": "user", "content": "另一个问题"}, {"role": "assistant", "content": "另一个答案"}]}Subsection 2 · 造 10 条示例数据
新建 train_data.jsonl,内容:
{"messages": [{"role": "user", "content": "你好"}, {"role": "assistant", "content": "您好,请问有什么可以帮您?"}]}{"messages": [{"role": "user", "content": "怎么退款"}, {"role": "assistant", "content": "亲,请在订单页点击申请退款,1-3个工作日到账。"}]}(再补 8 条类似客服对话)
过关:能写出标准 JSONL = Section 3 完成。
Section 4 · 准备你自己的数据集
Subsection 1 · 写脚本生成
新建 make_data.py:把你的"客服问答"整理成 JSONL:
import jsonpairs = [ ("你们几点发货", "我们工作日下午4点前下单当天发货。"), ("能开发票吗", "可以,下单时填写抬头,随货寄出。"), ("支持七天无理由吗", "支持,未拆封7天内可申请。"), # ... 再加 10~20 条]with open("train_data.jsonl", "w", encoding="utf-8") as f: for q, a in pairs: f.write(json.dumps({"messages": [ {"role": "user", "content": q}, {"role": "assistant", "content": a}, ]}, ensure_ascii=False) + "\n")print("生成完成,共", len(pairs), "条")Subsection 2 · 数据量建议
少样本风格微调:100~500 条高质量即可领域能力提升:1000~10000 条原则:宁可少而精,不要多而脏过关:数据集生成 + 了解数据量 = Section 4 完成。
Section 5 · 数据清洗与去重(代码)
Subsection 1 · 写清洗脚本
新建 clean_data.py:
import json# 读入rows = []with open("train_data.jsonl", encoding="utf-8") as f: rows = [json.loads(line) for line in f]# 1. 去重(按 user 问题去重)seen, cleaned = set(), []for r in rows: q = r["messages"][0]["content"] if q in seen: continue seen.add(q) cleaned.append(r)# 2. 过滤:答案太短的扔掉(<5字说明质量差)cleaned = [r for r in cleaned if len(r["messages"][1]["content"]) >= 5]# 3. 写回with open("train_data_clean.jsonl", "w", encoding="utf-8") as f: for r in cleaned: f.write(json.dumps(r, ensure_ascii=False) + "\n")print(f"原 {len(rows)} 条 → 清洗后 {len(cleaned)} 条")- 预期看到:条数减少(去重/过滤生效)。
- 脏数据会带偏模型,清洗比数量更重要。
过关:清洗脚本跑通 = Section 5 完成。
Section 6 · HF Transformers 训练入门
Subsection 1 · 装库
cmd:pip install transformers datasets accelerate
Subsection 2 · 跑最简训练
新建 hf_train.py:
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainerfrom datasets import Datasetimport json# 读数据rows = [json.loads(l) for l in open("train_data_clean.jsonl", encoding="utf-8")]dataset = Dataset.from_list(rows)# 加载小模型(CPU 也能跑 0.5B)model_name = "Qwen/Qwen2.5-0.5B-Instruct"tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(model_name, trust_remote_code=True)def fmt(ex): text = tokenizer.apply_chat_template(ex["messages"], tokenize=False) return tokenizer(text, truncation=True, max_length=256, padding="max_length")dataset = dataset.map(fmt)args = TrainingArguments( output_dir="hf_out", num_train_epochs=3, per_device_train_batch_size=1, logging_steps=1, save_strategy="no", report_to=[],)trainer = Trainer(model=model, args=args, train_dataset=dataset)trainer.train()print("训练完成")- 运行(第一次下载模型,可能 10 分钟;CPU 慢是正常的)
- 预期看到:loss 逐渐下降,最后"训练完成"。
过关:最简 SFT 训练跑通 = Section 6 完成。
Section 7 · 认识 LLaMA-Factory(微调神器)
Subsection 1 · 概念
LLaMA-Factory = 一行命令/一个网页 完成 LoRA 全参微调支持:SFT / LoRA / QLoRA / DPO,支持 Qwen 等全系模型Subsection 2 · 装
- 打开 https://github.com/hiyouga/LLaMA-Factory 按 README 安装:
git clone https://github.com/hiyouga/LLaMA-Factory.gitcd LLaMA-Factorypip install -e .- 预期看到:安装成功。
过关:LLaMA-Factory 装好 = Section 7 完成。
Section 8 · 用 LLaMA-Factory 跑 SFT(命令版)
Subsection 1 · 跑训练 在 LLaMA-Factory 目录运行:
python src/train_bash.py \ --model_name_or_path Qwen/Qwen2.5-1.5B-Instruct \ --dataset train_data_clean.jsonl \ --template qwen \ --output_dir ./output_sft \ --num_train_epochs 3 \ --per_device_train_batch_size 1 \ --learning_rate 5e-5 \ --save_strategy no- 首次会下载模型,需要网络;GPU 没有就用 0.5B 版本(CPU 也能,慢)。
- 预期看到:loss 下降,训练完成,输出目录里有模型。
过关:LLaMA-Factory 训练跑通 = Section 8 完成。
Section 9 · 推理:加载微调后的模型
Subsection 1 · 用微调模型回答
新建 infer_sft.py:
from transformers import AutoModelForCausalLM, AutoTokenizer# 加载你微调后的模型model = AutoModelForCausalLM.from_pretrained("./output_sft", trust_remote_code=True)tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-1.5B-Instruct", trust_remote_code=True)text = tokenizer.apply_chat_template( [{"role": "user", "content": "能开发票吗"}], tokenize=False, add_generation_prompt=True)inputs = tokenizer(text, return_tensors="pt")out = model.generate(**inputs, max_new_tokens=50)print(tokenizer.decode(out[0][len(inputs["input_ids"][0]):], skip_special_tokens=True))- 预期看到:模型用你数据里的语气回答(比较像你造的那几条客服话术)。
过关:微调模型能推理 = Section 9 完成。
Section 10 · 对比:微调前 vs 微调后
Subsection 1 · 对照测试
- 用原始模型(不加载 output_sft)问同样问题,记录回答。
- 用微调后模型问同样问题,记录回答。
- 预期看到:微调后更贴合你的客服语气/话术。
- 写对比笔记:哪些问题改进明显,哪些没变。
过关:能说清微调到底改进了什么 = Section 10 完成。
Section 11 · 评估微调效果(量化)
Subsection 1 · 写评估
- 准备 10 条"测试问题"(训练集里没出现过的)。
- 分别用两个模型回答,人工打分(0~5):回答是否贴切/语气是否对。
- 算平均分对比。
- 预期看到:微调后平均分更高。
- 这就是"评估集 + 打分"的最简评估,后面Part 16 会系统化。
过关:有量化的前后对比 = Section 11 完成。
Section 12 · DeepSpeed 认识(分布式微调)
Subsection 1 · 概念
DeepSpeed = 微软的分布式训练框架,让大模型在有限显存上训练 ZeRO 1/2/3:把优化器状态/梯度/参数分片到多卡作用:你本地单卡跑不动的模型,用 DeepSpeed + 多卡能跑- 学习阶段知道"它解决显存不够"即可,LLaMA-Factory 里可加
--deepspeed config.json启用。
过关:能说 DeepSpeed 解决什么 = Section 12 完成。
Section 13 · 常见坑
Subsection 1 · 记坑
坑1 显存 OOM → 换更小模型 / batch_size=1 / 加 gradient_accumulation坑2 中文乱码/重复 → max_length 太短或数据太脏,清洗+加长坑3 训练 loss 不降 → 学习率太大/数据太少,调小 lr 或加数据坑4 模型"忘了"原来能力(灾难性遗忘)→ 混入一些通用数据坑5 模板不匹配 → 用对 LLaMA-Factory 的 template(qwen/chatglm 等)过关:坑笔记写完 = Section 13 完成。
Section 14 · 综合:微调一个"固定风格助手"
Subsection 1 · 完整项目
做一个项目 finetune_demo:
- 造 100 条"可爱语气客服"数据(风格统一)
- 清洗 + 去重
- LLaMA-Factory 微调
- 微调前后对比 + 评估分数
- README 写流程
- 预期看到:一个完整、可复现的微调项目。
过关:完整项目跑通 = Section 14 完成。
Section 15 · 站 13 验收
勾选
- 能判断"微调/RAG/Prompt"场景
- 能选基座并说明理由
- 会写 JSONL 数据 + 清洗去重
- HF 最简训练跑通(Section 6)
- LLaMA-Factory SFT 跑通(Section 8)
- 微调后模型能推理(Section 9)
- 有量化前后对比(Section 11)
- 了解 DeepSpeed 解决什么
- 常见坑笔记写完
写 400 字Part 13 总结:微调全流程 + 你的数据/模型/效果数字。
全勾选 = Part 15 通过 → 进入下一站 Part 16 · PEFT 参数高效微调,20 天,重点 LoRA)。
