ai大模型微调

深圳今天好冷,瞬间入冬了,被子比较薄,半夜冻醒了几次,早上早早起来穿上厚衣服才暖和点。还有两个多月又要过年了,真快呀,今年还未回过,倒也没有什么期待的。

# 前言

公司目前又一站式大模型精调平台,用起来很方便,准备好数据,只需要在平台上点击就可以完成基座模型的微调。所谓微调,就是让模型学习某个特定领域的知识,在特定的场景中能够发挥更大的作用。有时候我在想,如果脱离了这个平台,能否利用手头的资源自己搭建一个微调环境呢?本文便是摸索过程的记录下的,希望能给未来研究者一些帮助。

本次我将以Qwen2.5基座模型进行微调,显卡资源是白嫖公司的英伟达L20,在TLinux系统服务器上完成全部的操作。

# 环境

# 机器配置

  • 操作系统:Tlinux 3.2
  • CPU:32核
  • 内存:64G
  • 硬盘:500G
  • 显卡:L20 1/3卡,显存14G

# 环境构建

使用LLaMA-Factory进行微调,在安装包时遇到了包冲突问题,故使用conda初始化一个干净环境

# conda安装并初始化环境

  1. 下载并进行安装
1
2
3
4
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm ~/miniconda3/miniconda.sh
  1. 创建一个新的环境
1
2
3
4
#默认创建到安装目录下
conda create --name llama-factory python=3.11
#在指定目录下安装
conda create -p /data/anaconda3/envs/llama-factory python=3.11
  1. 激活环境(进入环境)
1
conda activate llama-factory

# LLaMA-Factory环境构建

进入llama-factory环境后,便可以着手构建LLaMa-Factory环境,通过conda的新环境是不会遇到冲突问题的。

1
2
3
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

# awq量化环境

1
pip install autoawq

# 设置torch版本

这是在Qwen2.5需要进行的,详情可以见这篇文章

1
pip install torch==2.2

# 核心依赖包版本

  • transformers==4.46.1
  • torch==2.2

# 开始微调步骤

# 选择并下载基座模型

速度和资源的要求,选择Qwen/Qwen2.5-3B-Instruct-AWQ较为平衡,然后进行下载

1
pip install modelscope
1
2
3
#模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('/data/models/Qwen/Qwen2.5-3B-Instruct-AWQ')

# 检查环境

 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
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen2.5-3B-Instruct-AWQ"
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
prompt = "Give me a short introduction to large language model."
messages = [
    {"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)

执行这段代码,如果能够正常输出说明环境没问题。

# 编辑LLaMA-Factory训练参数

examples下面有很多示例的训练参数,参考编写Qwen2.5的微调配置

examples/train_lora/qwen2.5_3b_lora_sft.yaml

 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
32
33
34
35
36
37
38
39
### model
model_name_or_path: /data/models/Qwen/Qwen2.5-3B-Instruct-AWQ

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

### dataset
dataset: identity,alpaca_en_demo
template: qwen
cutoff_len: 2048
max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 16

### output
output_dir: /data/saves/qwen2.5-3b/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: 2
learning_rate: 1.0e-4
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
2
#指定模型路径,可以填写绝对路径
model_name_or_path: /data/models/Qwen/Qwen2.5-3B-Instruct-AWQ

# 方法配置

1
2
3
4
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
  • stage: sft:表示当前的训练阶段是 SFT(Supervised Fine-Tuning) 阶段,意味着模型将在特定的标注数据集上进行监督学习。
  • do_train: true:表示进行训练。
  • finetuning_type: lora:指定了微调的类型是 LoRA(Low-Rank Adapter),意味着通过低秩适配器层来进行微调,而不是全量训练整个模型。
  • lora_target: all:表示在模型的所有层上应用 LoRA 微调。你也可以选择特定的层,如 attention 或 ffn,但这里设置为 all,意味着所有的层都会应用 LoRA。

# 数据集配置

1
2
3
4
5
6
dataset: identity,alpaca_en_demo
template: qwen
cutoff_len: 2048
max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 16
  • dataset: identity,alpaca_en_demo:指定了要使用的数据集,这里列出了两个数据集:identity 和 alpaca_en_demo。你需要确保这两个数据集已经准备好并且路径正确。identity 可能是一个自定义数据集,alpaca_en_demo 是一个英文数据集。
  • template: qwen:指定了数据集的模板,这个模板通常用于数据预处理过程,它可能包括对文本的格式化或特殊的标注。
  • cutoff_len: 2048:指定了最大输入长度(单位为token)。如果输入文本超过这个长度,它将会被截断。这个长度与模型的最大接受长度有关,通常需要根据具体模型的设置调整。
  • max_samples: 1000:指定了使用的数据集样本的最大数量,这里设置为1000,意味着将只使用最多1000个样本进行训练。
  • overwrite_cache: true:如果缓存目录存在,则覆盖缓存。这个选项通常用于确保每次训练时使用最新的数据。
  • preprocessing_num_workers: 16:指定了数据预处理时使用的工作线程数,16个线程可以加速数据加载和预处理过程。

# 输出配置

1
2
3
4
5
output_dir: /data/saves/qwen2-7b/lora/sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
  • output_dir: /data/saves/qwen2-3b/lora/sft:指定了训练过程中保存模型和日志的输出目录。在此路径下,将保存微调后的模型、检查点等文件。
  • logging_steps: 10:每10步记录一次日志。
  • save_steps: 500:每500步保存一次模型检查点。这样你可以在训练过程中定期保存模型的状态,避免意外中断时丢失训练进度。
  • plot_loss: true:在训练过程中,启用损失值可视化(例如通过TensorBoard或其他工具)。这有助于监控训练过程中模型的表现。
  • overwrite_output_dir: true:如果输出目录已存在,则覆盖它。确保训练过程中不会因为目录存在而出现错误。

# 训练配置

1
2
3
4
5
6
7
8
per_device_train_batch_size: 1
gradient_accumulation_steps: 2
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000
  • per_device_train_batch_size: 1:每个设备的训练批次大小设置为1。这通常与GPU的显存大小相关,如果显存较小,批次大小可以设置为1。
  • gradient_accumulation_steps: 2:梯度累积的步数。如果批次大小设置为1,但需要更多的梯度累积,可以通过此设置实现。
  • learning_rate: 1.0e-4:设置学习率为 0.0001,这是训练时调整权重的步长。
  • num_train_epochs: 3.0:训练的总周期数,这里设置为3轮。通常需要根据训练集大小和收敛速度来调整这个值。
  • lr_scheduler_type: cosine:学习率调度器类型,使用 cosine 调度策略,通常能在训练后期逐渐减小学习率。
  • warmup_ratio: 0.1:学习率的预热比例,设置为 0.1 表示前10%的训练步骤中,学习率将逐步增加到初始值。
  • bf16: true:启用 bfloat16 精度进行训练,以减少显存消耗并加速训练。这通常需要支持 bfloat16 的硬件(如TPU)。
  • ddp_timeout: 180000000:设置 Distributed Data Parallel(DDP) 模式下的超时。这个值通常是为了防止分布式训练过程中发生超时错误。

# 评估配置

1
2
3
4
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500
  • val_size: 0.1:指定验证集的大小为训练数据的 10%,即从训练数据集中划分出10%作为验证集。
  • per_device_eval_batch_size: 1:评估时每个设备的批次大小为1。
  • eval_strategy: steps:评估策略设置为按步数评估,即每训练一定步数后进行评估。
  • eval_steps: 500:每500步进行一次评估。

# 执行微调

1
llamafactory-cli train examples/train_lora/qwen2.5_3b_lora_sft.yaml

# 微调领域大模型

# 参考

Licensed under CC BY-NC-SA 4.0