通用大模型在特定领域的表现往往差强人意。让它分析金融财报,它可能用一堆泛泛而谈的废话糊弄你;让它审查代码安全,它可能漏掉项目特有的风险模式。这时候就需要微调——用你的领域数据教会模型在特定任务上表现更好;
LoRA是目前性价比最高的微调方式。全量微调7B模型需要约28GB显存,LoRA只需要8GB左右;
LoRA的原理
LoRA(Low-Rank Adaptation)的思路很优雅:不修改原始模型的权重,而是在每层权重矩阵旁边加两个小的低秩矩阵。训练时冻结原始权重,只更新这两个小矩阵;
原始权重矩阵W的维度是d×d,LoRA加的两个矩阵A和B分别是d×r和r×d,其中r远小于d(通常8或16)。参数量从d²降到2dr,显存和计算量都大幅减少;
推理时把LoRA权重合并回原始模型:W’ = W + BA,几乎不增加推理开销;
工具:LLaMA Factory
LLaMA Factory是目前最易用的微调框架,支持几十种模型,提供Web界面和命令行两种方式;
pip install llamafactory
准备训练数据
数据格式是JSON数组,每条包含instruction、input、output三个字段:
[
{
"instruction": "分析以下Python代码的安全问题",
"input": "def login(user, pwd):\n query = f\"SELECT * FROM users WHERE name='{user}'\"\n return db.execute(query)",
"output": "存在SQL注入漏洞。用户输入直接拼接到SQL语句中。\n\n修复:使用参数化查询\n```python\ndef login(user, pwd):\n return db.execute(\"SELECT * FROM users WHERE name=?\", (user,))\n```"
}
]
数据质量比数量重要。100条高质量示例的效果经常好过1000条低质量数据。质量的标准是:指令清晰无歧义、输出准确且格式一致、覆盖常见场景和边界情况。
训练配置
### model
model_name_or_path: Qwen/Qwen2.5-7B-Instruct
quantization_bit: 4
### method
stage: sft
do_train: true
finetuning_type: lora
lora_rank: 8
lora_alpha: 16
lora_target: q_proj,v_proj
### dataset
dataset: my_custom_data
template: qwen
cutoff_len: 1024
### output
output_dir: ./output/qwen2.5-7b-lora
logging_steps: 10
save_steps: 100
### train
per_device_train_batch_size: 4
gradient_accumulation_steps: 4
learning_rate: 0.0001
num_train_epochs: 3
lr_scheduler_type: cosine
bf16: true
关键参数说明。lora_rank=8是起步值,表达能力够用且显存省。如果任务复杂(比如代码生成),可以试16或32。learning_rate从1e-4开始,如果loss震荡就降到5e-5。num_train_epochs=3通常够了,过多会过拟合。
开始训练
llamafactory-cli train config.yaml
训练过程中关注loss曲线。理想情况是稳步下降并收敛。如果loss不降反升,检查学习率和数据质量。
合并和使用
# 合并LoRA权重到基础模型
llamafactory-cli export config.yaml
合并后的模型可以像普通模型一样用Ollama或vLLM加载。
也可以不合并,在Ollama中用Modelfile引用LoRA:
FROM Qwen2.5-7B-Instruct
ADAPTER ./output/qwen2.5-7b-lora
效果评估
微调后一定要用独立测试集评估。关注三个维度:领域任务准确率是否提升;通用能力是否下降(灾难性遗忘);对未见过的数据泛化效果如何。
架构设计
一个好的AI应用架构需要考虑几个层面:
- 接入层:统一的API网关,处理认证、限流、路由;
- 业务层:prompt管理、上下文维护、工具调用编排;
- 模型层:多模型支持、负载均衡、降级策略;
- 数据层:向量数据库、缓存、日志存储;
各层之间通过消息队列或gRPC通信,避免紧耦合。模型层可以独立扩缩容,不影响业务层;
测试策略
AI应用的测试和传统应用不同。除了单元测试和集成测试,还需要:
- Prompt回归测试:修改prompt后自动跑一批测试用例,检查输出质量是否退化;
- 边界测试:空输入、超长输入、特殊字符、多语言混杂;
- 对抗测试:prompt注入、越狱尝试、恶意输入;
写在最后
LoRA微调的门槛已经很低了,几个小时就能训出一个在特定任务上明显更好的模型。关键在于数据质量——花80%的精力在数据准备上,20%在训练调参上,这个比例基本是对的。