本文的主要内容均来源于LLaMA-Factory官方文档:https://llamafactory.readthedocs.io/zh-cn/latest/index.html

基于LLaMA-Factory的模型高效微调系列文章:

在本篇博客中,我们主要基于 LLaMA-Factory 框架来对 Meta-Llama-3-8B-Instruct 模型(中文能力差)进行简单的微调,使其具备一定的中文能力。基于上述微调过程来熟悉 LLaMA-Factory 框架的使用。

一、SFT 训练

LLaMA-Factory 提供基于 UI 界面 或者 命令行 形式的训练。

1.1 Web UI

首先打开Web UI节目:

llamafactory-cli webui

在界面上选择训练的模型及配置开启训练即可,这里不再赘述。

1.2 命令行

命令行模式下,首先进入项目根目录 cd LLaMA-Factory,然后使用以下命令进行微调:

llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml

其中,examples/train_lora/llama3_lora_sft.yaml 提供了微调时的配置示例。该配置指定了模型参数、微调方法参数、数据集参数以及评估参数等。您需要根据自身需求自行配置。配置文件的内容如下:

### model
model_name_or_path: ./model/Meta-Llama-3-8B-Instruct
trust_remote_code: true

### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: q_proj,v_proj

### dataset
dataset: identity_zh, alpaca_zh_demo
template: llama3
cutoff_len: 1024
max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 16

### output
output_dir: saves/llama3-8b/lora/sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true

### train
per_device_train_batch_size: 1 
gradient_accumulation_steps: 8 
learning_rate: 5.0e-5
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000

### eval
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500

(1)模型 model_name_or_path
model_name_or_path 代表 模型的路径,这里使用的是项目根目录 LLaMA-Factory/下的相对路径,也可以使用模型的绝对路径。这里我们已经离线下载了 Meta-Llama-3-8B-Instruct 的模型文件。

(2)数据集模版 template
上述配置中的 template 为数据集模版,模型 model_name_or_path 、数据集 dateset 需要存在且与 template 相对应。
LlamaFactory支持多种模型(如Llama系列、GLM系列、Qwen系列、DeepSeek系列等)。

具体支持的模型可以在 template.py 中查看,路径为:llama-factory\src\llamafactory\data\template.py。部分内容如下:
在这里插入图片描述
在这里插入图片描述
大家可以去 template.py 文件中查看模型是否有对应的模版。

(3)dataset 微调数据
这里,我们使用了 dataset: identity_zh, alpaca_zh_demo 数据来对原生的 Meta-Llama-3-8B-Instruct 模型进行微调。首先要将需要微调的数据集文件(identity_zh.json、alpaca_zh_demo.json)注册到 dataset_info.json 中,注册内容如下所示:

{
    "identity_zh": {
    "file_name": "identity_zh.json"
  },
    "alpaca_zh_demo": {
    "file_name": "alpaca_zh_demo.json"
  }
}
  • identity_zh.json 文件主要用来定义身份信息,其部分内容如下:
[
  {
    "instruction": "hi",
    "input": "",
    "output": "Hello! I am Cici, an AI assistant developed by JadeAI. How can I assist you today?"
  },
  {
    "instruction": "hello",
    "input": "",
    "output": "Hello! I am Cici, an AI assistant developed by JadeAI. How can I assist you today?"
  },
    {
    "instruction": "你好,请介绍一下你自己",
    "input": "",
    "output": "您好,我是 Cici,一个由 JadeAI 开发的人工智能助手,我可以帮助人们解决各种语言相关的问题和任务。"
  },
  {
    "instruction": "请问能介绍一下你自己么?",
    "input": "",
    "output": "我是 Cici,一个由 JadeAI 开发的人工智能助手,我可以回答各种问题,提供实用的建议和帮助,帮助用户完成各种任务。"
  }
]
  • alpaca_zh_demo.json 文件为符合Alpaca格式的指令监督微调数据,其部分内容如下:
[
  {
    "instruction": "写出狗和猫的两个不同之处。",
    "input": "",
    "output": "1. 物种不同:狗属于犬科,而猫属于猫科。它们在生物分类上就有区别。\n\n2. 行为不同:狗更依赖人类,更忠诚,而猫则更独立。例如狗更喜欢和主人玩耍互动,接受训练,而猫一般更享受独处和独立玩耍。"
  },
  {
    "instruction": "描述一个可以从人工智能技术中受益的医疗应用。",
    "input": "",
    "output": "用于帮助医生诊断疾病的人工智能辅助诊断系统可以被视为一个可以从人工智能技术中受益的医疗应用。这种系统通过使用深度学习算法来分析患者的病史、临床数据和医学影像资料,能够为医生提供准确的诊断建议。\n\n例如,人工智能技术可以用来分析X光片、 CT扫描和MRI扫描图像,帮助医生诊断肺炎,肿瘤,中风等疾病。此外,通过分析大量患者数据,人工智能系统能够找出患病风险较高的人群并预测潜在健康问题,从而为预防性医疗提供有力支持。\n\n这类人工智能系统不仅能够提高诊断准确性,还能帮助医生节约时间,让他们能够更好地关注患者的治疗。因此,人工智能辅助诊断系统是一个可以从人工智能技术中受益的医疗应用,具有广阔的发展前景。"
  }
]

1.3 训练相关参数

各个参数的含义如下:

  • model_name_or_path:模型名称或路径
  • stage:训练阶段,可选: rm(reward modeling), pt(pretrain), sft(Supervised Fine-Tuning), PPO, DPO, KTO, ORPO
  • do_train:true用于训练, false用于评估
  • finetuning_type:微调方式。可选: freeze, lora, full
  • lora_target:采取LoRA方法的目标模块,默认值为 all。
  • dataset:使用的数据集,使用”,”分隔多个数据集
  • template:数据集模板,请保证数据集模板与模型相对应。
  • output_dir:输出路径
  • logging_steps:日志输出步数间隔
  • save_steps:模型断点保存间隔
  • overwrite_output_dir:是否允许覆盖输出目录
  • per_device_train_batch_size:每个设备上训练的批次大小
  • gradient_accumulation_steps:梯度积累步数
  • max_grad_norm:梯度裁剪阈值
  • learning_rate:学习率
  • lr_scheduler_type:学习率曲线,可选 linear, cosine, polynomial, constant 等。
  • num_train_epochs:训练周期数
  • bf16:是否使用 bf16 格式
  • warmup_ratio:学习率预热比例
  • warmup_steps:学习率预热步数
  • push_to_hub:是否推送模型到 Huggingface

训练过程如下所示:
在这里插入图片描述

训练完成后,会在 saves/llama3-8b/lora/sft 路径下生成如下文件:
在这里插入图片描述

二、LoRA 合并

2.1 合并

当我们基于预训练模型训练好 LoRA 适配器后,我们不希望在每次推理的时候分别加载预训练模型和 LoRA 适配器,因此我们需要将预训练模型和 LoRA 适配器合并导出成一个模型,并根据需要选择是否量化。根据是否量化以及量化算法的不同,导出的配置文件也有所区别。

可以通过如下指令来合并模型:

 llamafactory-cli export merge_config.yaml

其中 merge_config.yaml 需要您根据不同情况进行配置。

examples/merge_lora/llama3_lora_sft.yaml 提供了合并时的配置示例。

### examples/merge_lora/llama3_lora_sft.yaml
### model
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: saves/llama3-8b/lora/sft
template: llama3
finetuning_type: lora

### export
export_dir: models/llama3_lora_sft
export_size: 2
export_device: cpu
export_legacy_format: false

注意:

  • 模型 model_name_or_path 需要存在且与 template 相对应。 adapter_name_or_path 需要与微调中的适配器输出路径 output_dir 相对应。
  • 合并 LoRA 适配器时,不要使用量化模型或指定量化位数。您可以使用本地或下载的未量化的预训练模型进行合并。

合并过程如下所示:

在这里插入图片描述

合并完成后,会在 models/llama3_lora_sft 路径下生成如下文件:
在这里插入图片描述

2.2 量化

在完成模型合并并获得完整模型后,为了优化部署效果,人们通常会基于显存占用、使用成本和推理速度等因素,选择通过量化技术对模型进行压缩,从而实现更高效的部署。

量化(Quantization)通过数据精度压缩有效地减少了显存使用并加速推理。LLaMA-Factory 支持多种量化方法,包括:

  • AQLM
  • AWQ
  • GPTQ
  • QLoRA

(1)GPTQ
GPTQ 等后训练量化方法(Post Training Quantization)是一种在训练后对预训练模型进行量化的方法。我们通过量化技术将高精度表示的预训练模型转换为低精度的模型,从而在避免过多损失模型性能的情况下减少显存占用并加速推理,我们希望低精度数据类型在有限的表示范围内尽可能地接近高精度数据类型的表示,因此我们需要指定量化位数 export_quantization_bit 以及校准数据集 export_quantization_dataset

下面提供一个基于GPTQ进行量化的配置文件示例:

### examples/merge_lora/llama3_gptq.yaml
### model
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
template: llama3

### export
export_dir: models/llama3_gptq
export_quantization_bit: 4
export_quantization_dataset: data/c4_demo.json
export_size: 2
export_device: cpu
export_legacy_format: false

注意: 在进行模型合并时,请指定:

  • model_name_or_path: 预训练模型的名称或路径
  • template: 模型模板
  • export_dir: 导出路径
  • export_quantization_bit: 量化位数
  • export_quantization_dataset: 量化校准数据集
  • export_size: 最大导出模型文件大小
  • export_device: 导出设备
  • export_legacy_format: 是否使用旧格式导出

(2)QLoRA

QLoRA 是一种在 4-bit 量化模型基础上使用 LoRA 方法进行训练的技术。它在极大地保持了模型性能的同时大幅减少了显存占用和推理时间。

下面提供一个基于QLoRA 进行量化的配置文件示例:

### examples/merge_lora/llama3_q_lora.yaml
### model
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: saves/llama3-8b/lora/sft
template: llama3
finetuning_type: lora

### export
export_dir: models/llama3_lora_sft
export_size: 2
export_device: cpu
export_legacy_format: false

三、推理

LLaMA-Factory 支持多种推理与模型对话方式。

3.1 单次推理

(1)使用终端命令行进行对话

llamafactory-cli chat inference_config.yaml

(2)使用 Web UI 界面进行对话

llamafactory-cli webchat inference_config.yaml

对话时配置文件只需指定原始模型 model_name_or_pathtemplate ,并根据是否是微调模型指定 adapter_name_or_pathfinetuning_type

3.1.1 原始模型推理配置

对于原始模型推理, inference_config.yaml 中 只需指定原始模型 model_name_or_pathtemplate 即可。

### examples/inference/llama3.yaml
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
template: llama3
infer_backend: huggingface #choices: [huggingface, vllm]

这里,我们先使用原始模型 Meta-Llama-3-8B-Instruct 进行一个对话测试,对话截图如下:
在这里插入图片描述
可以看到,原始的 Meta-Llama-3-8B-Instruct 模型中文能力很弱,即使我们用中文提问,得到的仍然是英文的回复。

3.1.2 微调模型推理配置

对于微调模型推理,除原始模型和模板外,还需要指定适配器路径 adapter_name_or_path 和微调类型 finetuning_type

### examples/inference/llama3_lora_sft.yaml
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: saves/llama3-8b/lora/sft
template: llama3
finetuning_type: lora
infer_backend: huggingface #choices: [huggingface, vllm]

这里,我们使用原始模型与微调Adapter合并后的模型再次进行对话测试,对话如下:
在这里插入图片描述
可以看到,经过上述微调过程,模型已经具备了一定的中文能力,说明我们的微调起了作用。

3.1.3 多模态模型

对于多模态模型,您可以运行以下指令进行推理。

llamafactory-cli webchat examples/inferece/llava1_5.yaml

examples/inference/llava1_5.yaml 的配置示例如下:

model_name_or_path: llava-hf/llava-1.5-7b-hf
template: vicuna
infer_backend: huggingface  #choices: [huggingface, vllm]

3.2 批量推理

如果您希望向模型输入大量数据集进行快速的批量推理并保存推理结果,以下几种方式可以实现:

  • 启动 vllm 推理引擎对大量数据集进行快速的批量推理
  • 通过 部署 api 服务的形式通过 api 调用来进行批量推理

默认情况下,模型推理将使用 Huggingface 引擎。 您也可以指定 infer_backend: vllm 以使用 vllm 推理引擎以获得更快的推理速度。

3.2.1 数据集

您可以通过以下指令启动 vllm 推理引擎并使用数据集进行批量推理:

python scripts/vllm_infer.py --model_name_or_path path_to_merged_model --dataset alpaca_en_demo

3.2.2 api

如果您需要使用 api 进行批量推理,您只需指定模型、适配器(可选)、模板、微调方式等信息。

下面是一个配置文件的示例:

### examples/inference/llama3_lora_sft.yaml
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: saves/llama3-8b/lora/sft
template: llama3
finetuning_type: lora

下面是一个启动并调用 api 服务的示例。您可以使用以下命令启动 api 服务并运行以下示例程序进行调用:

API_PORT=8000 CUDA_VISIBLE_DEVICES=0 llamafactory-cli api examples/inference/llama3_lora_sft.yaml
# api_call_example.py
from openai import OpenAI
client = OpenAI(api_key="0",base_url="http://0.0.0.0:8000/v1")
messages = [{"role": "user", "content": "Who are you?"}]
result = client.chat.completions.create(messages=messages, model="meta-llama/Meta-Llama-3-8B-Instruct")
print(result.choices[0].message)

四、评估

4.1 通用能力评估

在完成模型训练后,您可以通过以下命令来评估模型效果:

 llamafactory-cli eval examples/train_lora/llama3_lora_eval.yaml

配置示例文件 examples/train_lora/llama3_lora_eval.yaml 具体如下:

### examples/train_lora/llama3_lora_eval.yaml
### model
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: saves/llama3-8b/lora/sft # 可选项

### method
finetuning_type: lora

### dataset
task: mmlu_test # mmlu_test, ceval_validation, cmmlu_test
template: fewshot
lang: en
n_shot: 5

### output
save_dir: saves/llama3-8b/lora/eval

### eval
batch_size: 4

4.2 NLG 评估

此外,您还可以通过如下命令来获得模型的 BLEU 和 ROUGE 分数以评价模型生成质量。

llamafactory-cli train examples/extras/nlg_eval/llama3_lora_predict.yaml

配置示例文件 examples/extras/nlg_eval/llama3_lora_predict.yaml 具体如下:

### examples/extras/nlg_eval/llama3_lora_predict.yaml
### model
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: saves/llama3-8b/lora/sft

### method
stage: sft
do_predict: true
finetuning_type: lora

### dataset
eval_dataset: identity,alpaca_en_demo
template: llama3
cutoff_len: 2048
max_samples: 50
overwrite_cache: true
preprocessing_num_workers: 16

### output
output_dir: saves/llama3-8b/lora/predict
overwrite_output_dir: true

### eval
per_device_eval_batch_size: 1
predict_with_generate: true
ddp_timeout: 180000000

同样,您也通过在 scripts/vllm_infer.py 中指定模型、数据集以使用 vllm 推理框架以取得更快的推理速度。

python scripts/vllm_infer.py --model_name_or_path path_to_merged_model --dataset alpaca_en_demo

4.3 评估相关参数

  • task:str类型,评估任务的名称,可选项有 mmlu_test, ceval_validation, cmmlu_test
  • task_dir:str类型,包含评估数据集的文件夹路径,默认值为 evaluation。
  • batch_size:int类型,每个GPU使用的批量大小,默认值为 4。
  • seed:int类型,用于数据加载器的随机种子,默认值为 42。
  • lang:str类型,评估使用的语言,可选值为 en、 zh。默认值为 en。
  • n_shot:int类型,few-shot 的示例数量,默认值为 5。
  • save_dir:str类型,保存评估结果的路径,默认值为 None。 如果该路径已经存在则会抛出错误。
  • download_mode:str类型,评估数据集的下载模式,默认值为 DownloadMode.REUSE_DATASET_IF_EXISTS。如果数据集已经存在则重复使用,否则则下载。
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐