LLaMA-Factory

LLaMA-Factory

  • 项目特色

    • 多种模型 :LLaMA、Mistral、Mixtral-MoE、Qwen、Yi、Gemma、Baichuan、ChatGLM、Phi 等等。
    • 集成方法 :(增量)预训练、指令监督微调、奖励模型训练、PPO 训练、DPO 训练 和 ORPO 训练。
    • 多种精度 :32 比特全参数微调、16 比特冻结微调、16 比特 LoRA 微调 和 基于 AQLM/AWQ/GPTQ/LLM.int8 的 2/4/8 比特 QLoRA 微调。
    • 先进算法 :GaLore、DoRA、LongLoRA、LLaMA Pro、LoRA+、LoftQ 和 Agent 微调。
    • 实用技巧 :FlashAttention-2、Unsloth、RoPE scaling、NEFTune 和 rsLoRA。
    • 实验监控 :LlamaBoard、TensorBoard、Wandb、MLflow 等等。
    • 极速推理 :基于 vLLM 的 OpenAI 风格 API、浏览器界面 和 命令行接口。

数据集

预训练数据集指令微调数据集偏好数据集

部分数据集的使用需要确认,使用下述命令登录您的 Hugging Face 账户。

1
2
pip install --upgrade huggingface_hub
huggingface-cli login

软硬件依赖

必需项 至少 推荐
python 3.8 3.10
torch 1.13.1 2.2.0
transformers 4.37.2 4.39.3
datasets 2.14.3 2.18.0
accelerate 0.27.2 0.28.0
peft 0.9.0 0.10.0
trl 0.8.1 0.8.1
可选项 至少 推荐
CUDA 11.6 12.2
deepspeed 0.10.0 0.14.0
bitsandbytes 0.39.0 0.43.0
flash-attn 2.3.0 2.5.6

硬件依赖

* 估算值

训练方法 精度 7B 13B 30B 70B 8x7B
全参数 AMP 120GB 240GB 600GB 1200GB 900GB
全参数 16 60GB 120GB 300GB 600GB 400GB
GaLore 16 16GB 32GB 64GB 160GB 120GB
部分参数 16 20GB 40GB 80GB 200GB 160GB
LoRA 16 16GB 32GB 64GB 160GB 120GB
QLoRA 8 10GB 20GB 40GB 80GB 60GB
QLoRA 4 6GB 12GB 24GB 48GB 30GB
QLoRA 2 4GB 8GB 16GB 24GB 18GB

安装过程

1.UV安装

1
2
3
4
5
6
7
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
uv init
uv python pin python3.10
uv pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e .[metrics]
#不配置 uv依赖,直接装torch gpu版本
uv pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu118

LLaMA Board 可视化界面

1
2
uv run llamafactory-cli webui
#bug,判断wsl为npu

2.普通安装

按照GitHub上介绍的过程安装即可,为了加快速度,增加了国内的pip 源。

1
2
3
4
5
git clone https://github.com/hiyouga/LLaMA-Factory.git
conda create -n llama_factory python=3.10
conda activate llama_factory
cd LLaMA-Factory
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e .[metrics]

可选的额外依赖项:deepspeed、metrics、unsloth、galore、vllm、bitsandbytes、gptq、awq、aqlm、qwen、quality

LLaMA Board 可视化界面

使用本地环境:

1
2
3
export CUDA_VISIBLE_DEVICES=0 # Windows 使用 `set CUDA_VISIBLE_DEVICES=0`

python src/train_web.py # 或 python -m llmtuner.webui.interface

数据准备

可以使用 HuggingFace / ModelScope 上的数据集或加载本地数据集。使用自定义数据集时,请更新 data/dataset_info.json 文件。

原始模型直接推理

CUDA_VISIBLE_DEVICES=0 是指定了当前程序使用第0张卡,是指定全局变量的作用, 也可以不使用

1
2
3
uv run llamafactory-cli webchat \
--model_name_or_path E:\Datasets\LLM\Llama-3.2-3B-Instruct \
--template llama3

需要注意的是,本次及后续所有的程序的入口都是 llamafactory-cli, 通过不同的参数控制现在是实现什么功能,比如现在是想使用网页版本直接推理,所以第一个参数设置为webchat, 所有的可选项包括

动作参数枚举 参数说明
version 显示版本信息
train 命令行版本训练
chat 命令行版本推理chat
export 模型合并和导出
api 启动API server,供接口调用
eval 使用mmlu等标准数据集做评测
webchat 前端版本纯推理的chat页面
webui 启动LlamaBoard前端页面,包含可视化训练,预测,chat,模型合并多个子页面

另外两个关键参数解释如下,后续的基本所有环节都会继续使用这两个参数

参数名称 参数说明
model_name_or_path 参数的名称(huggingface或者modelscope上的标准定义,如“meta-llama/Meta-Llama-3-8B-Instruct”), 或者是本地下载的绝对路径,如/media/codingma/LLM/llama3/Meta-Llama-3-8B-Instruct
template 模型问答时所使用的prompt模板,不同模型不同,请参考 https://github.com/hiyouga/LLaMA-Factory?tab=readme-ov-file#supported-models 获取不同模型的模板定义,否则会回答结果会很奇怪或导致重复生成等现象的出现。chat 版本的模型基本都需要指定,比如Meta-Llama-3-8B-Instruct的template 就是 llama3

当然你也可以提前把相关的参数存在yaml文件里,比如LLaMA-Factory/examples/inference/llama3.yaml at main · hiyouga/LLaMA-Factory, 本地位置是 examples/inference/llama3.yaml ,内容如下

1
2
model_name_or_path:  E:\Datasets\LLM\Llama-3.2-3B-Instruct
template: llama3

这样就可以通过如下命令启动,其效果跟上面是一样的,但是更方便管理

1
uv run llamafactory-cli webchat examples/inference/llama3.yaml

自定义数据集构建

数据集的格式要求在不同的阶段是不同的,本教程以sft阶段的数据集需求,将以系统自带的identity数据集和将自定义的一个商品文案生成数据集为例,介绍数据集的使用。更多详情可以在 https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README_zh.md 中找到相关解释。

系统目前支持 alpaca 和sharegpt两种数据格式,以alpaca为例,整个数据集是一个json对象的list,具体数据格式为

1
2
3
4
5
6
7
8
9
10
11
12
[
{
"instruction": "用户指令(必填)",
"input": "用户输入(选填)",
"output": "模型回答(必填)",
"system": "系统提示词(选填)",
"history": [
["第一轮指令(选填)", "第一轮回答(选填)"],
["第二轮指令(选填)", "第二轮回答(选填)"]
]
}
]

例子比如单轮(alpaca_data_zh_51k.json 中的例子, 数据集在data/dataset_info.json中注册为alpaca_zh)

1
2
3
4
5
{
"instruction": "写一个有效的比较语句",
"input": "篮球和足球",
"output": "篮球和足球都是受欢迎的运动。"
}

和多轮 (oaast_sft_zh.json 中的例子, 数据集在data/dataset_info.json中注册为oaast_sft_zh)

1
2
3
4
5
6
7
8
9
10
11
{
"instruction": "谢谢",
"input": "",
"output": "不用谢! 很高兴我提供的信息能够帮助到你! 如果还有什么其他问题也可以向我提问。",
"history": [
[
"请你给我写一个面试准备计划,我想要去面试微软的程序员岗位",
"首先,你可以去微软官网寻找招聘信息并申请面试。\n其次,您可以在社交媒体平台寻找微软公司对程序员的面试问题,并做好准备。\n最后,您可以自己对面试过程进行模拟,熟悉话题并减少紧张感。\n我希望你能面试成功。"
]
]
}

所以我们训练的数据最好也转换成这种格式,然后在 data/dataset_info.json中进行注册(如果不做字段名称转换,则需要在注册的时候在 columns字段中做两个数据的映射配置)

使用两个具体的例子来说明数据集的使用

1.你是谁:

第一个是系统自带的identity.json数据集(已默认在data/dataset_info.json 注册为identity),对应文件已经在data目录下,我们通过操作系统的文本编辑器的替换功能,可以替换其中的NAME 和 AUTHOR ,换成我们需要的内容。如果是linux系统,可以使用sed 完成快速替换。比如助手的名称修改为PonyBot, 由 LLaMA Factory 开发

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

替换前

1
2
3
4
5
{
"instruction": "Who are you?",
"input": "",
"output": "Hello! I am {{name}}, an AI assistant developed by {{author}}. How can I assist you today?"
}

替换后

1
2
3
4
5
{
"instruction": "Who are you?",
"input": "",
"output": "I am PonyBot, an AI assistant developed by LLaMA Factory. How can I assist you today?"
}
2.微调:

第二个是一个商品文案生成数据集,原始链接为 https://cloud.tsinghua.edu.cn/f/b3f119a008264b1cabd1/?dl=1

原始格式如下,很明显,训练目标是输入content (也就是prompt), 输出 summary (对应response)

1
2
3
4
{
"content": "类型#裤*版型#宽松*风格#性感*图案#线条*裤型#阔腿裤",
"summary": "宽松的阔腿裤这两年真的吸粉不少,明星时尚达人的心头爱。毕竟好穿时尚,谁都能穿出腿长2米的效果宽松的裤腿,当然是遮肉小能手啊。上身随性自然不拘束,面料亲肤舒适贴身体验感棒棒哒。系带部分增加设计看点,还让单品的设计感更强。腿部线条若隐若现的,性感撩人。颜色敲温柔的,与裤子本身所呈现的风格有点反差萌。"
}

想将该自定义数据集放到我们的系统中使用,则需要进行如下两步操作

  1. 复制该数据集到 data目录下
  2. 修改 data/dataset_info.json 新加内容完成注册, 该注册同时完成了3件事
  • 自定义数据集的名称为adgen_local,后续训练的时候就使用这个名称来找到该数据集
  • 指定了数据集具体文件位置
  • 定义了原数据集的输入输出和我们所需要的格式之间的映射关系

基于LoRA的sft指令微调

在准备好数据集之后,我们就可以开始准备训练了,我们的目标就是让原来的LLaMA3模型能够学会我们定义的“你是谁”,同时学会我们希望的商品文案的一些生成。

这里我们先使用命令行版本来做训练,从命令行更容易学习相关的原理。

本脚本参数改编自 LLaMA-Factory/examples/train_lora/llama3_lora_sft.yaml at main · hiyouga/LLaMA-Factory

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
CUDA_VISIBLE_DEVICES=0 llamafactory-cli train \
--stage sft \
--do_train \
--model_name_or_path /media/codingma/LLM/llama3/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

windows uv对应脚本 :

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
uv run llamafactory-cli train `
--stage sft `
--do_train `
--model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct `
--dataset alpaca_gpt4_zh,identity,adgen_local `
--dataset_dir ./data `
--template llama3 `
--finetuning_type lora `
--output_dir ./saves/LLaMA3.2-3B/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 `
--learning_rate 5e-5 `
--num_train_epochs 5.0 `
--max_samples 1000 `
--val_size 0.1 `
--plot_loss `
--fp16

#报错
--evaluation_strategy steps `
--load_best_model_at_end `
--evaluation_strategy steps \
--load_best_model_at_end \
这两行参数在windows下报错,修改epochs和steps参数并不能正常通过命令行传入
(1)Some specified arguments are not used by the HfArgumentParser
(2)--load_best_model_at_end requires the save and eval strategy to match, but found
- Evaluation strategy: no
- Save strategy: steps
删除后正常

关于参数的完整列表和解释可以通过如下命令来获取

1
llamafactory-cli train -h

这里对部分关键的参数做一下解释,model_name_or_path 和template 上文已解释

参数名称 参数说明
stage 当前训练的阶段,枚举值,有“sft”,”pt”,”rm”,”ppo”等,代表了训练的不同阶段,这里我们是有监督指令微调,所以是sft
do_train 是否是训练模式
dataset 使用的数据集列表,所有字段都需要按上文在data_info.json里注册,多个数据集用”,”分隔
dataset_dir 数据集所在目录,这里是 data,也就是项目自带的data目录
finetuning_type 微调训练的类型,枚举值,有”lora”,”full”,”freeze”等,这里使用lora
output_dir 训练结果保存的位置
cutoff_len 训练数据集的长度截断
per_device_train_batch_size 每个设备上的batch size,最小是1,如果GPU 显存够大,可以适当增加
fp16 使用半精度混合精度训练
max_samples 每个数据集采样多少数据
val_size 随机从数据集中抽取多少比例的数据作为验证集
  1. pt (Pre-training / 预训练)

    • 目标: 让模型学习语言的基本规律、语法结构、世界知识和上下文理解能力。这是构建强大 LLM 的基础。
    • 数据: 通常使用海量的、无标注的文本数据,例如来自互联网的书籍、文章、网站内容等。
    • 任务: 最常见的预训练任务是语言建模 (Language Modeling)
      • Causal Language Modeling (CLM) / 因果语言建模: 模型学习根据前面的文本预测下一个词 (token)。例如,给定 “今天天气很”,模型应该能预测出 “好”、”晴朗” 等。GPT 系列模型主要采用这种方式。
      • Masked Language Modeling (MLM) / 掩码语言建模: 模型学习预测文本中被随机遮盖 (mask) 掉的词。例如,给定 “今天[MASK]很好”,模型应该能预测出 “[MASK]” 是 “天气”。BERT 系列模型主要采用这种方式。
    • 产出: 一个基础模型 (base model)。这个模型拥有广泛的知识和语言理解能力,但可能不擅长直接回答问题或遵循特定指令。它更像是一个知识库,而不是一个对话助手。
    • 特点: 计算量巨大,需要大量的计算资源和时间。
  2. sft (Supervised Fine-Tuning / 指令微调 / 有监督微调)

    • 目标: 教会预训练好的模型如何遵循人类的指令,并以期望的格式生成回答。这是让模型从一个“知识库”转变为一个“助手”的关键一步。
    • 数据: 使用高质量的、成对的“指令-回答”(instruction-response) 数据集。这些数据通常由人工编写或筛选,或者由更强大的模型生成后再经人工校验。Alpaca 格式的数据就是典型的 SFT 数据。
      • 例如:
        • 指令: “写一首关于春天的诗”
        • 回答: (一首关于春天的诗)
        • 指令: “解释什么是黑洞”
        • 回答: (关于黑洞的解释)
    • 任务: 模型学习在给定一个指令 (可能还有额外的输入上下文) 的情况下,生成一个符合该指令的、高质量的回答。这仍然是一个监督学习任务,模型试图最小化其生成的回答与数据集中标准回答之间的差异。
    • 产出: 一个经过指令微调的模型。这个模型能够更好地理解并执行用户的指令,生成的回答也更有针对性。
    • 特点: 相比预训练,SFT 需要的数据量较少,计算成本也低得多。但数据质量对 SFT 的效果至关重要。
  3. rm (Reward Modeling / 奖励模型训练)

    • 目标: 训练一个模型,使其能够评估给定指令下,模型生成的不同回答的质量好坏,并给出一个标量分数 (奖励值) 来表示其质量。这个奖励模型是后续强化学习阶段 (PPO) 的核心。
    • 数据: 需要人类对模型生成的多个回答进行排序或打分的数据。
      • 通常的做法是:给定一个相同的用户指令,让 SFT 阶段的模型生成多个不同的回答 (或者从不同模型收集回答)。然后,让人类标注员对这些回答进行排序,指出哪个更好,哪个次之,哪个最差。
      • 例如:
        • 指令: “推荐一部科幻电影”
        • 回答 A: “《星际穿越》”
        • 回答 B: “《流浪地球》”
        • 回答 C: “《银翼杀手2049》”
        • 人类标注: B > A > C (表示 B 最好,C 最差)
    • 任务: 奖励模型学习预测人类对回答的偏好。它输入一个指令和模型的一个回答,输出一个标量奖励分数。目标是让奖励模型给出的分数与人类的排序偏好尽可能一致(例如,人类认为更好的回答,奖励模型也应该给出更高的分数)。
    • 产出: 一个奖励模型 (Reward Model, RM)。这个模型本身不直接与用户交互,而是作为后续 PPO 阶段的“裁判”。
    • 特点: 需要大量的人类标注数据,标注成本较高。奖励模型的质量直接影响 PPO 阶段的效果。
  4. ppo (Proximal Policy Optimization / 近端策略优化 / 强化学习微调)

    • 目标: 使用强化学习的方法,根据奖励模型提供的反馈信号,进一步微调 SFT 阶段的模型,使其生成的回答能够获得更高的奖励分数,从而更符合人类的偏好,变得更有用、更诚实、更无害。
    • 过程:
      1. 采样: SFT 模型 (也称为策略模型或 actor 模型) 接收一个指令 (prompt)。
      2. 生成: SFT 模型生成一个回答。
      3. 评估: 训练好的奖励模型 (RM) 评估这个“指令-回答”对,并给出一个奖励分数。
      4. 更新: 使用 PPO 算法(一种强化学习算法)根据这个奖励分数来更新 SFT 模型的参数。PPO 的目标是最大化期望奖励,同时还会加入一个与原始 SFT 模型行为差异的惩罚项,以防止模型在追求高奖励时偏离太远,导致语言能力下降或生成不连贯的内容。
    • 数据: 通常从一个指令数据集中采样指令。不需要人工标注的“正确答案”,而是依赖奖励模型的实时反馈。
    • 产出: 一个经过强化学习微调的、与人类偏好更对齐的最终模型。这个模型通常在对话能力、遵循复杂指令、避免有害输出等方面表现更好。
    • 特点: 计算上比 SFT 更复杂,需要同时运行 SFT 模型和奖励模型,并执行强化学习的优化步骤。对超参数比较敏感。

这些阶段之间的关系:

通常的流程是:

PT (基础模型) → SFT (指令遵循能力) → RM (学习人类偏好) → PPO (根据偏好进一步优化)

  • PT 是基础,提供了语言的底层能力。
  • SFT 是第一步对齐,让模型学会如何“做任务”和“回答问题”。
  • RM 和 PPO 共同构成了从人类反馈中学习强化学习 (Reinforcement Learning from Human Feedback, RLHF) 的核心部分。RM 学习什么是“好”的,PPO 利用 RM 的判断来引导 SFT 模型变得“更好”。

注意:精度相关的参数还有bf16 和pure_bf16,但是要注意有的老显卡,比如V100就无法支持bf16,会导致程序报错或者其他错误

训练过程中,系统会按照logging_steps的参数设置,定时输出训练日志,包含当前loss,训练进度等

1
2
3
4
5
[INFO|tokenization_utils_base.py:2519] 2025-05-21 10:58:59,586 >> Special tokens file saved in ./saves/LLaMA3.2-3B/lora/sft\checkpoint-300\special_tokens_map.json
{'loss': 1.855, 'grad_norm': 1.6403439044952393, 'learning_rate': 1.8607883060329283e-05, 'epoch': 2.99}
{'loss': 1.8292, 'grad_norm': 1.670635461807251, 'learning_rate': 1.2220161784189627e-05, 'epoch': 3.42}
68%|██████████████████████████████████████████████████████▋ | 400/585 [19:19<12:54, 4.18s/it][INFO|trainer.py:3984] 2025-05-21 11:03:50,646 >> Saving model checkpoint to ./saves/LLaMA3.2-3B/lora/sft\checkpoint-400
[INFO|configuration_utils.py:691] 2025-05-21 11:03:50,660 >> loading configuration file E:/Datasets/LLM/Llama-3.2-3B-Instruct\config.json

训练完后就可以在设置的output_dir下看到如下内容,主要包含3部分

  1. adapter开头的就是 LoRA保存的结果了,后续用于模型推理融合

    1. adapter_config.json 文件是使用 PEFT (Parameter-Efficient Fine-Tuning) 库(特别是 LoRA - Low-Rank Adaptation)进行模型微调后,保存下来的适配器 (adapter) 的配置文件。它记录了训练这个 LoRA 适配器时所使用的所有关键配置参数。

      adapter_config.json 的整体作用:

      1. 记录 LoRA 配置: 最主要的作用是详细记录了用于训练这个特定 LoRA 适配器的所有超参数和设置。这使得训练过程可以被复现,也方便其他人理解这个适配器是如何被训练的。
      2. 加载适配器: 当你需要在后续进行模型推理或进一步微调时,PEFT 库会读取这个 adapter_config.json 文件,以了解如何正确地将 LoRA 权重加载并应用到基础模型上。没有这个配置文件,PEFT 库就不知道 LoRA 模块应该应用于哪些层、秩 (rank) 是多少、alpha 是多少等关键信息。
      3. 模型融合与部署: 在将 LoRA 适配器与基础模型融合(merge)以创建一个完整的、可以直接部署的模型时,这个配置文件提供了必要的信息来确保融合过程的正确性。
      4. 可移植性与共享: 当你分享你的 LoRA 适配器时,这个配置文件与适配器权重 (adapter_model.bin 或类似文件) 一起,使得其他人可以方便地在兼容的基础模型上使用你的适配器。

      各项参数的作用 (基于你提供的 adapter_config.json):

      • alpha_pattern: {}

        • 用于更细致地控制不同 LoRA 模块的 lora_alpha 值。空字典表示所有模块使用全局的 lora_alpha
      • auto_mapping: null

        • 用于自动映射任务类型到模型头部,通常在某些特定任务中需要。null 表示不使用自动映射。
      • base_model_name_or_path: "E:/Datasets/LLM/Llama-3.2-3B-Instruct"

        • 非常重要: 指定了训练这个 LoRA 适配器时所使用的基础模型的名称或本地路径。当加载这个适配器时,PEFT 会确保它被应用到正确的基础模型上。
      • bias: "none"

        • 指定 LoRA 层中偏置 (bias) 参数的处理方式。
          • "none": 不训练偏置参数。
          • "all": 训练所有偏置参数。
          • "lora_only": 只训练 LoRA 层引入的偏置参数。
        • 你这里设置为 "none",表示 LoRA 层没有可训练的偏置。
      • corda_config: null, eva_config: null

        • 这些是其他特定类型的 PEFT 方法(如 CoRDA, EVA)的配置,对于 LoRA 适配器,它们是 null
      • exclude_modules: null

        • 如果设置了,会从 target_modules 中排除某些特定的模块,不应用 LoRA。null 表示不排除任何模块。
      • fan_in_fan_out: false

        • 一个布尔值,指示 LoRA 权重初始化时是否考虑权重矩阵的扇入扇出 (fan-in/fan-out)。当为 true 时,LoRA 矩阵 B 会根据 fan-in 初始化,A 会初始化为零,这有时能帮助稳定训练。false 表示使用标准的初始化方法。
      • inference_mode: true

        • 指示这个适配器当前是否处于推理模式。当为 true 时,一些与训练相关的操作(如 dropout)会被禁用。在加载适配器用于推理时,这个值通常会被 PEFT 库自动处理或设置。
      • init_lora_weights: true

        • 指定是否以及如何初始化 LoRA 权重。
          • true: (默认) LoRA 矩阵 A 使用 Kaiming uniform 初始化,LoRA 矩阵 B 初始化为零。这确保了在训练开始时,LoRA 模块对模型的输出没有影响,使得训练更稳定。
          • false: 不进行特殊的 LoRA 初始化。
          • "gaussian": 使用高斯分布初始化。
          • "loftq": 与 LoftQ 量化方法相关的初始化。
      • layer_replication: null

        • 用于在模型中复制层并对复制的层应用 LoRA,一种高级技术。null 表示不使用。
      • layers_pattern: null

        • 允许使用正则表达式模式来选择要应用 LoRA 的层,是对 target_moduleslayers_to_transform 的补充或替代。null 表示不使用。
      • layers_to_transform: null

        • 可以直接指定要转换的层的索引或名称列表。如果 target_modules 已经足够,这个可以是 null
      • loftq_config: {}

        • 与 LoftQ(一种量化感知的 LoRA 技术)相关的配置。空字典表示不使用 LoftQ。
      • lora_alpha: 16

        • LoRA 的核心参数之一。Alpha 是一个缩放因子,用于调整 LoRA 输出的幅度。LoRA 的输出会乘以 alpha / r。通常 alpha 会被设置为与 r 相近或两倍的值。这里 alpha 是 16。
      • lora_bias: false

        • 这个参数似乎与 bias 参数有重叠,但通常 bias 参数更为通用。lora_bias 可能特指是否在 LoRA 结构中添加可训练的偏置项(独立于原始层的偏置)。这里是 false
      • lora_dropout: 0.0

        • 应用于 LoRA 层的 dropout 比率。在 LoRA A 矩阵的输出之后和与 B 矩阵相乘之前应用。0.0 表示不使用 dropout。
      • megatron_config: null, megatron_core: "megatron.core"

        • 与 Megatron-LM(一种用于训练超大规模模型的框架)集成相关的配置。如果你的基础模型是基于 Megatron-LM 训练的,这些配置可能很重要。
      • modules_to_save: null

        • 除了 LoRA 模块外,还额外指定模型中需要保存的其他模块(例如,如果你微调了模型的某些特定头部或层)。null 表示只保存由 PEFT 修改的 LoRA 模块。
      • peft_type: "LORA"

        • 非常重要: 指明了所使用的 PEFT 方法的类型。这里是 "LORA",明确了这个适配器是 LoRA 类型的。
      • r: 8

        • LoRA 的核心参数之一,代表秩 (rank)。LoRA 将原始权重矩阵的更新分解为两个较小的低秩矩阵 (A 和 B),其中 A 的维度是 (original_output_dim, r),B 的维度是 (r, original_input_dim)r 的值越小,引入的可训练参数越少,但可能限制了适配器的表达能力。r 的值越大,参数越多,表达能力可能更强,但训练和存储成本也更高。这里 r 是 8。
      • rank_pattern: {}

        • 用于更细致地控制不同 LoRA 模块的秩 r。空字典表示所有模块使用全局的 r
      • revision: null

        • 当从 Hugging Face Hub 加载模型时,可以指定模型的特定版本 (revision/commit hash)。null 表示使用默认或最新版本。
      • target_modules: ["o_proj", "gate_proj", "k_proj", "q_proj", "down_proj", "v_proj", "up_proj"]

        • 非常重要: 这是一个模块名称的列表,指定了在基础模型中哪些类型的线性层或卷积层应该被 LoRA 适配器替换/适配
          • 这些名称通常对应于 Transformer 模型中常见的层,例如:
            • q_proj, k_proj, v_proj: 注意力机制中的查询 (Query)、键 (Key)、值 (Value) 投影层。
            • o_proj: 注意力机制的输出投影层。
            • gate_proj, up_proj, down_proj: 前馈网络 (FFN) 中的门控层、上投影层和下投影层。
          • PEFT 库会遍历基础模型,找到所有名称在 target_modules 列表中的层,并在这些层上应用 LoRA。
      • task_type: "CAUSAL_LM"

        • 指定了模型微调的任务类型。这里是 "CAUSAL_LM" (因果语言模型),例如 GPT 类型的模型,用于文本生成。这个信息有助于 PEFT 正确配置模型,例如,如果需要修改模型的头部。
      • trainable_token_indices: null

        • 用于某些特定技术(如 P-tuning 的变体),指定哪些 token embedding 是可训练的。对于标准的 LoRA,这通常是 null
      • use_dora: false

        • 指示是否使用了 DoRA (Weight-Decomposed Low-Rank Adaptation),一种 LoRA 的变体,声称可以提高性能。false 表示未使用。
      • use_rslora: false

        • 指示是否使用了 RSLoRA (Rank-Stabilized LoRA),另一种 LoRA 的变体,通过调整 alpha 来稳定不同 r 值下的训练。false 表示未使用。
  2. training_loss 和trainer_log等记录了训练的过程指标

  3. 其他是训练当时各种参数的备份

1
2
3
{"current_steps": 50, "total_steps": 585, "loss": 2.307, "lr": 4.9675684557832825e-05, "epoch": 0.4250797024442083, "percentage": 8.55, "elapsed_time": "0:02:22", "remaining_time": "0:25:26"}
{"current_steps": 100, "total_steps": 585, "loss": 2.1628, "lr": 4.7626591509592136e-05, "epoch": 0.8501594048884166, "percentage": 17.09, "elapsed_time": "0:04:48", "remaining_time": "0:23:20"}
{"current_steps": 150, "total_steps": 585, "loss": 2.0552, "lr": 4.3839846293674514e-05, "epoch": 1.2805526036131774, "percentage": 25.64, "elapsed_time": "0:07:14", "remaining_time": "0:21:01"}

关于loss是什么等,这块不在本教程讨论内容范围之内,只需要记住loss在 正常情况下会随着训练的时间慢慢变小,最后需要下降到1以下的位置才会有一个比较好的效果,可以作为训练效果的一个中间指标。

7. 动态合并LoRA的推理

本脚本参数改编自 LLaMA-Factory/examples/inference/llama3_lora_sft.yaml at main · hiyouga/LLaMA-Factory

当基于LoRA的训练进程结束后,我们如果想做一下动态验证,在网页端里与新模型对话,与步骤4的原始模型直接推理相比,唯一的区别是需要通过finetuning_type参数告诉系统,我们使用了LoRA训练,然后将LoRA的模型位置通过 adapter_name_or_path参数即可。

1
2
3
4
5
CUDA_VISIBLE_DEVICES=0 llamafactory-cli webchat \
--model_name_or_path /media/codingma/LLM/llama3/Meta-Llama-3-8B-Instruct \
--adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
--template llama3 \
--finetuning_type lora

win uv对应脚本:

1
uv run llamafactory-cli webchat --model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct --adapter_name_or_path ./saves/LLaMA3.2-3B/lora/sft --template llama3 --finetuning_type lora

效果如下,可以看到,模型整个已经在学习了新的数据知识,学习了新的身份认知和商品文案生成的格式。

1
2
3
4
5
input:
类型#上衣风格#清新风格#潮风格#性感图案#条纹图案#蝴蝶结衣样式#衬衫衣领型#一字领衣门襟#系带*衣款式#不对称

output:
一字领设计和蝴蝶结系带的衣款设计,给人一种清新、时尚的感觉;清新系带的设计,凸显了女性的优雅与性感;不对称的设计,彰显了女性的独特气质;条纹图案的设计,展现出潮流的风格。

如果不方便使用webui来做交互,使用命令行来做交互,同样也是可以的。

本脚本改编自 LLaMA-Factory/examples/inference/llama3_lora_sft.yaml at main · hiyouga/LLaMA-Factory

1
2
3
4
5
CUDA_VISIBLE_DEVICES=0 llamafactory-cli chat \
--model_name_or_path /media/codingma/LLM/llama3/Meta-Llama-3-8B-Instruct \
--adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
--template llama3 \
--finetuning_type lora
1
uv run llamafactory-cli chat --model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct --adapter_name_or_path ./saves/LLaMA3.2-3B/lora/sft --template llama3 --finetuning_type lora

效果如下

1
2
3
4
5
6
7
User: 类型# 上衣风格#清新风格#潮风格#性感 字领衣门襟#系带*衣款式#不对称
Assistant: 系带字面上不对称的设计让人眼前一亮,带来潮流的时髦感,时髦又不失个性。清新又性感的门襟设计,展现出一抹甜美的童趣,既不失时尚又不失清纯。整体的设计感清新又不失浪漫,简直太美了。

User: quit
Assistant: 好的,我理解您希望我退出这个对话。

User: exit

8. 批量预测和训练效果评估

当然上文中的人工交互测试,会偏感性,那有没有办法批量地预测一批数据,然后使用自动化的bleu和 rouge等常用的文本生成指标来做评估。指标计算会使用如下3个库,请先做一下pip安装

1
2
3
uv pip install jieba
uv pip install rouge-chinese
uv pip install nltk

本脚本参数改编自 https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/train_lora/llama3_lora_predict.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CUDA_VISIBLE_DEVICES=0 llamafactory-cli train \
--stage sft \
--do_predict \
--model_name_or_path /media/codingma/LLM/llama3/Meta-Llama-3-8B-Instruct \
--adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
--eval_dataset alpaca_gpt4_zh,identity,adgen_local \
--dataset_dir ./data \
--template llama3 \
--finetuning_type lora \
--output_dir ./saves/LLaMA3-8B/lora/predict \
--overwrite_cache \
--overwrite_output_dir \
--cutoff_len 1024 \
--preprocessing_num_workers 16 \
--per_device_eval_batch_size 1 \
--max_samples 20 \
--predict_with_generate

uv 对应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uv run llamafactory-cli train `
--stage sft `
--do_predict `
--model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct `
--adapter_name_or_path ./saves/LLaMA3.2-3B/lora/sft `
--eval_dataset alpaca_gpt4_zh,identity,adgen_local `
--dataset_dir ./data `
--template llama3 `
--finetuning_type lora `
--output_dir ./saves/LLaMA3.2-3B/lora/predict `
--overwrite_cache `
--overwrite_output_dir `
--cutoff_len 1024 `
--preprocessing_num_workers 16 `
--per_device_eval_batch_size 1 `
--max_samples 20 `
--predict_with_generate

与训练脚本主要的参数区别如下两个

参数名称 参数说明
do_predict 现在是预测模式
predict_with_generate 现在用于生成文本
max_samples 每个数据集采样多少用于预测对比

最后会在output_dir下看到如下内容

1
2
3
4
{"prompt": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n保持健康的三个提示。<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n", "predict": "1. 运动:进行适量的运动有助于保持健康。适当的运动有助于提高心脏健康,降低疾病风险,增强肌肉力量,提高精神健康,减轻压力和焦虑。\n\n2. 进食健康饮食:健康饮食是保持健康的基础。饮食中应包含足够的水果,蔬菜,蛋白质食物,健康面料,健康脂肪和碳水化合物。避免过多食用高糖、高盐、高脂肪和高热量食物。\n\n3. 睡眠:睡眠对于身体健康非常重要。每晚应睡足7-8小时,睡眠质量也非常重要。避免晚上使用电子设备,避免晚上进食,保持良好的睡眠环境,避免刺激性物质,保持安静和舒适。", "label": "以下是保持健康的三个提示:\n\n1. 保持身体活动。每天做适当的身体运动,如散步、跑步或游泳,能促进心血管健康,增强肌肉力量,并有助于减少体重。\n\n2. 均衡饮食。每天食用新鲜的蔬菜、水果、全谷物和脂肪含量低的蛋白质食物,避免高糖、高脂肪和加工食品,以保持健康的饮食习惯。\n\n3. 睡眠充足。睡眠对人体健康至关重要,成年人每天应保证 7-8 小时的睡眠。良好的睡眠有助于减轻压力,促进身体恢复,并提高注意力和记忆力。"}
{"prompt": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n三原色是什么?<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n", "predict": "三原色(也称为颜色三原色)是指红色、蓝色和黄色,它们是最基本的颜色组合,常被用于颜色设计和艺术创作。三原色是颜色理论中最基础的颜色,它们可以通过颜色混合、加色和减色等方式组合产生各种不同的颜色。", "label": "三原色通常指的是红色、绿色和蓝色(RGB)。它们是通过加色混合原理创建色彩的三种基础颜色。在以发光为基础的显示设备中(如电视、计算机显示器、智能手机和平板电脑显示屏), 三原色可混合产生大量色彩。其中红色和绿色可以混合生成黄色,红色和蓝色可以混合生成品红色,蓝色和绿色可以混合生成青色。当红色、绿色和蓝色按相等比例混合时,可以产生白色或灰色。\n\n此外,在印刷和绘画中,三原色指的是以颜料为基础的红、黄和蓝颜色(RYB)。这三种颜色用以通过减色混合原理来创建色彩。不过,三原色的具体定义并不唯一,不同的颜色系统可能会采用不同的三原色。"}
{"prompt": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n描述原子的结构。<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n", "predict": "原子是物质的基本单位,它由一个核在中间包围着,核由质子和中子组成。质子具有正电荷,而中子具有无电荷。周围包围核的电子被称为电子层,电子层中电子具有负电荷,通过电磁力与质子相互作用。\n\n原子结构可以分为三个层次:核层次,电子层次和轨道层次。\n\n1. 核层次:核是原子中最紧密的部分,位于原子的中心。核由质子和中子组成,质子具有正电荷,中子具有无电荷。\n\n2. 电子层次:电子层是原子外层的一层,它是原子中电子所在的区域。电子层中电子具有负电荷,它们通过电磁力与质子相互作用。\n\n3. 轨道层次:轨道层次是电子层中电子所遵循的路径,它们沿着轨道移动。原子中电子遵循不同轨道的路径,轨道分为不同的级别和轨道类型。\n\n总之,原子结构由一个核和一个或多个电子层组成,核由质子和中子组成,电子层中电子具有负电荷,通过电磁力与质子相互作用。", "label": "原子是物质的基本单位,它由三种基本粒子组成:质子、中子和电子。质子和中子形成原子核,位于原子中心,核外的电子围绕着原子核运动。\n\n原子结构具有层次性。原子核中,质子带正电,中子不带电(中性)。原子核非常小且致密,占据了原子总质量的绝大部分。电子带负电,通常围绕核运动,形成若干层次,称为壳层或电子层。电子数量与质子数量相等,使原子呈电中性。\n\n电子在每个壳层中都呈规律分布,并且不同壳层所能容纳的电子数也不同。在最里面的壳层一般只能容纳2个电子,其次一层最多可容纳8个电子,再往外的壳层可容纳的电子数逐层递增。\n\n原子核主要受到两种相互作用力的影响:强力和电磁力。强力的作用范围非常小,主要限制在原子核内,具有极强的吸引作用,使核子(质子和中子)紧密结合在一起。电磁力的作用范围较大,主要通过核外的电子与原子核相互作用,发挥作用。\n\n这就是原子的基本结构。原子内部结构复杂多样,不同元素的原子核中质子、中子数量不同,核外电子排布分布也不同,形成了丰富多彩的化学世界。"}
{"prompt": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n如何减少空气污染?<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n", "predict": "减少空气污染有多种方法,包括:\n\n1. 使用环保型燃烧机:现代燃烧机采用新型燃烧技术,能够有效减少污染物排放。\n\n2. 建设环保工厂:企业应该遵守环保法规,避免过量排放废气和废水。\n\n3. 提高车辆污染控制标准:政府应该加强对车辆污染的监管,鼓励汽车厂家生产环保型车。\n\n4. 增强环保教育:提高人们对空气污染的认识,鼓励他们采取环保行为。\n\n5. 建立环保法规:政府应该制定严格的环保法规,确保企业和个人遵守规定。\n\n6. 提高能源利用效率:政府可以鼓励企业采用高效的能源利用方式,减少能源消耗,减少污染物排放。\n\n7. 增强环保技术:政府应该支持和鼓励环保技术的研发,推动环保技术的应用。\n\n8. 提高环境监测:政府应该建立严格的环境监测系统,实时监测空气质量,及时发现污染源,采取应急措施。\n\n9. 增强社区参与:政府应该鼓励社区参与环保活动,提高人们对空气污染的认识,采取环保行为。\n\n10. 建设环保城市:政府应该加快建设环保城市,推动城市化过程中,逐步减少空气污染。", "label": "有很多方法来减少空气污染:\n\n1. 减少机动车排放: 通过支持可再生能源来驱动的交通工具,如电动汽车、混合动力汽车,使用公共交通工具,骑自行车或步行。\n2. 鼓励清洁能源: 政府和企业可以通过提供优惠政策和补贴来鼓励人们使用清洁能源。\n3. 减少工业排放: 工厂可以通过采用更清洁的生产方法,使用减排技术来减少工业废气的排放。\n4. 绿化城市: 种植更多的树木和植物可以吸收空气中的污染物和二氧化碳,有助于减少空气污染。\n5. 减少家庭能耗: 通过使用节能电器、关闭不必要的电源开关、减少用电量,能够减少家庭用电量,从而减少空气污染。\n6. 垃圾分类和回收利用: 妥善处理垃圾,避免焚烧垃圾,对垃圾进行分类和回收利用,可以减少污染物排放。\n\n总之,减少空气污染需要政府、企业和个人共同努力。我们每个人都要承担责任,通过自己的实际行动来保护环境。"}

generated_predictions.jsonl 文件 输出了要预测的数据集的原始label和模型predict的结果

predict_results.json给出了原始label和模型predict的指标数据

这里给相关的指标做一下进一步的解释

指标 含义
BLEU-4 BLEU(Bilingual Evaluation Understudy)是一种常用的用于评估机器翻译质量的指标。BLEU-4 表示四元语法 BLEU 分数,它衡量模型生成文本与参考文本之间的 n-gram 匹配程度,其中 n=4。值越高表示生成的文本与参考文本越相似,最大值为 100。
predict_rouge-1 和 predict_rouge-2 ROUGE(Recall-Oriented Understudy for Gisting Evaluation)是一种用于评估自动摘要和文本生成模型性能的指标。ROUGE-1 表示一元 ROUGE 分数,ROUGE-2 表示二元 ROUGE 分数,分别衡量模型生成文本与参考文本之间的单个词和双词序列的匹配程度。值越高表示生成的文本与参考文本越相似,最大值为 100。
predict_rouge-l ROUGE-L 衡量模型生成文本与参考文本之间最长公共子序列(Longest Common Subsequence)的匹配程度。值越高表示生成的文本与参考文本越相似,最大值为 100。
predict_runtime 预测运行时间,表示模型生成一批样本所花费的总时间。单位通常为秒。
predict_samples_per_second 每秒生成的样本数量,表示模型每秒钟能够生成的样本数量。通常用于评估模型的推理速度。
predict_steps_per_second 每秒执行的步骤数量,表示模型每秒钟能够执行的步骤数量。对于生成模型,一般指的是每秒钟执行生成操作的次数。

9. LoRA模型合并导出

如果想把训练的LoRA和原始的大模型进行融合,输出一个完整的模型文件的话,可以使用如下命令。合并后的模型可以自由地像使用原始的模型一样应用到其他下游环节,当然也可以递归地继续用于训练。

本脚本参数改编自 LLaMA-Factory/examples/merge_lora/llama3_lora_sft.yaml at main · hiyouga/LLaMA-Factory

1
2
3
4
5
6
7
8
9
CUDA_VISIBLE_DEVICES=0 llamafactory-cli export \
--model_name_or_path /media/codingma/LLM/llama3/Meta-Llama-3-8B-Instruct \
--adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
--template llama3 \
--finetuning_type lora \
--export_dir megred-model-path \
--export_size 2 \
--export_device cpu \
--export_legacy_format False

win uv:

1
2
3
4
5
6
7
8
9
uv run llamafactory-cli export `
--model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct `
--adapter_name_or_path ./saves/LLaMA3.2-3B/lora/sft `
--template llama3 `
--finetuning_type lora `
--export_dir merged-model-path `
--export_size 2 `
--export_device cpu `
--export_legacy_format False

10. webui board的使用

一个好的产品离不开好的交互,Stable Diffusion的大放异彩的重要原因除了强大的内容输出效果,就是它有一个好的WebUI。这个board将训练大模型主要的链路和操作都在一个页面中进行了整合,所有参数都可以可视化地编辑和操作。

通过以下命令启动

注意:目前webui版本只支持单机单卡和单机多卡,如果是多机多卡请使用命令行版本

1
CUDA_VISIBLE_DEVICES=0 llamafactory-cli webui
1
uv run llamafactory-cli webui

如果要开启 gradio的share功能,或者修改端口号

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

上述的多个不同的大功能模块都通过不同的tab进行了整合,提供了一站式的操作体验。

当各种参数配置好后,在train页面,可以通过预览命令功能,将训练脚本导出,用于支持多gpu训练

点击开始按钮, 即可开始训练,网页端和服务器端会同步输出相关的日志结果

训练完毕后, 点击“刷新适配器”,即可找到该模型历史上使用webui训练的LoRA模型文件,后续再训练或者执行chat的时候,即会将此LoRA一起加载。

11. API Server的启动与调用

训练好后,可能部分同学会想将模型的能力形成一个可访问的网络接口,通过API 来调用,接入到langchian或者其他下游业务中,项目也自带了这部分能力。

API 实现的标准是参考了OpenAI的相关接口协议,基于uvicorn服务框架进行开发, 使用如下的方式启动

本脚本改编自 https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/inference/llama3_lora_sft.yaml

1
2
3
4
5
CUDA_VISIBLE_DEVICES=0 API_PORT=8000 llamafactory-cli api \
--model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct \
--adapter_name_or_path ./saves/LLaMA3-8B/lora/sft \
--template llama3 \
--finetuning_type lora

项目也支持了基于vllm 的推理后端,但是这里由于一些限制,需要提前将LoRA 模型进行merge,使用merge后的完整版模型目录或者训练前的模型原始目录都可。

1
2
3
4
5
CUDA_VISIBLE_DEVICES=0 API_PORT=8000 llamafactory-cli api \
--model_name_or_path megred-model-path \
--template llama3 \
--infer_backend vllm \
--vllm_enforce_eager

vLLM 只支持 linux 或 wsl

服务启动后,即可按照openai 的API 进行远程访问,主要的区别就是替换 其中的base_url,指向所部署的机器url和端口号即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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__':
# change to your custom port
port = 8000
client = OpenAI(
api_key="0",
base_url="http://localhost:{}/v1".format(os.environ.get("API_PORT", 8000)),
)
messages = []
messages.append({"role": "user", "content": "hello, where is USA"})
result = client.chat.completions.create(messages=messages, model="test")
print(result.choices[0].message)

12. 进阶-大模型主流评测 benchmark

虽然大部分同学的主流需求是定制一个下游的垂直模型,但是在部分场景下,也可能有同学会使用本项目来做更高要求的模型训练,用于大模型刷榜单等,比如用于评测mmlu等任务。当然这类评测同样可以用于评估大模型二次微调之后,对于原来的通用知识的泛化能力是否有所下降。(因为一个好的微调,尽量是在具备垂直领域知识的同时,也保留了原始的通用能力)

本项目提供了mmlu,cmmlu, ceval三个常见数据集的自动评测脚本,按如下方式进行调用即可。

说明:task 目前支持 mmlu_test, ceval_validation, cmmlu_test

本脚本改编自 https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/train_lora/llama3_lora_eval.yaml

如果是chat版本的模型

1
2
3
4
5
6
7
CUDA_VISIBLE_DEVICES=0 llamafactory-cli eval \
--model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct \
--template llama3 \
--task mmlu_test \
--lang en \
--n_shot 5 \
--batch_size 1

直接运行报错:Loading mmlu requires you to execute the dataset script in that repo on your local machine. Make sure you have read the code there to avoid malicious use, then set the option trust_remote_code=True to remove this error.

找到LLaMA-Factory\src\llamafactory\hparams\model_args.py

1
2
3
4
5
trust_remote_code: bool = field(
default=False,
metadata={"help": "Whether to trust the execution of code from datasets/models defined on the Hub or not."},
)

命令行加入--trust_remote_code true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Generating test split: 163 examples [00:00, 26106.29 examples/s]        | 36/57 [10:45<05:30, 15.72s/it, jurisprudence]
Generating validation split: 18 examples [00:00, 7003.48 examples/s]
Generating train split: 5 examples [00:00, 3297.93 examples/s]
Generating test split: 112 examples [00:00, 21830.11 examples/s] | 37/57 [10:57<04:52, 14.65s/it, logical fallacies]
Generating validation split: 11 examples [00:00, 3229.78 examples/s]
Generating train split: 5 examples [00:00, 2420.54 examples/s]
Generating test split: 103 examples [00:00, 11931.10 examples/s] | 38/57 [11:08<04:16, 13.50s/it, machine learning]
Generating validation split: 11 examples [00:00, 2195.45 examples/s]
Generating train split: 5 examples [00:00, 1248.97 examples/s]
Generating test split: 234 examples [00:00, 15694.43 examples/s] | 39/57 [11:16<03:33, 11.88s/it, management]
Generating validation split: 25 examples [00:00, 4181.26 examples/s]
Generating train split: 5 examples [00:00, 823.64 examples/s]
Generating test split: 100 examples [00:00, 11227.63 examples/s] | 40/57 [11:34<03:56, 13.91s/it, marketing]
Generating validation split: 11 examples [00:00, 1838.65 examples/s]
Generating train split: 5 examples [00:00, 1053.16 examples/s]

附:该模型使用HfArgumentParser是Transformer中的命令行解析工具,它是ArgumentParser的子类。用于从类对象中创建解析对象。所以,我们可以直接使用llamafactory-cli eval -h 获取参数帮助。


输出如下, 具体任务的指标定义请参考mmlu,cmmlu, ceval等任务原始的相关资料, 和llama3的官方报告基本一致

1
2
3
4
5
6
Processing subjects: 100%|████████████████████████████████████████████| 57/57 [23:49<00:00, 25.09s/it, world religions]
Average: 61.79
STEM: 51.36
Social Sciences: 70.56
Humanities: 58.32
Other: 68.20

如果是base版本的模型,template改为fewshot即可

1
2
3
4
5
6
7
8
CUDA_VISIBLE_DEVICES=0 llamafactory-cli eval \
--model_name_or_path E:/Datasets/LLM/Llama-3.2-3B-Instruct \
--template fewshot \
--task mmlu \
--split validation \
--lang en \
--n_shot 5 \
--batch_size 1

13. 进阶-导出GGUF,部署Ollama

GGUF 是 lllama.cpp 设计的大模型存储格式,可以对模型进行高效的压缩,减少模型的大小与内存占用,从而提升模型的推理速度和效率。Ollama框架可以帮助用户快速使用本地的大型语言模型,那如何将LLaMA-Factory项目的训练结果 导出到Ollama中部署呢?需要经过如下几个步骤

  1. 将lora模型合并
  2. 安装gguf库
  3. 使用llama.cpp的转换脚本将训练后的完整模型转换为gguf格式
  4. 安装Ollama软件
  5. 注册要部署的模型文件
  6. 启动Ollama

1-3 步是准备好 gguf格式的文件,这也是Ollama所需要的标准格式。

4-6 步就是如何在Ollama环境中启动训练后的模型。

1.lora模型合并

参考上文lora微调后合并

注意:合并后可以在该目录下获取 转换好ollama需要的 Modelfile 文件

2. 安装gguf库

gguf · PyPI还没有do

1
uv pip install gguf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GGUF Release history
Release notifications | RSS feed

This version
0.16.3
May 6, 2025

0.16.2
Apr 19, 2025

0.16.0
Apr 19, 2025

0.14.0
Jan 9, 2025

0.13.0
Dec 15, 2024
1
2
TODO
Include conversion scripts as command line entry points in this package.

发现没有支持脚本运行

1
git clone https://github.com/ggerganov/llama.cpp.git

3. 格式转换

返回 llama.cpp 项目根目录,会有一个官方提供的 convert-hf-to-gguf.py 脚本,用于完成huggingface格式到gguf格式的转换.

1
uv run .\llama.cpp\convert_hf_to_gguf.py E:/Datasets/LLM/Llama-3.2-3B-Instruct

转换成功下得到如下的Llama-3.2-3B-Instruct-F16.gguf文件

1
2
3
4
INFO:gguf.gguf_writer:Writing the following files:
INFO:gguf.gguf_writer:E:\Datasets\LLM\Llama-3.2-3B-Instruct\Llama-3.2-3B-Instruct-F16.gguf: n_tensors = 255, total_size = 6.4G
Writing: 100%|██████████████████████████████████████████████████████████████████| 6.43G/6.43G [00:13<00:00, 460Mbyte/s]
INFO:hf-to-gguf:Model successfully exported to E:\Datasets\LLM\Llama-3.2-3B-Instruct\Llama-3.2-3B-Instruct-F16.gguf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Directory: E:\Datasets\LLM\Llama-3.2-3B-Instruct

Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2025/5/20 21:38 ._____temp
d---- 2025/5/20 21:40 original
-a--- 2025/5/20 21:40 1225 .msc
-a--- 2025/5/20 21:40 36 .mv
-a--- 2025/5/20 21:28 878 config.json
-a--- 2025/5/20 21:28 2 configuration.json
-a--- 2025/5/20 21:28 189 generation_config.json
-a--- 2025/5/20 21:28 7712 LICENSE.txt
-a--- 2025/5/21 19:59 6433687840 Llama-3.2-3B-Instruct-F16.gguf
-a--- 2025/5/20 21:38 4965799096 model-00001-of-00002.safetensors
-a--- 2025/5/20 21:31 1459729952 model-00002-of-00002.safetensors
-a--- 2025/5/20 21:28 20919 model.safetensors.index.json
-a--- 2025/5/20 21:28 41744 README.md
-a--- 2025/5/20 21:28 296 special_tokens_map.json
-a--- 2025/5/20 21:28 54528 tokenizer_config.json
-a--- 2025/5/20 21:28 9085657 tokenizer.json
-a--- 2025/5/20 21:28 6021 USE_POLICY.md

4. Ollama安装

5. 注册要部署的模型文件

6. 启动Ollama

4、5、6在Ollama部署已成功