LLaMA-Factory微调实战:从环境到API部署

在大模型应用落地日益加速的今天,一个现实问题摆在开发者面前:如何在有限算力下快速定制出具备特定领域能力的语言模型?传统微调流程动辄需要数天调试、依赖管理复杂、代码门槛高,让许多团队望而却步。而开源社区中涌现出的一站式微调框架正在改变这一局面。

其中,LLaMA-Factory 凭借其极简的操作流程和强大的功能集成,成为当前最受欢迎的大模型微调工具之一。它不仅支持包括 LLaMA、Qwen、Baichuan、ChatGLM 在内的数十种主流架构,还统一了从数据准备、训练、评估到服务部署的完整链路。更重要的是,它的 WebUI 界面让非工程背景的研究者也能轻松上手。

本文将以 Meta-Llama-3-8B-Instruct 模型为例,带你走完一条完整的“端到端”微调路径——从环境配置开始,经过 LoRA 微调、效果验证、权重合并,最终以 OpenAI 兼容 API 的形式对外提供服务。整个过程无需编写核心训练代码,真正实现“开箱即用”。


环境准备:不是越贵越好,而是要配得准

很多人一上来就追求 A100 集群,但实际项目中更关键的是资源与任务的匹配度。对于像 Llama-3-8B 这样的中等规模模型,单张 24GB 显存的消费级显卡(如 RTX 4090)已足够支撑 QLoRA 微调。以下是推荐配置:

类别推荐配置
GPU至少一块 NVIDIA 显卡(推荐 A100 / RTX 4090),显存 ≥ 24GB
CUDA11.8 或 12.1
PyTorch2.0+ (需与CUDA版本匹配)
Python3.10 ~ 3.11
存储空间≥ 100GB(用于存放模型、缓存和训练输出)
系统Linux(Ubuntu 20.04/22.04 推荐)

💡 实践建议:若显存不足,可优先使用 QLoRA + gradient checkpointing 组合,在 24GB 显卡上完成微调;轻量测试时也可选用 Qwen-7B 或 Baichuan2-7B 等较小模型降低负担。


安装与依赖:一次搞定,避免后续踩坑

我们从源码安装入手,确保能使用最新特性:

git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory

为加速安装并减少网络波动影响,建议使用国内镜像源:

pip install -e ".[torch,metrics]" -i https://mirrors.aliyun.com/pypi/simple/

如果遇到依赖冲突,可以先跳过依赖检查再手动补全:

pip install --no-deps -e .

安装完成后,通过内置命令验证是否成功:

llamafactory-cli version

正常输出如下:

----------------------------------------------------------
| Welcome to LLaMA Factory, version 0.9.1.dev0           |
|                                                        |
| Project page: https://github.com/hiyouga/LLaMA-Factory |
----------------------------------------------------------

紧接着确认关键库的状态:

>>> import torch
>>> torch.cuda.is_available()
True
>>> torch.cuda.get_device_name(0)
'NVIDIA GeForce RTX 4090'
>>> torch.__version__
'2.4.0+cu121'

>>> import transformers
>>> transformers.__version__
'4.45.2'

这一步看似简单,却是后续所有操作的基础。我曾见过不少用户因 CUDA 版本不匹配导致 bitsandbytes 加载失败,务必提前排查。


模型获取:Hugging Face vs ModelScope

LLaMA-Factory 支持双平台模型加载,你可以选择 Hugging Face 或阿里云 ModelScope 下载目标模型。

Meta-Llama-3-8B-Instruct 为例,通过 ModelScope 获取更稳定:

git clone https://www.modelscope.cn/LLM-Research/Meta-Llama-3-8B-Instruct.git

或使用 HF 格式(需登录认证):

model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct

记得先运行:

huggingface-cli login

保存路径示例:

/srv/testenv/train/Meta-Llama-3-8B-Instruct

这个本地路径将在后续所有命令中作为 --model_name_or_path 参数传入。


原始模型推理:先看看“出厂设置”什么样

微调前必须了解基座模型的能力边界。我们可以用 webchat 快速启动网页对话界面:

llamafactory-cli webchat \
    --model_name_or_path /srv/testenv/train/Meta-Llama-3-8B-Instruct \
    --template llama3

访问 http://localhost:7860 即可交互。

🔍 关键点提醒:

  • --template 必须正确设置,否则会引发 prompt 错位甚至死循环生成。
  • 不同模型对应不同模板,参考官方文档 Supported Models 查询。
  • 多次运行时建议添加 --port 指定端口,避免冲突。

也可以用 YAML 配置简化重复命令:

# examples/inference/llama3.yaml
model_name_or_path: /srv/testenv/train/Meta-Llama-3-8B-Instruct
template: llama3

然后执行:

llamafactory-cli webchat examples/inference/llama3.yaml

此时输入“你是谁?”这类问题,观察原始回答风格,为后续对比微调效果建立基准。


数据集构建:质量决定上限

微调的本质是“教会”模型新的行为模式,而数据就是教材。LLaMA-Factory 使用 JSON 文件管理数据,并通过 dataset_info.json 注册。

修改内置数据集

项目自带 data/identity.json,可用于个性化身份微调。例如将助手名改为 “PonyBot”:

sed -i 's/{{name}}/PonyBot/g' data/identity.json
sed -i 's/{{author}}/LLaMA\ Factory\ Team/g' data/identity.json

查看内容示例:

[
  {
    "instruction": "你是谁?",
    "input": "",
    "output": "我是 PonyBot,由 LLaMA Factory Team 开发。"
  }
]

该数据集已在 data/dataset_info.json 中注册为 identity,可直接调用。

添加自定义任务数据集

引入广告文案生成任务 AdGen 数据集:

wget https://cloud.tsinghua.edu.cn/seafhttp/files/1746ec39-a653-4c81-9197-55383e942282/AdvertiseGen.tar.gz
tar -zxvf AdvertiseGen.tar.gz
mv AdvertiseGen LLaMA-Factory/data/

data/dataset_info.json 中注册:

,
"adgen_local": {
  "file_name": "AdvertiseGen/train.json",
  "columns": {
    "prompt": "content",
    "response": "summary"
  }
}

字段说明:
- file_name: 相对路径
- columns.prompt: 输入字段名
- columns.response: 输出字段名

现在就可以用 adgen_local 名称调用该数据集进行训练。


LoRA指令微调:高效训练的核心技巧

真正的重头戏来了。我们将使用 LoRA(Low-Rank Adaptation)技术进行有监督微调(SFT)。LoRA 的精髓在于冻结原模型权重,只训练低秩矩阵,极大降低显存消耗。

启动训练命令:

export NCCL_P2P_DISABLE="1"
export NCCL_IB_DISABLE="1"

llamafactory-cli train \
    --stage sft \
    --do_train \
    --model_name_or_path /srv/testenv/train/Meta-Llama-3-8B-Instruct \
    --dataset alpaca_gpt4_zh,identity,adgen_local \
    --dataset_dir ./data \
    --template llama3 \
    --finetuning_type lora \
    --output_dir ./saves/LLaMA3-8B/lora/sft \
    --overwrite_cache \
    --overwrite_output_dir \
    --cutoff_len 1024 \
    --preprocessing_num_workers 16 \
    --per_device_train_batch_size 2 \
    --per_device_eval_batch_size 1 \
    --gradient_accumulation_steps 8 \
    --lr_scheduler_type cosine \
    --logging_steps 50 \
    --warmup_steps 20 \
    --save_steps 100 \
    --eval_steps 50 \
    --evaluation_strategy steps \
    --load_best_model_at_end \
    --learning_rate 5e-5 \
    --num_train_epochs 5.0 \
    --max_samples 1000 \
    --val_size 0.1 \
    --plot_loss \
    --fp16

几个关键参数的经验之谈:

  • --cutoff_len 1024:控制上下文长度,太长易爆显存,太短损失信息;
  • --per_device_train_batch_size 2:根据显存调整,24GB 卡建议设为 2;
  • --gradient_accumulation_steps 8:模拟全局 batch size=16,有助于收敛;
  • --fp16:开启混合精度训练,节省约 40% 显存;
  • --max_samples:调试阶段可设小值加快迭代;
  • --val_size 0.1:自动划分 10% 作为验证集,无需手动拆分。

训练过程中会实时绘制 loss 曲线,结束后可在 ./saves/LLaMA3-8B/lora/sft 找到:
- adapter_model.bin:LoRA 权重文件
- training_args.bin:训练参数快照
- trainer_state.json:训练状态记录
- runs/:TensorBoard 日志目录


动态加载推理:不用合并也能试效果

训练完成后,可以直接加载基础模型 + LoRA 权重进行动态推理,省去合并步骤。

命令行对话模式:

llamafactory-cli chat \
    --model_name_or_path /srv/testenv/train/Meta-Llama-3-8B-Instruct \
    --adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
    --template llama3 \
    --finetuning_type lora

提问:“帮我写一段关于儿童保温杯的广告语”,你应该能看到更具营销感的回答,而非通用描述。

同样可通过 WebChat 可视化体验:

llamafactory-cli webchat examples/inference/llama3_lora_sft.yaml

YAML 配置如下:

model_name_or_path: /srv/testenv/train/Meta-Llama-3-8B-Instruct
adapter_name_or_path: ./saves/LLaMA3-8B/lora/sft
template: llama3
finetuning_type: lora

这种方式适合快速验证,尤其在多适配器切换场景下非常实用。


效果评估:别只靠肉眼看

人工测试虽直观,但缺乏量化依据。LLaMA-Factory 支持批量预测并计算 BLEU、ROUGE 等指标。

先安装评估依赖:

pip install jieba rouge-chinese nltk

运行预测:

llamafactory-cli train \
    --stage sft \
    --do_predict \
    --model_name_or_path /srv/testenv/train/Meta-Llama-3-8B-Instruct \
    --adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
    --eval_dataset adgen_local \
    --dataset_dir ./data \
    --template llama3 \
    --finetuning_type lora \
    --output_dir ./saves/LLaMA3-8B/lora/predict \
    --cutoff_len 1024 \
    --per_device_eval_batch_size 1 \
    --max_samples 50 \
    --predict_with_generate

输出目录将生成两个关键文件:
- generated_predictions.jsonl:每条样本的真实 label 与生成结果
- predict_results.json:自动计算的各项指标

常见指标解读:
| 指标 | 含义 |
|------|------|
| BLEU-4 | 四元语法匹配度,越高越好(0~100) |
| rouge-1, rouge-2 | 一元/二元召回率,反映关键词覆盖 |
| rouge-l | 最长公共子序列相似度,衡量整体一致性 |
| predict_samples_per_second | 推理吞吐量,性能参考 |

这些数字可用于横向比较不同训练策略的效果,指导超参优化。


模型合并导出:走向独立部署的关键一步

如果你想脱离 LLaMA-Factory 框架部署,就需要将 LoRA 权重合并进原模型。

使用 export 命令完成融合:

llamafactory-cli export \
    --model_name_or_path /srv/testenv/train/Meta-Llama-3-8B-Instruct \
    --adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
    --template llama3 \
    --finetuning_type lora \
    --export_dir ./merged-model-path \
    --export_size 2 \
    --export_device cpu \
    --export_legacy_format false

参数说明:
- --export_dir:合并后模型保存路径
- --export_size:分块大小(GB),便于传输
- --export_device cpu:推荐 CPU 合并,避免显存溢出
- --export_legacy_format false:使用新格式,兼容性更好

合并后的模型是一个标准 Hugging Face 模型目录,可用于:
- Transformers 直接加载推理
- vLLM 高速服务部署
- 上传至 Hugging Face Model Hub 分享


WebUI 可视化面板:零代码玩家的福音

LLaMA-Factory 提供了功能完整的图形界面 webui,特别适合初学者或非技术背景用户。

启动命令:

CUDA_VISIBLE_DEVICES=0 GRADIO_SHARE=1 GRADIO_SERVER_PORT=7860 llamafactory-cli webui

访问 http://localhost:7860,你会看到五大模块:
- Train:拖拽式配置训练参数,实时看 loss 曲线
- Evaluate:一键跑 MMLU/CEVAL/CMLLU 测评
- Inference:交互式对话测试
- Export:可视化选择模型与适配器合并
- Dataset:管理自定义数据集

无需写一行代码,即可完成全流程操作。我在带实习生做项目时,常用这套界面让他们快速理解微调逻辑。


API 服务部署:接入外部系统的桥梁

最后一步,把模型变成可用的服务接口。LLaMA-Factory 的 API 完全兼容 OpenAI 协议,迁移成本几乎为零。

启动 API 服务(动态加载 LoRA)

CUDA_VISIBLE_DEVICES=0 API_PORT=8000 llamafactory-cli api \
    --model_name_or_path /srv/testenv/train/Meta-Llama-3-8B-Instruct \
    --adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
    --template llama3 \
    --finetuning_type lora

服务监听地址:http://localhost:8000/v1

Python 客户端调用示例:

import os
from openai import OpenAI
from transformers.utils.versions import require_version

require_version("openai>=1.5.0", "To fix: pip install openai>=1.5.0")

if __name__ == '__main__':
    port = os.environ.get("API_PORT", 8000)
    client = OpenAI(
        api_key="0",  # LLaMA-Factory 不校验 key
        base_url=f"http://localhost:{port}/v1"
    )

    messages = [{"role": "user", "content": "请写一则关于防晒霜的广告语"}]
    response = client.chat.completions.create(
        model="default",  # 实际加载的是微调模型
        messages=messages,
        temperature=0.7,
        max_tokens=100
    )

    print(response.choices[0].message.content)

输出应体现微调后的风格倾向,比如语言更具营销色彩。

⚠️ 注意事项:若想使用 vLLM 加速推理,必须先合并模型,再以 --infer_backend vllm 启动:

llamafactory-cli api \
    --model_name_or_path ./merged-model-path \
    --template llama3 \
    --infer_backend vllm \
    --vllm_enforce_eager

主流 Benchmark 自动评测:防止“学偏了”

微调不能以牺牲通用能力为代价。LLaMA-Factory 内置了多个权威测评脚本,帮助你判断是否存在“灾难性遗忘”。

支持任务:
- MMLU(英文多任务理解)
- CMMLU(中文多任务理解)
- C-Eval(综合性中文评测)

以 MMLU 英文测试为例:

llamafactory-cli eval \
    --model_name_or_path ./merged-model-path \
    --template llama3 \
    --task mmlu_test \
    --lang en \
    --n_shot 5 \
    --batch_size 1

典型输出:

Average: 63.42
STEM: 58.21
Social Sciences: 71.33
Humanities: 60.15
Other: 68.90

理想情况是:垂直领域能力提升的同时,通用知识水平保持稳定。如果发现某类得分大幅下降,可能需要重新设计训练数据分布。


这种高度集成的设计思路,正引领着智能音频设备向更可靠、更高效的方向演进。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐