LLMs之ChatGLM2:ChatGLM-Finetuning(基于DeepSpeed)的简介、使用方法(四种微调方法(Freeze方法/Lora方法/P-Tuning方法/全量参数)+单卡/多卡训

LLMs之ChatGLM2:ChatGLM-Finetuning(基于DeepSpeed)的简介、使用方法(四种微调方法(Freeze方法/Lora方法/P-Tuning方法/全量参数)+单卡/多卡训练设置+显存资源占用对比)、案例应用(基于4张A800-80G+采用ChatGLM-6B模型+全量参数+基于DeepSpeed框架(ZeRO3的模型拆分技术)流水线实现)之详细攻略

目录

相关文章

相关论文

LLMs之GLM-130B/ChatGLM:《GLM-130B: AN OPEN BILINGUAL PRE-TRAINED MODEL》翻译与解读

LLMs之ChatGLM2:ChatGLM2-6B的简介、安装、使用方法之详细攻略

实战案例

LLMs:从头到尾手把手教大家利用ChatGLM-6B模型实现训练、部署、推理(CLI/Gradio交互界面)、微调(两个提效技巧【混合精度+ZeRO零冗余提效】+三种微调方法【fine-tuning/P-tuning v2改变参数分布/LoRA低秩近似降低要更新参数量】)图文教程之详细攻略

LLMs之ChatGLM:基于Langchain框架利用text2vec-large-chinese+ChatGLM大模型(Docker 部署)接入本地知识库(生成本地知识库/分割/向量化+基于问题【Embdding+向量化+匹配TopK作为上下文】=生成Prompt喂给大模型→LLMs响应)实现问答响应项目(CLI/WebUI/VUE)图文教程之详细攻略

LLMs之ChatGLM:ChatGLM Efficient Tuning(一款高效微调ChatGLM-6B/ChatGLM2-6B的工具【LoRA/P-Tunin】)的简介、安装、使用方法之详细攻略

LLMs之ChatGLM2:ChatGLM2-6B本地部署之单机推理(API/CLI/GUI)、低成本部署(GPU量化部署/CPU及其量化部署/Mac部署/多卡部署)、有限资源下高效微调(全参/P-tuning v2)、模型评估和推理之图文教程之详细攻略

LLMs之ChatGLM2:基于ChatGLM Efficient Tuning(微调工具包)实现对ChatGLM2进行LoRA微调并进行推理测试图文教程之详细攻略

LLMs:LLaMA Efficient Tuning(一款可高效微调【全参数/LoRA/QLoRA】主流大模型【ChatGLM2/LLaMA2/Baichuan等】的高效工具【预训练+指令监督微调+奖励模型训练+PPO 训练+DPO 训练】)的简介、安装、使用方法之详细攻略

LLMs:LangChain-Chatchat(一款可实现本地知识库问答应用)的简介、安装、使用方法之详细攻略

LLMs之ChatGLM2:ChatGLM-Finetuning的简介、使用方法(四种微调方法(Freeze方法/Lora方法/P-Tuning方法/全量参数)+单卡/多卡训练设置+显存资源占用对比)、案例应用之详细攻略

LLMs之ChatGLM2:ChatGLM-Finetuning之源码解读(train.py文件)—解析命令行(模型路径+数据集相关【最大序列长度/最大输入长度】+训练参数相关【批次大小/学习率/权重衰减系数/训练轮数/梯度累计步数/学习率预热比例】+结果输出相关【输出路径/训练方式【四种方式微调,如Freeze/Lora/P-Tuning/全量参数】/进程标志/loss频率/保存模型频率】+否启用梯度检查点+DeepSpeed配置+LoRA/Freeze/P-tuning配置)及初始化设置(是否启用分布式GPU+加载DeepSpeed配置参数+日志写入器)→加载数据(加载tokenizer/训练集)→模型训练(载入优化器和学习率调度器并设置参数+判断启用梯度检查点+将模型和优化器包装到deepspeed中【DeepSpeed封装数据并行】+执行模型训练【训练epoch循环+迭代训练数据+计算loss+反向传播+梯度裁剪技术】)+模型保存(定期显示训练损失并保存模型,判断zero3训练时其模型参数需要合并保存)

ChatGLM-Finetuning的简介

ChatGLM-Finetuning的安装及其使用方法

1、配置环境

1.1、下载项目代码

1.2、配置环境,各个包版本的要求

2、微调方法:基于4卡 A800-80G采用微调训练,最长2小时左右

T1、Freeze方法:修改train_type=freeze及其freeze_module_name参数

(1)、ChatGLM单卡训练

(2)、ChatGLM四卡训练:设置CUDA_VISIBLE_DEVICES参数

(3)、ChatGLM2单卡训练

(4)、ChatGLM2四卡训练:设置CUDA_VISIBLE_DEVICES参数

(5)、耗费显存资源占用对比—Freeze方法:对比ChaGLM和ChaGLM2

T2、PT方法(即P-Tuning及P-Tuning V2):修改train_type为ptuning、prefix_projection=True

(1)、ChatGLM单卡训练

(2)、ChatGLM四卡训练

(3)、ChatGLM2单卡训练

(4)、ChatGLM2四卡训练

(5)、耗费显存资源占用对比—PT方法:对比ChaGLM和ChaGLM2

T3、Lora方法:修改train_type=lora及其lora_dim=16、lora_alpha=64、lora_dropout=0.1、lora_module_name="query_key_value"

(1)、ChatGLM单卡训练

(2)、ChatGLM四卡训练

(3)、ChatGLM2单卡训练

(4)、ChatGLM2四卡训练

(5)、耗费显存资源占用对比—LoRA方法:对比ChaGLM和ChaGLM2

T4、全参方法(基于DeepSpeed-Zero3方法【对模型参数进行多卡分割】+Offload方法【将优化器参数卸载到CPU上】):修改train_type=all

(1)、ChatGLM四卡训练

(2)、ChatGLM2四卡训练

(3)、耗费显存资源占用对比—全参方法:对比ChaGLM和ChaGLM2

多种微调技巧结果对比:PT-only-Embedding(37G【显卡占用】,53m【训练耗时】+3m【测试耗时】)、PT(30G,135m+3m)、Freeze(24G,112m+3m)、Lora(39G,65m+4m)四种微调结果

ChatGLM-Finetuning的案例应用

1、流水线并行训练案例:基于4张A800-80G+采用ChatGLM-6B模型+全量参数+基于DeepSpeed框架(ZeRO3的模型拆分技术)流水线实现

(1)、训练阶段:采用三元组数据进行模型训练及测试

(2)、推理阶段:模型转换脚本

(3)、结果对比

显卡实时占比:每张卡依次占比55/80G、80/80G、80/80G、70/80G

F1得分在0.59左右


相关文章

相关论文

LLMs之GLM-130B/ChatGLM:《GLM-130B: AN OPEN BILINGUAL PRE-TRAINED MODEL》翻译与解读

LLMs之GLM-130B/ChatGLM:《GLM-130B: AN OPEN BILINGUAL PRE-TRAINED MODEL》翻译与解读_一个处女座的程序猿的博客-CSDN博客

LLMs之ChatGLM2:ChatGLM2-6B的简介、安装、使用方法之详细攻略

LLMs之ChatGLM2:ChatGLM2-6B的简介、安装、使用方法之详细攻略_一个处女座的程序猿的博客-CSDN博客

实战案例

LLMs:从头到尾手把手教大家利用ChatGLM-6B模型实现训练、部署、推理(CLI/Gradio交互界面)、微调(两个提效技巧【混合精度+ZeRO零冗余提效】+三种微调方法【fine-tuning/P-tuning v2改变参数分布/LoRA低秩近似降低要更新参数量】)图文教程之详细攻略

https://yunyaniu.blog.csdn.net/article/details/120249551

LLMs之ChatGLM:基于Langchain框架利用text2vec-large-chinese+ChatGLM大模型(Docker 部署)接入本地知识库(生成本地知识库/分割/向量化+基于问题【Embdding+向量化+匹配TopK作为上下文】=生成Prompt喂给大模型→LLMs响应)实现问答响应项目(CLI/WebUI/VUE)图文教程之详细攻略

https://yunyaniu.blog.csdn.net/article/details/130998758

LLMs之ChatGLM:ChatGLM Efficient Tuning(一款高效微调ChatGLM-6B/ChatGLM2-6B的工具【LoRA/P-Tunin】)的简介、安装、使用方法之详细攻略

LLMs之ChatGLM:ChatGLM Efficient Tuning(一款高效微调ChatGLM-6B/ChatGLM2-6B的工具【LoRA/P-Tunin】)的简介、安装、使用方法之详细攻略_一个处女座的程序猿的博客-CSDN博客

LLMs之ChatGLM2:ChatGLM2-6B本地部署之单机推理(API/CLI/GUI)、低成本部署(GPU量化部署/CPU及其量化部署/Mac部署/多卡部署)、有限资源下高效微调(全参/P-tuning v2)、模型评估和推理之图文教程之详细攻略

LLMs之ChatGLM2:ChatGLM2-6B本地部署之单机推理(API/CLI/GUI)、低成本部署(GPU量化部署/CPU及其量化部署/Mac部署/多卡部署)、有限资源下高效微调(全参/P-t_一个处女座的程序猿的博客-CSDN博客

LLMs之ChatGLM2:基于ChatGLM Efficient Tuning(微调工具包)实现对ChatGLM2进行LoRA微调并进行推理测试图文教程之详细攻略

LLMs之ChatGLM2:基于ChatGLM Efficient Tuning(微调工具包)实现对ChatGLM2进行LoRA微调并进行推理测试图文教程之详细攻略_一个处女座的程序猿的博客-CSDN博客

LLMs:LLaMA Efficient Tuning(一款可高效微调【全参数/LoRA/QLoRA】主流大模型【ChatGLM2/LLaMA2/Baichuan等】的高效工具【预训练+指令监督微调+奖励模型训练+PPO 训练+DPO 训练】)的简介、安装、使用方法之详细攻略

LLMs:LLaMA Efficient Tuning(一款可高效微调【全参数/LoRA/QLoRA】主流大模型【ChatGLM2/LLaMA2/Baichuan等】的高效工具【预训练+指令监督微调+_一个处女座的程序猿的博客-CSDN博客

LLMs:LangChain-Chatchat(一款可实现本地知识库问答应用)的简介、安装、使用方法之详细攻略

LLMs:LangChain-Chatchat(一款可实现本地知识库问答应用)的简介、安装、使用方法之详细攻略_一个处女座的程序猿的博客-CSDN博客

LLMs之ChatGLM2:ChatGLM-Finetuning的简介、使用方法(四种微调方法(Freeze方法/Lora方法/P-Tuning方法/全量参数)+单卡/多卡训练设置+显存资源占用对比)、案例应用之详细攻略

https://yunyaniu.blog.csdn.net/article/details/132613495

LLMs之ChatGLM2:ChatGLM-Finetuning之源码解读(train.py文件)—解析命令行(模型路径+数据集相关【最大序列长度/最大输入长度】+训练参数相关【批次大小/学习率/权重衰减系数/训练轮数/梯度累计步数/学习率预热比例】+结果输出相关【输出路径/训练方式【四种方式微调,如Freeze/Lora/P-Tuning/全量参数】/进程标志/loss频率/保存模型频率】+否启用梯度检查点+DeepSpeed配置+LoRA/Freeze/P-tuning配置)及初始化设置(是否启用分布式GPU+加载DeepSpeed配置参数+日志写入器)→加载数据(加载tokenizer/训练集)→模型训练(载入优化器和学习率调度器并设置参数+判断启用梯度检查点+将模型和优化器包装到deepspeed中【DeepSpeed封装数据并行】+执行模型训练【训练epoch循环+迭代训练数据+计算loss+反向传播+梯度裁剪技术】)+模型保存(定期显示训练损失并保存模型,判断zero3训练时其模型参数需要合并保存)

LLMs之ChatGLM2:ChatGLM-Finetuning之源码解读(train.py文件)—解析命令→加载数据→模型训练(四种方式微调+DeepSpeed封装数据并行)+模型保存(定期输出lo_一个处女座的程序猿的博客-CSDN博客

ChatGLM-Finetuning的简介

本项目主要针对ChatGLM和ChatGLM2模型进行不同方式的微调(Freeze方法、Lora方法、P-Tuning方法、全量参数等),训练代码均采用DeepSpeed进行训练,并对比大模型在不同微调方法上的效果,主要针对信息抽取任务、生成任务、分类任务等。
本项目支持单卡训练&多卡训练,由于采用单指令集方式微调,模型微调之后并没有出现严重的灾难性遗忘。由于官方代码和模型一直在更新,目前代码和模型使用的是最新版本(20230806)。
PS:没有用Trainer(虽然Trainer代码简单,但不易修改,大模型时代算法工程师本就成为了数据工程师,因此更需了解训练流程)

地址GitHub - liucongg/ChatGLM-Finetuning: 基于ChatGLM-6B、ChatGLM2-6B模型,进行下游具体任务微调,涉及Freeze、Lora、P-tuning、全参微调等

ChatGLM-Finetuning的安装及其使用方法

1、配置环境

1.1、下载项目代码

代码地址GitHub - liucongg/ChatGLM-Finetuning: 基于ChatGLM-6B、ChatGLM2-6B模型,进行下游具体任务微调,涉及Freeze、Lora、P-tuning、全参微调等

1.2、配置环境,各个包版本的要求

cpm_kernels==1.0.11
deepspeed==0.9.0
numpy==1.24.2
peft==0.3.0
sentencepiece==0.1.96
tensorboard==2.11.0
tensorflow==2.13.0
torch==1.13.1+cu116
tqdm==4.64.1
transformers==4.27.1

2、微调方法:基于4卡 A800-80G采用微调训练,最长2小时左右

模型微调时,如果遇到显存不够的情况,可以开启gradient_checkpointing、zero3、offload等参数来节省显存。下面model_name_or_path参数为模型路径,请根据可根据自己实际模型保存地址进行修改。

T1、Freeze方法:修改train_type=freeze及其freeze_module_name参数

Freeze方法,即参数冻结,对原始模型部分参数进行冻结操作,仅训练部分参数,以达到在单卡或多卡,不进行TP(张量并行)或PP(管道并行)操作就可以对大模型进行训练。

微调代码,见train.py,核心部分如下:

freeze_module_name = args.freeze_module_name.split(",")
for name, param in model.named_parameters():
	if not any(nd in name for nd in freeze_module_name):
		param.requires_grad = False

针对模型不同层进行修改,可以自行修改freeze_module_name参数配置,例如"layers.27.,layers.26.,layers.25.,layers.24."。 训练代码均采用DeepSpeed进行训练,可设置参数包含train_path、model_name_or_path、mode、train_type、freeze_module_name、ds_file、num_train_epochs、per_device_train_batch_size、gradient_accumulation_steps、output_dir等, 可根据自己的任务配置。

(1)、ChatGLM单卡训练

CUDA_VISIBLE_DEVICES=0 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM-6B/ \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm \
                --train_type freeze \
                --freeze_module_name "layers.27.,layers.26.,layers.25.,layers.24." \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --output_dir ./output-glm

(2)、ChatGLM四卡训练:设置CUDA_VISIBLE_DEVICES参数

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM-6B/ \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm \
                --train_type freeze \
                --freeze_module_name "layers.27.,layers.26.,layers.25.,layers.24." \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --output_dir ./output-glm

(3)、ChatGLM2单卡训练

CUDA_VISIBLE_DEVICES=0 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM2-6B/ \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm2 \
                --train_type freeze \
                --freeze_module_name "layers.27.,layers.26.,layers.25.,layers.24." \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --output_dir ./output-glm2

(4)、ChatGLM2四卡训练:设置CUDA_VISIBLE_DEVICES参数

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM2-6B/ \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm2 \
                --train_type freeze \
                --freeze_module_name "layers.27.,layers.26.,layers.25.,layers.24." \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --output_dir ./output-glm2

(5)、耗费显存资源占用对比—Freeze方法:对比ChaGLMChaGLM2

PS:ChatGLM微调时所用显存要比ChatGLM2多,详细显存占比如下:

Model DeepSpeed-Stage Offload Gradient Checkpointing Batch Size Max Length GPU-A40 Number 所耗显存
ChaGLM zero2 No Yes 1 1560 1 36G
ChaGLM zero2 No No 1 1560 1 38G
ChaGLM zero2 No Yes 1 1560 4 24G
ChaGLM zero2 No No 1 1560 4 29G
ChaGLM2 zero2 No Yes 1 1560 1 35G
ChaGLM2 zero2 No No 1 1560 1 36G
ChaGLM2 zero2 No Yes 1 1560 4 22G
ChaGLM2 zero2 No No 1 1560 4 27G

T2、PT方法(即P-Tuning及P-Tuning V2):修改train_type为ptuning、prefix_projection=True

PT方法,即P-Tuning方法,参考ChatGLM官方代码 ,是一种针对于大模型的soft-prompt方法。

  • P-Tuning仅对大模型的Embedding加入新的参数。paper
  • P-Tuning-V2,将大模型的Embedding和每一层前都加上新的参数。paper

微调代码,见train.py,核心部分如下:

config = MODE[args.mode]["config"].from_pretrained(args.model_name_or_path)
config.pre_seq_len = args.pre_seq_len
config.prefix_projection = args.prefix_projection
model = MODE[args.mode]["model"].from_pretrained(args.model_name_or_path, config=config)
for name, param in model.named_parameters():
	if not any(nd in name for nd in ["prefix_encoder"]):
		param.requires_grad = False

当prefix_projection为True时,为P-Tuning-V2方法,在大模型的Embedding和每一层前都加上新的参数;为False时,为P-Tuning方法,仅在大模型的Embedding上新的参数。

训练代码均采用DeepSpeed进行训练,可设置参数包含train_path、model_name_or_path、mode、train_type、pre_seq_len、prefix_projection、ds_file、num_train_epochs、per_device_train_batch_size、gradient_accumulation_steps、output_dir等, 可根据自己的任务配置。

(1)、ChatGLM单卡训练

CUDA_VISIBLE_DEVICES=0 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM-6B \
                --per_device_train_batch_size 1 \
                --max_len 768 \
                --max_src_len 512 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm \
                --train_type ptuning \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --pre_seq_len 16 \
                --prefix_projection True \
                --output_dir ./output-glm

(2)、ChatGLM四卡训练

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM-6B \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm \
                --train_type ptuning \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --pre_seq_len 16 \
                --prefix_projection True \
                --output_dir ./output-glm

(3)、ChatGLM2单卡训练

CUDA_VISIBLE_DEVICES=0 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM2-6B \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm2 \
                --train_type ptuning \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --pre_seq_len 16 \
                --prefix_projection True \
                --output_dir ./output-glm2

(4)、ChatGLM2四卡训练

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
                --train_path data/spo_0.json \
                --model_name_or_path ChatGLM2-6B \
                --per_device_train_batch_size 1 \
                --max_len 1560 \
                --max_src_len 1024 \
                --learning_rate 1e-4 \
                --weight_decay 0.1 \
                --num_train_epochs 2 \
                --gradient_accumulation_steps 4 \
                --warmup_ratio 0.1 \
                --mode glm2 \
                --train_type ptuning \
                --seed 1234 \
                --ds_file ds_zero2_no_offload.json \
                --gradient_checkpointing \
                --show_loss_step 10 \
                --pre_seq_len 16 \
                --prefix_projection True \
                --output_dir ./output-glm2

(5)、耗费显存资源占用对比—PT方法:对比ChaGLMChaGLM2

PS:ChatGLM微调时所用显存要比ChatGLM2多,详细显存占比如下:

Model DeepSpeed-Stage Offload Gradient Checkpointing Batch Size Max Length GPU-A40 Number 所耗显存
ChaGLM zero2 No Yes 1 768 1 43G
ChaGLM zero2 No No 1 300 1 44G
ChaGLM zero2 No Yes 1 1560 4 37G
ChaGLM zero2 No No 1 1360 4 44G
ChaGLM2 zero2 No Yes 1 1560 1 20G
ChaGLM2 zero2 No No 1 1560 1 40G
ChaGLM2 zero2 No Yes 1 1560 4 19G
ChaGLM2 zero2 No No 1 1560 4 39G

T3、Lora方法:修改train_type=lora及其lora_dim=16、lora_alpha=64、lora_dropout=0.1、lora_module_name="query_key_value"

Lora方法,即在大型语言模型上对指定参数(权重矩阵)并行增加额外的低秩矩阵,并在模型训练过程中,仅训练额外增加的并行低秩矩阵的参数。 当“秩值”远小于原始参数维度时,新增的低秩矩阵参数量也就很小。在下游任务tuning时,仅须训练很小的参数,但能获取较好的表现结果。

微调代码,见train.py,核心部分如下:

model = MODE[args.mode]["model"].from_pretrained(args.model_name_or_path)
lora_module_name = args.lora_module_name.split(",")
config = LoraConfig(r=args.lora_dim,
					lora_alpha=args.lora_alpha,
					target_modules=lora_module_name,
					lora_dropout=args.lora_dropout,
					bias="none",
					task_type="CAUSAL_LM",
					inference_mode=False,
					)
model = get_peft_model(model, config)
model.config.torch_dtype = torch.float32

训练代码均采用DeepSpeed进行训练,可设置参数包含train_path、model_name_or_path、mode、train_type、lora_dim、lora_alpha、lora_dropout、lora_module_name、ds_file、num_train_epochs、per_device_train_batch_size、gradient_accumulation_steps、output_dir等, 可根据自己的任务配置。

(1)、ChatGLM单卡训练

CUDA_VISIBLE_DEVICES=0 deepspeed --master_port 520 train.py \
              --train_path data/spo_0.json \
              --model_name_or_path ChatGLM-6B \
              --per_device_train_batch_size 1 \
              --max_len 1560 \
              --max_src_len 1024 \
              --learning_rate 1e-4 \
              --weight_decay 0.1 \
              --num_train_epochs 2 \
              --gradient_accumulation_steps 4 \
              --warmup_ratio 0.1 \
              --mode glm \
              --train_type lora \
              --lora_dim 16 \
              --lora_alpha 64 \
              --lora_dropout 0.1 \
              --lora_module_name "query_key_value" \
              --seed 1234 \
              --ds_file ds_zero2_no_offload.json \
              --gradient_checkpointing \
              --show_loss_step 10 \
              --output_dir ./output-glm

(2)、ChatGLM四卡训练

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
              --train_path data/spo_0.json \
              --model_name_or_path ChatGLM-6B \
              --per_device_train_batch_size 1 \
              --max_len 1560 \
              --max_src_len 1024 \
              --learning_rate 1e-4 \
              --weight_decay 0.1 \
              --num_train_epochs 2 \
              --gradient_accumulation_steps 4 \
              --warmup_ratio 0.1 \
              --mode glm \
              --train_type lora \
              --lora_dim 16 \
              --lora_alpha 64 \
              --lora_dropout 0.1 \
              --lora_module_name "query_key_value" \
              --seed 1234 \
              --ds_file ds_zero2_no_offload.json \
              --gradient_checkpointing \
              --show_loss_step 10 \
              --output_dir ./output-glm

(3)、ChatGLM2单卡训练

CUDA_VISIBLE_DEVICES=0 deepspeed --master_port 520 train.py \
              --train_path data/spo_0.json \
              --model_name_or_path ChatGLM2-6B \
              --per_device_train_batch_size 1 \
              --max_len 1560 \
              --max_src_len 1024 \
              --learning_rate 1e-4 \
              --weight_decay 0.1 \
              --num_train_epochs 2 \
              --gradient_accumulation_steps 4 \
              --warmup_ratio 0.1 \
              --mode glm2 \
              --train_type lora \
              --lora_dim 16 \
              --lora_alpha 64 \
              --lora_dropout 0.1 \
              --lora_module_name "query_key_value,dense_h_to_4h,dense_4h_to_h,dense" \
              --seed 1234 \
              --ds_file ds_zero2_no_offload.json \
              --gradient_checkpointing \
              --show_loss_step 10 \
              --output_dir ./output-glm2

(4)、ChatGLM2四卡训练

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
              --train_path data/spo_0.json \
              --model_name_or_path ChatGLM2-6B \
              --per_device_train_batch_size 1 \
              --max_len 1560 \
              --max_src_len 1024 \
              --learning_rate 1e-4 \
              --weight_decay 0.1 \
              --num_train_epochs 2 \
              --gradient_accumulation_steps 4 \
              --warmup_ratio 0.1 \
              --mode glm2 \
              --train_type lora \
              --lora_dim 16 \
              --lora_alpha 64 \
              --lora_dropout 0.1 \
              --lora_module_name "query_key_value,dense_h_to_4h,dense_4h_to_h,dense" \
              --seed 1234 \
              --ds_file ds_zero2_no_offload.json \
              --gradient_checkpointing \
              --show_loss_step 10 \
              --output_dir ./output-glm2

(5)、耗费显存资源占用对比—LoRA方法:对比ChaGLMChaGLM2

PS:ChatGLM微调时所用显存要比ChatGLM2多,详细显存占比如下:

Model DeepSpeed-Stage Offload Gradient Checkpointing Batch Size Max Length GPU-A40 Number 所耗显存
ChaGLM zero2 No Yes 1 1560 1 20G
ChaGLM zero2 No No 1 1560 1 45G
ChaGLM zero2 No Yes 1 1560 4 20G
ChaGLM zero2 No No 1 1560 4 45G
ChaGLM2 zero2 No Yes 1 1560 1 20G
ChaGLM2 zero2 No No 1 1560 1 43G
ChaGLM2 zero2 No Yes 1 1560 4 19G
ChaGLM2 zero2 No No 1 1560 4 42G

注意:Lora方法在模型保存时仅保存了Lora训练参数,因此在模型预测时需要将模型参数进行合并,具体参考merge_lora.py。

T4、全参方法(基于DeepSpeed-Zero3方法【对模型参数进行多卡分割】+Offload方法【将优化器参数卸载到CPU上】):修改train_type=all

全参方法,对大模型进行全量参数训练,主要借助DeepSpeed-Zero3方法,对模型参数进行多卡分割,并借助Offload方法,将优化器参数卸载到CPU上以解决显卡不足问题。

微调代码,见train.py,核心部分如下:

model = MODE[args.mode]["model"].from_pretrained(args.model_name_or_path)

训练代码均采用DeepSpeed进行训练,可设置参数包含train_path、model_name_or_path、mode、train_type、ds_file、num_train_epochs、per_device_train_batch_size、gradient_accumulation_steps、output_dir等, 可根据自己的任务配置。

(1)、ChatGLM四卡训练

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
              --train_path data/spo_0.json \
              --model_name_or_path ChatGLM-6B \
              --per_device_train_batch_size 1 \
              --max_len 1560 \
              --max_src_len 1024 \
              --learning_rate 1e-4 \
              --weight_decay 0.1 \
              --num_train_epochs 2 \
              --gradient_accumulation_steps 4 \
              --warmup_ratio 0.1 \
              --mode glm \
              --train_type all \
              --seed 1234 \
              --ds_file ds_zero3_offload.json \
              --gradient_checkpointing \
              --show_loss_step 10 \
              --output_dir ./output-glm

(2)、ChatGLM2四卡训练

通过CUDA_VISIBLE_DEVICES控制具体哪几块卡进行训练,如果不加该参数,表示使用运行机器上所有卡进行训练

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 520 train.py \
              --train_path data/spo_0.json \
              --model_name_or_path ChatGLM2-6B \
              --per_device_train_batch_size 1 \
              --max_len 1560 \
              --max_src_len 1024 \
              --learning_rate 1e-4 \
              --weight_decay 0.1 \
              --num_train_epochs 2 \
              --gradient_accumulation_steps 4 \
              --warmup_ratio 0.1 \
              --mode glm2 \
              --train_type all \
              --seed 1234 \
              --ds_file ds_zero3_no_offload.json \
              --gradient_checkpointing \
              --show_loss_step 10 \
              --output_dir ./output-glm2

(3)、耗费显存资源占用对比—全参方法:对比ChaGLMChaGLM2

PS:ChatGLM微调时所用显存要比ChatGLM2多,详细显存占比如下:

Model DeepSpeed-Stage Offload Gradient Checkpointing Batch Size Max Length GPU-A40 Number 所耗显存
ChaGLM zero3 Yes Yes 1 1560 4 33G
ChaGLM2 zero3 No Yes 1 1560 4 44G
ChaGLM2 zero3 Yes Yes 1 1560 4 26G

后面补充DeepSpeed的Zero-Stage的相关内容说明。

多种微调技巧结果对比:PT-only-Embedding(37G【显卡占用】,53m【训练耗时】+3m【测试耗时】)、PT(30G,135m+3m)、Freeze(24G,112m+3m)、Lora(39G,65m+4m)四种微调结果

ChatGLM-Finetuning的案例应用

1、流水线并行训练案例:基于4张A800-80G+采用ChatGLM-6B模型+全量参数+基于DeepSpeed框架(ZeRO3的模型拆分技术)流水线实现

本项目代码采用了4张A800-80G进行训练(实际上2张卡也行),结果显示F1得分在0.55~0.65之间;虽然Lora、P-tuing等技术,使得13b模型也可以在单张A100上训练,但是如果模型参数量过大,单张显卡不足以加载训练模型时,流水线并行是必不可少的。

(1)、训练阶段:采用三元组数据进行模型训练及测试

训练脚本

CUDA_VISIBLE_DEVICES=0,1,2,3 deepspeed --master_port 5524 train_pipeline.py \

 --train_path data/spo_0.json \

 --model_name_or_path ./ChatGLM-6B/ \

 --per_device_train_batch_size 14 \

 --max_len 1024 \

 --max_src_len 512 \

 --num_train_epochs 5 \

 --gradient_accumulation_steps 1 \

 --seed 1234 \

 --show_loss_step 20 \

 --num_stages 4 \

 --save_model_step 100 \

 --output_dir ./output-glm-pp

(2)、推理阶段:模型转换脚本

由于pipeline训练时,模型存在的变量名称与原始模型有所区别,因此在推理阶段,如果采用原始模型结构时,需要将convert_model_to_hf.py文件中,保存模型进行变量名称转换。

模型转化代码

模型转化代码如下所示

model_static_dict = {}

for path in Path(pipeline_model_dir).iterdir():

    print("已经处理文件:{}".format(path))

    if not path.name.startswith('layer'):

        continue

    small_static_dict = torch.load(path, map_location="cpu")

    layer_i = int(path.name.split('-')[0].replace('layer_', ''))

    if layer_i == 0:

        model_static_dict["transformer.word_embeddings.weight"] = small_static_dict["word_embeddings.weight"]

    elif layer_i == 30:

        model_static_dict["lm_head.weight"] = small_static_dict["word_embeddings.weight"]

    elif layer_i == 29:

        for k, v in small_static_dict.items():

            model_static_dict["transformer." + k] = v

    else:

        for k, v in small_static_dict.items():

            model_static_dict["transformer." + k.replace("layer.", "layers.{}.".format(layer_i - 1))] = v

torch.save(model_static_dict, join(save_model_dir, "pytorch_model.bin"))

推理脚本

python3 convert_model_to_hf.py \

 --ori_model_dir ./ChatGLM-6B/ \

 --pipeline_model_dir output-glm-pp/global_step300/ \

 --save_model_dir output-glm-pp/gs300/

(3)、结果对比

显卡实时占比:每张卡依次占比55/80G、80/80G、80/80G、70/80G

F1得分在0.59左右

步数 300 400 500
F1值 0.5882 0.5793 0.5874

猜你喜欢

转载自blog.csdn.net/qq_41185868/article/details/132613495