「LLaMA-Factory」 是一个开源的大模型微调框架,支持 100+ 种 LLM 的微调训练。
特点 | 说明 |
|---|---|
「模型支持广泛」 | LLaMA、Qwen、ChatGLM、Mistral、Baichuan 等 |
「微调方法丰富」 | Full、LoRA、QLoRA、Freeze 等 |
「零代码操作」 | 提供 WebUI 界面,无需编写代码 |
「一站式流程」 | 训练、评估、对话、导出一体化 |
适用于没有 GPU 的环境,仅用于学习和测试。
mkdir -p llama-factory/{data,output,cache}
cd llama-factory
version: "3.9"
services:
llamafactory:
image:hiyouga/llamafactory:latest
container_name:llamafactory
ports:
-"7860:7860" # WebUI 端口
-"8000:8000" # API 端口
volumes:
-./data:/app/data # 数据集目录
-./output:/app/output # 模型输出目录
-./cache:/root/.cache # 模型缓存目录
environment:
-GRADIO_SERVER_NAME=0.0.0.0
-GRADIO_SERVER_PORT=7860
-USE_MODELSCOPE_HUB=1
command:llamafactory-cliwebui
restart:unless-stopped
stdin_open:true
tty:true
docker-compose pull
docker-compose up -d
打开浏览器访问:http://localhost:7860
适用于有 NVIDIA GPU 的环境,推荐用于实际微调任务。
# 检查 GPU 是否可用
nvidia-smi
version: "3.9"
services:
llamafactory:
image:hiyouga/llamafactory:latest
container_name:llamafactory
ports:
-"7860:7860"
-"8000:8000"
volumes:
-./data:/app/data
-./output:/app/output
-./cache:/root/.cache
-./saves:/app/saves # 检查点保存目录
environment:
-GRADIO_SERVER_NAME=0.0.0.0
-GRADIO_SERVER_PORT=7860
-USE_MODELSCOPE_HUB=1 # 使用 ModelScope 下载模型(国内更快)
command:llamafactory-cliwebui
restart:unless-stopped
stdin_open:true
tty:true
deploy:
resources:
reservations:
devices:
-driver:nvidia
count:all # 使用所有 GPU,可改为具体数字如 1
capabilities:[gpu]
docker-compose pull
docker-compose up -d
docker exec llamafactory nvidia-smi
如果不使用 Docker,可以本地安装。
# 克隆仓库
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
# 创建虚拟环境
conda create -n llamafactory python=3.10 -y
conda activate llamafactory
# 安装依赖
pip install -e ".[torch,metrics]"
# 启动 WebUI
llamafactory-cli webui
标签页 | 功能 | 说明 |
|---|---|---|
「Train」 | 训练 | 配置并启动微调任务 |
「Evaluate」 | 评估 | 评估模型在测试集上的表现 |
「Chat」 | 对话 | 与模型进行对话测试 |
「Export」 | 导出 | 将微调后的模型导出 |
┌─────────────────────────────────────────────────────────────┐
│ Model 区域 │
│ ├── Model name(模型选择) │
│ ├── Finetuning method(微调方法) │
│ └── Quantization bit(量化位数) │
├─────────────────────────────────────────────────────────────┤
│ Data 区域 │
│ ├── Dataset(数据集选择) │
│ └── Max samples(最大样本数) │
├─────────────────────────────────────────────────────────────┤
│ Train 区域 │
│ ├── Learning rate / Epochs / Batch size │
│ ├── Gradient accumulation / Compute type │
│ └── Output dir │
├─────────────────────────────────────────────────────────────┤
│ LoRA 区域(选择 LoRA 方法时显示) │
│ ├── LoRA rank / LoRA alpha / LoRA dropout │
│ └── LoRA target │
├─────────────────────────────────────────────────────────────┤
│ 日志输出区域 │
│ └── 训练进度、loss 等信息 │
└─────────────────────────────────────────────────────────────┘
以下是一个完整的微调示例,使用 Qwen2-0.5B 模型 + identity 数据集。
如果 Dataset 下拉框为空,需要先下载数据集配置:
# 进入容器下载
docker exec llamafactory wget -O /app/data/dataset_info.json \
https://raw.githubusercontent.com/hiyouga/LLaMA-Factory/main/data/dataset_info.json
docker exec llamafactory wget -O /app/data/identity.json \
https://raw.githubusercontent.com/hiyouga/LLaMA-Factory/main/data/identity.json
参数 | CPU 环境 | GPU 环境 |
|---|---|---|
「Model name」 | Qwen/Qwen2-0.5B | Qwen/Qwen2-7B 或更大 |
「Finetuning method」 | lora | lora / qlora |
「Quantization bit」 | None | 4(QLoRA)或 None |
参数 | 设置值 | 说明 |
|---|---|---|
「Dataset」 | identity | 内置身份认知数据集 |
「Max samples」 | 100 | 限制样本数,加快测试 |
参数 | CPU 环境 | GPU 环境 |
|---|---|---|
「Learning rate」 | 5e-5 | 5e-5 |
「Epochs」 | 1 | 3 |
「Batch size」 | 1 | 4-8 |
「Gradient accumulation」 | 4 | 4 |
「Compute type」 | fp32 | bf16 / fp16 |
「Output dir」 | output/test | output/test |
参数 | 推荐值 | 说明 |
|---|---|---|
「LoRA rank」 | 8 | 低秩矩阵维度 |
「LoRA alpha」 | 16 | 缩放系数 |
「LoRA dropout」 | 0.1 | Dropout 比例 |
点击页面底部的 「Start」 按钮,观察日志输出。
「作用」:控制每次参数更新的步长大小
新参数 = 旧参数 - 学习率 × 梯度
学习率 | 效果 |
|---|---|
太大(如 1e-2) | 训练不稳定,loss 震荡甚至爆炸 |
太小(如 1e-7) | 收敛极慢,可能陷入局部最优 |
合适(如 5e-5) | 稳定下降,收敛到较优解 |
「推荐值」:
微调方法 | 推荐学习率 |
|---|---|
Full | 1e-5 ~ 5e-6 |
LoRA | 1e-4 ~ 5e-5 |
QLoRA | 1e-4 ~ 2e-4 |
「作用」:数据集完整遍历的次数
1 Epoch = 模型看完所有训练数据一遍
Epochs | 效果 |
|---|---|
太少(1-2) | 欠拟合,模型学得不够 |
太多(10+) | 过拟合,模型"背答案",泛化差 |
合适(3-5) | 学到规律,又能泛化 |
「判断依据」:观察 loss 曲线
「作用」:每次参数更新使用多少样本计算梯度
Batch Size | 优点 | 缺点 |
|---|---|---|
小(1-4) | 显存占用低,更新频繁 | 梯度噪声大,训练不稳定 |
大(32-128) | 梯度估计准确,训练稳定 | 显存占用高 |
「作用」:在显存不足时模拟大 batch 训练
实际等效 Batch = batch_size × gradient_accumulation
「示例」:
「作用」:限制梯度的最大值,防止梯度爆炸
if 梯度范数 > max_grad_norm:
梯度 = 梯度 × (max_grad_norm / 梯度范数)
「通常设为 1.0」,基本不需要调整。
类型 | 精度 | 显存 | 速度 | 适用场景 |
|---|---|---|---|---|
「fp32」 | 高 | 大 | 慢 | CPU、精度要求高 |
「fp16」 | 中 | 小 | 快 | NVIDIA GPU |
「bf16」 | 中 | 小 | 快 | 新款 GPU(A100、RTX 30/40 系列) |
「重要」:CPU 必须用 fp32,否则会报错。
策略 | 行为 |
|---|---|
「constant」 | 保持不变 |
「linear」 | 线性下降 |
「cosine」 | 余弦曲线下降(推荐) |
「作用」:训练初期逐渐增加学习率
warmup_ratio = 0.1 表示前 10% 的步数用于预热
学习率变化曲线:
0 ──→ 预热阶段 ──→ 最大学习率 ──→ 逐渐下降 ──→ 0
(warmup) (peak) (decay)
参数 | 作用 | 推荐值 |
|---|---|---|
「LoRA rank (r)」 | 低秩矩阵的秩,越大表达能力越强 | 8-64 |
「LoRA alpha」 | 缩放系数,通常设为 rank 的 2 倍 | 16-128 |
「LoRA dropout」 | Dropout 比例,防止过拟合 | 0.05-0.1 |
「LoRA target」 | 应用 LoRA 的目标模块 | 默认即可 |
「缩放关系」:
实际缩放 = alpha / rank
「梯度 = 告诉模型"往哪个方向调整参数,能让预测更准"」
形象比喻:蒙眼下山
梯度值 | 含义 | 应该怎么调 |
|---|---|---|
正数(如 +0.5) | 参数增大 → loss 增大 | 应该减小参数 |
负数(如 -0.3) | 参数增大 → loss 减小 | 应该增大参数 |
接近 0 | 参数变化对 loss 影响小 | 已接近最优 |
LLaMA-Factory 支持多种格式,最常用的是 「Alpaca 格式」:
[
{
"instruction": "用户的指令/问题",
"input": "可选的额外输入(可为空)",
"output": "期望模型输出的回答"
}
]
创建文件 data/my_custom_data.json:
[
{
"instruction": "你们的营业时间是什么?",
"input": "",
"output": "我们的营业时间是周一至周五 9:00-18:00,周末及法定节假日休息。"
},
{
"instruction": "如何申请退款?",
"input": "",
"output": "您可以在订单页面点击"申请退款",填写退款原因后提交。我们会在1-3个工作日内处理您的申请。"
},
{
"instruction": "支持哪些支付方式?",
"input": "",
"output": "我们支持微信支付、支付宝、银行卡等多种支付方式。"
}
]
编辑 data/dataset_info.json,添加:
{
"my_custom_data": {
"file_name": "my_custom_data.json"
},
// ... 其他数据集
}
docker cp data/my_custom_data.json llamafactory:/app/data/
docker cp data/dataset_info.json llamafactory:/app/data/
刷新 WebUI 页面后,即可在 Dataset 下拉框中看到新数据集。
要点 | 说明 |
|---|---|
「数据量」 | 建议至少 100-1000 条,越多越好 |
「数据质量」 | 确保 output 是高质量的标准答案 |
「多样性」 | 同一问题用不同方式表述 |
「格式统一」 | 保持 JSON 格式正确 |
[
{
"conversations": [
{"from": "human", "value": "你好"},
{"from": "gpt", "value": "你好!有什么可以帮助你的吗?"},
{"from": "human", "value": "今天天气怎么样?"},
{"from": "gpt", "value": "抱歉,我无法获取实时天气信息。"}
]
}
]
注册时需要指定格式:
{
"my_sharegpt_data": {
"file_name": "my_sharegpt_data.json",
"formatting": "sharegpt",
"columns": {
"messages": "conversations"
}
}
}
导出后的模型可以独立使用,无需再加载 LoRA 权重。
微调完成后,需要将模型部署到生产环境提供服务。
方式 | 适用场景 | 复杂度 | 性能 |
|---|---|---|---|
「vLLM」 | 高并发 API 服务 | 中 | 极高 |
「Ollama」 | 本地/轻量部署 | 低 | 中 |
「Text Generation Inference (TGI)」 | 企业级部署 | 中 | 高 |
「LLaMA-Factory API」 | 快速测试 | 低 | 中 |
「Transformers 直接加载」 | 开发调试 | 低 | 低 |
┌─────────────────────────────────────────────────────────────┐
│ 1. 导出模型(合并 LoRA 权重) │
│ ↓ │
│ 2. 选择推理框架(vLLM / TGI / Ollama) │
│ ↓ │
│ 3. 部署为 API 服务 │
│ ↓ │
│ 4. 业务系统通过 HTTP 调用 │
└─────────────────────────────────────────────────────────────┘
「特点」:高吞吐、低延迟、支持并发,生产环境首选
# 安装
pip install vllm
# 启动 API 服务
python -m vllm.entrypoints.openai.api_server \
--model /path/to/merged_model \
--host 0.0.0.0 \
--port 8000
import openai
client = openai.OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed"
)
response = client.chat.completions.create(
model="/path/to/merged_model",
messages=[{"role": "user", "content": "你好"}]
)
print(response.choices[0].message.content)
# docker-compose.yml
version:"3.9"
services:
vllm:
image:vllm/vllm-openai:latest
container_name:vllm-server
ports:
-"8000:8000"
volumes:
-./models:/models
command:>
--model /models/merged_model
--host 0.0.0.0
--port 8000
deploy:
resources:
reservations:
devices:
-driver:nvidia
count:1
capabilities:[gpu]
「特点」:一键部署,适合本地和轻量场景
# 1. 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 2. 创建 Modelfile
cat > Modelfile << EOF
FROM /path/to/merged_model
PARAMETER temperature 0.7
EOF
# 3. 创建模型
ollama create my-model -f Modelfile
# 4. 运行
ollama run my-model
curl http://localhost:11434/api/generate -d '{
"model": "my-model",
"prompt": "你好"
}'
「特点」:无需额外部署,适合快速测试
# 启动 API 服务
llamafactory-cli api \
--model_name_or_path Qwen/Qwen2-0.5B \
--adapter_name_or_path /path/to/lora_checkpoint \
--template qwen
访问 http://localhost:8000/docs 查看 API 文档。
生产部署前,需要将 LoRA 权重合并到基座模型:
llamafactory-cli export \
--model_name_or_path Qwen/Qwen2-0.5B \
--adapter_name_or_path saves/Qwen2-0.5B/lora/train_xxx \
--template qwen \
--export_dir ./merged_model
┌─────────────────┐
│ 负载均衡器 │
│ (Nginx/K8s) │
└────────┬────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ vLLM 实例 1 │ │ vLLM 实例 2 │ │ vLLM 实例 3 │
│ (GPU 1) │ │ (GPU 2) │ │ (GPU 3) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────┴───────────────────┘
│
┌────────▼────────┐
│ 模型存储 │
│ (NFS/S3) │
└─────────────────┘
方案 | 并发能力 | 显存优化 | 部署难度 | 适用场景 |
|---|---|---|---|---|
「vLLM」 | 高 | PagedAttention | 中 | 生产环境首选 |
「TGI」 | 高 | 连续批处理 | 中 | HuggingFace 生态 |
「Ollama」 | 低 | 一般 | 低 | 本地/演示 |
「LLaMA-Factory API」 | 低 | 一般 | 低 | 开发测试 |
优化项 | 方法 |
|---|---|
「量化」 | 使用 AWQ/GPTQ 量化减少显存 |
「批处理」 | 开启 continuous batching |
「缓存」 | 使用 KV Cache 加速推理 |
「多卡」 | Tensor Parallel 分布式推理 |
import requests
def chat(prompt):
response = requests.post(
"http://localhost:8000/v1/chat/completions",
json={
"model": "merged_model",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.7,
"max_tokens": 512
}
)
return response.json()["choices"][0]["message"]["content"]
# 使用
answer = chat("你好,请介绍一下你自己")
print(answer)
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed"
)
def chat(prompt):
response = client.chat.completions.create(
model="merged_model",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=512
)
return response.choices[0].message.content
# 使用
answer = chat("你好,请介绍一下你自己")
print(answer)
「原因」:CPU 不支持 bf16 精度
「解决」:将 Compute type 改为 fp32
「原因」:容器内没有数据集配置文件
「解决」:
docker exec llamafactory wget -O /app/data/dataset_info.json \
https://raw.githubusercontent.com/hiyouga/LLaMA-Factory/main/data/dataset_info.json
「解决方案」:
方法 | 操作 |
|---|---|
减小 batch_size | 设为 1-2 |
增加梯度累积 | gradient_accumulation 设为 8-16 |
使用 QLoRA | 开启 4-bit 量化 |
减小模型 | 选择更小的模型(如 0.5B、1.8B) |
减小序列长度 | 降低 cutoff_length |
「可能原因及解决」:
原因 | 解决方案 |
|---|---|
CPU 训练 | 使用 GPU |
模型太大 | 选择更小的模型 |
精度设置 | GPU 使用 bf16/fp16 |
「解决」:使用 ModelScope 镜像
environment:
- USE_MODELSCOPE_HUB=1
# 查看容器日志
docker logs -f llamafactory
# 进入容器
docker exec -it llamafactory bash
# 停止服务
docker-compose down
# 重启服务
docker-compose restart
# 查看 GPU 使用情况(GPU 环境)
docker exec llamafactory nvidia-smi
参数 | 值 |
|---|---|
Model | Qwen/Qwen2-0.5B |
Finetuning method | lora |
Batch size | 1 |
Gradient accumulation | 4 |
Compute type | fp32 |
LoRA rank | 8 |
参数 | 值 |
|---|---|
Model | Qwen/Qwen2-1.5B |
Finetuning method | lora |
Quantization bit | None |
Batch size | 4 |
Gradient accumulation | 4 |
Compute type | bf16 |
LoRA rank | 16 |
参数 | 值 |
|---|---|
Model | Qwen/Qwen2-7B |
Finetuning method | lora |
Quantization bit | None |
Batch size | 8 |
Gradient accumulation | 2 |
Compute type | bf16 |
LoRA rank | 32 |
方法 | 说明 | 显存需求 | 适用场景 |
|---|---|---|---|
「Full」 | 更新所有参数 | 非常高 | 大规模数据、充足资源 |
「LoRA」 | 只训练低秩矩阵 | 低 | 最常用,效果好 |
「QLoRA」 | LoRA + 量化 | 更低 | 消费级显卡 |
「Freeze」 | 冻结部分层 | 中等 | 特定场景 |
LLaMA-Factory 提供了一个简单易用的大模型微调平台,通过 WebUI 可以零代码完成:
掌握本指南中的内容,你就可以开始自己的大模型微调之旅了!