前言

前面那篇微调入门讲了概念和决策框架。这篇是纯操作——用 LLaMA-Factory 这个工具,不用写多少代码,就能完成 LoRA 微调。

选 LLaMA-Factory 的原因是它把模型加载、数据预处理、训练配置、评估、导出这些步骤全封装好了,支持 Web UI 操作,对新手友好。

一、端到端微调工程流


二、安装与国内镜像配置

1. 基础环境搭建

1
2
3
4
5
6
7
8
# 推荐使用 Conda 隔离 Python 3.10 / 3.11 环境
conda create -n llama-factory python=3.11 -y
conda activate llama-factory

# 克隆官方仓库并安装核心依赖
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

2. 国内开发者网络避坑(重要)

在国内直接从 Hugging Face 下载模型或数据集极易发生超时失败(ConnectionResetError)。LLaMA-Factory 内置原生支持阿里云 ModelScope(魔搭社区),只需在终端设置环境变量即可自动切换为国内高速源:

1
2
3
4
5
# 设置优先从魔搭社区拉取模型权重与数据集
export USE_MODELSCOPE_HUB=1

# 验证 CLI 安装是否就绪
llamafactory-cli version

三、准备数据

数据格式(Alpaca 格式)

在 data/ 目录下创建 my_data.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[
{
"instruction": "你是一个运维工程师,请根据用户描述给出 Linux 命令",
"input": "查看占用 8080 端口的进程",
"output": "sudo lsof -i :8080\n或者\nsudo ss -tlnp | grep 8080"
},
{
"instruction": "你是一个运维工程师,请根据用户描述给出 Linux 命令",
"input": "查看磁盘使用情况",
"output": "df -h"
},
{
"instruction": "你是一个运维工程师,请根据用户描述给出 Linux 命令",
"input": "查找 /var/log 下大于 100MB 的文件",
"output": "find /var/log -type f -size +100M -exec ls -lh {} \\;"
}
]

然后在 data/dataset_info.json 中注册:

1
2
3
4
5
6
7
8
9
10
{
"my_linux_data": {
"file_name": "my_data.json",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output"
}
}
}

数据量建议

  • 最少 100 条才能看到风格与格式的初步收敛
  • 300-1000 条能获得非常稳定的特定任务专业表现
  • 1000-3000 条适合复杂规则与深度领域任务

四、开始微调(Web UI 方式)

1
llamafactory-cli webui

浏览器打开 http://localhost:7860。

关键配置步骤:

  1. 模型选择 → 选你要微调的基座模型,如 Qwen2.5-7B-Instruct
  2. 微调方法 → 选 lora,量化等级选 none(显存不足 20G 选 4-bit QLoRA)
  3. 数据集 → 选择上一步注册的 my_linux_data
  4. 超参数设置:
    • 学习率:5e-5(7B 模型的推荐标准值)
    • 训练轮数(epochs):3(先试 3 轮观察收敛趋势)
    • 批大小(batch_size):4(显存受限可调为 2 或 1)
    • 梯度累积(gradient_accumulation):4(等效 batch = 4×4 = 16)
    • 最大长度(max_length):1024
  5. LoRA 参数:
    • rank (r):8 或 16(能力与显存平衡点)
    • alpha:16 或 32(通常设为 rank 的 2 倍)
    • target:all(覆盖 q, k, v, o, gate, up, down 全线性投影层)
  6. 点击”开始训练”,页面下方将实时绘制 Loss 下降曲线图。

五、命令行方式微调(CLI 无头生产模式)

适合在云端无 GUI 算力服务器上挂后台执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
llamafactory-cli train \
--model_name_or_path Qwen/Qwen2.5-7B-Instruct \
--dataset my_linux_data \
--output_dir ./output/linux-expert \
--stage sft \
--finetuning_type lora \
--lora_rank 8 \
--lora_alpha 16 \
--lora_target all \
--learning_rate 5e-5 \
--num_train_epochs 3 \
--per_device_train_batch_size 4 \
--gradient_accumulation_steps 4 \
--lr_scheduler_type cosine \
--warmup_ratio 0.1 \
--logging_steps 10 \
--save_steps 200 \
--plot_loss \
--bf16

训练完成后,./output/linux-expert 下会生成仅几十 MB 的轻量 LoRA 权重。


六、测试微调后的模型(严谨验证)

微调后先不要直接合并原模型,通过 PEFT 动态挂载进行即时测试对比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

base_model = "Qwen/Qwen2.5-7B-Instruct"
lora_path = "./output/linux-expert"

tokenizer = AutoTokenizer.from_pretrained(base_model)
model = AutoModelForCausalLM.from_pretrained(
base_model,
device_map="auto",
torch_dtype=torch.bfloat16
)

# 动态载入 LoRA 适配层并置于 evaluation 模式
model = PeftModel.from_pretrained(model, lora_path)
model.eval()

def test_model(prompt):
messages = [
{"role": "system", "content": "你是一个运维工程师,请根据用户描述给出 Linux 命令"},
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to(model.device)

# 务必在 torch.no_grad() 下推理,避免无意义的梯度图缓存导致显存溢出
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=256,
temperature=0.2,
top_p=0.9
)
# 截取大模型实际生成的输出部分
gen_tokens = outputs[0][len(inputs.input_ids[0]):]
return tokenizer.decode(gen_tokens, skip_special_tokens=True).strip()

# 对比测试
test_cases = [
"如何查看系统内存使用情况",
"找出最近 7 天内修改过的配置文件",
"批量杀死所有包含 'python' 的进程",
]
for case in test_cases:
print(f"Q: {case}")
print(f"A:\n{test_model(case)}\n{'-'*30}")

七、合并并导出模型(服务化上线)

测试满意后,可将 LoRA 增量矩阵参数直接融入原模型底座,彻底消除旁路计算开销,便于后续用 vLLM 或 Ollama 部署:

1. 导出完整 Safetensors 模型(供给 vLLM / HuggingFace)

1
2
3
4
5
6
7
8
llamafactory-cli export \
--model_name_or_path Qwen/Qwen2.5-7B-Instruct \
--adapter_name_or_path ./output/linux-expert \
--template qwen \
--finetuning_type lora \
--export_dir ./output/linux-expert-merged \
--export_size 2 \
--export_legacy_format false

导出的 ./output/linux-expert-merged 是一个标准独立的 Safetensors 精度模型,无需再附带 PEFT 依赖,可直接由 vLLM 或 TGI 加载。

2. 导出 GGUF 格式并接入 Ollama

针对 Mac、笔记本或纯 CPU/边缘服务器,LLaMA-Factory 支持直接量化导出为 GGUF 格式:

1
2
3
4
5
6
7
8
9
10
# 合并 LoRA 并直接量化导出为 GGUF 文件 (4-bit Medium 量化)
llamafactory-cli export \
--model_name_or_path Qwen/Qwen2.5-7B-Instruct \
--adapter_name_or_path ./output/linux-expert \
--template qwen \
--finetuning_type lora \
--export_dir ./output/linux-expert-gguf \
--export_quantization_bit 4 \
--export_quantization_device cpu \
--export_legacy_format false

导出成功后,在 ./output/linux-expert-gguf 文件夹下会生成 .gguf 量化权重文件。通过 Modelfile 即可一键拉起服务:

1
2
3
4
5
6
7
8
# 1. 创建 Modelfile 指向 GGUF
cat > Modelfile << EOF
FROM ./output/linux-expert-gguf/qwen-7b-sft-q4_k_m.gguf
EOF

# 2. 导入 Ollama 并极速运行
ollama create linux-expert -f Modelfile
ollama run linux-expert

八、常见问题与工业级排错指南

1. 训练过程中 Loss 不下降或震荡:

  • 学习率设置不合理:7B 推荐从 5e-5 开始微调;若 Loss 剧烈跳跃,降至 2e-5;
  • 数据质量异常:检查是否出现指令(instruction)与目标回答(output)错位、标签全空或存在大量乱码;
  • 检查 warmup_ratio:建议设置 0.05 ~ 0.1,避免初始步数过冲导致梯度爆炸。

2. 训练时报 CUDA Out of Memory (OOM):

  • 开启 4-bit 量化(QLoRA),基座模型显存占用立即降至 4GB 左右;
  • 开启 --gradient_checkpointing(梯度检查点),以轻微计算重算为代价换取大量显存节约;
  • 将 per_device_train_batch_size 设为 1 或 2,同时成倍提高 gradient_accumulation_steps(保持总等效 Batch 不变);
  • 裁剪 max_length 至 1024 或 512。

3. 评测过拟合(训练 Loss 极低,但业务提问回答生硬或死板):

  • 减少训练轮数(垂直小数据集 2~3 个 Epochs 即可);
  • 在 LoRA 模块中增加 Dropout 参数(如 --lora_dropout 0.05);
  • 扩展数据样本的多样性,改写相似表达。

4. 灾难性遗忘(微调后原有日常对话或推理能力丢失):

  • 在当前运维数据集中,按 5%~10% 的比例混入高质量通用中英文开源问答集(如 Alpaca-CoT 数据);
  • 避免全量微调,坚持使用低秩 LoRA(Rank 建议 8~16)。