返回学习路线

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:

python
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:

python
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:

python
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 · 装

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:

python
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:

  1. 造 100 条"可爱语气客服"数据(风格统一)
  2. 清洗 + 去重
  3. LLaMA-Factory 微调
  4. 微调前后对比 + 评估分数
  5. 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)。