惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
V
V2EX
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Y
Y Combinator Blog
小众软件
小众软件
Jina AI
Jina AI
V2EX - 技术
V2EX - 技术
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
博客园 - 三生石上(FineUI控件)
T
Threatpost
博客园 - 聂微东
Scott Helme
Scott Helme
IT之家
IT之家
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
MongoDB | Blog
MongoDB | Blog
T
Tor Project blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
About on SuperTechFans
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Check Point Blog
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
Attack and Defense Labs
Attack and Defense Labs
T
Tailwind CSS Blog
罗磊的独立博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Webroot Blog
Webroot Blog
Help Net Security
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest

博客园 - 小纸条

ruoyiai 启动指南 反向传播 numpy的使用 B 和 B+树 红黑树 ruoyi-vue 梯度下降法 博弈论 离散化 AcWing 907. 区间覆盖 AcWing 906. 区间分组 AcWing 908 最大不相交区间数量 AcWing 905. 区间选点 AcWing 104. 货仓选址 动态规划经典题 窗口函数 1226. 哲学家进餐 1195. 交替打印字符串 1117. H2O 生成 1116. 打印零与奇偶数 关联子查询
模型微调
小纸条 · 2026-07-03 · via 博客园 - 小纸条

LLaMA-Factory 大模型微调实操指南(实战版)

本指南基于实际项目经验编写,覆盖 环境安装 → 数据准备 → YAML 配置 → 训练启动 → 模型测试 → 合并导出 全流程。所有命令可直接执行,每个关键步骤附带预期输出。


下载微调工具LlamaFactory:https://github.com/hiyouga/LlamaFactory.git

1 环境安装

1.1 基础环境确认

# 确认 CUDA
cd ~
nvcc -V

预期输出:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Cuda compilation tools, release 12.2, V12.2.140

1.2 创建虚拟环境

conda create -n llama_factory python=3.10
conda activate llama_factory

1.3 安装 PyTorch

conda install pytorch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 pytorch-cuda=12.1 -c pytorch -c nvidia

1.4 安装 LLaMA-Factory

cd ~
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
# 以可编辑模式安装当前目录下的 Python 包,并额外安装 torch 和 metrics 相关的依赖。
pip install -e ".[torch,metrics]"

预期输出:

Successfully installed llamafactory-0.x.x ...

1.5 验证安装

python -m llamafactory.cli train -h

预期输出(节选):

usage: llamafactory-cli train [-h] [ARGS...]

training arguments:
  --stage {pt,sft,rm,ppo,dpo,kto}
  --do_train {True,False}
  --model_name_or_path MODEL_NAME_OR_PATH
  ...

说明: python -m llamafactory.clillamafactory-cli 更兼容,即使环境变量 PATH 没配好也能跑。


2 数据准备

2.1 创建数据集

cd ~/LLaMA-Factory/data
# 创建你的数据集文件
touch my_data.json

SFT 数据格式(Alpaca):

[
  {
    "instruction": "你是谁",
    "input": "",
    "output": "我是甄嬛,家父是大理寺少卿甄远道"
  },
  {
    "instruction": "帮我写一封请假条",
    "input": "",
    "output": "尊敬的张老师:\n\n您好!因身体不适,特向您请假一天..."
  }
]

DPO 偏好数据格式:

[
  {
    "instruction": "写一段关于春天的描写",
    "input": "",
    "chosen_output": "春风拂过柳梢,桃花映红了小桥流水,燕子在檐下呢喃。",
    "rejected_output": "春天来了,花开了,树绿了。"
  }
]

2.2 注册数据集

编辑 ~/LLaMA-Factory/data/dataset_info.json

{
  "my_data": {
    "file_name": "my_data.json"
  },
  "my_data_dpo": {
    "file_name": "my_data_dpo.json",
    "ranking": true
  }
}

关键: DPO 数据必须加 "ranking": true,否则 LLaMA-Factory 不会识别 chosen/rejected。


3 创建 YAML 配置文件

YAML 配置是最推荐的训练方式,可复用、可版本管理。

3.1 SFT 配置示例

创建 ~/LLaMA-Factory/my_train.yaml

### model
model_name_or_path: Qwen/Qwen2.5-3B-Instruct
trust_remote_code: true

### method
stage: sft
do_train: true
finetuning_type: lora
lora_rank: 8
lora_target: all

### dataset
dataset: my_data
template: qwen
cutoff_len: 1024
max_samples: 500
overwrite_cache: true

### output
output_dir: saves/my_model/lora/sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
report_to: none

### train
per_device_train_batch_size: 1
gradient_accumulation_steps: 4
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true

3.2 DPO 配置示例

### model
model_name_or_path: Qwen/Qwen2.5-3B-Instruct
adapter_name_or_path: saves/my_model/lora/sft   # 基于 SFT 的 LoRA 继续训练
trust_remote_code: true

### method
stage: dpo
do_train: true
finetuning_type: lora
lora_rank: 8
lora_target: all

### dataset
dataset: my_data_dpo
template: qwen
cutoff_len: 1024
max_samples: 500
overwrite_cache: true

### output
output_dir: saves/my_model/lora/dpo
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
report_to: none

### train
per_device_train_batch_size: 1
gradient_accumulation_steps: 4
learning_rate: 5.0e-5
num_train_epochs: 2.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true

### dpo
dpo_beta: 0.1

3.3 核心参数详解

参数 作用 建议值 说明
model_name_or_path 基础模型 Qwen/Qwen2.5-3B-Instruct 自动从 ModelScope 下载
trust_remote_code 信任远程代码 true Qwen 系列需要
stage 训练阶段 sft / dpo / pt
finetuning_type 微调方式 lora 个人练习首选
lora_rank LoRA 秩 8 效果与显存的平衡点
lora_target 作用层 all 初学者用 all,只作用注意力层用 q_proj,v_proj
dataset 数据集名称 my_data 对应 dataset_info.json 中的 key
template 提示词模板 qwen 必须与模型匹配
cutoff_len 最大序列长度 1024 根据数据长度调整
learning_rate 学习率 1e-4 (LoRA) / 5e-5 (DPO) LoRA 用较大学习率
num_train_epochs 训练轮数 3 数据量 1000 条左右时 3 轮
per_device_train_batch_size 单卡 batch 1 显存有限时设为 1
gradient_accumulation_steps 梯度累积 4 等效 batch = 1×4=4
bf16 bfloat16 精度 true Ampere 架构(30系/40系/A100)支持
dpo_beta DPO KL 系数 0.1 越大越保守

3.4 15GB 显存配置要点

# 15GB 显存稳妥配置
model_name_or_path: Qwen/Qwen2.5-3B-Instruct   # 3B 模型约 6GB
finetuning_type: lora                           # LoRA 约 2GB
per_device_train_batch_size: 1                  # 1GB
gradient_accumulation_steps: 4                  # 不增加显存
cutoff_len: 1024                                # 序列长度
bf16: true                                      # 省显存
# 总计约 10GB,留 5GB 余量

15GB 跑 3B 模型很稳。想上 7B 需要 QLoRA(quantization_bit: 4),但效果会打折。


4 启动训练

4.1 使用 ModelScope 下载模型(国内网络必备)

export USE_MODELSCOPE_HUB=1
cd ~/LLaMA-Factory
python -m llamafactory.cli train my_train.yaml

预期输出(首次运行会自动下载模型):

[INFO] Using ModelScope Hub
[INFO] Downloading model Qwen/Qwen2.5-3B-Instruct from ModelScope...
[INFO] Loading dataset my_data from data/my_data.json
[INFO] trainable params: 9,994,240 || all params: 3,000,000,000 || trainable%: 0.33
...
{'loss': 2.3451, 'learning_rate': 9.95e-05, 'epoch': 0.01}
{'loss': 1.8723, 'learning_rate': 9.50e-05, 'epoch': 0.05}
...
{'loss': 0.5891, 'learning_rate': 5.00e-07, 'epoch': 1.00}
...
***** train metrics *****
  train_loss = 0.9876
  train_runtime = 0:25:32

关键: USE_MODELSCOPE_HUB=1 让模型自动从 ModelScope(国内)下载,不走 HuggingFace(需要FQ)。

4.2 中断后继续训练

在 YAML 中增加:

resume_from_checkpoint: saves/my_model/lora/sft/checkpoint-500

或在命令行指定:

python -m llamafactory.cli train my_train.yaml \
    --resume_from_checkpoint saves/my_model/lora/sft/checkpoint-500

4.3 多卡训练

CUDA_VISIBLE_DEVICES=0,1 python -m llamafactory.cli train my_train.yaml

LLaMA-Factory 会自动使用 PyTorch DDP 分布式训练。


5 测试微调后的模型

5.1 使用 transformers + peft 测试(推荐,可集成到代码)

创建 ~/LLaMA-Factory/test_my_model.py

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
import torch

# 基础模型路径(从 ModelScope 缓存或本地)
BASE_PATH = "/root/.cache/modelscope/hub/models/Qwen/Qwen2___5-3B-Instruct"
ADAPTER_PATH = "saves/my_model/lora/sft"

# 加载 tokenizer
tokenizer = AutoTokenizer.from_pretrained(BASE_PATH, trust_remote_code=True)

# 加载基础模型
model = AutoModelForCausalLM.from_pretrained(
    BASE_PATH,
    torch_dtype=torch.bfloat16,
    device_map="cuda",
    trust_remote_code=True,
)

# 加载 LoRA 权重
model = PeftModel.from_pretrained(model, ADAPTER_PATH)
model.eval()

# 测试
prompt = "你是谁"
messages = [
    {"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},
    {"role": "user", "content": prompt},
]

# 构建 prompt
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)

# 编码输入
inputs = tokenizer(text, return_tensors="pt").to("cuda")

# 生成
with torch.no_grad():
    outputs = model.generate(
        **inputs,
        max_new_tokens=200,
        do_sample=True,
        temperature=0.7,
        top_p=0.9,
    )

# 解码输出(只取新生成的部分)
response = tokenizer.decode(
    outputs[0][inputs["input_ids"].shape[1]:],
    skip_special_tokens=True
)
print(response)

运行:

cd ~/LLaMA-Factory
python test_my_model.py

预期输出:

我是甄嬛,家父是大理寺少卿甄远道。

代码要点:

  • device_map="cuda" 直接放 GPU(也可以 "auto" 自动分配)
  • trust_remote_code=True Qwen 系列必须加
  • outputs[0][inputs["input_ids"].shape[1]:] 只取新生成的 token,不重复输入

5.2 使用 LLaMA-Factory 命令行测试

CUDA_VISIBLE_DEVICES=0 python -m llamafactory.cli chat \
    --model_name_or_path Qwen/Qwen2.5-3B-Instruct \
    --adapter_name_or_path saves/my_model/lora/sft \
    --template qwen \
    --finetuning_type lora

预期交互:

User> 你是谁
Assistant> 我是甄嬛,家父是大理寺少卿甄远道

6 合并导出

LoRA 权重需要合并到基础模型才能独立使用。

6.1 使用 LLaMA-Factory 合并

CUDA_VISIBLE_DEVICES=0 python -m llamafactory.cli export \
    --model_name_or_path Qwen/Qwen2.5-3B-Instruct \
    --adapter_name_or_path saves/my_model/lora/sft \
    --template qwen \
    --finetuning_type lora \
    --export_dir ./my-merged-model \
    --export_size 2 \
    --export_device cpu \
    --export_legacy_format False

预期输出:

[INFO] Loading model from Qwen/Qwen2.5-3B-Instruct
[INFO] Loading adapter from saves/my_model/lora/sft
[INFO] Merging adapter weights into model
[INFO] Saving merged model to ./my-merged-model
model-00001-of-00002.safetensors
model-00002-of-00002.safetensors
config.json
tokenizer.json

6.2 合并后测试

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

MODEL_PATH = "./my-merged-model"

tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
    MODEL_PATH,
    torch_dtype=torch.bfloat16,
    device_map="cuda",
    trust_remote_code=True,
)
model.eval()

# 直接推理,不需要 peft
messages = [{"role": "user", "content": "你是谁"}]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to("cuda")

with torch.no_grad():
    outputs = model.generate(**inputs, max_new_tokens=200)

print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))

7 完整流程速查

# Step 1: 准备数据
cd ~/LLaMA-Factory/data
vim my_data.json          # 写入数据
vim dataset_info.json     # 注册数据集

# Step 2: 写 YAML 配置
cd ~/LLaMA-Factory
vim my_train.yaml         # 写入训练配置

# Step 3: 启动训练
export USE_MODELSCOPE_HUB=1
python -m llamafactory.cli train my_train.yaml

# Step 4: 测试
python test_my_model.py

# Step 5: 合并导出
python -m llamafactory.cli export \
    --model_name_or_path Qwen/Qwen2.5-3B-Instruct \
    --adapter_name_or_path saves/my_model/lora/sft \
    --template qwen --finetuning_type lora \
    --export_dir ./my-merged-model --export_device cpu

8 常见问题

Q: 模型下载慢或失败?

  • 确保加了 export USE_MODELSCOPE_HUB=1
  • 或使用 ModelScope SDK 手动下载:snapshot_download('qwen/Qwen2.5-3B-Instruct')

Q: trust_remote_code=True 有什么用?

  • Qwen、ChatGLM 等非标准架构的模型需要加载自定义模型类,必须设为 true
  • 标准架构模型(Llama、Mistral)不需要

Q: 显存溢出?

  • 减小 cutoff_len(如 512)
  • 减小 per_device_train_batch_size(设为 1)
  • 增大 gradient_accumulation_steps(如 8)
  • 换更小的模型(3B → 1.5B)

Q: 测试时输出乱码?

  • 检查 template 是否与模型匹配(Qwen 用 qwen,Llama 用 llama3
  • 检查 apply_chat_template 的参数是否正确
  • 检查 tokenizer 的 eos_token 是否设置正确

Q: DPO 训练报错找不到 chosen/rejected?

  • 检查 dataset_info.json 中是否设置了 "ranking": true
  • 检查数据文件字段名是否正确

Q: bf16: true 报错不支持?

  • 只有 Ampere 架构(RTX 30系/40系、A100、A10、H100)支持 bf16
  • 老显卡(RTX 20系、V100)改用 fp16: true