LoRA微调实战:用自有数据训练行业专属大模型

2026-03-22 · 阅读约14分钟

通用大模型在特定行业场景下表现往往不够好:医疗术语不准确、法律条文理解偏差、金融分析缺乏专业性。LoRA(Low-Rank Adaptation)微调是目前最主流的解决方案——用少量行业数据,在不改变原始模型的前提下,让模型学会你的领域知识。

这篇文章记录了我从数据准备到模型部署的完整流程,使用Llama Factory + QLoRA方案,在单张消费级显卡上完成微调。

一、LoRA原理简述

全量微调(Full Fine-tuning)需要更新模型的所有参数,以一个7B模型为例,需要约56GB显存,一般人根本做不了。

LoRA的核心思想是:不动原始权重,在旁边加一个小的"适配器"

# 原始线性层
y = W * x     # W是一个 [4096 x 4096] 的大矩阵

# LoRA改造后
y = W * x + (B * A) * x
# A: [4096 x r] 的小矩阵  (r通常取8-64)
# B: [r x 4096] 的小矩阵
# 只训练 A 和 B,W冻结不动

# 参数量对比
# 原始: 4096 * 4096 = 16,777,216 个参数
# LoRA (r=16): 4096 * 16 + 16 * 4096 = 131,072 个参数
# 减少了 128 倍!

QLoRA:进一步压缩显存

QLoRA在LoRA基础上增加了量化:将原始模型权重从FP16量化为4-bit(NF4格式),显存需求再降一半:

方法7B模型显存需求14B模型显存需求
全量微调 (FP16)~56GB~112GB
LoRA (FP16)~28GB~56GB
QLoRA (4-bit)~8GB~16GB

一张RTX 4090(24GB显存)就能QLoRA微调14B模型,一张RTX 3090/4060也能跑7B模型。

二、数据准备

微调数据的质量远比数量重要。500条高质量数据的效果,往往好于5000条低质量数据。

数据格式

主流框架使用的训练数据格式是对话格式JSON

# alpaca格式(Llama Factory默认支持)
[
  {
    "instruction": "你是一个专业的中医助手。",
    "input": "请解释什么是气虚,有哪些典型症状?",
    "output": "气虚是中医学中的基本病理概念,指元气不足、功能减退的状态。\n\n典型症状包括:\n1. 神疲乏力:总觉得累,不想动\n2. 气短懒言:说话没力气,不想多说\n3. 自汗:稍微活动就出汗\n4. 舌淡胖、有齿痕:舌头颜色淡,边缘有齿印\n5. 脉虚弱:把脉时脉象无力\n\n常见的调理方药有四君子汤(党参、白术、茯苓、甘草),日常可用黄芪泡水。"
  },
  {
    "instruction": "你是一个专业的中医助手。",
    "input": "风寒感冒和风热感冒怎么区分?",
    "output": "区分要点:\n\n【风寒感冒】\n- 怕冷明显,发热轻\n- 鼻涕清稀、痰白\n- 头痛、身体酸痛\n- 舌苔薄白\n- 治则:辛温解表,如麻黄汤、桂枝汤\n\n【风热感冒】\n- 发热明显,怕冷轻\n- 鼻涕黄稠、痰黄\n- 咽喉肿痛\n- 舌苔薄黄\n- 治则:辛凉解表,如银翘散、桑菊饮\n\n简单判断:怕冷重→风寒,喉咙痛重→风热。"
  }
]

数据构建方法

  1. 从已有文档提取:把行业文档、FAQ、手册等转化为问答对
  2. 用大模型生成:用强模型(如DeepSeek-V3)根据文档生成训练数据
  3. 人工标注:最高质量,但成本高,适合核心场景
  4. 混合策略:大模型批量生成 + 人工筛选修正
def generate_training_data(document, llm_client):
    """用大模型从文档生成训练数据"""
    prompt = f"""根据以下文档内容,生成10组高质量的问答训练数据。

要求:
- 问题要自然、多样化,模拟真实用户的提问方式
- 回答要准确、完整,基于文档内容
- 回答中要体现专业术语和行业知识
- 输出JSON数组格式

文档内容:
{document}"""

    response = llm_client.chat(prompt)
    return json.loads(response)
用大模型生成的训练数据一定要人工检查。AI生成的数据可能包含事实性错误或不符合行业规范的表述。一条错误数据的危害,大于十条正确数据的价值

三、使用Llama Factory进行微调

Llama Factory是目前最好用的微调工具框架之一,支持100+模型、多种微调方法,还有Web界面。

环境安装

# 克隆仓库
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory

# 安装依赖
pip install -e ".[torch,metrics]"

# 验证安装
llamafactory-cli version

注册自定义数据集

# 将数据文件放入 data/ 目录
cp my_medical_data.json data/

# 在 data/dataset_info.json 中注册
{
  "my_medical": {
    "file_name": "my_medical_data.json",
    "formatting": "alpaca",
    "columns": {
      "prompt": "instruction",
      "query": "input",
      "response": "output"
    }
  }
}

训练配置

# train_config.yaml
### 模型
model_name_or_path: Qwen/Qwen2.5-7B-Instruct  # 基座模型

### 微调方法
stage: sft
do_train: true
finetuning_type: lora
lora_target: all        # 对所有线性层添加LoRA
lora_rank: 16           # LoRA秩,越大容量越强,显存越多
lora_alpha: 32          # 通常设为2*rank
lora_dropout: 0.05

### 量化(QLoRA)
quantization_bit: 4
quantization_method: bitsandbytes

### 数据
dataset: my_medical
template: qwen
cutoff_len: 2048        # 最大序列长度
max_samples: 5000       # 最大样本数

### 训练参数
output_dir: output/medical_lora
num_train_epochs: 3.0
per_device_train_batch_size: 2
gradient_accumulation_steps: 8    # 等效batch_size = 2 * 8 = 16
learning_rate: 2.0e-4
lr_scheduler_type: cosine
warmup_ratio: 0.1
logging_steps: 10
save_steps: 100

### 优化
bf16: true              # 使用BF16混合精度
optim: adamw_torch

启动训练

# 命令行方式
llamafactory-cli train train_config.yaml

# 或者使用Web界面
llamafactory-cli webui
Llama Factory的Web界面非常友好,可以可视化配置所有参数、实时查看训练loss曲线、在线测试模型效果。非常适合快速迭代调参。

四、关键参数调优

LoRA Rank的选择

Rank值可训练参数量适用场景
8~17M简单任务(风格迁移、格式适配)
16~33M中等任务(行业知识注入,推荐默认值)
32~67M复杂任务(大量新知识、能力扩展)
64~134M接近全量微调效果,显存需求高

学习率

训练轮数

五、效果评估

自动评估

# 使用Llama Factory内置评估
llamafactory-cli eval \
  --model_name_or_path Qwen/Qwen2.5-7B-Instruct \
  --adapter_name_or_path output/medical_lora \
  --template qwen \
  --task mmlu \
  --lang zh

人工评估(更重要)

准备50-100条行业测试问题,对比微调前后的回答质量:

# 对比测试脚本
test_questions = load_json("test_questions.json")

for q in test_questions:
    answer_before = inference(base_model, q)  # 原始模型回答
    answer_after = inference(lora_model, q)    # 微调模型回答
    print(f"问题: {q}")
    print(f"原始: {answer_before}")
    print(f"微调: {answer_after}")
    print("---")

评估维度

六、模型导出与部署

# 合并LoRA权重到基座模型
llamafactory-cli export \
  --model_name_or_path Qwen/Qwen2.5-7B-Instruct \
  --adapter_name_or_path output/medical_lora \
  --template qwen \
  --export_dir output/medical_merged \
  --export_size 4  # 分片大小(GB)

# 使用vLLM部署推理服务
python -m vllm.entrypoints.openai.api_server \
  --model output/medical_merged \
  --port 8000 \
  --max-model-len 4096

七、踩坑记录

  1. 数据格式问题:JSON中的中文引号、全角符号会导致解析失败。统一用半角符号。
  2. 显存不足:降低cutoff_len(如从2048降到1024)、减小batch_size、增加gradient_accumulation_steps
  3. 训练loss不降:检查数据格式是否正确、template是否与模型匹配。
  4. 灾难性遗忘:在训练数据中混入一定比例的通用对话数据(如10-20%)。
  5. 不要在量化模型上再做量化:如果基座模型已经是GPTQ/AWQ量化版,不要再用QLoRA的4-bit量化,会严重损失精度。
← 返回文章列表