深圳今天好冷,瞬间入冬了,被子比较薄,半夜冻醒了几次,早上早早起来穿上厚衣服才暖和点。还有两个多月又要过年了,真快呀,今年还未回过,倒也没有什么期待的。
前言
公司目前又一站式大模型精调平台,用起来很方便,准备好数据,只需要在平台上点击就可以完成基座模型的微调。所谓微调,就是让模型学习某个特定领域的知识,在特定的场景中能够发挥更大的作用。有时候我在想,如果脱离了这个平台,能否利用手头的资源自己搭建一个微调环境呢?本文便是摸索过程的记录下的,希望能给未来研究者一些帮助。
本次我将以Qwen2.5基座模型进行微调,显卡资源是白嫖公司的英伟达L20,在TLinux系统服务器上完成全部的操作。
环境
机器配置
- 操作系统:Tlinux 3.2
- CPU:32核
- 内存:64G
- 硬盘:500G
- 显卡:L20 1/3卡,显存14G
环境构建
使用LLaMA-Factory进行微调,在安装包时遇到了包冲突问题,故使用conda初始化一个干净环境
conda安装并初始化环境
- 下载并进行安装
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
2
3
4
|
#默认创建到安装目录下
conda create --name llama-factory python=3.11
#在指定目录下安装
conda create -p /data/anaconda3/envs/llama-factory python=3.11
|
- 激活环境(进入环境)
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量化环境
设置torch版本
这是在Qwen2.5需要进行的,详情可以见这篇文章
核心依赖包版本
- transformers==4.46.1
- torch==2.2
开始微调步骤
选择并下载基座模型
速度和资源的要求,选择Qwen/Qwen2.5-3B-Instruct-AWQ较为平衡,然后进行下载
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
|
微调领域大模型
参考