一、前言
预训练模型提供的是通用能力,对于某些特定领域的问题可能不够擅长,通过微调可以让模型更适应这些特定领域的需求,让它更擅长解决具体的问题。
二、术语介绍
2.1. LoRA微调
LoRA (Low-Rank Adaptation) 用于微调大型语言模型 (LLM)。 是一种有效的自适应策略,它不会引入额外的推理延迟,并在保持模型质量的同时显着减少下游任务的可训练参数数量。
2.2. Firefly
Firefly 是一个开源的大模型训练项目,支持对主流的大模型进行预训练、指令微调和DPO,包括但不限于Gemma、Qwen1.5、MiniCPM、Llama、InternLM、Baichuan、ChatGLM、Yi、Deepseek、Qwen、Orion、Ziya、Xverse、Mistral、Mixtral-8x7B、Zephyr、Vicuna、Bloom等。 本项目支持全量参数训练、LoRA、QLoRA高效训练,支持预训练、SFT、DPO。
2.3. Qwen1.5
Qwen1.5 is the beta version of Qwen2, a transformer-based decoder-only language model pretrained on a large amount of data. In comparison with the previous released Qwen, the improvements include:
- 6 model sizes, including 0.5B, 1.8B, 4B, 7B, 14B, and 72B;
- Significant performance improvement in human preference for chat models;
- Multilingual support of both base and chat models;
- Stable support of 32K context length for models of all sizes
- No need of
trust_remote_code
.
For more details, please refer to our blog post and GitHub repo.
三、构建环境
3.1. 基础环境
- 操作系统:centos7
- Tesla V100-SXM2-32GB CUDA Version: 12.2
3.2.下载qwen1.5-7b-chat模型
方式一:通过huggingface下载
https://huggingface.co/Qwen/Qwen1.5-7B-Chat/tree/main
方式二:通过ModelScope下载
git clone https://www.modelscope.cn/qwen/Qwen1.5-7B-Chat.git
下载好的项目放置在/model目录下,并重命名为qwen1.5-7b-chat
3.3.下载Firefly项目
方式一:直接下载
方式二:使用git克隆项目
git clone https://github.com/yangjianxin1/Firefly.git
下载好的项目放置在/service目录下,并重命名为firefly
3.4.安装依赖
conda create --name firefly python=3.10
conda activate firefly
pip install -r /service/firefly/requirements.txt
requirements.txt文件内容为:
若出现安装速度较慢的情况,可以指定第三方源,例如:
3.5.准备训练数据
示例数据如下:
- JSON格式
- 每行一个json对象
- conversation属性可以包含对轮对话内容
{"conversation_id": 1, "category": "Brainstorming", "conversation": [{"human": "您是谁", "assistant": "我是人见人爱,车见车载的叮当猫,我非常乐意解决您的问题。"}]}
{"conversation_id": 2, "category": "Brainstorming", "conversation": [{"human": "您身份是啥", "assistant": "我是人见人爱,车见车载的叮当猫。"}]}
{"conversation_id": 3, "category": "Brainstorming", "conversation": [{"human": "你的名字是什么", "assistant": "我是叮当猫"}]}
准备好的数据放置在/service/firefly/data目录,并根据需要重命名,这里保持文件名为:test_data.jsonl
3.6.修改微调脚本
修改配置/service/firefly/train_args/sft/lora/qwen1.5-7b-sft-lora.json
{
"output_dir": "/model/fine-tuning/firefly1.5-qwen-7b-chat",
"model_name_or_path": "/model/qwen1.5-7b-chat",
"train_file": "/service/firefly/data/test_data.jsonl",
"template_name": "qwen",
"train_mode": "lora",
"num_train_epochs": 1,
"per_device_train_batch_size": 2,
"gradient_accumulation_steps": 8,
"learning_rate": 2e-4,
"max_seq_length": 1024,
"logging_steps": 100,
"save_steps": 100,
"save_total_limit": 1,
"lr_scheduler_type": "constant_with_warmup",
"warmup_steps": 100,
"lora_rank": 64,
"lora_alpha": 16,
"lora_dropout": 0.05,
"gradient_checkpointing": true,
"disable_tqdm": false,
"optim": "paged_adamw_32bit",
"seed": 42,
"fp16": true,
"report_to": "tensorboard",
"dataloader_num_workers": 0,
"save_strategy": "steps",
"weight_decay": 0,
"max_grad_norm": 0.3,
"remove_unused_columns": false
}
主要参数说明如下:
- output_dir:训练输出目录,存储checkpoint、tokenizer、tensorboard等
- model_name_or_path:预训练模型的本地目录,或者在huggingface上的模型名称。
- train_file:训练数据集路径。sft时,需要设置为文件,可以使用data/dummy_data.jsonl进行debug。pretrain时,需要设置为目录。脚本会自动扫描目录下的所有jsonl文件。
- template_name:指令微调时,使用的模板名称。具体有哪些template_name,可参考component/template.py文件
- num_train_epochs:训练的轮次。如果数据量足够大,一般建议只训一个epoch。
- tokenize_num_workers:预训练时,tokenize的线程数,默认为10。
- deepspeed:deepspeed的训练配置文件。全量参数训练时,将采用deepspeed,关于deepspeed的参数配置说明,请参考deepspeed文档
- train_mode:训练模式,full、lora或qlora,默认为qlora。
- task_type:任务类型,pretrain、sft或dpo,默认为sft。
- per_device_train_batch_size:每张显卡的batch size。
- gradient_accumulation_steps:梯度累计步数。global batch=num_gpus * per_device_train_batch_size * gradient_accumulation_steps。
- gradient_checkpointing:如果显存捉襟见肘,可以开启。以时间换空间,模型不缓存激活状态,会进行两次forward计算,以节省显存。
- learning_rate:学习率。全量参数微调的时候,建议小一些,1e-5或5e-6。
- max_seq_length:训练时的最大长度。按照自己的设备进行设置,越长需要占用越多显存。
- max_prompt_length:进行dpo时,prompt的最大长度。
- logging_steps:每隔多少步统计一次train loss。
- save_steps:每隔多少步保存一个模型。
- save_total_limit:output_dir目录中最多保存多少个checkpoint,超出则会将最旧的删除。
- lr_scheduler_type:学习率变化策略。
- warmup_steps:warm up步数。学习率经过多少步,增长到指定的数值。
- optim:优化器。如果是全量参数微调,建议使用adamw_hf。
- seed:随机种子,用于复现实验结果。
- fp16:使用使用fp16混合精度。V100建议开启。
- bf16:使用使用bf16混合精度。A100建议开启。
3.7.创建启动脚本
vi start_train_qwen1.5_7b_chat.sh
加入以下内容:
cd /service/firefly
source /opt/anaconda3/bin/activate firefly
/opt/anaconda3/envs/firefly/bin/torchrun --nproc_per_node=1 /service/firefly/train.py --train_args_file /service/firefly/train_args/sft/lora/qwen1.5-7b-sft-lora.json
增加执行权限:
chmod +x start_train_qwen1.5_7b_chat.sh
四、部署服务
通过微调改变模型的自我认知
4.1.启动训练
执行后:
ps:上述只用了有限的几条数据做训练展示,所以用时较短
生成的Lora权重如下:
五、附带说明
5.1.GPU资源不足
尽量减少gradient_accumulation_steps、gradient_accumulation_steps、model_max_length
这三个值。
5.2.flash_attn安装失败
flash_attn非必须,可以从requirements.txt移除,有需要再通过源码安装