从入门到落地:AI 大模型微调全景实战指南
文章摘要 本文系统介绍了大语言模型微调技术(Fine-Tuning),重点聚焦生产落地最成熟的SFT+LoRA/QLoRA方案。微调能以1%算力获得90%模型能力,是企业应用的最佳选择。文章详解了微调技术演进(从全参量到QLoRA)、核心概念(SFT/LoRA/RLHF等)和完整9步流程,并通过中文医疗问答模型实战演示:从数据制备(20万条医学数据)、基座选择(Qwen2.5-7B)、QLoRA配
·
0. 什么是“微调”?为什么必须微调?
| 方式 | 数据量 | 计算资源 | 效果 | 场景 |
|---|---|---|---|---|
| 提示工程 | 0 | CPU 即可 | 60~70 分 | 临时对话 |
| RAG | 千级文档 | CPU/GPU | 70~80 分 | 动态知识 |
| 微调(SFT) | 万~百万样本 | 1~8×A100 | 85~95 分 | 领域专家 |
| 预训练 | 千亿 token | 千卡 | 100 分 | 底座模型 |
微调 = 用 1% 算力拿到 90% 能力,是绝大多数企业的“甜点区”。
1. 微调技术演进图
2018 Fine-Tune 全参量
↓
2021 Adapter / LoRA / AdaLoRA(参数高效)
↓
2023 QLoRA(4-bit 量化 + LoRA)+ RLHF(人类偏好)
↓
2024 GaLore、DoRA、LongLoRA(继续降显存 / 长文本)
本文聚焦生产落地最成熟的 SFT + LoRA/QLoRA 路线。
2. 概念速览(3 分钟弄懂)
| 缩写 | 全称 | 一句话 |
|---|---|---|
| SFT | Supervised Fine-Tuning | 有监督指令微调,让模型“说人话” |
| LoRA | Low-Rank Adaptation | 只训练两个小矩阵,冻结原模型 |
| QLoRA | Quantized LoRA | 先量化到 4 bit,再 LoRA,显存减半 |
| RLHF | Reinforcement Learning from Human Feedback | 用人类打分训练奖励模型,再 PPO |
| PEFT | Parameter-Efficient Fine-Tuning | 所有“小参数”技巧统称 |
3. 微调全流程(9 步)
- 场景定义 → 2. 数据制备 → 3. 基座选型 → 4. 环境搭设
- 参数高效策略 → 6. 训练 → 7. 评估 → 8. 合并导出 → 9. 上线推理
4. Step-by-Step 实战:中文医疗问答模型
4.1 场景定义
目标:让 7B 模型回答“感冒能喝咖啡吗”等中文医疗咨询,减少幻觉。
4.2 数据制备
| 来源 | 量级 | 处理要点 |
|---|---|---|
| 医学百科 | 15 万条 | 清洗 HTML、去广告 |
| 医患对话开源集 | 5 万条 | 脱敏、去隐私 |
| 自建指令集 | 1 万条 | 医生审核,标注“是否可答” |
格式:Alpaca 指令模板
{
"instruction": "患者问:感冒能喝咖啡吗?",
"input": "",
"output": "感冒期间不建议大量饮用咖啡..."
}
经验:领域指令 ≥ 1 万条即可让 7B 模型脱胎换骨。
4.3 基座选型
| 候选 | 参数量 | 中文 | 商用 | 选择 |
|---|---|---|---|---|
| Llama-3-8B | 8 B | ★★☆ | ❌ | 英文优 |
| Qwen2.5-7B | 7 B | ★★★ | ✅ | ✔ |
| Baichuan2-7B | 7 B | ★★★ | ✅ | 备选 |
最终锁定 Qwen2.5-7B-Instruct(已 SFT 一次,继续二次增强)。
4.4 环境搭设
# CUDA 12.1 驱动
pip install transformers>=4.41 peft accelerate bitsandbytes \
datasets transformers_stream_generator
单卡 A100 40 GB 或 RTX 4090 24 GB 均可跑 QLoRA。
4.5 参数高效策略(QLoRA)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
import torch, transformers
model_id = "Qwen/Qwen2.5-7B-Instruct"
tokenizer = transformers.AutoTokenizer.from_pretrained(model_id)
# 4-bit 量化加载
model = transformers.AutoModelForCausalLM.from_pretrained(
model_id,
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
device_map="auto"
)
model = prepare_model_for_kbit_training(model)
# LoRA 配置
lora_config = LoraConfig(
r=64,
lora_alpha=128,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters() # 仅 0.8% 参数参与训练!
4.6 训练脚本(Trainer 版)
train_dataset = load_dataset("json", data_files="med_zh.jsonl", split="train")
def template(example):
prompt = f"Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\n{example['instruction']}\n\n### Response:\n{example['output']}"
return {"text": prompt}
train_dataset = train_dataset.map(template, remove_columns=train_dataset.column_names)
trainer = transformers.Trainer(
model=model,
train_dataset=train_dataset,
args=transformers.TrainingArguments(
per_device_train_batch_size=1,
gradient_accumulation_steps=32,
num_train_epochs=3,
learning_rate=2e-4,
fp16=True,
logging_steps=10,
output_dir="./qwen_med_qlora",
optim="paged_adamw_8bit",
save_strategy="epoch",
),
data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False),
)
trainer.train()
显存占用:7B/4-bit + LoRA ≈ 18 GB(4090 即可跑)。
4.7 评估(自动化 + 人工)
- 自动化:BLEU-4 / ROUGE-L / perplexity
- 对抗测试:
- 输入:“一岁宝宝发烧 39 度怎么办?”
- 要求:必须出现“及时就医”关键词 → 未出现即判负
- 医生盲审:100 条样本双盲打分,胜率 85% 即达标。
4.8 合并导出(LoRA 与基座合一)
from peft import PeftModel
# 加载 LoRA
model = PeftModel.from_pretrained(model, "./qwen_med_qlora/checkpoint-xxx")
# 合并
merged = model.merge_and_unload()
merged.save_pretrained("./qwen_med_merged")
tokenizer.save_pretrained("./qwen_med_merged")
产出 单文件 .bin 或 .safetensors,方便 vLLM / TensorRT-LLM 部署。
4.9 上线推理(vLLM 高并发)
pip install vllm
python -m vllm.entrypoints.openai.api_server \
--model ./qwen_med_merged \
--tensor-parallel-size 2 \
--served-model-name qwen-med-7b
业务侧 零改造 替换 base_url 即可。
5. 超参数经验表(直接抄)
| 参数 | 医疗 7B | 闲聊 13B | 代码 34B | 备注 |
|---|---|---|---|---|
| LoRA r | 64 | 128 | 256 | 越大越贵 |
| lora_alpha | 128 | 256 | 512 | 一般 2×r |
| learning_rate | 2e-4 | 1e-4 | 5e-5 | 大模型要更小 |
| batch_size | 1 | 2 | 4 | 显存决定 |
| gradient_accum | 32 | 64 | 128 | 线性放大 |
| num_epochs | 3 | 2 | 1 | 早停防止过拟 |
| max_seq_len | 1024 | 2048 | 8192 | 长文本用 LongLoRA |
6. 成本与速度实测(单卡 A100 40 GB)
| 方案 | 可训练参数量 | 显存 | 速度 (token/s) | 3 万条 1024 长度耗时 |
|---|---|---|---|---|
| 全参量 | 7 B | 28 GB | 2100 | 38 h |
| LoRA 16 | 0.1 B | 22 GB | 2000 | 36 h |
| QLoRA 64 | 0.05 B | 18 GB | 1900 | 34 h |
QLoRA 仅 2% 参数、显存降 35%,效果与 LoRA 持平 → 生产首选。
7. 进阶:RLHF 让模型“说人话”
流程:
- 训练奖励模型(RM)—— 医生对回答打分 → 训练 BERT 回归器
- PPO 强化学习 —— 用 RM 当奖励,微调策略模型
- KL 惩罚 —— 防止模型“放飞”
工具:
- TRLX / ColossalChat 已封装 PPO,3 万样本 8×A100 一天跑完
- 医疗场景 RLHF 后,有用性 +9.2%,有害率 -4.1%(内部盲审)
8. 常见坑 & 解决
| 坑 | 症状 | 解决 |
|---|---|---|
| loss=0 | 学习率太高 | 降到 1e-5 |
| 显存爆 | 没开梯度检查点 | model.gradient_checkpointing_enable() |
| 生成乱码 | 模板不一致 | 推理模板必须与训练完全一致 |
| 过拟合 | 评估指标下降 | LoRA r 减小 + dropout 0.1 + early stopping |
9. 总结:一张思维导图带走
场景定义 → 数据 1w+ → Qwen2.5-7B
↓
QLoRA 4-bit + r=64
↓
3 epoch + 2e-4 + GPU 24 GB
↓
merge → vLLM 部署 → RLHF(可选)
记住:“大模型微调不是炼金术,而是数据工程 + 参数高效策略 + 系统评估”。
更多推荐


所有评论(0)