9.5 个性化与微调生态
从「通用大模型」到「专属小模型」——合成数据 → 微调 → 评估 → 部署的完整闭环,让 AI 真正适配你的业务场景。
为什么需要个性化微调?
通用大模型(GPT-4o / Claude)的局限:
❌ 不了解你的业务术语和知识
❌ 输出风格不符合品牌调性
❌ 每次调用都要付 API 费用
❌ 数据发送到第三方有隐私风险
❌ 对特定任务的准确率不够高
微调后的专属模型:
✅ 精准掌握领域知识和术语
✅ 输出风格一致、可控
✅ 本地部署零 API 成本
✅ 数据完全自控
✅ 特定任务准确率可提升 20-50%合成数据生成
为什么用合成数据?
真实标注数据成本高、周期长。用大模型生成训练数据,再用人工审核,可以 10x 加速数据准备。
实战:用 GPT-4o 生成训练数据
python
from openai import OpenAI
import json
client = OpenAI()
async def generate_training_data(
task_description: str,
num_samples: int = 100,
output_format: str = "sharegpt"
) -> list[dict]:
"""用大模型生成微调训练数据"""
system_prompt = f"""你是一个训练数据生成专家。
任务描述:{task_description}
要求:
1. 生成多样化的用户问题(覆盖不同表达方式)
2. 回答必须准确、专业、符合业务规范
3. 每条数据独立,不要重复
4. 输出 JSON 数组格式"""
all_data = []
batch_size = 10
for i in range(0, num_samples, batch_size):
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"生成 {batch_size} 条训练数据,JSON 数组格式"}
],
response_format={"type": "json_object"},
temperature=0.9 # 高温度增加多样性
)
batch = json.loads(response.choices[0].message.content)
all_data.extend(batch.get("data", []))
print(f"已生成 {len(all_data)}/{num_samples} 条")
return all_data
# 使用示例
data = await generate_training_data(
task_description="电商客服对话,回答关于退货、换货、物流查询的问题",
num_samples=500
)数据质量控制
python
def quality_filter(data: list[dict]) -> list[dict]:
"""过滤低质量训练数据"""
filtered = []
for item in data:
q = item.get("question", "")
a = item.get("answer", "")
# 规则 1:长度检查
if len(q) < 5 or len(a) < 20:
continue
# 规则 2:去重(基于问题相似度)
if any(similar(q, f["question"]) > 0.9 for f in filtered):
continue
# 规则 3:敏感内容过滤
if contains_sensitive(a):
continue
filtered.append(item)
print(f"质量过滤:{len(data)} → {len(filtered)} 条({len(filtered)/len(data)*100:.0f}%)")
return filtered导出为微调格式
python
def to_sharegpt(data: list[dict], output_path: str):
"""导出为 ShareGPT 格式(LLaMA-Factory 通用)"""
formatted = []
for item in data:
formatted.append({
"conversations": [
{"from": "human", "value": item["question"]},
{"from": "gpt", "value": item["answer"]}
]
})
with open(output_path, "w", encoding="utf-8") as f:
json.dump(formatted, f, ensure_ascii=False, indent=2)
print(f"已导出 {len(formatted)} 条到 {output_path}")
def to_alpaca(data: list[dict], output_path: str):
"""导出为 Alpaca 格式"""
formatted = [
{
"instruction": item["question"],
"input": "",
"output": item["answer"]
}
for item in data
]
with open(output_path, "w", encoding="utf-8") as f:
json.dump(formatted, f, ensure_ascii=False, indent=2)LoRA 微调实战
使用 LLaMA-Factory(推荐)
bash
# 安装
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics]"
# 启动 Web UI
llamafactory-cli webui
# 浏览器打开 http://localhost:7860yaml
# config/my_lora.yaml — LoRA 微调配置
### 模型
model_name_or_path: Qwen/Qwen2.5-7B-Instruct
### 方法
stage: sft
do_train: true
finetuning_type: lora
lora_rank: 16
lora_alpha: 32
lora_target: all
### 数据
dataset: my_custom_data # 放在 data/ 目录下
template: qwen
cutoff_len: 2048
### 训练参数
num_train_epochs: 3
per_device_train_batch_size: 4
gradient_accumulation_steps: 4
learning_rate: 2.0e-4
lr_scheduler_type: cosine
warmup_ratio: 0.1
fp16: true
### 输出
output_dir: saves/my-model-lora
logging_steps: 10
save_steps: 500bash
# 命令行启动训练
llamafactory-cli train config/my_lora.yaml
# 合并 LoRA 权重
llamafactory-cli export config/merge_lora.yaml
# 推理测试
llamafactory-cli chat config/inference.yaml评估与迭代
自动化评估
python
from openai import OpenAI
client = OpenAI()
def llm_judge(question: str, answer: str, reference: str) -> dict:
"""LLM-as-Judge:用 GPT-4o 评估微调模型输出质量"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": f"""评估以下回答的质量,打分 1-5 并说明理由。
问题:{question}
参考答案:{reference}
待评估答案:{answer}
评分维度:
1. 准确性(是否正确回答了问题)
2. 完整性(是否涵盖了关键信息)
3. 流畅性(语言是否自然流畅)
4. 专业性(是否使用了正确的术语)
输出 JSON:{{"score": 1-5, "reason": "..."}}"""
}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)评估流程
合成数据(500条)
↓
质量过滤(→ 400条)
↓
训练集/测试集拆分(360 / 40)
↓
LoRA 微调(3 epochs)
↓
测试集评估(LLM-as-Judge)
↓
得分 ≥ 4.0?──Yes──→ 部署上线
│
No
↓
分析低分样本 → 补充训练数据 → 重新微调LoRA 即服务(LoRA-as-a-Service)
概念
一个基础模型 + 多个 LoRA 适配器 = 多个专属模型,共享 GPU 内存。
┌─────────────────────────────┐
│ 基础模型(Qwen-7B) │ ← 只加载一次
│ │
│ ┌───────┐ ┌───────┐ ┌────┐│
│ │LoRA A │ │LoRA B │ │... ││ ← 按需热切换
│ │客服 │ │法律 │ │ ││
│ └───────┘ └───────┘ └────┘│
└─────────────────────────────┘vLLM 多 LoRA 部署
bash
# 启动 vLLM,加载基座 + 多个 LoRA
vllm serve Qwen/Qwen2.5-7B-Instruct \
--enable-lora \
--lora-modules \
customer_service=/path/to/lora_a \
legal_assistant=/path/to/lora_b \
--max-loras 4 \
--max-lora-rank 16python
# 调用时指定 LoRA
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1")
# 使用客服 LoRA
response = client.chat.completions.create(
model="customer_service", # LoRA 名称
messages=[{"role": "user", "content": "我想退货"}]
)
# 使用法律 LoRA
response = client.chat.completions.create(
model="legal_assistant", # 切换 LoRA
messages=[{"role": "user", "content": "劳动合同解除的条件"}]
)优势:
- 一台 GPU 服务多个场景
- LoRA 热切换,无需重启
- 每个 LoRA 只有几十 MB,便于分发和管理
学习资源